dslinux/user/pixil/packages/dvdview/dvdview/oldlibgfx/libvideogfx/graphics/filters .cvsignore Makefile.am linear.cc linear.hh nonlin.cc nonlin.hh resize.cc resize.hh

amadeus dslinux_amadeus at user.in-berlin.de
Tue Oct 3 13:25:53 CEST 2006


Update of /cvsroot/dslinux/dslinux/user/pixil/packages/dvdview/dvdview/oldlibgfx/libvideogfx/graphics/filters
In directory antilope:/tmp/cvs-serv11916/packages/dvdview/dvdview/oldlibgfx/libvideogfx/graphics/filters

Added Files:
	.cvsignore Makefile.am linear.cc linear.hh nonlin.cc nonlin.hh 
	resize.cc resize.hh 
Log Message:
adding pristine copy of pixil to HEAD so I can branch from it

--- NEW FILE: .cvsignore ---
Makefile
Makefile.in
*.lo
_libs
.libs
.deps
libvideogfx-graphics-filters.la

--- NEW FILE: nonlin.hh ---
/*********************************************************************
  libvideogfx/graphics/filters/nonlin.hh

  purpose:
    Nonlinear filters:
    - Median YUV 3x3 - only luminance information is used to choose the
                       pixel to be copied. The color information will
		       simply be copied accordingly.

  notes:

  to do:

  author(s):
   - Dirk Farin, farin at ti.uni-mannheim.de
     University Mannheim, Dept. Circuitry and Simulation
     B 6,26 EG, room 0.10 / D-68131 Mannheim / Germany

  modifications:
    24/Aug/1999 - Dirk Farin - functions are not template functions
    21/Jul/1999 - Dirk Farin - cleanup and speed improvements of median filter
    29/Jun/1999 - Dirk Farin - first implementation of median filter
 *********************************************************************/

#ifndef LIBVIDEOGFX_GRAPHICS_FILTERS_NONLIN_HH
#define LIBVIDEOGFX_GRAPHICS_FILTERS_NONLIN_HH

#include "libvideogfx/graphics/basic/image.hh"

template <class Pel> void Median_YUV_3x3(const Image_YUV<Pel>& img,Image_YUV<Pel>& dest);

#endif

--- NEW FILE: Makefile.am ---
## Makefile.am for libvideogfx/libvideogfx/graphics/filters

noinst_LTLIBRARIES = libvideogfx-graphics-filters.la

libvideogfx_graphics_filters_la_SOURCES = \
	linear.cc	\
	linear.hh

INCLUDES = \
	-I$(top_srcdir)

.PHONY: files

files:
	@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
	  echo $$p; \
	done

--- NEW FILE: linear.hh ---
/*********************************************************************
  libvideogfx/graphics/filters/linear.hh

  purpose:
    linear filters:
    - LowPass ( 0 1 0 / 1 4 1 / 0 1 0 )
    - LowPass ( 1 1 1 / 1 1 1 / 1 1 1 )

  notes:

  to do:

  author(s):
   - Dirk Farin, farin at ti.uni-mannheim.de
     University Mannheim, Dept. Circuitry and Simulation
     B 6,26 EG, room 0.10 / D-68131 Mannheim / Germany

  modifications:
    21/Jul/1999 - Dirk Farin - first implementation
 *********************************************************************/

#ifndef LIBVIDEOGFX_GRAPHICS_FILTERS_LINEAR_HH
#define LIBVIDEOGFX_GRAPHICS_FILTERS_LINEAR_HH

#include "libvideogfx/graphics/basic/image.hh"
#include "libvideogfx/containers/array.hh"


/* Low-pass filtering is done using this kernel:

   1   /  0  1  0  \
   - * |  1  4  1  |
   8   \  0  1  0  /
*/
void LowPass_5pt(const Image_YUV<Pixel>& img,Image_YUV<Pixel>& dest);


/* Low-pass filtering is done using this kernel:

   1   /  1  1  1  \
   - * |  1  1  1  |
   9   \  1  1  1  /
*/
void LowPass_3x3mean(const Image_YUV<Pixel>& img,Image_YUV<Pixel>& dest);


template <class Pel> void ConvolveH(const Bitmap<Pel>& src,Bitmap<Pel>& dst,
				    const Array<double>& filter,bool useborder=true);
