//     Classes ArrayAdapter           R. Ansari  05/98
// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA

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

// #include "ctimer.h"   Pour mesure TCPU 
#include "sopnamsp.h"
#include "nbtri.h"
#include "parradapter.h"

//++
// Class	P1DArrayAdapter
// Lib		PI
// include	parradapter.h
//
//	Adaptateur de tableaux 1-D . La méthode "Value(i)" doit être redéfinie
//	dans une classe dérivée.
//
//--
//++
// Links	Voir aussi
// P2DArrayAdapter
// P1DAdapter<T>
//--

//++
// Titre	Constructeur, méthodes
//--
//++
// P1DArrayAdapter(int sz)
//	Constructeur - Tableau 1D de taille "sz"
// double  Value(int i)
//	Retourne la valeur de l'element "i" - virtuelle pure - doit etre 
//	surchargee dans une classe derivee.
// int Size()
//	Retourne la taille du tableau
// void DefineXCoordinate(double x0, double dx)
//	Definition de l'axe des coordonnees correspondant a l'indice du tableau
//	a partir d'un offser "x0" et d'un increment "dx"
// double X(int i)
//	Retourne l'abcisse de l'element "i"
// int  DecodeOptionString(vector<string> & opt, bool rmdecopt=true)
//	Effectue le décodage des options du traceur à partir de "opt". Si "rmdecopt==true"
//	les options décodées sont supprimées du vecteur "opt". 
//	Retourne le nombre d'options décodées.
//	L'implémentation par défaut ne fait rien. Cette méthode est appelée par les drawers
//	utilisant l'objet. 
// int  OptionToString(vector<string> & opt) const
//	Méthode virtuelle qui peut être redéfinie dans les classes filles,
//	pour fournir des chaines de caracteres décodable par *DecodeOptionString()* .
//	Renvoie le nombre d'éléments ajoutés.
//	L'implémentation par défaut ne fait rien.
//--

/* --Methode-- */
P1DArrayAdapter::P1DArrayAdapter(int sz)
{
mSize=sz;
DefineXCoordinate(0, 1.);
}

/* --Methode-- */
P1DArrayAdapter::~P1DArrayAdapter()
{
}

/* --Methode-- */
void P1DArrayAdapter::DefineXCoordinate(double x0, double dx)
{
mOx = x0;  mDx = dx;
}

/* --Methode-- */
double P1DArrayAdapter::X(int i)
{
return(mOx+mDx*i);
}

/* --Methode-- */
int P1DArrayAdapter::DecodeOptionString(vector<string> & /* opt */, bool /*rmdecopt*/)
{
return 0;
}
/* --Methode-- */
int P1DArrayAdapter::OptionToString(vector<string> & /*opt*/) const
{
return 0;
}

//++
// Class	P2DArrayAdapter
// Lib		PI
// include	parradapter.h
//
//	Adaptateur de tableaux 2-D . La méthode "Value(i,j)" doit être redéfinie
//	dans une classe dérivée.
//
//--
//++
// Links	Voir aussi
// P1DArrayAdapter
// P2DAdapter<T>
//--

//++
// Titre	Constructeur, méthodes
//--
//++
// P2DArrayAdapter(int sx=0, int sy=0)
//	Constructeur - Tableau 2D "sx * sy"
// void ConfigureAxes(bool invx=false, bool invy=false, bool exy=false, \
//                    int sx=-1, int sy=-1)
//	Definit la configuration des axes - Les axes X et Y peuvent etre
//	inverses, et echanges. Si "sx" et "sy" sont positifs, ils definissent
//	les nouvelles valeurs de la taille du tableau.
// GetAxesConfiguration(bool& invx, bool& invy, bool& exy)
//	Renvoie la configuration des axes.
// DefineXYCoordinates(double x0, double y0, double dx, double dy)
//	Definit le systeme de coordonnees associe aux deux axes du tableau,
//	a partir d'un offser et d'un increment.
// double Value(int ix, int iy)
//	Renvoie la valeur du tableau en "(i,j)" - Doit etre definie par les 
//	classes derivees.
// void XYfromxy(int ix, int iy, double& x, double& y)
//	Coordonnees "x,y" a partir d'indice du tableau
// int  DecodeOptionString(vector<string> & opt, bool rmdecopt=true)
//	Effectue le décodage des options du traceur à partir de "opt". Si "rmdecopt==true"
//	les options décodées sont supprimées du vecteur "opt". 
//	Retourne le nombre d'options décodées.
//	L'implémentation par défaut ne fait rien. Cette méthode est appelée par les drawers
//	utilisant l'objet, ou par PIImage .
// int  OptionToString(vector<string> & opt) const
//	Méthode virtuelle qui peut être redéfinie dans les classes filles,
//	pour fournir des chaines de caracteres décodable par *DecodeOptionString()* .
//	Renvoie le nombre d'éléments ajoutés.
//	L'implémentation par défaut ne fait rien.
//--

