/*
------------------------------------------------------------------------------
denef - Decode NEF image files
Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org)

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 2
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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
------------------------------------------------------------------------------
*/

#include <iostream.h>
#include <math.h>
#include <stdlib.h>

#include "interp.h"

static const char *rcsid="$Id: interp_basic.cc,v 1.2 2000/09/18 07:51:43 daniel Exp $";

// Basic interpolator - uses nearest neighbors.

basicInterpolator::basicInterpolator()
{
}

basicInterpolator::~basicInterpolator()
{
}

int
basicInterpolator::Fringe() const
{
    return 2;
}

int
basicInterpolator::Max_Width() const
{
    return 10000000;
}

int
basicInterpolator::Max_Height() const
{
    return 10000000;
}

void
basicInterpolator::Interpolate(const nefImageData &nef,
			       int xofs, int yofs,
			       int width, int height,
			       fullImageData &result,
			       int rxofs, int ryofs)
{
    /* This function takes a chunk of the NEF data and creates the decoded
       image from it.

       Very basic algorithm using neighbors
    */

    for (int y=0; y<height; ++y) {
	const short *pn  = nef.Data(xofs, yofs + y - 1);
	const short *p   = nef.Data(xofs, yofs + y    );
	const short *ps  = nef.Data(xofs, yofs + y + 1);

	bool green_pixel = (y & 1);

	double r,g,b;

	for (int x=0; x<width;
	     ++x, ++pn, ++p, ++ps, green_pixel = !green_pixel) {
	    if (green_pixel) {
		g = p[0];
		if (y & 1) {
		    r = (double)(p[-1] + p[1]) / 2.0;
		    b = (double)(pn[0] + ps[0]) / 2.0;
		} else {
		    b = (double)(p[-1] + p[1]) / 2.0;
		    r = (double)(pn[0] + ps[0]) / 2.0;
		}
	    } else {
		g = (double)(p[-1] + p[1] + pn[0] + ps[0]) / 4.0;
		double o = (double)(pn[-1] + pn[1] + ps[-1] + ps[1]) / 4.0;
		if (y & 1) {
		    r = p[0];
		    b = o;
		} else {
		    r = o;
		    b = p[0];
		}
	    }

	    rgbTriple &res = result(rxofs+x, ryofs+y);

	    res.r = r / (double)nef.Max_Value();
	    res.g = g / (double)nef.Max_Value();
	    res.b = b / (double)nef.Max_Value();
	}
    }

}

