Basic support for some foveon cams (SD1, SD1 Merrill, DP1 Merrill, DP2 Merrill, DP3 Merrill, SD14), Issue 2729

This commit is contained in:
Ingo 2015-04-17 16:27:38 +02:00
parent c7162b9430
commit 16d0841f1e
21 changed files with 147 additions and 38 deletions

View File

@ -38,6 +38,7 @@ Other contributors (profiles, ideas, mockups, testing, forum activity, translati
Thorsten Bartolomäus Thorsten Bartolomäus
Patrik Brunner Patrik Brunner
Fernando Carello Fernando Carello
Rodrigo Nuno Bragança da Cunha
Pat David Pat David
Reine Edvardsson Reine Edvardsson
André Gauthier André Gauthier

View File

@ -1139,6 +1139,38 @@ Quality X: unknown, ie we knowing to little about the camera properties to know
} }
}, },
{ // Quality c, corrections for frame size, black level not declared properly
"make_model": "Sigma SD14",
"dcraw_matrix": [ 16411,-4764,-2383,8110,2603,-645,3135,3878,1984 ], // experimental inverted icc wp12 - build with BL=15
// "dcraw_matrix": [ 13804,-4156,-1896,6917,1909,-431,2768,2989,1741 ], // experimental inverted icc wp10 - build with BL=15
"ranges": { "black": 15, "white": 4080 },// peripheral black stripes give BL around 37
"raw_crop": [ 18, 12, 2652, 1768 ]
},
{ // Quality c, correction for frame width
"make_model": "Sigma SD1",
"dcraw_matrix": [ 5270,42,-814,3737,5506,124,1112,9714,4510 ], // experimental from icm 1.04477,-0.74838,1.01617, -0.54028,2.52690,-3.83257, 0.54869,-0.69556,3.73746
"ranges": { "black": 16, "white": 4070 },// BL is 16 or 31, should be measured at the horizontal black stripe at the top
"raw_crop": [ 12, 52, -110, -8 ]
},
{ // Quality C, correction for frame width, color matrix investigated ..
"make_model": "Sigma SD1 Merrill",
"dcraw_matrix": [ 7211,-1577,-769,4996,3428,440,2717,7117,4699 ], // experimental inverted icc cloudy8140 d65
// "dcraw_matrix": [ 5666,139,-892,3780,5428,270,1366,9757,4526 ], // experimental inverted icc sunny8161
// "dcraw_matrix": [ 10288,-2449,-1718,8976,1868,-1608,7011,5039,-249 ], // experimental inverted icc tungsten8130 wp11
// "dcraw_matrix": [ 5864,679,-1491,2963,7635,-919,-640,13738,2790 ], // experimental inverted icc sunny8160
// "dcraw_matrix": [ 14032,-2231,-1016,-5263,14816,170,-112,183,9113 ], // hardcoded
"ranges": { "black": 16, "white": 4070 }, // BL is 16 or 31, should be measured at the horizontal black stripe at the top
"raw_crop": [ 12, 52, -110, -8 ] // for small size all numbers/2
},
{ // Quality C, correction for frame width, color matrix guessed ..
"make_model": [ "Sigma DP1 Merrill", "Sigma DP2 Merrill", "Sigma DP3 Merrill" ],
"dcraw_matrix": [ 7211,-1577,-769,4996,3428,440,2717,7117,4699 ], // copy fron SD1 Merrill icc cloudy8140 d65
"ranges": { "black": 16, "white": 4070 }, // BL is 16 or 31, should be measured at the horizontal black stripe at the bottom
"raw_crop": [ 12, 0, -110, -62 ] // for small size all numbers/2
},
{ // Quality A, correction for color matrix from Colin Walker's d50 to dng d65 { // Quality A, correction for color matrix from Colin Walker's d50 to dng d65
"make_model": "Sony NEX-C3", "make_model": "Sony NEX-C3",
// "dcraw_matrix": [ 5130,-1055,-269,-4473,11797,3050,-701,1310,7121 ], // Colin walker's d50 kept for possible consistency issues // "dcraw_matrix": [ 5130,-1055,-269,-4473,11797,3050,-701,1310,7121 ], // Colin walker's d50 kept for possible consistency issues

View File

@ -3255,7 +3255,7 @@ void CLASS foveon_sd_load_raw()
pred[c] += diff[dindex->leaf]; pred[c] += diff[dindex->leaf];
if (pred[c] >> 16 && ~pred[c] >> 16) derror(); if (pred[c] >> 16 && ~pred[c] >> 16) derror();
} }
FORC3 image[row*width+col][c] = pred[c]; FORC3 image[row*width+col][c] = pred[c] < 0 ? 0 : pred[c];
} }
} }
} }
@ -8306,6 +8306,7 @@ void CLASS identify()
if (height > width) pixel_aspect = 2; if (height > width) pixel_aspect = 2;
filters = 0; filters = 0;
simple_coeff(0); simple_coeff(0);
adobe_coeff (make, model);
} else if (!strcmp(make,"Canon") && tiff_bps == 15) { } else if (!strcmp(make,"Canon") && tiff_bps == 15) {
switch (width) { switch (width) {
case 3344: width -= 66; case 3344: width -= 66;

View File

@ -1,5 +1,5 @@
--- dcraw.c 2014-07-24 16:15:36.700261700 +0200 --- dcraw.c 2015-04-17 13:02:57 +0000
+++ dcraw.cc 2015-02-10 18:21:01.213732653 +0100 +++ dcraw.cc 2015-04-17 13:09:41 +0000
@@ -1,3 +1,15 @@ @@ -1,3 +1,15 @@
+/*RT*/#include <glib.h> +/*RT*/#include <glib.h>
+/*RT*/#include <glib/gstdio.h> +/*RT*/#include <glib/gstdio.h>
@ -647,6 +647,15 @@
struct decode *cur; struct decode *cur;
int i, len; int i, len;
@@ -2960,7 +3255,7 @@
pred[c] += diff[dindex->leaf];
if (pred[c] >> 16 && ~pred[c] >> 16) derror();
}
- FORC3 image[row*width+col][c] = pred[c];
+ FORC3 image[row*width+col][c] = pred[c] < 0 ? 0 : pred[c];
}
}
}
@@ -3571,6 +3866,8 @@ @@ -3571,6 +3866,8 @@
if (load_raw == &CLASS phase_one_load_raw || if (load_raw == &CLASS phase_one_load_raw ||
load_raw == &CLASS phase_one_load_raw_c) load_raw == &CLASS phase_one_load_raw_c)
@ -1375,7 +1384,15 @@
case 34892: load_raw = &CLASS lossy_dng_load_raw; break; case 34892: load_raw = &CLASS lossy_dng_load_raw; break;
default: load_raw = 0; default: load_raw = 0;
} }
@@ -8347,7 +8385,7 @@ @@ -8268,6 +8306,7 @@
if (height > width) pixel_aspect = 2;
filters = 0;
simple_coeff(0);
+ adobe_coeff (make, model);
} else if (!strcmp(make,"Canon") && tiff_bps == 15) {
switch (width) {
case 3344: width -= 66;
@@ -8347,7 +8386,7 @@
width -= 44; width -= 44;
} else if (!strcmp(model,"D3200") || } else if (!strcmp(model,"D3200") ||
!strcmp(model,"D600") || !strcmp(model,"D600") ||
@ -1384,7 +1401,7 @@
width -= 46; width -= 46;
} else if (!strcmp(model,"D4") || } else if (!strcmp(model,"D4") ||
!strcmp(model,"Df")) { !strcmp(model,"Df")) {
@@ -8567,24 +8605,53 @@ @@ -8567,24 +8606,53 @@
if (load_raw == &CLASS lossless_jpeg_load_raw) if (load_raw == &CLASS lossless_jpeg_load_raw)
load_raw = &CLASS hasselblad_load_raw; load_raw = &CLASS hasselblad_load_raw;
if (raw_width == 7262) { if (raw_width == 7262) {
@ -1440,7 +1457,7 @@
} else if (raw_width == 4090) { } else if (raw_width == 4090) {
strcpy (model, "V96C"); strcpy (model, "V96C");
height -= (top_margin = 6); height -= (top_margin = 6);
@@ -8637,6 +8704,7 @@ @@ -8637,6 +8705,7 @@
filters = 0x16161616; filters = 0x16161616;
} }
} else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) { } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) {
@ -1448,7 +1465,7 @@
if ((flen - data_offset) / (raw_width*8/7) == raw_height) if ((flen - data_offset) / (raw_width*8/7) == raw_height)
load_raw = &CLASS panasonic_load_raw; load_raw = &CLASS panasonic_load_raw;
if (!load_raw) { if (!load_raw) {
@@ -8654,6 +8722,7 @@ @@ -8654,6 +8723,7 @@
} }
filters = 0x01010101 * (uchar) "\x94\x61\x49\x16" filters = 0x01010101 * (uchar) "\x94\x61\x49\x16"
[((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3]; [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3];
@ -1456,7 +1473,7 @@
} else if (!strcmp(model,"C770UZ")) { } else if (!strcmp(model,"C770UZ")) {
height = 1718; height = 1718;
width = 2304; width = 2304;
@@ -8883,6 +8952,14 @@ @@ -8883,6 +8953,14 @@
memcpy (rgb_cam, cmatrix, sizeof cmatrix); memcpy (rgb_cam, cmatrix, sizeof cmatrix);
raw_color = 0; raw_color = 0;
} }
@ -1471,7 +1488,7 @@
if (raw_color) adobe_coeff (make, model); if (raw_color) adobe_coeff (make, model);
if (load_raw == &CLASS kodak_radc_load_raw) if (load_raw == &CLASS kodak_radc_load_raw)
if (raw_color) adobe_coeff ("Apple","Quicktake"); if (raw_color) adobe_coeff ("Apple","Quicktake");
@@ -8899,7 +8976,7 @@ @@ -8899,7 +8977,7 @@
if (!tiff_bps) tiff_bps = 12; if (!tiff_bps) tiff_bps = 12;
if (!maximum) maximum = (1 << tiff_bps) - 1; if (!maximum) maximum = (1 << tiff_bps) - 1;
if (!load_raw || height < 22 || width < 22 || if (!load_raw || height < 22 || width < 22 ||
@ -1480,7 +1497,7 @@
is_raw = 0; is_raw = 0;
#ifdef NO_JASPER #ifdef NO_JASPER
if (load_raw == &CLASS redcine_load_raw) { if (load_raw == &CLASS redcine_load_raw) {
@@ -8978,195 +9055,250 @@ @@ -8978,195 +9056,250 @@
} }
#endif #endif
@ -1906,7 +1923,7 @@
struct tiff_tag { struct tiff_tag {
ushort tag, type; ushort tag, type;
int count; int count;
@@ -9188,585 +9320,12 @@ @@ -9188,585 +9321,12 @@
unsigned gps[26]; unsigned gps[26];
char desc[512], make[64], model[64], soft[32], date[20], artist[64]; char desc[512], make[64], model[64], soft[32], date[20], artist[64];
}; };

View File

@ -121,7 +121,7 @@ void dfInfo::updateRawImage()
int H = ri->get_height(); int H = ri->get_height();
int W = ri->get_width(); int W = ri->get_width();
ri->compress_image(); ri->compress_image();
int rSize = W*((ri->getSensorType()!=ST_NONE)?1:3); int rSize = W*((ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS)?1:3);
acc_t **acc = new acc_t*[H]; acc_t **acc = new acc_t*[H];
for( int row=0; row<H;row++) for( int row=0; row<H;row++)
acc[row] = new acc_t[rSize ]; acc[row] = new acc_t[rSize ];
@ -137,7 +137,7 @@ void dfInfo::updateRawImage()
if( !temp->loadRaw(true)){ if( !temp->loadRaw(true)){
temp->compress_image(); //\ TODO would be better working on original, because is temporary temp->compress_image(); //\ TODO would be better working on original, because is temporary
nFiles++; nFiles++;
if( ri->getSensorType()!=ST_NONE ){ if( ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS ){
for( int row=0; row<H;row++){ for( int row=0; row<H;row++){
for( int col=0; col < W;col++) for( int col=0; col < W;col++)
acc[row][col] += temp->data[row][col]; acc[row][col] += temp->data[row][col];
@ -174,7 +174,7 @@ void dfInfo::updateRawImage()
void dfInfo::updateBadPixelList( RawImage *df ) void dfInfo::updateBadPixelList( RawImage *df )
{ {
const float threshold=10.f/8.f; const float threshold=10.f/8.f;
if( ri->getSensorType()!=ST_NONE ){ if( ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS ){
std::vector<badPix> badPixelsTemp; std::vector<badPix> badPixelsTemp;
#pragma omp parallel #pragma omp parallel

View File

@ -57,7 +57,7 @@ void RawImageSource::processRawWhitepoint(float expos, float preser) {
if (fabs(preser)<0.001f) { if (fabs(preser)<0.001f) {
// No highlight protection - simple mutiplication // No highlight protection - simple mutiplication
if (ri->getSensorType()!=ST_NONE) if (ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS)
#pragma omp parallel for #pragma omp parallel for
for (int row=0;row<height;row++) for (int row=0;row<height;row++)
for (int col=0;col<width;col++) for (int col=0;col<width;col++)
@ -71,7 +71,7 @@ void RawImageSource::processRawWhitepoint(float expos, float preser) {
rawData[row][col*3+2] *= expos; rawData[row][col*3+2] *= expos;
} }
} else { } else {
if (ri->getSensorType()!=ST_NONE) { if (ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS) {
// Demosaic to allow calculation of luminosity. // Demosaic to allow calculation of luminosity.
if(ri->getSensorType()==ST_BAYER) if(ri->getSensorType()==ST_BAYER)
fast_demosaic (0,0,W,H); fast_demosaic (0,0,W,H);
@ -84,7 +84,7 @@ void RawImageSource::processRawWhitepoint(float expos, float preser) {
#pragma omp parallel #pragma omp parallel
{ {
float maxValFloatThr = 0.f; float maxValFloatThr = 0.f;
if (ri->getSensorType()!=ST_NONE) if (ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS)
#pragma omp for schedule(dynamic,16) nowait #pragma omp for schedule(dynamic,16) nowait
for(int row=0;row<height;row++) for(int row=0;row<height;row++)
for (int col=0;col<width;col++) { for (int col=0;col<width;col++) {
@ -95,7 +95,8 @@ void RawImageSource::processRawWhitepoint(float expos, float preser) {
#pragma omp for schedule(dynamic,16) nowait #pragma omp for schedule(dynamic,16) nowait
for(int row=0;row<height;row++) for(int row=0;row<height;row++)
for (int col=0;col<width;col++) { for (int col=0;col<width;col++) {
for (int c=0;c<3;c++) if (rawData[row][col*3+c]>maxValFloatThr) for (int c=0;c<3;c++)
if (rawData[row][col*3+c]>maxValFloatThr)
maxValFloatThr = rawData[row][col*3+c]; maxValFloatThr = rawData[row][col*3+c];
} }
@ -124,7 +125,7 @@ void RawImageSource::processRawWhitepoint(float expos, float preser) {
lut[(int)j] = exp(EV*((float)maxVal-j) / ((float)maxVal-K) * log(2.0)); lut[(int)j] = exp(EV*((float)maxVal-j) / ((float)maxVal-K) * log(2.0));
} }
if (ri->getSensorType()!=ST_NONE) if (ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS)
#pragma omp parallel for schedule(dynamic,16) #pragma omp parallel for schedule(dynamic,16)
for(int row=0;row<height;row++) for(int row=0;row<height;row++)
for(int col=0;col<width;col++){ for(int col=0;col<width;col++){

View File

@ -115,7 +115,7 @@ void ffInfo::updateRawImage()
int H = ri->get_height(); int H = ri->get_height();
int W = ri->get_width(); int W = ri->get_width();
ri->compress_image(); ri->compress_image();
int rSize = W*((ri->getSensorType()!=ST_NONE)?1:3); int rSize = W*((ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS)?1:3);
acc_t **acc = new acc_t*[H]; acc_t **acc = new acc_t*[H];
for( int row=0; row<H;row++) for( int row=0; row<H;row++)
acc[row] = new acc_t[rSize ]; acc[row] = new acc_t[rSize ];
@ -131,7 +131,7 @@ void ffInfo::updateRawImage()
if( !temp->loadRaw(true)){ if( !temp->loadRaw(true)){
temp->compress_image(); //\ TODO would be better working on original, because is temporary temp->compress_image(); //\ TODO would be better working on original, because is temporary
nFiles++; nFiles++;
if( ri->getSensorType()!=ST_NONE ){ if( ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS ){
for( int row=0; row<H;row++){ for( int row=0; row<H;row++){
for( int col=0; col < W;col++) for( int col=0; col < W;col++)
acc[row][col] += temp->data[row][col]; acc[row][col] += temp->data[row][col];

View File

@ -63,7 +63,7 @@ namespace rtengine {
ST_NONE, // use this value if the image is already demosaiced (i.e. not a raw file) ST_NONE, // use this value if the image is already demosaiced (i.e. not a raw file)
ST_BAYER, ST_BAYER,
ST_FUJI_XTRANS, ST_FUJI_XTRANS,
//ST_FOVEON, ST_FOVEON,
//ST_FUJI_EXR //ST_FUJI_EXR
} eSensorType; } eSensorType;

View File

@ -50,6 +50,8 @@ eSensorType RawImage::getSensorType() {
return ST_BAYER; return ST_BAYER;
else if (isXtrans()) else if (isXtrans())
return ST_FUJI_XTRANS; return ST_FUJI_XTRANS;
else if (isFoveon())
return ST_FOVEON;
return ST_NONE; return ST_NONE;
} }
@ -403,6 +405,25 @@ int RawImage::loadRaw (bool loadData, bool closeFile, ProgressListener *plistene
crop_masked_pixels(); crop_masked_pixels();
free (raw_image); free (raw_image);
raw_image=NULL; raw_image=NULL;
} else {
if (cc && cc->has_rawCrop()) { // foveon images
int lm, tm, w, h;
cc->get_rawCrop(lm, tm, w, h);
left_margin = lm;
top_margin = tm;
if (w < 0) {
width += w;
width -= left_margin;
} else if (w > 0) {
width = min((int)width,w);
}
if (h < 0) {
height += h;
height -= top_margin;
} else if (h > 0) {
height = min((int)height,h);
}
}
} }
// Load embedded profile // Load embedded profile
@ -534,9 +555,9 @@ float** RawImage::compress_image()
#pragma omp parallel for #pragma omp parallel for
for (int row = 0; row < height; row++) for (int row = 0; row < height; row++)
for (int col = 0; col < width; col++) { for (int col = 0; col < width; col++) {
this->data[row][3 * col + 0] = image[row * width + col][0]; this->data[row][3 * col + 0] = image[(row+top_margin) * iwidth + col+left_margin][0];
this->data[row][3 * col + 1] = image[row * width + col][1]; this->data[row][3 * col + 1] = image[(row+top_margin) * iwidth + col+left_margin][1];
this->data[row][3 * col + 2] = image[row * width + col][2]; this->data[row][3 * col + 2] = image[(row+top_margin) * iwidth + col+left_margin][2];
} }
} }
free(image); // we don't need this anymore free(image); // we don't need this anymore

View File

@ -110,6 +110,7 @@ protected:
int maximum_c4[4]; int maximum_c4[4];
bool isBayer() const { return (filters!=0 && filters!=9); } bool isBayer() const { return (filters!=0 && filters!=9); }
bool isXtrans() const { return filters==9; } bool isXtrans() const { return filters==9; }
bool isFoveon() const { return is_foveon; }
public: public:
@ -117,6 +118,10 @@ public:
std::string get_filename() const { return filename;} std::string get_filename() const { return filename;}
int get_width() const { return width; } int get_width() const { return width; }
int get_height() const { return height; } int get_height() const { return height; }
int get_iwidth() const { return iwidth; }
int get_iheight() const { return iheight; }
int get_leftmargin() const { return left_margin; }
int get_topmargin() const { return top_margin; }
int get_FujiWidth() const { return fuji_width; } int get_FujiWidth() const { return fuji_width; }
eSensorType getSensorType(); eSensorType getSensorType();

View File

@ -330,7 +330,7 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre
#pragma omp for #pragma omp for
#endif #endif
for (int ix=0; ix<imheight; ix++) { int i=sy1+skip*ix;if (i>=maxy-skip) i=maxy-skip-1; // avoid trouble for (int ix=0; ix<imheight; ix++) { int i=sy1+skip*ix;if (i>=maxy-skip) i=maxy-skip-1; // avoid trouble
if (ri->getSensorType()!=ST_NONE || ri->get_colors() == 1) { if (ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS || ri->get_colors() == 1) {
for (int j=0,jx=sx1; j<imwidth; j++,jx+=skip) {if (jx>=maxx-skip) jx=maxx-skip-1; // avoid trouble for (int j=0,jx=sx1; j<imwidth; j++,jx+=skip) {if (jx>=maxx-skip) jx=maxx-skip-1; // avoid trouble
float rtot,gtot,btot; float rtot,gtot,btot;
rtot=gtot=btot=0; rtot=gtot=btot=0;
@ -1118,6 +1118,8 @@ int RawImageSource::load (Glib::ustring fname, bool batch) {
if(ri->getSensorType()==ST_FUJI_XTRANS) if(ri->getSensorType()==ST_FUJI_XTRANS)
border = 7; border = 7;
else if(ri->getSensorType()==ST_FOVEON)
border = 0;
if ( ri->get_profile() ) if ( ri->get_profile() )
embProfile = cmsOpenProfileFromMem (ri->get_profile(), ri->get_profileLen()); embProfile = cmsOpenProfileFromMem (ri->get_profile(), ri->get_profileLen());
@ -1390,7 +1392,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
cfa_linedn(0.00002*(raw.bayersensor.linenoise)); cfa_linedn(0.00002*(raw.bayersensor.linenoise));
} }
if ( (raw.ca_autocorrect || fabs(raw.cared)>0.001 || fabs(raw.cablue)>0.001) && ri->getSensorType()!=ST_FUJI_XTRANS ) { // Auto CA correction disabled for X-Trans, for now... if ( (raw.ca_autocorrect || fabs(raw.cared)>0.001 || fabs(raw.cablue)>0.001) && ri->getSensorType() == ST_BAYER ) { // Auto CA correction disabled for X-Trans, for now...
if (plistener) { if (plistener) {
plistener->setProgressStr ("CA Auto Correction..."); plistener->setProgressStr ("CA Auto Correction...");
plistener->setProgress (0.0); plistener->setProgress (0.0);
@ -1707,7 +1709,7 @@ void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, Raw
{ {
unsigned short black[4]={ri->get_cblack(0),ri->get_cblack(1),ri->get_cblack(2),ri->get_cblack(3)}; unsigned short black[4]={ri->get_cblack(0),ri->get_cblack(1),ri->get_cblack(2),ri->get_cblack(3)};
if (ri->getSensorType()!=ST_NONE) { if (ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS) {
if (!rawData) if (!rawData)
rawData(W,H); rawData(W,H);
if (riDark && W == riDark->get_width() && H == riDark->get_height()) { // This works also for xtrans-sensors, because black[0] to black[4] are equal for these if (riDark && W == riDark->get_width() && H == riDark->get_height()) { // This works also for xtrans-sensors, because black[0] to black[4] are equal for these
@ -1953,7 +1955,7 @@ void RawImageSource::scaleColors(int winx,int winy,int winw,int winh, const RAWP
//adjust black level (eg Canon) //adjust black level (eg Canon)
bool isMono = false; bool isMono = false;
if (getSensorType()==ST_BAYER) { if (getSensorType()==ST_BAYER || getSensorType()==ST_FOVEON ) {
black_lev[0]=raw.bayersensor.black1;//R black_lev[0]=raw.bayersensor.black1;//R
black_lev[1]=raw.bayersensor.black0;//G1 black_lev[1]=raw.bayersensor.black0;//G1

View File

@ -330,7 +330,7 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
unsigned filter = ri->get_filters(); unsigned filter = ri->get_filters();
int firstgreen = 1; int firstgreen = 1;
// locate first green location in the first row // locate first green location in the first row
if(ri->getSensorType()!=ST_FUJI_XTRANS) if(ri->getSensorType()==ST_BAYER)
while (!FISGREEN(filter,1,firstgreen)) while (!FISGREEN(filter,1,firstgreen))
firstgreen++; firstgreen++;
@ -415,9 +415,14 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
} }
} }
} else { } else {
for (int row = 1, y = 0; row < height - 1 && y < tmph; row += vskip, y++) { int iwidth = ri->get_iwidth();
rofs = row * width; int iheight = ri->get_iheight();
for (int col = firstgreen, x = 0; col < width - 1 && x < tmpw; col += hskip, x++) { int left_margin = ri->get_leftmargin();
firstgreen += left_margin;
int top_margin = ri->get_topmargin();
for (int row = 1 + top_margin, y = 0; row < iheight + top_margin - 1 && y < tmph; row += vskip, y++) {
rofs = row * iwidth;
for (int col = firstgreen, x = 0; col < iwidth + left_margin - 1 && x < tmpw; col += hskip, x++) {
int ofs = rofs + col; int ofs = rofs + col;
tmpImg->r(y,x) = image[ofs][0]; tmpImg->r(y,x) = image[ofs][0];
tmpImg->g(y,x) = image[ofs][1]; tmpImg->g(y,x) = image[ofs][1];
@ -493,7 +498,7 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
tpp->aeHistogram[((int)(image[i* width+j][0]))>>tpp->aeHistCompression]+=gadd; tpp->aeHistogram[((int)(image[i* width+j][0]))>>tpp->aeHistCompression]+=gadd;
tpp->aeHistogram[((int)(image[i* width+j][0]))>>tpp->aeHistCompression]+=badd; tpp->aeHistogram[((int)(image[i* width+j][0]))>>tpp->aeHistCompression]+=badd;
} }
} else if(ri->getSensorType()!=ST_FUJI_XTRANS) { } else if(ri->getSensorType()==ST_BAYER) {
for (int j = start; j < end; j++) for (int j = start; j < end; j++)
if (FISGREEN(filter,i,j)) if (FISGREEN(filter,i,j))
tpp->aeHistogram[((int)(tpp->camwbGreen*image[i* width+j][1]))>>tpp->aeHistCompression]+=gadd; tpp->aeHistogram[((int)(tpp->camwbGreen*image[i* width+j][1]))>>tpp->aeHistCompression]+=gadd;
@ -501,7 +506,7 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
tpp->aeHistogram[((int)(tpp->camwbRed * image[i* width+j][0]))>>tpp->aeHistCompression]+=radd; tpp->aeHistogram[((int)(tpp->camwbRed * image[i* width+j][0]))>>tpp->aeHistCompression]+=radd;
else if (FISBLUE(filter,i,j)) else if (FISBLUE(filter,i,j))
tpp->aeHistogram[((int)(tpp->camwbBlue *image[i* width+j][2]))>>tpp->aeHistCompression]+=badd; tpp->aeHistogram[((int)(tpp->camwbBlue *image[i* width+j][2]))>>tpp->aeHistCompression]+=badd;
} else { } else if(ri->getSensorType()==ST_FUJI_XTRANS) {
for (int j = start; j < end; j++) for (int j = start; j < end; j++)
if (ri->ISXTRANSGREEN(i,j)) if (ri->ISXTRANSGREEN(i,j))
tpp->aeHistogram[((int)(tpp->camwbGreen*image[i* width+j][1]))>>tpp->aeHistCompression]+=gadd; tpp->aeHistogram[((int)(tpp->camwbGreen*image[i* width+j][1]))>>tpp->aeHistCompression]+=gadd;
@ -509,6 +514,12 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
tpp->aeHistogram[((int)(tpp->camwbRed * image[i* width+j][0]))>>tpp->aeHistCompression]+=radd; tpp->aeHistogram[((int)(tpp->camwbRed * image[i* width+j][0]))>>tpp->aeHistCompression]+=radd;
else if (ri->ISXTRANSBLUE(i,j)) else if (ri->ISXTRANSBLUE(i,j))
tpp->aeHistogram[((int)(tpp->camwbBlue *image[i* width+j][2]))>>tpp->aeHistCompression]+=badd; tpp->aeHistogram[((int)(tpp->camwbBlue *image[i* width+j][2]))>>tpp->aeHistCompression]+=badd;
} else /* if(ri->getSensorType()==ST_FOVEON) */{
for (int j = start; j < end; j++) {
tpp->aeHistogram[((int)(image[i* width+j][0]*2.f))>>tpp->aeHistCompression]+=radd;
tpp->aeHistogram[((int)(image[i* width+j][1]))>>tpp->aeHistCompression]+=gadd;
tpp->aeHistogram[((int)(image[i* width+j][2]*0.5f))>>tpp->aeHistCompression]+=badd;
}
} }
} }
@ -530,7 +541,7 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
start = 32; start = 32;
end = width - 32; end = width - 32;
} }
if(ri->getSensorType()!=ST_FUJI_XTRANS) { if(ri->getSensorType()==ST_BAYER) {
for (int j = start; j < end; j++) { for (int j = start; j < end; j++) {
if (!filter) { if (!filter) {
double d = tpp->defGain * image[i * width + j][0]; double d = tpp->defGain * image[i * width + j][0];
@ -560,7 +571,7 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
bn++; bn++;
} }
} }
} else { } else if(ri->getSensorType()==ST_FUJI_XTRANS) {
for (int j = start; j < end; j++) { for (int j = start; j < end; j++) {
if (ri->ISXTRANSGREEN(i,j)) { if (ri->ISXTRANSGREEN(i,j)) {
double d = tpp->defGain * image[i * width + j][1]; double d = tpp->defGain * image[i * width + j][1];
@ -584,6 +595,24 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
bn++; bn++;
} }
} }
} else /* if(ri->getSensorType()==ST_FOVEON) */ {
for (int j = start; j < end; j++) {
double d = tpp->defGain * image[i * width + j][0];
if (d <= 64000.) {
avg_r += d;
rn++;
}
d = tpp->defGain * image[i * width + j][1];
if (d <= 64000.) {
avg_g += d;
gn++;
}
d = tpp->defGain * image[i * width + j][2];
if (d <= 64000.) {
avg_b += d;
bn++;
}
}
} }
} }