/* --Methode-- */
P2DArrayAdapter::P2DArrayAdapter(int sx, int sy)
{
sX = sx; sY = sy; 
sgnX = sgnY = 1;
offX = offY = 0;
invX = invY = eXY = false;
DefineXYCoordinates(0.,0.,1.,1.);
SetInfoStringFunction(NULL);
}

/* --Methode-- */
P2DArrayAdapter::~P2DArrayAdapter()
{
}

/* --Methode-- */
void P2DArrayAdapter::ConfigureAxes(bool invx, bool invy, bool exy, int sx, int sy)
{
invX = invx;  invY = invy;  eXY = exy; 
if ( (sx > 0) && (sy > 0) )   { sX = sx; sY = sy; }
if (invX) { sgnX = -1;  offX = sX-1; } 
else { sgnX = 1; offX = 0; }
if (invY) { sgnY = -1;  offY = sY-1; } 
else { sgnY = 1; offY = 0; }
}

/* --Methode-- */
void P2DArrayAdapter::DefineXYCoordinates(double x0, double y0, double dx, double dy)
{
mOx = x0;   mOy = y0;
mDx = dx;   mDy = dy;
}

/* --Methode-- */
double  P2DArrayAdapter::MeanVal(int ix1, int ix2, int jy1, int jy2)
{
int ec;
if (ix1>ix2) { ec=ix1; ix1=ix2; ix2=ec; }
if (jy1>jy2) { ec=jy1; jy1=jy2; jy2=ec; }    
// On calcule la somme des pixels dans la zone
double ss = 0.;
for(int j=jy1; j<=jy2; j++) 
  for(int i=ix1; i<=ix2; i++)  ss += Value(i,j);

ss /= (double)((jy2-jy1+1)*(ix2-ix1+1));
return ss;  
}   

/* --Methode-- */
void P2DArrayAdapter::XYfromxy(int ix, int iy, double& x, double& y)
{
x = mOx+ix*mDx;
y = mOy+iy*mDy; 
}

static char ibuff[256];

/* --Methode-- */
char * P2DArrayAdapter::InfoString(int ix, int iy)
{
  double x,y;
  this->Coord(ix, iy, x, y);
  const char * isr = "";
  if (ISFunc != NULL)  isr = ISFunc(this, ix, iy);
  sprintf(ibuff,"X= %g Y= %g  Pix= %g %s   ", 
          x, y , (*this)(ix, iy), isr);
  return (ibuff);
}

/* --Methode-- */
int P2DArrayAdapter::CheckDyn(double& min, double& max, double& moy, double& sig, int& nbnul, int& nbsat, int vit)
{
// TIMEF ; 
double m = 0.;
double s = 0.;
double dv; 

int n9 = 0;
int n0 = 0;

if (min >= max) { min = -9.e69; max = 9.e69; }
double minpix = max;
double maxpix = min; 
double pixv;
// printf("DEBUG_CHECKDYN-IN %d - %g %g ", vit, min, max);

int n = 0;
if (vit < 1) vit = 1;
if (sX*sY/vit < 1000) {
  vit = sX*sY/1000;
  if (vit < 1) vit = 1;
}

// printf(" -> vit=%d \n", vit);
for(int j=0; j<sY; j++) 
  for(int i=0; i<sX; i++)   {
    if (++n % vit != 0)  continue;
    pixv = Value(i,j);
    if (pixv <= max && pixv >= min) {  
      if (pixv < minpix)  minpix = pixv;
      if (pixv > maxpix)  maxpix = pixv; 
      dv = (double)pixv;
      m += dv;  s += (dv*dv);
      }
    else  {  
      if (pixv > max)  n9++;
      if (pixv < min)  n0++; 
    }
  }

nbnul = n0*vit;  nbsat = n9*vit;
min = minpix;  max = maxpix; 

n -= (n0+n9);
if (n > 0)
  { dv = (double)n;  m /= dv;  s = s/dv - m*m;
  if (s>0.)  s = sqrt(s);  else s = 0.;
  moy = m;  sig = s; }
else { moy = 0.;  sig = -1.; }

// printf("DEBUG_CHECKDYN: %d %g %g - %g %g \n", n, min, max, moy, sig);
return(n);
}


/* --Methode-- */
void P2DArrayAdapter::ComputeLut_PicHisto(double& min, double& max, bool htail, 
					  double nbsig, double fracmax)
// htail = true --> on vire le pic et on garde la queue de l'histo
// htail = false --> on garde le pic le l'histo 
{
// TIMEF ; 
int MINNBIN = 64;
int MAXNBIN = 1024;

int nbin = sX*sY/10;
nbin = (nbin < MINNBIN) ? MINNBIN : ((nbin > MAXNBIN) ? MAXNBIN : nbin );
int vitesse = sX*sY / 50000;
vitesse = (vitesse < 1) ? 1 : ((vitesse > 25) ? 25 : vitesse );


//  Variable decrivant l'histogramme 
double minhis, maxhis, binwidth;
int under,over,tothis;
int_4 *phis;
int_4 *q;

double MINDYNAMIC = 1.e-48;          /* Gamme dynamique minimale (MaxAff-MinAff)*/
double FRACPIC = 0.6065;            /*  Valeur de exp(-0.5)   */



if ( min >= (max-MINDYNAMIC) ) { 
  int nbnul, nbsat, nok;
  double moy, sig; 
  nok = CheckDyn(min, max, moy, sig, nbnul, nbsat, vitesse);
  if (nok < 1) { min=0.; max = 1.;  return; }
  }
if ( min >= (max-MINDYNAMIC) )  max = min+MINDYNAMIC;
minhis = min;
maxhis = max;
binwidth = (maxhis-minhis) / nbin;
if (binwidth < MINDYNAMIC/MINNBIN) { 
  binwidth = MINDYNAMIC/MINNBIN;
  maxhis = nbin*binwidth + minhis;
  }
// printf("DEBUG nbin minhis maxhis binwidth = %d %g %g %g \n", nbin, minhis, maxhis, binwidth);

/* allocation dynamique de memoire et mise a zero de l'histogramme */
phis = new int_4[nbin];
for ( q=phis ; q<phis+nbin ; *q++ = 0 )  ;
under = over = tothis = 0;

//  Boucle sur les pixels   
//  Pour aller plus vite, on prend un pixel sur vitesse   
int kk = 0;
int bin;
for(int j=0; j<sY; j++)
  for(int i=0; i<sX; i++) {
    if ( (++kk % vitesse) != 0) continue;
   /* remplissage de l'histogramme */
    bin = (int)((Value(i, j) - minhis) / binwidth) ;
    if ( bin < 0 )  under++;
    else  {
      if (bin < nbin) { (*(phis+bin))++; tothis++; }
      else   over++; 
      }
    }     /*  Fin de for : Boucle sur les pixels   */

/*  On verifie qu'il y a eu une entree ds l'histo */
if (tothis <= 0)
  { delete[] phis;  return; }
  
/* recherche du maximum */
int binmax = -1 ; 
int hmax = -1 ; 
q = phis;
for (kk = 0 ; kk < nbin ;  kk++, q++ )
  if ( *(q) > hmax ) {hmax = *(q) ; binmax = kk ;}

if ( (binmax < 0) || (binmax >= nbin) )
  { delete[] phis;  return; }


/*   On va chercher le sigma du fond  SigmaLeft, SigmaRight */
int hmin = (int) ( (double)(hmax) * FRACPIC ) ;

int sigr = 0;
q = phis+binmax;
while ( ((*q) > hmin) && (sigr < (nbin-binmax)) )  { sigr++;  q++; }
if (sigr < 1) sigr = 1;
int sigl = 0;
q = phis+binmax;
while ( ((*q) > hmin) && (sigl < binmax) )  { sigl++; q--; }
if (sigl < 1) sigl = 1;

if (nbsig <= 0.) nbsig = 1.;
if (htail == false)  {  /*   On recherche le min/max autour du pic de l'histo  */
  if ( (bin = binmax-int(nbsig*sigl)) < 0 )  bin = 0;
  min = minhis + (double)bin*binwidth;
  if ( (bin = binmax+int(nbsig*sigr)) >= nbin ) bin = nbin-1;
  max = minhis + (double)bin*binwidth;
  if (max < (min+MINDYNAMIC))  max = min+MINDYNAMIC;
  delete[] phis;  return; 
  }

//  On recherche le min/max en supprimant le pic de l'histo  (la queue, > pic)
if ( (bin = binmax+int(nbsig*sigl)) >= nbin ) {
  min = minhis + binmax*binwidth;
  max = maxhis;
  if (max < (min+MINDYNAMIC))  max = min+MINDYNAMIC;
  delete[] phis;  return;
  }

min = minhis + bin*binwidth;

/*   Calcul du nb de pixel entre MinAff et ValSat  */
int nbpix = 0;
for( q = phis+bin ; q < phis+nbin ; q++)  nbpix += (*q);
nbpix = (int_4)((double)nbpix * fracmax);
int nbpix2 = 0; q = phis+bin; 
int k = bin;
while( (nbpix2 < nbpix) && (k < nbin) )  
  { nbpix2 += (*q); k++; q++; }

max = minhis + (double)k*binwidth;
delete[] phis;
if (max < (min+MINDYNAMIC))  max = min+MINDYNAMIC;

return;
}

/* --Methode-- */
int P2DArrayAdapter::ComputeLut_Range(double& min, double& max, double fracmin, double fracmax,int nmax)
// Compute min and max by throwing away the "fracmin" lowest values and the "fracmax" greatest values
// .."fracmin" in [0,1[  and   "fracmax" in [0,1[. If not they are set to zero.
// ..If min<max, use only the values inside [min,max]
// ..Maximum number values to be used is "nmax" (uniformly spread)
//     if "nmax" is in [-100,0[ take "-nmax%" values (-nmax/100*sX*sY)
//     if "nmax=0" or "nmax<-100" take all the values (sX*sY)
// ..If failed: min,max stay unchanged.
{
 int lp=0;
 if(fracmin<0. || fracmin>=1.) fracmin=0.;
 if(fracmax<0. || fracmax>=1.) fracmax=0.;
 if(nmax>=-100 && nmax<0) nmax = int(-nmax/100. * sX*sY);
 if(nmax<=2) nmax = sX*sY;

 int vit = sX*sY/nmax;  // Not too many values, we are using qsort !
 if(vit<1) vit = 1;
 // On recalcule nmax pour bien echantillonner le tableau:
 // ex: sX*sY=9999, nmax=5000 -> vit=1
 //     - si on ne recalcule pas nmax alors on echantillonne [0,5000[
 //          et on ne considere pas les 4999 dernieres valeurs!
 //     - si on recalcule nmax=sX*sY/vit=9999 on echantillonne tout le tableau
 //          le prix a payer: l'allocation varie entre nmax et 2*nmax-1
 nmax = sX*sY/vit;

 double *buff = new double[nmax+1]; // +1 pour protection si sX=sY=0

 if(lp) {printf("ComputeLut_Range: sX*sY=%d fracmin=%g fracmax=%g nmax=%d min=%g max=%g\n"
		,sX*sY,fracmin,fracmax,nmax,min,max); fflush(stdout);}

 int npix=0, nfill=0;
 for(int j=0;j<sY;j++) for(int i=0;i<sX;i++)   {
   if(nfill>=nmax) {j+=sY; break;} // On arrete completement: sortie bouble interne + j>sY
   if((npix++)%vit!=0) continue;
   double val = Value(i,j);
   if( min>=max || (val>=min && val<=max) ) buff[nfill++] = val;
 }

 if(nfill<=1) {delete [] buff; return nfill;}

 qsort(buff,(size_t) nfill,sizeof(double),qSort_Dble);

 int i1 = int(nfill*fracmin);       if(i1<0) i1=0;
 int i2 = int(nfill*(1.-fracmax));  if(i2>=nfill) i2=nfill-1;
 if(i2<=i1) {i1=0; i2=nfill-1;}
 if(buff[i1]<buff[i2]) {min=buff[i1]; max=buff[i2];}

 if(lp) {printf("   ...npix=%d nfill=%d [0]=%g [n]=%g min=[%d]=%g max=[%d]=%g\n"
		,npix,nfill,buff[0],buff[nfill-1],i1,min,i2,max); fflush(stdout);}

 delete [] buff;
 return(nfill);
}

/* --Methode-- */
void P2DArrayAdapter::ComputePixmap(LUT* lut, int ofx, int ofy, int zm, 
                                    int xwsz, int ywsz, PIPixColIdx & pixc)
{
// TIMEF ; 
int zmm=1;
int npx, npy, nppx, nppy;
int i,j,k,l;

/*
printf("Debug_ComputePixmap off= %d %d zm=%d Size=(%d,%d) \n", 
      ofx, ofy, zm, XSize(), YSize());
*/

if ( (XSize() <= 0) || (YSize() <= 0) || (lut == NULL) || (ofx < 0) || (ofy < 0) ) {
  pixc.DeAlloc();  return; 
}

npx = XSize()-ofx;
npy = YSize()-ofy;

if ((zm == 0) || (zm == -1))  zm = 1;

if (zm >= 1)
  {
  if (npx > (xwsz/zm))  npx = xwsz/zm; 
  if (npy > (ywsz/zm))  npy = ywsz/zm;
  nppx = npx*zm;   nppy = npy*zm;
  }
else
  {
  zmm = -zm;
  nppx = npx/zmm;   nppy = npy/zmm;
  if (nppx > xwsz)  nppx = xwsz; 
  if (nppy > ywsz)  nppy = ywsz;
  npx = nppx*zmm;   npy = nppy*zmm; 
  }


/* printf("Debug_ComputePixmap %d %d %d (%d-%d %d-%d)\n", 
      ofx, ofy, zm, npx,nppx, npy,nppy); */
if (lut->NCol() <= 256) {  // On fait un pixmap de type Byte/pixel 
/*
printf("Debug_ComputePixmap- pixc.AllocateByte() type=%d - %d %d %d - %d %d %d - %d %d %d \n",
  lut->Type(), 
  lut->ApplyFast(0.), lut->ApplyFast(1.), lut->ApplyFast(2.), 
  lut->ApplyRGB(0.), lut->ApplyRGB(1.), lut->ApplyRGB(2.), 
  lut->Apply(0.), lut->Apply(1.), lut->Apply(2.));
*/  
unsigned char *pp, ucp;
pixc.AllocateByte(nppx, nppy);
pp = pixc.BytePointer();
if (eXY) { // Echange Axe X,Y 
  if (zm == 1)  {  // Pas de zoom  
    for(j=ofy; j<ofy+npy; j++)
      for(i=ofx; i<ofx+npx; i++) 
        { *pp = (unsigned char) lut->ApplyFast( 
                this->Value(j*sgnX+offX, i*sgnY+offY));  
           pp++; }
    }
  else if (zm < -1) {       // Compression 
    for(j=ofy; j<ofy+npy; j+=zmm)
      for(i=ofx; i<ofx+npx; i+=zmm) { 
        *pp = lut->ApplyFast( MeanVal(j*sgnX+offX, (j+zmm-1)*sgnX+offX, 
                                      i*sgnY+offY, (i+zmm-1)*sgnY+offY) );
        pp++;
      }
    }
  else  {      // Agrandissement
    for(j=ofy; j<ofy+npy; j++)
      for(i=ofx; i<ofx+npx; i++)  {
        ucp = (unsigned char) lut->ApplyFast(this->Value(j*sgnX+offX, i*sgnY+offY));
        for(l=0; l<zm; l++)  {
          pp = pixc.BytePointer()+((j-ofy)*zm+l)*nppx+((i-ofx)*zm);
          for(k=0; k<zm; k++)  { *pp = ucp; pp++; }  
	  }
        }
    }
  }     // Fin du cas avec echange d'axe X/Y 
else {
  if (zm == 1)  {  // Pas de zoom  
    for(j=ofy; j<ofy+npy; j++)
      for(i=ofx; i<ofx+npx; i++) 
        { *pp = (unsigned char) lut->ApplyFast( 
                this->Value(i*sgnX+offX, j*sgnY+offY));  
           pp++; }
    }
  else if (zm < -1) {       // Compression 
    for(j=ofy; j<ofy+npy; j+=zmm)
      for(i=ofx; i<ofx+npx; i+=zmm) {
        *pp = lut->ApplyFast( MeanVal(i*sgnX+offX, (i+zmm-1)*sgnX+offX, 
                                      j*sgnY+offY, (j+zmm-1)*sgnY+offY) );
        pp++;
      }
    }
  else  {      // Agrandissement
    for(j=ofy; j<ofy+npy; j++)
      for(i=ofx; i<ofx+npx; i++)  {
        ucp = (unsigned char) lut->ApplyFast(this->Value(i*sgnX+offX, j*sgnY+offY));
        for(l=0; l<zm; l++)  {
          pp = pixc.BytePointer()+((j-ofy)*zm+l)*nppx+((i-ofx)*zm);
          for(k=0; k<zm; k++)  { *pp = ucp; pp++; }  
	  }
        }
    }
  }
}  //  ---- Fin pixmap de type Byte
else {  // On fait un pixmap de type short/pixel 
// printf("Debug_ComputePixmap- pixc.AllocateShort() \n");
unsigned short *pp, ucp;
pixc.AllocateShort(nppx, nppy);
pp = pixc.ShortPointer();
if (eXY) { // Echange Axe X,Y 
  if (zm == 1)  {  // Pas de zoom  
    for(j=ofy; j<ofy+npy; j++)
      for(i=ofx; i<ofx+npx; i++) {
        *pp = lut->ApplyFast(this->Value(j*sgnX+offX, i*sgnY+offY));  pp++; 
      }
    }
  else if (zm < -1) {       // Compression 
    for(j=ofy; j<ofy+npy; j+=zmm)
      for(i=ofx; i<ofx+npx; i+=zmm) { 
        *pp = lut->ApplyFast( MeanVal(j*sgnX+offX, (j+zmm-1)*sgnX+offX, 
                                      i*sgnY+offY, (i+zmm-1)*sgnY+offY) );
        pp++;
      }
    }
  else  {      // Agrandissement
    for(j=ofy; j<ofy+npy; j++)
      for(i=ofx; i<ofx+npx; i++)  {
        ucp = lut->ApplyFast(this->Value(j*sgnX+offX, i*sgnY+offY));
        for(l=0; l<zm; l++)  {
          pp = pixc.ShortPointer()+((j-ofy)*zm+l)*nppx+((i-ofx)*zm);
          for(k=0; k<zm; k++)  { *pp = ucp; pp++; }  
	  }
        }
    }
  }     // Fin du cas avec echange d'axe X/Y 
else {
  if (zm == 1)  {  // Pas de zoom  
    for(j=ofy; j<ofy+npy; j++)
      for(i=ofx; i<ofx+npx; i++) {
        *pp = lut->ApplyFast(this->Value(i*sgnX+offX, j*sgnY+offY));  pp++; 
      }
    }
  else if (zm < -1) {       // Compression 
    for(j=ofy; j<ofy+npy; j+=zmm)
      for(i=ofx; i<ofx+npx; i+=zmm) {
        *pp = lut->ApplyFast( MeanVal(i*sgnX+offX, (i+zmm-1)*sgnX+offX, 
                                      j*sgnY+offY, (j+zmm-1)*sgnY+offY) );
        pp++;
      }
    }
  else  {      // Agrandissement
    for(j=ofy; j<ofy+npy; j++)
      for(i=ofx; i<ofx+npx; i++)  {
        ucp = lut->ApplyFast(this->Value(i*sgnX+offX, j*sgnY+offY));
        for(l=0; l<zm; l++)  {
          pp = pixc.ShortPointer()+((j-ofy)*zm+l)*nppx+((i-ofx)*zm);
          for(k=0; k<zm; k++)  { *pp = ucp; pp++; }  
	  }
        }
    }
  }
}  //  ---- Fin pixmap de type Byte

return;
}

