/*
*/
/*
Copyright (C) 2014 Ferrero Andrea
This program 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.
This program 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 this program. If not, see .
*/
/*
These files are distributed with PhotoFlow - http://aferrero2707.github.io/PhotoFlow/
*/
#ifndef FAST_DEMOSAIC_XTRANS_H
#define FAST_DEMOSAIC_XTRANS_H
#include
//#include
#include "../base/operation.hh"
#include "../base/rawmatrix.hh"
#include
namespace PF
{
class FastDemosaicXTransPar: public OpParBase
{
bool normalize;
public:
FastDemosaicXTransPar();
bool has_intensity() { return false; }
bool has_opacity() { return false; }
bool needs_input() { return true; }
bool do_normalize() { return normalize; }
void set_normalize( bool n ) { normalize = n; }
void set_image_hints( VipsImage* img )
{
if( !img ) return;
OpParBase::set_image_hints( img );
rgb_image( get_xsize(), get_ysize() );
set_demand_hint( VIPS_DEMAND_STYLE_FATSTRIP );
}
/* Function to derive the output area from the input area
*/
virtual void transform(const VipsRect* rin, VipsRect* rout, int /*id*/)
{
rout->left = rin->left+5;
rout->top = rin->top+5;
rout->width = rin->width-10;
rout->height = rin->height-10;
}
/* Function to derive the area to be read from input images,
based on the requested output area
*/
virtual void transform_inv(const VipsRect* rout, VipsRect* rin, int /*id*/)
{
rin->left = rout->left-5;
rin->top = rout->top-5;
rin->width = rout->width+10;
rin->height = rout->height+10;
}
VipsImage* build(std::vector& in, int first,
VipsImage* imap, VipsImage* omap,
unsigned int& level);
};
template < OP_TEMPLATE_DEF >
class FastDemosaicXTransProc
{
public:
void render(VipsRegion** in, int n, int in_first,
VipsRegion* imap, VipsRegion* omap,
VipsRegion* out, FastDemosaicXTransPar* par)
{
//fast_demosaic( in, n, in_first,
// imap, omap, out, par );
}
};
#define fcol(r,c) ((int)(rawData[r].color(c)))
template < OP_TEMPLATE_DEF_TYPE_SPEC >
class FastDemosaicXTransProc< OP_TEMPLATE_IMP_TYPE_SPEC(float) >
{
public:
void render(VipsRegion** ir, int n, int in_first,
VipsRegion* imap, VipsRegion* omap,
VipsRegion* oreg, FastDemosaicXTransPar* par)
{
VipsRect *r = &oreg->valid;
int width = r->width;
int height = r->height;
//#ifndef NDEBUG
if(r->left==0)std::cout<<"fast_demosaic_xtrans(): left="<left<<" top="<top<im->Xsize, ir[in_first]->im->Ysize};
VipsRect r_raw = {r->left - 5, r->top - 5, r->width + 10, r->height + 10};
vips_rect_intersectrect (&r_raw, &r_img, &r_raw);
PF::RawMatrix rawData;
rawData.init( r_raw.width, r_raw.height, r_raw.top, r_raw.left );
for( int y = 0; y < r_raw.height; y++ ) {
PF::raw_pixel_t* ptr = ir ? (PF::raw_pixel_t*)VIPS_REGION_ADDR( ir[0], r_raw.left, y+r_raw.top ) : NULL;
rawData.set_row( y+r_raw.top, ptr );
}
int left = r->left;
int right = r->left + width - 1;
int top = r->top;
int bottom = r->top + height - 1;
for(int row = top; row <= bottom; row++) {
float* ptr = (float*)VIPS_REGION_ADDR( oreg, left, row );
for(int col = left, x = 0; col <= right; col++, x+= 3) {
float sum[3] = {0.f};
for(int v = -1; v <= 1; v++) {
for(int h = -1; h <= 1; h++) {
sum[fcol(row + v, col + h)] += rawData[row + v][(col + h)];
}
}
switch(fcol(row, col)) {
case 0:
ptr[x] = rawData[row][col];
ptr[x+1] = sum[1] * 0.2f;
ptr[x+2] = sum[2] * 0.33333333f;
break;
case 1:
ptr[x] = sum[0] * 0.5f;
ptr[x+1] = rawData[row][col];
ptr[x+2] = sum[2] * 0.5f;
break;
case 2:
ptr[x] = sum[0] * 0.33333333f;
ptr[x+1] = sum[1] * 0.2f;
ptr[x+2] = rawData[row][col];
break;
}
if( par->do_normalize() ) {
ptr[x] /= 65535.f;
ptr[x+1] /= 65535.f;
ptr[x+2] /= 65535.f;
}
if( row < 10 && col < 10 )
std::cout<<"r="<|