Index: /trunk/SophyaPI/PI/lut.cc
===================================================================
--- /trunk/SophyaPI/PI/lut.cc	(revision 3544)
+++ /trunk/SophyaPI/PI/lut.cc	(revision 3545)
@@ -12,5 +12,17 @@
 #include "lut.h"
 
-
+//++
+// Class	LUT
+// Lib		PI
+// include	lut.h
+//
+//	Classe Look-Up table : transformation de valeurs (intensite/RGB) en index de couleur
+//--
+//++
+// Links	Voir aussi
+// PIColorMap
+// PIPixmap
+// PIImage
+//--
 /* --Methode-- */
 
@@ -80,6 +92,5 @@
   {
   int i;
-  double dx;
-  double dlx;
+  double dx, dlx, fmx;
   switch (typ)
     {
@@ -91,7 +102,13 @@
       break;
     case kLutType_Log :
-      dlx = log(max-min) / (double)nLevel;
+      fmx = (max-min)/(exp(1.)-1.);
+      dlx = 1./(double)nLevel;
       for(i=0; i<nLevel; i++)
-        bornes[i] = min+(double)exp((double)i*dlx);
+        bornes[i] = min+((double)exp((double)i*dlx)-1.)*fmx;
+      break;
+    case kLutType_Exp :
+      dlx = (exp(1.)-1.)/(double)nLevel;
+      for(i=0; i<nLevel; i++)
+        bornes[i] = min+(double)log(1.+(double)i*dlx)*(max-min);
       break;
     case kLutType_Sqrt :
@@ -114,5 +131,5 @@
 else  bornes[0] = 0.5*(min+max);
 // ComputeTable((ntable > nLevel) ? ntable : tablenbin);
-ComputeTable(0);
+if (type != kLutType_RGB) ComputeTable(0);
 return; 
 }
@@ -131,5 +148,5 @@
 
 /* --Methode-- */
-unsigned short LUT::Apply(double x)
+unsigned short LUT::ApplyI(double x)
 {
 int i;
@@ -154,5 +171,12 @@
 void LUT::ComputeTable(int nt)
 {
-if (nt <= 0) nt = 16*(nLevel+2);
+if (nt <= 0) { 
+  int fm = 16;
+  if ((nLevel+2)>4096) fm = 1;
+  else if ((nLevel+2)>2048) fm = 2;
+  else if ((nLevel+2)>1024) fm = 4;
+  else if ((nLevel+2)>512) fm = 8;
+  nt = fm*(nLevel+2);
+}
 else if (nt < (nLevel+2))  nt = (nLevel+2);
 tablenbin = nt;
@@ -161,4 +185,4 @@
 tablebinwidth = (Max()-Min())/(nt-2);
 double x = Min()+0.5*tablebinwidth;
-for(int i=0; i<nt-2; i++)  { table[i] = Apply(x); x += tablebinwidth; }
+for(int i=0; i<nt-2; i++)  { table[i] = ApplyI(x); x += tablebinwidth; }
 }
Index: /trunk/SophyaPI/PI/lut.h
===================================================================
--- /trunk/SophyaPI/PI/lut.h	(revision 3544)
+++ /trunk/SophyaPI/PI/lut.h	(revision 3545)
@@ -13,5 +13,5 @@
 
 // Type de lut possibles 
-enum {kLutType_Lin=1, kLutType_Log=2, kLutType_Sqrt=3, kLutType_Square=4, kLutType_RGB=11 };
+enum {kLutType_Lin=1, kLutType_Log=2, kLutType_Exp=3, kLutType_Sqrt=4, kLutType_Square=5, kLutType_RGB=11 };
 
 class LUT 
@@ -24,6 +24,10 @@
   void SetLut(double min, double max, int typ=kLutType_Lin);
   void Print();
-  unsigned short Apply(double x);
-  unsigned short ApplyRGB(double x);
+
+  inline unsigned short Apply(double x)
+    { 
+    if (type == kLutType_RGB) return ApplyRGB(x); 
+    else return ApplyI(x);	
+    } 
 
   inline unsigned short ApplyFast(double x)
@@ -42,4 +46,6 @@
 protected:
   void ComputeTable(int nt);
+  unsigned short ApplyI(double x);
+  unsigned short ApplyRGB(double x);
   inline unsigned short AppFast(double x)
     {
Index: /trunk/SophyaPI/PI/picmap.cc
===================================================================
--- /trunk/SophyaPI/PI/picmap.cc	(revision 3544)
+++ /trunk/SophyaPI/PI/picmap.cc	(revision 3545)
@@ -6,4 +6,5 @@
 #include "picmap.h"
 #include <iostream>
+
 
 //++
@@ -24,10 +25,10 @@
 //--
 
-#define  MXMAPIDS   33
+#define  MXMAPIDS   34
 static   int    MapNCols[MXMAPIDS] = {
   256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
   256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 
   256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
-  216, 512, 4096  };
+  216, 512, 4096, 32768  };
 
 // Tables de couleurs :
@@ -41,4 +42,5 @@
 // 1 Standard PI , 512 couleurs RGB (8x8x8)
 // 1 Standard PI , 4096 couleurs RGB (16x16x16)
+// 1 Standard PI , 32768 couleurs RGB (32x32x32)
 
 static   const char*  MapNoms[MXMAPIDS]  = {
@@ -51,5 +53,6 @@
                       "MIDAS_Stairs9","MIDAS_StairCase","MIDAS_Color",
                       "MIDAS_ManyCol","MIDAS_Idl14","MIDAS_Idl15",
- 		      "MultiCol16","MultiCol64","RGB216CM","RGB512CM","RGB4096CM"};
+ 		      "MultiCol16","MultiCol64",
+                      "RGB216CM","RGB512CM","RGB4096CM","RGB32768CM"};
 
 static   CMapId MapIds[MXMAPIDS] = { 
@@ -62,5 +65,6 @@
                       CMAP_MIDAS_Stairs9, CMAP_MIDAS_StairCase, CMAP_MIDAS_Color, 
                       CMAP_MIDAS_ManyCol, CMAP_MIDAS_Idl14, CMAP_MIDAS_Idl15, 
-                      CMAP_COL16, CMAP_COL64, CMAP_RGB216, CMAP_RGB512, CMAP_RGB4096, } ;
+                      CMAP_COL16, CMAP_COL64, 
+                      CMAP_RGB216, CMAP_RGB512, CMAP_RGB4096, CMAP_RGB32768} ;
 
 static   int mColTNums[8192];   // Max 8192 tables differentes pour le moment  
