/* 
 *
 *  This file is part of DVD2AVI, a free MPEG-2 decoder
 *	
 *  DVD2AVI 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, or (at your option)
 *  any later version.
 *   
 *  DVD2AVI 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 GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *
 */

#ifndef DVD2AVI_INC_FILTERS_H
#define DVD2AVI_INC_FILTERS_H

#include "types.h"


void InitFilters();
void ApplyFilters(unsigned char* src[] = 0);
void KillFilters();
unsigned char* GetFilteredOutput();

//void Luminance_Filter(unsigned char *src, unsigned char *dst);

void conv420to422(int frame_type, unsigned char *src, unsigned char *dst);
void conv422to444(unsigned char *src, unsigned char *dst);
void conv444toRGB24odd(unsigned char *py, unsigned char *pu, unsigned char *pv, unsigned char *dst);
void conv444toRGB24even(unsigned char *py, unsigned char *pu, unsigned char *pv, unsigned char *dst);
void conv422toyuy2odd(unsigned char *py, unsigned char *pu, unsigned char *pv, unsigned char *dst);
void conv422toyuy2even(unsigned char *py, unsigned char *pu, unsigned char *pv, unsigned char *dst);

class ResamplingFunction 
{
public:
  virtual double f(double x) const = 0;
  virtual double support() const = 0;
};

class TriangleFilter : public ResamplingFunction 
{
public:
  double f(double x) const {
    x = fabs(x);
    return (x<1.0) ? 1.0-x : 0.0;
  }
  double support() const{ return 1.0; }
};

class MitchellNetravaliFilter : public ResamplingFunction 
{
  double p0,p2,p3,q0,q1,q2,q3;
public:
  MitchellNetravaliFilter(double b, double c) {
    p0 = (  6. -  2.*b        ) / 6.;
    p2 = (-18. + 12.*b +  6.*c) / 6.;
    p3 = ( 12. -  9.*b -  6.*c) / 6.;
    q0 = (	     8.*b + 24.*c) / 6.;
    q1 = (	  - 12.*b - 48.*c) / 6.;
    q2 = (	     6.*b + 30.*c) / 6.;
    q3 = (     -     b -  6.*c) / 6.;
  }
  double f(double x) const {
    x = fabs(x);
    return (x<1) ? (p0+x*x*(p2+x*p3)) : (x<2) ? (q0+x*(q1+x*(q2+x*q3))) : 0.0;
  }
  double support() const { return 2.0; }
};

class FilteredResizeH 
{
  int* /*const*/ pattern_luma;
  int* /*const*/ pattern_chroma;
  int original_width;
  unsigned char *tempY, *tempUV;
  int width;
  int height;
  StorageColorFormat m_ColorSpace;
public:
  FilteredResizeH(StorageColorFormat p_ColorSpace, int wi, int he, double subrange_left, double subrange_width, int target_width, const ResamplingFunction& func);
  void ResizeFrame(unsigned char* srcp, unsigned char* dstp, int src_pitch, int dst_pitch); 
  ~FilteredResizeH();
};

class FilteredResizeV  
{
  int* resampling_pattern;
  int *yOfs;
  int width;
  int height;
  StorageColorFormat m_ColorSpace;
public:
  FilteredResizeV(StorageColorFormat p_ColorSpace,int wi, int he, int subrange_top, int subrange_height, int target_height, const ResamplingFunction& func);
  void ResizeFrame(unsigned char* srcp, unsigned char* dstp, int src_pitch, int dst_pitch, int row_size);
  ~FilteredResizeV();
};

class YV12Resizer
{
	__int64* luma_pattern;
	__int64* chroma_pattern;
	int *luma_yOfs;
	int *chroma_yOfs;
	int filter;//1 for bilinear, 2 for bicubic
	int width,origine_width,origine_left,top;
	int height;
	int origine_height;
public:
	YV12Resizer(int wi, int he, int target_height,int top,int left,int right, ResamplingFunction * func);
	void ResizeFrame(unsigned char* src[], unsigned char* dstp);
	~YV12Resizer();
};


#endif