template <class Pel> void ConvolveV(const Bitmap<Pel>& src,Bitmap<Pel>& dst,
				    const Array<double>& filter,bool useborder=true);
template <class Pel> void ConvolveHV(const Bitmap<Pel>& src,Bitmap<Pel>& dst,
				     const Array<double>& filter,bool useborder=true);

void NormalizeFilter(Array<double>& filter); // Make coefficients sum up to 1.0 .


void CreateGaussFilter     (Array<double>& filter,double sigma,double cutoffval=0.01,bool normalize=true);
void CreateGaussDerivFilter(Array<double>& filter,double sigma,double cutoffval=0.01);

#endif

--- NEW FILE: linear.cc ---
/*
 *  linear.cc
 */

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

#include "linear.hh"


void LowPass_5pt(const Image_YUV<Pixel>& img,Image_YUV<Pixel>& dest)
{
  // Get image parameters and assure that they are in the right format.
  ImageParam_YUV param;
  img.GetParam(param);

  ImageParam_YUV param2;
  dest.GetParam(param2);

  assert(param.chroma ==Chroma444);
  assert(param2.chroma==Chroma444);
  assert(&img != &dest);  // Lowpass needs two image buffers for correct operation.

  // Give hint as the destination image will be completely overwritten.
  dest.Hint_ContentsIsNotUsedAnymore();


  Pixel*const* yp2  = dest.AskFrameY();
  Pixel*const* up2  = dest.AskFrameU();
  Pixel*const* vp2  = dest.AskFrameV();

  const Pixel*const* yp  = img.AskFrameY_const();
  const Pixel*const* up  = img.AskFrameU_const();
  const Pixel*const* vp  = img.AskFrameV_const();

  /* Do lowpass filtering.
     We filter all of the image except a one pixel wide border because the
     filter size is 3x3. This border will simply be copied from the original
     image.
  */
     
  int w = param.width;
  int h = param.height;

  for (int y=1;y<param.height-1;y++)
    for (int x=1;x<param.width-1;x++)
      {
	yp2[y][x] = (  yp[y-1][x  ] +
		       yp[y+1][x  ] +
		       yp[y  ][x-1] +
		       yp[y  ][x+1] +
		     4*yp[y  ][x  ]    +4)/8;
	up2[y][x] = (  up[y-1][x  ] +
 		       up[y+1][x  ] +
		       up[y  ][x-1] +
		       up[y  ][x+1] +
		     4*up[y  ][x  ]    +4)/8;
	vp2[y][x] = (  vp[y-1][x  ] +
		       vp[y+1][x  ] +
		       vp[y  ][x-1] +
		       vp[y  ][x+1] +
		     4*vp[y  ][x  ]    +4)/8;
      }

  // Copy border from old image to filtered one.

  for (int x=0;x<param.width;x++)
    {
      yp2[  0][x]=yp[  0][x]; up2[  0][x]=up[  0][x]; vp2[  0][x]=vp[  0][x];
      yp2[h-1][x]=yp[h-1][x]; up2[h-1][x]=up[h-1][x]; vp2[h-1][x]=vp[h-1][x];
    }

  for (int y=0;y<param.height;y++)
    {
      yp2[y][  0]=yp[y][  0]; up2[y][0  ]=up[y][  0]; vp2[y][  0]=vp[y][  0];
      yp2[y][w-1]=yp[y][w-1]; up2[y][w-1]=up[y][w-1]; vp2[y][w-1]=vp[y][w-1];
    }
}



void LowPass_3x3mean(const Image_YUV<Pixel>& img,Image_YUV<Pixel>& dest)
{
  // Get image parameters and assure that they are in the right format.
  ImageParam_YUV param;
  img.GetParam(param);

  ImageParam_YUV param2;
  dest.GetParam(param2);

  assert(param.chroma ==Chroma444);
  assert(param2.chroma==Chroma444);
  assert(&img != &dest);  // Lowpass needs two image buffers for correct operation.

  // Give hint as the destination image will be completely overwritten.
  dest.Hint_ContentsIsNotUsedAnymore();


  Pixel*const* yp2  = dest.AskFrameY();
  Pixel*const* up2  = dest.AskFrameU();
  Pixel*const* vp2  = dest.AskFrameV();

  const Pixel*const* yp  = img.AskFrameY_const();
  const Pixel*const* up  = img.AskFrameU_const();
  const Pixel*const* vp  = img.AskFrameV_const();

  /* Do lowpass filtering.
     We filter all of the image except a one pixel wide border because the
     filter size is 3x3. This border will simply be copied from the original
     image.
  */
     
  int w = param.width;
  int h = param.height;

  for (int y=1;y<param.height-1;y++)
    for (int x=1;x<param.width-1;x++)
      {
	yp2[y][x] = (  yp[y-1][x-1] +
		       yp[y-1][x  ] +
		       yp[y-1][x+1] +
		       yp[y  ][x-1] +
		       yp[y  ][x  ] +
		       yp[y  ][x+1] +
		       yp[y+1][x-1] +
		       yp[y+1][x  ] +
		       yp[y+1][x+1]    +4)/9;
	up2[y][x] = (  up[y-1][x-1] +
		       up[y-1][x  ] +
		       up[y-1][x+1] +
		       up[y  ][x-1] +
		       up[y  ][x  ] +
		       up[y  ][x+1] +
		       up[y+1][x-1] +
		       up[y+1][x  ] +
		       up[y+1][x+1]    +4)/9;
	vp2[y][x] = (  vp[y-1][x-1] +
		       vp[y-1][x  ] +
		       vp[y-1][x+1] +
		       vp[y  ][x-1] +
		       vp[y  ][x  ] +
		       vp[y  ][x+1] +
		       vp[y+1][x-1] +
		       vp[y+1][x  ] +
		       vp[y+1][x+1]    +4)/9;
      }

  // Copy border from old image to filtered one.

  for (int x=0;x<param.width;x++)
    {
      yp2[  0][x]=yp[  0][x]; up2[  0][x]=up[  0][x]; vp2[  0][x]=vp[  0][x];
      yp2[h-1][x]=yp[h-1][x]; up2[h-1][x]=up[h-1][x]; vp2[h-1][x]=vp[h-1][x];
    }

  for (int y=0;y<param.height;y++)
    {
      yp2[y][  0]=yp[y][  0]; up2[y][0  ]=up[y][  0]; vp2[y][  0]=vp[y][  0];
      yp2[y][w-1]=yp[y][w-1]; up2[y][w-1]=up[y][w-1]; vp2[y][w-1]=vp[y][w-1];
    }
}


template <class Pel> void ConvolveH(const Bitmap<Pel>& src,Bitmap<Pel>& dst,
				    const Array<double>& filter,bool useborder)
{
  int left = -filter.AskBase();
  int right=  filter.AskSize()-left-1;

  int border=0;
  if (useborder) border=src.AskBorderWidth();

  int xs = -border+left; if (xs<0) xs=0;
  int xe = src.AskWidth()-1+border-right; if (xe>src.AskWidth()-1) xe=src.AskWidth()-1;

  // cout << "H-Filtering from " << xs << " to " << xe << endl;

  int h = src.AskHeight();
  int borderw = src.AskBorderWidth();

  dst.Create(xe-xs+1,h,1,1,borderw);

  const double* f = filter.Data_const();

  const Pel*const* sp = src.AskFrame_const();
        Pel*const* dp = dst.AskFrame();

  for (int y=-borderw;y<h+borderw;y++)
    for (int x=xs;x<=xe;x++)
      {
	double sum=0.0;
	for (int xx=-left;xx<=right;xx++)
	  sum += f[xx]*sp[y][x+xx];
    
	dp[y][x-xs] = (Pel)sum;
      }
}


template <class Pel> void ConvolveV(const Bitmap<Pel>& src,Bitmap<Pel>& dst,
				    const Array<double>& filter,bool useborder)
{
  int top   = -filter.AskBase();
  int bottom=  filter.AskSize()-top-1;

  int border=0;
  if (useborder) border=src.AskBorderWidth();

  int ys = -border+top; if (ys<0) ys=0;
  int ye = src.AskHeight()-1+border-bottom; if (ye>src.AskHeight()-1) ye=src.AskHeight()-1;

  // cout << "V-Filtering from " << ys << " to " << ye << endl;

  int w = src.AskWidth();
  int borderw = src.AskBorderWidth();

  dst.Create(w,ye-ys+1,1,1,borderw);

  const double* f = filter.Data_const();

  const Pel*const* sp = src.AskFrame_const();
        Pel*const* dp = dst.AskFrame();

  for (int y=ys;y<=ye;y++)
    for (int x=-borderw;x<w+borderw;x++)
      {
	double sum=0.0;
	for (int yy=-top;yy<=bottom;yy++)
	  sum += f[yy]*sp[y+yy][x];
    
	dp[y-ys][x] = (Pel)sum;
      }
}


template <class Pel> void ConvolveHV(const Bitmap<Pel>& src,Bitmap<Pel>& dst,
				     const Array<double>& filter,bool useborder)
{
  Bitmap<Pel> tmpbm;
  ConvolveH(src,tmpbm,filter,useborder);
  ConvolveV(tmpbm,dst,filter,useborder);
}


void NormalizeFilter(Array<double>& filter)
{
  double sum=0.0;
  int i0 = filter.AskStartIdx();
  int i1 = filter.AskEndIdx();

  double* f = filter.Data();

  for (int i=i0;i<=i1;i++)
    sum += f[i];

  const double fact = 1.0/sum;

  for (int i=i0;i<=i1;i++)
    f[i] *= fact;
}


void CreateGaussFilter(Array<double>& filter,double sigma,double cutoffval,bool normalize)
{
#define MAXRANGE 100
  double filt[MAXRANGE];

  double minus_twosigma2inv = -1.0/(2*sigma*sigma);

  int lastidx=MAXRANGE-1;
  for (int i=0;i<MAXRANGE;i++)
    {
      filt[i] = exp(i*i*minus_twosigma2inv);

      if (filt[i] < cutoffval)
	{ lastidx = i-1; break; }
    }

  if (lastidx==MAXRANGE-1)
    throw "CreateGaussFilter(): Gauss filter is too wide.";

  filter.Create(2*lastidx+1 , -lastidx);
  double* f = filter.Data();

  for (int i=0;i<=lastidx;i++)
    f[-i]=f[i]=filt[i];

  if (normalize) NormalizeFilter(filter);
}


void CreateGaussDerivFilter(Array<double>& filter,double sigma,double cutoffval=0.01)
{
  CreateGaussFilter(filter,sigma,cutoffval,false);

  for (int i=filter.AskStartIdx();i<=filter.AskEndIdx();i++)
    filter.Data()[i] *= i;

  // normalize

  double sum=0.0;

  int i0 = filter.AskStartIdx();
  int i1 = filter.AskEndIdx();

  double* f = filter.Data();

  for (int i=i0;i<=i1;i++)
    sum += i*f[i];

  const double fact = 1.0/sum;

  for (int i=i0;i<=i1;i++)
    f[i] *= fact;
}


template class Array<double>;
template void ConvolveH (const Bitmap<Pixel>&,Bitmap<Pixel>&,const Array<double>&,bool);
template void ConvolveV (const Bitmap<Pixel>&,Bitmap<Pixel>&,const Array<double>&,bool);
template void ConvolveHV(const Bitmap<Pixel>&,Bitmap<Pixel>&,const Array<double>&,bool);

template void ConvolveH (const Bitmap<double>&,Bitmap<double>&,const Array<double>&,bool);
template void ConvolveV (const Bitmap<double>&,Bitmap<double>&,const Array<double>&,bool);
template void ConvolveHV(const Bitmap<double>&,Bitmap<double>&,const Array<double>&,bool);

#include "libvideogfx/containers/array.cc"

--- NEW FILE: resize.cc ---

#include "libvideogfx/graphics/filters/resize.hh"