@@ -75,5 +79,5 @@
                                   NULL, NULL, NULL, NULL, NULL, 
                                   NULL, NULL, NULL, NULL, NULL,
-                                  NULL, NULL, NULL,  };
+                                  NULL, NULL, NULL, NULL };
 
 int  PIColorMap::NumberStandardColorMaps()
@@ -130,7 +134,9 @@
 //|	CMAP_RGB512     :  512 couleurs, 8x8x8 couleurs en composantes RGB
 //|	CMAP_RGB4096    :  4096 couleurs, 16x16x16 couleurs en composantes RGB
+//|	CMAP_RGB4096    :  32768 couleurs, 32x32x32 couleurs en composantes RGB
 
 //	Toutes les tables de couleurs standard possèdent 256 cellules de couleurs,
-//	contenant 16 ou 32 ou 128 (ou 216) couleurs distinctes, sauf CMAP_RGB512 et CMAP_RGB4096.
+//	contenant 16 ou 32 ou 128 (ou 216) couleurs distinctes, 
+//	sauf CMAP_RGB512 , CMAP_RGB4096 et CMAP_RGB32768.
 //
 // PIColorMap(string const& nom, int nCol)
@@ -153,5 +159,6 @@
 
    if (NMaxTableAuto == 0) { //  Il faut allouer les tables de depart
-     if ( TotNbColors() > 4096 ) NMaxTableAuto = MXMAPIDS-1;
+     if ( TotNbColors() >= 4096 ) NMaxTableAuto = MXMAPIDS-2;
+     if ( TotNbColors() >= 65536 ) NMaxTableAuto = MXMAPIDS-1;
      else NMaxTableAuto = 3; 
      //     for(k=0; k<NMaxTableAuto; k++)  { 
@@ -167,5 +174,5 @@
    for(kdx=0; kdx<MXMAPIDS; kdx++)  if (id == MapIds[kdx])  break;
    if (kdx == MXMAPIDS)  { id = MapIds[0];  kdx = 0; }
-   for(k=0; k<NMaxTableAuto; k++) {
+   for(k=0; k<=NMaxTableAuto; k++) {
      if ((MapIds[k] == id) && (mMaps[k] == NULL))  { //  Table pas encore alloue 
        mnom = MapNoms[k]; 
@@ -185,7 +192,12 @@
        if ( mMaps[k] ) {  
          mColTNums[mMaps[k]->mCTId] = 1;  // Je force a liberer les couleurs 
-         delete mMaps[k] ;
+         delete mMaps[k] ;   mMaps[k] = NULL;
+         mnom = MapNoms[k]; 
+         cout << " PIColorMap::PIColorMap(CMapId id) Freeing colors for ColorMap " 
+	      << mnom << " ... " << endl;
        }
        mnom = MapNoms[kdx];
+       cout << " PIColorMap::PIColorMap(CMapId id) Allocating ColorMap " 
+	     << mnom << " ... " << endl;
        mMaps[k] = new PIColorMap(MapIds[kdx],  MapNCols[kdx], mnom); 
      }
@@ -592,7 +604,9 @@
     case CMAP_RGB512 :
     case CMAP_RGB4096 :
+    case CMAP_RGB32768 :
       {
       int nlev = 8;
-      if ( mType == CMAP_RGB4096)  nlev = 16;
+      if (mType == CMAP_RGB4096)  nlev = 16;
+      else if (mType == CMAP_RGB32768)  nlev = 32;
       int drgb = 65535/(nlev-1);
       i = 0;
Index: /trunk/SophyaPI/PI/picmap.h
===================================================================
--- /trunk/SophyaPI/PI/picmap.h	(revision 3544)
+++ /trunk/SophyaPI/PI/picmap.h	(revision 3545)
@@ -52,5 +52,6 @@
  CMAP_RGB216      = 993,        // 216 couleurs avec toutes les nuances RGB
  CMAP_RGB512      = 994,        // 512 couleurs avec toutes les nuances RGB
- CMAP_RGB4096     = 995         // 4096 couleurs avec toutes les nuances RGB
+ CMAP_RGB4096     = 995,        // 4096 couleurs avec toutes les nuances RGB
+ CMAP_RGB32768    = 996         // 32768 couleurs avec toutes les nuances RGB
  };
 
Index: /trunk/SophyaPI/PI/picmapview.cc
===================================================================
--- /trunk/SophyaPI/PI/picmapview.cc	(revision 3544)
+++ /trunk/SophyaPI/PI/picmapview.cc	(revision 3545)
@@ -79,5 +79,8 @@
   if ( cmap && (cmp->Type() == cmap->Type()) && (cmp->Type() != CMAP_OTHER)
        && (cmp->IsColorIndexReversed() == cmap->IsColorIndexReversed())
-       && (fabs(vmin-min) < 1.e-69)  && (fabs(vmax-max) > -1.e-69) )  return;
+       && (fabs(vmin-min) < 1.e-69)  && (fabs(vmax-max) > -1.e-69) )  { 
+    if (refr)  Refresh();      
+    return;
+  }
   if (cmap) delete cmap;
   cmap = new PIColorMap(*cmp);
@@ -93,5 +96,8 @@
        (cmap->IsColorIndexReversed() == revidx) &&
        ((vmin-min) < 1.e-69) &&  ((vmin-min) > -1.e-69) &&
-       ((vmax-max) < 1.e-69) &&  ((vmax-max) > -1.e-69) )  return;
+       ((vmax-max) < 1.e-69) &&  ((vmax-max) > -1.e-69) )  { 
+    if (refr)  Refresh();      
+    return;
+  }
   if (cmap) delete cmap;
   cmap = new PIColorMap(cmapid);