/* --Methode-- */
int P2DArrayAdapter::DecodeOptionString(vector<string> & /* opt */, bool /*rmdecopt*/)
{
return 0;
}
/* --Methode-- */
int P2DArrayAdapter::OptionToString(vector<string> & /*opt*/) const
{
return 0;
}


//++
// Class	P1DAdapter<T>
// Lib		PI
// include	parradapter.h
//
//	Adaptateur de tableaux 1-D, construit à partir d'un pointeur
//	"T* data"
//--
//++
// Links	Voir aussi
// P1DArrayAdapter
// P2DAdapter<T>
//--

//++
// Titre	Constructeur
//--
//++
// P1DAdapter<T>(T* data, int sz, bool ad=false)
//	Constructeur à partir d'un tableau "T* data", de taille "sz".
//	Si "ad==true", le destructeur libere l'espace mémoire de "data"
//	par delete. 
//--

//++
// Class	P2DAdapter<T>
// Lib		PI
// include	parradapter.h
//
//	Adaptateur de tableaux 2-D, construit a partir d'un pointeur
//	"T* data"
//--
//++
// Links	Voir aussi
// P2DArrayAdapter
// P1DAdapter<T>
//--

//++
// Titre	Constructeur
//--
//++
// P2DAdapter(T* data, int sx, int sy, bool ad=false)
//	Constructeur à partir d'un pointeur "T* data", représentant un
//	tableau 2D de taille "sx * sy".
//	Si "ad==true", le destructeur libere l'espace mémoire de "data"
//	par delete. 
//--