void HalfSize_Subsample(const Image_YUV<Pixel>& img,Image_YUV<Pixel>& dest)
{












  // Get image parameters and assure that they are in the right format.
  ImageParam_YUV param;
  img.GetParam(param);

  ImageParam_YUV param2;
  dest.GetParam(param2);

  assert(param.chroma ==Chroma444);
  assert(param2.chroma==Chroma444);
  assert(&img != &dest);  // Lowpass needs two image buffers for correct operation.

  // Give hint as the destination image will be completely overwritten.
  dest.Hint_ContentsIsNotUsedAnymore();


  Pixel*const* yp2  = dest.AskFrameY();
  Pixel*const* up2  = dest.AskFrameU();
  Pixel*const* vp2  = dest.AskFrameV();

  const Pixel*const* yp  = img.AskFrameY_const();
  const Pixel*const* up  = img.AskFrameU_const();
  const Pixel*const* vp  = img.AskFrameV_const();

  /* Do lowpass filtering.
     We filter all of the image except a one pixel wide border because the
     filter size is 3x3. This border will simply be copied from the original
     image.
  */
     
  int w = param.width;
  int h = param.height;

  for (int y=1;y<param.height-1;y++)
    for (int x=1;x<param.width-1;x++)
      {
	yp2[y][x] = (  yp[y-1][x  ] +
		       yp[y+1][x  ] +
		       yp[y  ][x-1] +
		       yp[y  ][x+1] +
		     4*yp[y  ][x  ]    +4)/8;
	up2[y][x] = (  up[y-1][x  ] +
 		       up[y+1][x  ] +
		       up[y  ][x-1] +
		       up[y  ][x+1] +
		     4*up[y  ][x  ]    +4)/8;
	vp2[y][x] = (  vp[y-1][x  ] +
		       vp[y+1][x  ] +
		       vp[y  ][x-1] +
		       vp[y  ][x+1] +
		     4*vp[y  ][x  ]    +4)/8;
      }

  // Copy border from old image to filtered one.

  for (int x=0;x<param.width;x++)
    {
      yp2[  0][x]=yp[  0][x]; up2[  0][x]=up[  0][x]; vp2[  0][x]=vp[  0][x];
      yp2[h-1][x]=yp[h-1][x]; up2[h-1][x]=up[h-1][x]; vp2[h-1][x]=vp[h-1][x];
    }

  for (int y=0;y<param.height;y++)
    {
      yp2[y][  0]=yp[y][  0]; up2[y][0  ]=up[y][  0]; vp2[y][  0]=vp[y][  0];
      yp2[y][w-1]=yp[y][w-1]; up2[y][w-1]=up[y][w-1]; vp2[y][w-1]=vp[y][w-1];
    }
}


--- NEW FILE: nonlin.cc ---

#include "libvideogfx/graphics/filters/nonlin.hh"

struct SortData
{
  int val;
  int u,v;
};

template <class Pel> void Median_YUV_3x3(const Image_YUV<Pel>& img,Image_YUV<Pel>& dest)
{
  // Get image parameters and assure that they are in the right format.
  ImageParam_YUV param;
  img.GetParam(param);

  ImageParam_YUV param2;
  dest.GetParam(param2);

  const bool color = !(param.nocolor);

  if (color)
    {
      assert(param.chroma ==Chroma444);
      assert(param2.chroma==Chroma444);
    }
  assert(&img != &dest);  // Median needs two image buffers for correct operation.

  // Give hint as the destination image will be completely overwritten.
  dest.Hint_ContentsIsNotUsedAnymore();

  Pel*const* yp2  = dest.AskFrameY();
  Pel*const* up2  = (color ? dest.AskFrameU() : 0);
  Pel*const* vp2  = (color ? dest.AskFrameV() : 0);

  const Pel*const* yp  = img.AskFrameY_const();
  const Pel*const* up  = (color ? img.AskFrameU_const() : 0);
  const Pel*const* vp  = (color ? img.AskFrameV_const() : 0);

  SortData a[9];


  /* Do median filtering.
     We filter all of the image except a one pixel wide border because the
     filter size is 3x3. This border will simply be copied from the original
     image.
  */
     
  int w = param.width;
  int h = param.height;

  for (int y=1;y<param.height-1;y++)
    for (int x=1;x<param.width-1;x++)
      {
	// Fill array with filter kernel for sorting.

	a[0].val = yp[y-1][x-1];
	a[1].val = yp[y-1][x  ];
	a[2].val = yp[y-1][x+1];
	a[3].val = yp[y  ][x-1];
	a[4].val = yp[y  ][x  ];
	a[5].val = yp[y  ][x+1];
	a[6].val = yp[y+1][x-1];
	a[7].val = yp[y+1][x  ];
	a[8].val = yp[y+1][x+1];

	if (color)
	  {
	    a[0].u   = up[y-1][x-1];
	    a[0].v   = vp[y-1][x-1];
	    a[1].u   = up[y-1][x  ];
	    a[1].v   = vp[y-1][x  ];
	    a[2].u   = up[y-1][x+1];
	    a[2].v   = vp[y-1][x+1];
	    a[3].u   = up[y  ][x-1];
	    a[3].v   = vp[y  ][x-1];
	    a[4].u   = up[y  ][x  ];
	    a[4].v   = vp[y  ][x  ];
	    a[5].u   = up[y  ][x+1];
	    a[5].v   = vp[y  ][x+1];
	    a[6].u   = up[y+1][x-1];
	    a[6].v   = vp[y+1][x-1];
	    a[7].u   = up[y+1][x  ];
	    a[7].v   = vp[y+1][x  ];
	    a[8].u   = up[y+1][x+1];
	    a[8].v   = vp[y+1][x+1];
	  }

#if 0
	// --- Bubble Sort ---

	/* We only need 5 passes over the array because then the middle element of the
	   array keeps stable. */
	for (int i=0;i<5;i++)
	  for (int j=0;j<8-i;j++)
	    {
	      if (a[j].d.val>a[j+1].d.val)
		{
		  int m;
		  m = a[j].dummy; a[j].dummy=a[j+1].dummy; a[j+1].dummy=m;
		}
	    }

	// copy result into image

	yp2[y][x] = a[4].d.val;
	up2[y][x] = a[4].d.u;
	vp2[y][x] = a[4].d.v;
#endif

#if 1
	/* This is an alternative implementation of finding the median.
	   It works by sorting out the minimum and maximum element four times
	   which leaves the median.
	   This version is equivalent to the above bubble sort implementation
	   except ties (which could result in different chrominance information).
	   It is a little bit faster than the bubble sort.
	*/

	int last=8;
	for (int i=0;i<4;i++)
	  {
	    int maxid=0,maxval=a[0].val;
	    int minid=0,minval=a[0].val;

	    // Find minimum and maximum element.

	    for (int j=1;j<=last;j++)
	      {
		if (a[j].val > maxval) { maxval=a[j].val; maxid=j; }
		else if (a[j].val < minval) { minval=a[j].val; minid=j; }
	      }

	    // Compress the array by leaving out the two extreme elements.
	    if (minid==last)
	      {
		a[maxid]=a[last-1];
	      }
	    else
	      {
		a[maxid]=a[last  ];
		a[minid]=a[last-1];
	      }

	    last-=2;
	  }

	// copy result into image

	yp2[y][x] = a[0].val;
	if (color)
	  {
	    up2[y][x] = a[0].u;
	    vp2[y][x] = a[0].v;
	  }
#endif
      }

  // Copy border from old image to filtered one.

  for (int x=0;x<param.width;x++)
    {
      yp2[  0][x]=yp[  0][x]; if (color) { up2[  0][x]=up[  0][x]; vp2[  0][x]=vp[  0][x]; }
      yp2[h-1][x]=yp[h-1][x]; if (color) { up2[h-1][x]=up[h-1][x]; vp2[h-1][x]=vp[h-1][x]; }
    }

  for (int y=0;y<param.height;y++)
    {
      yp2[y][  0]=yp[y][  0]; if (color) { up2[y][0  ]=up[y][  0]; vp2[y][  0]=vp[y][  0]; }
      yp2[y][w-1]=yp[y][w-1]; if (color) { up2[y][w-1]=up[y][w-1]; vp2[y][w-1]=vp[y][w-1]; }
    }
}


--- NEW FILE: resize.hh ---
/*********************************************************************
  libvideogfx/graphics/filters/resize.hh

  purpose:

  notes:

  to do:

  author(s):
   - Dirk Farin, farin at ti.uni-mannheim.de
     University Mannheim, Dept. Circuitry and Simulation
     B 6,26 EG, room 0.10 / D-68131 Mannheim / Germany

  modifications:
    03/Aug/1999 - Dirk Farin - first implementation
 *********************************************************************/

#ifndef LIBVIDEOGFX_GRAPHICS_FILTERS_RESIZE_HH
#define LIBVIDEOGFX_GRAPHICS_FILTERS_RESIZE_HH

#include "libvideogfx/graphics/basic/image.hh"

void HalfSize_Subsample(const Image_YUV<Pixel>& img,Image_YUV<Pixel>& dest);

#endif




More information about the dslinux-commit mailing list