@@ -117,9 +123,12 @@
 
   int k;
+  // On limite le nombre de carres de couleurs traces, si trop de couleur ...
+  int dk = cmap->NCol()/128;
+  if (dk<1) dk=1;
   if (sx > sy) {    // horizontal
     int xc, dx;
     xc = 0;
-    for(k=0; k<cmap->NCol(); k++) {
-      dx = (sx-xc)/(cmap->NCol()-k);
+    for(k=0; k<cmap->NCol(); k+=dk) {
+      dx = dk*(sx-xc)/(cmap->NCol()-k);
       g->SelForeground((*cmap), k);
       g->DrawFBox(xc, 0, dx+1, sy);
@@ -130,6 +139,6 @@
     int yc, dy;
     yc = sy;
-    for(k=0; k<cmap->NCol(); k++) {
-      dy = yc/(cmap->NCol()-k);
+    for(k=0; k<cmap->NCol(); k+=dk) {
+      dy = dk*yc/(cmap->NCol()-k);
       yc -= dy;
       g->SelForeground((*cmap), k);
Index: /trunk/SophyaPI/PI/picmapx.cc
===================================================================
--- /trunk/SophyaPI/PI/picmapx.cc	(revision 3544)
+++ /trunk/SophyaPI/PI/picmapx.cc	(revision 3545)
@@ -187,4 +187,5 @@
   mColRGB = new PIColor[mNCol];
   mNewCol = new bool[mNCol];
+  /*   Remplace par memcpy pour performances, Reza, Nov 2008
   for (int i=0; i<mNCol; i++)  
     { mColors[i] = ((PIColorMapX *)x)->mColors[i];
@@ -192,3 +193,8 @@
 // C'est la table de couleur originale qui est responsable de liberer les couleurs - Reza 8/2/98
     mNewCol[i] = false; }  
-}
+  -> memcpy (Nov08) */
+  memcpy(mColors, ((PIColorMapX *)x)->mColors, sizeof(PIXColor)*mNCol);
+  memcpy(mColRGB, ((PIColorMapX *)x)->mColRGB, sizeof(PIColor)*mNCol);
+// C'est la table de couleur originale qui est responsable de liberer les couleurs - Reza 8/2/98
+  for (int i=0; i<mNCol; i++)   mNewCol[i] = false;
+}
Index: /trunk/SophyaPI/PI/piimage.cc
===================================================================
--- /trunk/SophyaPI/PI/piimage.cc	(revision 3544)
+++ /trunk/SophyaPI/PI/piimage.cc	(revision 3545)
@@ -628,4 +628,5 @@
       if (opts.substr(4,3) == "lin")  typlut=kLutType_Lin;
       else if (opts.substr(4,3) == "log")  typlut=kLutType_Log;
+      else if (opts.substr(4,3) == "exp")  typlut=kLutType_Exp;
       else if (opts.substr(4,4) == "sqrt")  typlut=kLutType_Sqrt;
       else if (opts.substr(4,6) == "square")  typlut=kLutType_Square;
@@ -724,4 +725,10 @@
 {
 if (!cmp)  return;
+int ncolold = 0;
+if (cmap) ncolold = cmap->NCol();
+bool fgapp = false;
+if (refr && cmp->NCol() != ncolold) {
+  fgapp = true;  refr = false;
+}
 int cmapid = cmp->Type();
 if ( (cmapid == CMAP_GREY32) || (cmapid == CMAP_GREYINV32) || 
@@ -732,6 +739,13 @@
 if (refr) { xcurs =  ycurs = -1; }
 if (zow)  zow->SetColMap(cmp, refr);
-if (gvw)  gvw->SetColMap(cmp, refr);
+if (gvw)  { 
+    if (cmap->NCol() != ncolold) { 
+    ComputeGloVPixmap();
+    SetGloVPixmap();
+  }
+  else  gvw->SetColMap(cmp, refr);
+}
 if (cmvw) cmvw->SetColMap(cmap, Lut()->Min(), Lut()->Max(), refr);
+if (fgapp)  Apply();
 return;
 }
@@ -740,13 +754,27 @@
 void PIImage::SetColMapId(CMapId cmapid, bool revidx, bool refr)
 {
+int ncolold = 0;
+if (cmap) ncolold = cmap->NCol();
 if ( (cmapid == CMAP_GREY32) || (cmapid == CMAP_GREYINV32) || 
      (cmapid == CMAP_GREY128) || (cmapid == CMAP_GREYINV128))  mdrw->GetGraphicAtt().SetColAtt(PI_Red);
 else mdrw->GetGraphicAtt().SetColAtt(PI_Turquoise);
 PIPixmap::SetColMapId(cmapid, revidx, false);
+if (refr) { xcurs =  ycurs = -1; }
+bool fgapp = false;
+if (refr && cmap->NCol() != ncolold) {
+  fgapp = true;  refr = false;
+}
 if (lut) lut->SetNCol(GetColMap()->NCol());
 if (refr) Refresh();
 if (zow)  zow->SetColMapId(cmapid, revidx, refr);
-if (gvw)  gvw->SetColMapId(cmapid, revidx, refr);
+if (gvw)  { 
+    if (cmap->NCol() != ncolold) { 
+    ComputeGloVPixmap();
+    SetGloVPixmap();
+  }
+  else  gvw->SetColMapId(cmapid, revidx, refr);
+}
 if (cmvw) cmvw->SetColMapId(cmapid, revidx, Lut()->Min(), Lut()->Max(), refr);
+if (fgapp)  Apply();
 return;
 }
Index: /trunk/SophyaPI/PI/piimgtools.cc
===================================================================
--- /trunk/SophyaPI/PI/piimgtools.cc	(revision 3544)
+++ /trunk/SophyaPI/PI/piimgtools.cc	(revision 3545)
@@ -99,8 +99,9 @@
 mOpt[0] = new PIOptMenu(this, "imglut-opt-1", 1.5*bsx, bsy, cpx, cpy);
 mOpt[0]->AppendItem("Linear", 1100);
-mOpt[0]->AppendItem("Log.", 1101);
-mOpt[0]->AppendItem("Sqrt", 1102);
-mOpt[0]->AppendItem("Square", 1103);
-mOpt[0]->AppendItem("RGB", 1104);
+mOpt[0]->AppendItem("Log", 1101);
+mOpt[0]->AppendItem("Exp", 1102);
+mOpt[0]->AppendItem("Sqrt", 1103);
+mOpt[0]->AppendItem("Square", 1104);
+mOpt[0]->AppendItem("RGB", 1105);
 mOpt[0]->SetValue(1100);
 mOpt[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
@@ -175,6 +176,7 @@
 mCasc[1] = new PIMenu(mOptzc[0]->Menu(), "PIUniCol32");
 mCasc[2] = new PIMenu(mOptzc[0]->Menu(), "MIDAS-CMap");
-
-int nsct1,nsct2,nsct3,nsct4;
+mCasc[3] = new PIMenu(mOptzc[0]->Menu(), "RGB-CMap");
+
+int nsct1,nsct2,nsct3,nsct4,nsct5;
 //  D'abord les tables standard de PI  32 couleurs
 nsct1 = 5;   // Les 5 premieres tables
@@ -191,12 +193,16 @@
 mOptzc[0]->AppendPDMenu(mCasc[1]);
 //  Apres les tables importees de MIDAS
-nsct4 = PIColorMap::NumberStandardColorMaps()-5; // Les reste jusqu'a l'avant derniere
+nsct4 = PIColorMap::NumberStandardColorMaps()-6; // Les reste jusqu'a l'avant derniere
 for(kcc=nsct3; kcc<nsct4; kcc++) 
   mCasc[2]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
 mOptzc[0]->AppendPDMenu(mCasc[2]);
-// Les tables qui restent ( RGB218, Col16 , ... )
-for(kcc=nsct4; kcc<PIColorMap::NumberStandardColorMaps(); kcc++) 
+nsct5 = PIColorMap::NumberStandardColorMaps()-4; // Les reste jusqu'aux tables RGB
+for(kcc=nsct4; kcc<nsct5; kcc++) 
   mOptzc[0]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
-// On ajoute un CheckItem pour inverser les index de table de couleur
+// Les tables de couleur RGB  ( RGB216, RGB512 , ... )
+for(kcc=nsct5; kcc<PIColorMap::NumberStandardColorMaps(); kcc++) 
+  mCasc[3]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+mOptzc[0]->AppendPDMenu(mCasc[3]);
+  // On ajoute un CheckItem pour inverser les index de table de couleur
 mOptzc[0]->Menu()->AppendSeparator();
 mOptzc[0]->Menu()->AppendCheckItem("Reverse CMap", 299);
@@ -311,5 +317,5 @@
 for(i=0; i<3; i++)  delete mBut[i];
 delete mButR;
-for(i=0; i<2; i++)  delete mCasc[i];
+for(i=0; i<4; i++)  delete mCasc[i];
 for(i=0; i<5; i++)  delete mButsz[i];
 for(i=0; i<3; i++)  delete mButcax[i];
@@ -372,7 +378,8 @@
   if     ( (mpii->Lut())->Type() == kLutType_Lin )    mOpt[0]->SetValue(1100);
   else if( (mpii->Lut())->Type() == kLutType_Log )    mOpt[0]->SetValue(1101);
-  else if( (mpii->Lut())->Type() == kLutType_Sqrt )   mOpt[0]->SetValue(1102);
-  else if( (mpii->Lut())->Type() == kLutType_Square ) mOpt[0]->SetValue(1103);
-  else if( (mpii->Lut())->Type() == kLutType_RGB )    mOpt[0]->SetValue(1104);
+  else if( (mpii->Lut())->Type() == kLutType_Exp )    mOpt[0]->SetValue(1102);
+  else if( (mpii->Lut())->Type() == kLutType_Sqrt )   mOpt[0]->SetValue(1103);
+  else if( (mpii->Lut())->Type() == kLutType_Square ) mOpt[0]->SetValue(1104);
+  else if( (mpii->Lut())->Type() == kLutType_RGB )    mOpt[0]->SetValue(1105);
   else                                                mOpt[0]->SetValue(1100);
 }
@@ -390,5 +397,5 @@
 double min, max, del;
 int lauto, typ;
-int typlut[5] = {kLutType_Lin, kLutType_Log, kLutType_Sqrt, kLutType_Square, kLutType_RGB } ; 
+int typlut[6] = {kLutType_Lin, kLutType_Log,  kLutType_Exp, kLutType_Sqrt, kLutType_Square, kLutType_RGB } ; 
 AutoLutType alts[13] = { AutoLut_No, 
 			 AutoLut_MeanSigma, AutoLut_MeanSigma, AutoLut_MeanSigma,
@@ -448,5 +455,5 @@
     if ((lauto < 0) || (lauto > 12))  lauto = 12;
     typ = mOpt[0]->GetValue() - 1100;
-    if ( (typ < 0) || (typ > 4) )  typ = 0;
+    if ( (typ < 0) || (typ > 5) )  typ = 0;
     (PIImage::CurrentPIImage())->SetLut(alts[lauto], min, max, typlut[typ], nsas[lauto]);
     if (msg == 2500) { 
Index: /trunk/SophyaPI/PI/pipixmapx.cc
===================================================================
--- /trunk/SophyaPI/PI/pipixmapx.cc	(revision 3544)
+++ /trunk/SophyaPI/PI/pipixmapx.cc	(revision 3545)
@@ -8,4 +8,5 @@
 #include "pipixmapx.h"
 #include <iostream>
+
 using namespace std;
 
Index: /trunk/SophyaPI/PI/pipixutils.cc
===================================================================
--- /trunk/SophyaPI/PI/pipixutils.cc	(revision 3544)
+++ /trunk/SophyaPI/PI/pipixutils.cc	(revision 3545)
@@ -92,5 +92,5 @@
   sx_ = sy_ = 0;
   rgbpix_ = NULL; 
-  // lecture fichier a faire 	
+  ReadFrFile(filename); 	
 }
 
@@ -100,9 +100,52 @@
 }
 
-void PIPixRGBArray::SaveToFile(const char * filename)
+int PIPixRGBArray::SaveToFile(const char * filename)
 {
-  // ECRIRE fichier A FAIRE
-  return;	
+  FILE * fip = fopen(filename,"wb");
+  if (fip == NULL) {
+    cout << " PIPixRGBArray::SaveToFile()/Error opening file " << filename << endl;
+    return 1;
+  }
+  char buff[48];
+  for(int k=0; k<48; k++) buff[k] = '\0';
+  sprintf(buff, "PI-RGB File Sx,Sy= %d %d", sx_, sy_);
+  fwrite((void *)buff, 1, 48, fip);
+  fwrite((void *)rgbpix_, sizeof(PIPixRGB), sx_*sy_, fip);
+  fclose(fip);
+  //  cout << " PIPixRGBArray::SaveToFile()*DBG* sizeof(PIPixRGB)=" << sizeof(PIPixRGB) 
+  //     << " sx*sy=" << sx_*sy_ << endl;
+  return 0;	
 }
 
+int PIPixRGBArray::ReadFrFile(const char * filename)
+{
+  if (rgbpix_) { 
+  	delete[] rgbpix_;	
+    sx_ = sy_ = 0;
+    rgbpix_ = NULL; 
+  }
+  FILE * fip = fopen(filename,"rb");
+  if (fip == NULL) {
+    cout << " PIPixRGBArray::ReadFrFile()/Error opening file " << filename << endl;
+    return 1;
+  }
+  char buff[48];
+  fread((void *)buff, 1, 48, fip);
+  if (strncmp(buff, "PI-RGB File Sx,Sy=",18) != 0) {
+    cout << " PIPixRGBArray::ReadFrFile()/Error wrong header - file=" << filename << endl;
+    return 2;
+  }
+  sscanf(buff+18,"%d %d", &sx_, &sy_);
+  size_t sz = sx_*sy_;
+  if (sz>0) { 
+  	rgbpix_ = new PIPixRGB[sz];
+  	fread((void *)rgbpix_, sizeof(PIPixRGB), sx_*sy_, fip);
+  }
+  else rgbpix_ = NULL;  
+  
+  fclose(fip);
+  // cout << " PIPixRGBArray::ReadFrFile()*DBG* sizeof(PIPixRGB)=" << sizeof(PIPixRGB) 
+  //     << " Sx=" << sx_ << " Sy=" << sy_ << endl;
+  return 0;	  
+}
 
Index: /trunk/SophyaPI/PI/pipixutils.h
===================================================================
--- /trunk/SophyaPI/PI/pipixutils.h	(revision 3544)
+++ /trunk/SophyaPI/PI/pipixutils.h	(revision 3545)
@@ -70,5 +70,6 @@
     { return rgbpix_[j*sx_+i]; }
  
-  void SaveToFile(const char * filename);
+  int SaveToFile(const char * filename);
+  int ReadFrFile(const char * filename);
     
 protected:
