Index: trunk/SophyaExt/FitsIOServer/fabtcolread.cc
===================================================================
--- trunk/SophyaExt/FitsIOServer/fabtcolread.cc	(revision 2451)
+++ trunk/SophyaExt/FitsIOServer/fabtcolread.cc	(revision 2453)
@@ -110,5 +110,58 @@
  }
 
- void FitsOpenFile::printerror(int sta) const
+//////////////////////////////////////////////////////////////
+//// Methodes statiques
+//////////////////////////////////////////////////////////////
+/*!
+  Read a fitsheader key into double
+  \param fitsptr : cfitio pointer to Fits file
+  \param keyname : name of the key
+  \return value into double
+*/
+double FitsOpenFile::ReadKey(fitsfile *fitsptr,char *keyname)
+{
+ if(keyname==NULL) return 0.;
+ int sta=0; double val=0.;
+ if(fits_read_key(fitsptr,TDOUBLE,keyname,&val,NULL,&sta))
+   printerror(sta);
+ return val;
+}
+
+/*!
+  Read a fitsheader key into long
+  \param fitsptr : cfitio pointer to Fits file
+  \param keyname : name of the key
+  \return value into long
+*/
+long FitsOpenFile::ReadKeyL(fitsfile *fitsptr,char *keyname)
+{
+ if(keyname==NULL) return 0;
+ int sta=0; long val=0;
+ if(fits_read_key(fitsptr,TLONG,keyname,&val,NULL,&sta))
+   printerror(sta);
+ return val;
+}
+
+/*!
+  Read a fitsheader key into string
+  \param fitsptr : cfitio pointer to Fits file
+  \param keyname : name of the key
+  \return value into string
+*/
+string FitsOpenFile::ReadKeyS(fitsfile *fitsptr,char *keyname)
+{
+ if(keyname==NULL) return (string)"";
+ int sta=0; char val[FLEN_VALUE];
+ if(fits_read_key(fitsptr,TSTRING,keyname,val,NULL,&sta))
+   printerror(sta);
+ string sval = val;
+ return sval;
+}
+
+/*!
+  CFitsIO error printing routine
+  \param sta : cfitio error return code
+*/
+ void FitsOpenFile::printerror(int sta)
  {
   int stat = sta;
@@ -268,5 +321,5 @@
  if(IHdu<=0 || IHdu>NHdu)
    for(int ihdu=1;ihdu<=NHdu;ihdu++) {
-     if(fits_movabs_hdu(FitsPtr,ihdu,&HduType,&sta)) printerror(sta);
+     if(fits_movabs_hdu(FitsPtr,ihdu,&HduType,&sta)) FitsOpenFile::printerror(sta);
      if(DbgLevel>1) cout<<"...Init ihdu="
                         <<ihdu<<" HduType="<<HduType<<endl;
@@ -279,5 +332,5 @@
  }
  if(fits_movabs_hdu(FitsPtr,IHdu,&HduType,&sta)) {
-   printerror(sta); Delete();
+   FitsOpenFile::printerror(sta); Delete();
    throw RangeCheckError("FitsABTColRd::Init: Error moving to requested HDU\n");
  }
@@ -289,5 +342,5 @@
  // Get number of columns
  if(fits_get_num_cols(FitsPtr,&NBcol,&sta)) {
-   printerror(sta); Delete();
+   FitsOpenFile::printerror(sta); Delete();
    throw NotAvailableOperation("FitsABTColRd::Init: Error getting number of columns\n");
  }
@@ -300,5 +353,5 @@
  // Get number of rows
  if(fits_get_num_rows(FitsPtr,&NBline,&sta)) {
-   printerror(sta); Delete();
+   FitsOpenFile::printerror(sta); Delete();
    throw NotAvailableOperation("FitsABTColRd::Init: Error getting number of rows\n");
  }
@@ -314,5 +367,5 @@
    strcpy(labelcol,ColLabel.c_str());
    if(fits_get_colnum(FitsPtr,CASESEN,labelcol,&ColNum,&sta)) {
-     printerror(sta); Delete();
+     FitsOpenFile::printerror(sta); Delete();
      throw NotAvailableOperation("FitsABTColRd::Init: Error getting column name\n");
    }
@@ -327,5 +380,5 @@
  // Get column type
  if(fits_get_coltype(FitsPtr,ColNum+1,&ColTypeCode,NULL,NULL,&sta)) {
-   printerror(sta); Delete();
+   FitsOpenFile::printerror(sta); Delete();
    throw ParmError("FitsABTColRd::Init: Error getting column type\n");
  }
@@ -349,5 +402,5 @@
  }
  if(rc) {
-   printerror(sta); Delete();
+   FitsOpenFile::printerror(sta); Delete();
    throw RangeCheckError("FitsABTColRd::Init: Error getting the column caracteristics\n");
  }
@@ -414,9 +467,5 @@
 double FitsABTColRd::ReadKey(char *keyname)
 {
- if(keyname==NULL) return 0.;
- int sta=0; double val=0.;
- if(fits_read_key(FitsPtr,TDOUBLE,keyname,&val,NULL,&sta))
-   printerror(sta);
- return val;
+ return FitsOpenFile::ReadKey(FitsPtr,keyname);
 }
 
@@ -428,9 +477,5 @@
 long FitsABTColRd::ReadKeyL(char *keyname)
 {
- if(keyname==NULL) return 0;
- int sta=0; long val=0;
- if(fits_read_key(FitsPtr,TLONG,keyname,&val,NULL,&sta))
-   printerror(sta);
- return val;
+ return FitsOpenFile::ReadKeyL(FitsPtr,keyname);
 }
 
@@ -442,10 +487,5 @@
 string FitsABTColRd::ReadKeyS(char *keyname)
 {
- if(keyname==NULL) return 0;
- int sta=0; char val[FLEN_VALUE];
- if(fits_read_key(FitsPtr,TSTRING,keyname,val,NULL,&sta))
-   printerror(sta);
- string sval = val;
- return sval;
+ return FitsOpenFile::ReadKeyS(FitsPtr,keyname);
 }
 
@@ -476,5 +516,5 @@
    fits_read_col(FitsPtr,TDOUBLE,ColNum+1,n+1,1,1,NULL,&val,NULL,&sta);
    if(sta) {
-     printerror(sta);
+     FitsOpenFile::printerror(sta);
      throw NotAvailableOperation("FitsABTColRd::Read: Error Reading Fits file\n");
    }
@@ -511,5 +551,5 @@
    fits_read_col(FitsPtr,TDOUBLE,ColNum+1,row1,1,nrow,NULL,Buffer,NULL,&sta);
    if(sta) {
-     printerror(sta);
+     FitsOpenFile::printerror(sta);
      LineDeb = LineFin = -1;
      throw NotAvailableOperation("FitsABTColRd::Read: Error Reading Fits file\n");
@@ -569,5 +609,5 @@
  fits_read_col(FitsPtr,TDOUBLE,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
  if(sta) {
-   printerror(sta);
+   FitsOpenFile::printerror(sta);
    throw NotAvailableOperation("FitsABTColRd::Read_TVector<double>: Error Reading Fits file\n");
  }
@@ -593,5 +633,5 @@
  fits_read_col(FitsPtr,TFLOAT,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
  if(sta) {
-   printerror(sta);
+   FitsOpenFile::printerror(sta);
    throw NotAvailableOperation("FitsABTColRd::Read_TVector<float>: Error Reading Fits file\n");
  }
@@ -616,5 +656,5 @@
  fits_read_col(FitsPtr,TUSHORT,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
  if(sta) {
-   printerror(sta);
+   FitsOpenFile::printerror(sta);
    throw NotAvailableOperation("FitsABTColRd::Read_TVector<uint_2>: Error Reading Fits file\n");
  }
@@ -641,5 +681,5 @@
  fits_read_col(FitsPtr,T,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
  if(sta) {
-   printerror(sta);
+   FitsOpenFile::printerror(sta);
    throw NotAvailableOperation("FitsABTColRd::Read_TVector<int_4>: Error Reading Fits file\n");
  }
@@ -665,5 +705,5 @@
  fits_read_col(FitsPtr,TLONGLONG,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
  if(sta) {
-   printerror(sta);
+   FitsOpenFile::printerror(sta);
    throw NotAvailableOperation("FitsABTColRd::Read_TVector<int_8>: Error Reading Fits file\n");
  }
@@ -731,13 +771,4 @@
  if(bchange) ChangeBuffer(BuffLen,bsens);
  return row;
-}
-
-/////////////////////////////////////////////////
-void FitsABTColRd::printerror(int sta) const
-{
- int stat = sta;
- fits_report_error(stdout,stat);
- fflush(stdout);
- return;
 }
 
@@ -857,2 +888,264 @@
  if(FitsOF!=NULL) delete FitsOF;
 }
+
+///////////////////////////////////////////////////////////////////
+//! Class for reading a 2D image from a FITS file
+
+/*!
+  \class SOPHYA::FitsImg2DRd
+  \ingroup FitsIOServer
+  Class for reading a 2D image from a FITS file
+*/
+
+//////////////////////////////////////////////////////////////
+/*!
+  Constructor.
+  \param fof : Pointer to the Class for opening the FITS file
+  \param ihdu : number of the HDU where the column is.
+  \param lp : debug level
+  \verbatim
+  - if ihdu=0 or ihdu>nhdu first binary or ASCII table is taken
+  \endverbatim
+  \warning ihdu = [1,nhdu]
+*/
+FitsImg2DRd::FitsImg2DRd(FitsOpenFile* fof,int ihdu,int lp)
+{
+ Init(fof,ihdu,lp);
+}
+
+/*! Constructor by copy */
+FitsImg2DRd::FitsImg2DRd(FitsImg2DRd& fbt)
+{
+ Init(fbt.GetFitsOpenFile(),fbt.GetHDU(),fbt.DbgLevel);
+}
+
+/*! Constructor by default */
+FitsImg2DRd::FitsImg2DRd()
+{
+ FitsFN = "";
+ IHdu = 0; NHdu = 0; HduType = 0;
+ Naxis[0] = Naxis[1] = 0;
+ SetNulVal(); SetDebug(0);
+ FitsOF = NULL; FitsPtr = NULL;
+}
+
+/*! Init routine called by the constructor */
+void FitsImg2DRd::Init(FitsOpenFile* fof,int ihdu,int lp)
+{
+ // Initialisation des Parametres Generaux
+ FitsFN = "";
+ IHdu = ihdu; NHdu = 0; HduType = 0;
+ Naxis[0] = Naxis[1] = 0;
+ SetNulVal(); SetDebug(lp);
+ FitsOF = NULL; FitsPtr = NULL;
+
+ // Caracteristiques du FitsOpenFile
+ FitsOF = fof;
+ if(FitsOF==NULL)
+   throw NullPtrError("FitsImg2DRd::Init: FitsOpenFile pointer is NULL\n");
+ FitsPtr = FitsOF->GetFitsPtr();
+ if(FitsPtr==NULL)
+   throw NullPtrError("FitsImg2DRd::Init: FitsPtr pointer is NULL\n");
+ NHdu = FitsOF->GetNHdu();
+ if(DbgLevel>1) cout<<"FitsImg2DRd::Init  NHdu="<<NHdu<<endl;
+ if(NHdu<=0)
+   throw SzMismatchError("FitsImg2DRd::Init: Bad NHdu\n");
+ FitsFN = FitsOF->GetFileName();
+ if(FitsFN.size() <= 0 )
+   throw ParmError("FitsImg2DRd::Init: Fits file name error\n");
+
+ int sta = 0;
+
+ // Get HDU 2D image
+ // si IHdu <=0 || >NHdu on cherche la 1ere image
+ // sinon on se positionne sur IHdu
+ if(IHdu<=0 || IHdu>NHdu)
+   for(int ihdu=1;ihdu<=NHdu;ihdu++) {
+     if(fits_movabs_hdu(FitsPtr,ihdu,&HduType,&sta)) FitsOpenFile::printerror(sta);
+     if(DbgLevel>1)
+       cout<<"...Init ihdu="<<ihdu<<" HduType="<<HduType<<endl;
+     if(HduType==IMAGE_HDU) {IHdu = ihdu; break;}
+   }
+ if(IHdu<=0 || IHdu>NHdu) {
+   cout<<"NO IMAGE_HDU hdu found"<<endl;
+   IHdu = 0;
+   throw TypeMismatchExc("FitsImg2DRd::Init: NO IMAGE_HDU hdu found\n");
+ }
+ if(fits_movabs_hdu(FitsPtr,IHdu,&HduType,&sta)) {
+   FitsOpenFile::printerror(sta);
+   throw RangeCheckError("FitsImg2DRd::Init: Error moving to requested HDU\n");
+ }
+ if(HduType!=IMAGE_HDU)
+   throw TypeMismatchExc("FitsImg2DRd::Init: HDU not IMAGE_HDU\n");
+
+ // Get NAXIS 1 et 2
+ int nfound=0;
+ if(fits_read_keys_lng(FitsPtr,"NAXIS",1,2,Naxis,&nfound,&sta)) {
+   FitsOpenFile::printerror(sta);
+   throw RangeCheckError("FitsImg2DRd::Init: Error reading NAXIS cards\n");
+ }
+ if(DbgLevel>1)
+   cout<<"...Init(hdu="<<IHdu<<")  NAXIS1="<<Naxis[0]<<" NAXIS2="<<Naxis[1]<<" (nfound="<<nfound<<")"<<endl;
+ if(nfound!=2 || Naxis[0]<=0 || Naxis[1]<=0)
+   throw NotAvailableOperation("FitsImg2DRd::Init: bad Naxis[0-1] value\n");
+
+}
+
+/*! Destructor. */
+FitsImg2DRd::~FitsImg2DRd()
+{
+ //--- Surtout on ne "fits_close_file" pas le fichier FITS !!!
+ Naxis[0] = Naxis[1] = 0;
+}
+
+//////////////////////////////////////////////////////////////
+/*!
+  Read a fitsheader key into double
+  \param keyname : name of the key
+  \return value into double
+*/
+double FitsImg2DRd::ReadKey(char *keyname)
+{
+ return FitsOpenFile::ReadKey(FitsPtr,keyname);
+}
+
+/*!
+  Read a fitsheader key into long
+  \param keyname : name of the key
+  \return value into long
+*/
+long FitsImg2DRd::ReadKeyL(char *keyname)
+{
+ return FitsOpenFile::ReadKeyL(FitsPtr,keyname);
+}
+
+/*!
+  Read a fitsheader key into string
+  \param keyname : name of the key
+  \return value into string
+*/
+string FitsImg2DRd::ReadKeyS(char *keyname)
+{
+ return FitsOpenFile::ReadKeyS(FitsPtr,keyname);
+}
+
+//////////////////////////////////////////////////////////////
+/* REMARQUE:
+ * Si une image FITS a NAXIS1=100 et NAXIS2=50
+ * alors un tableau 2D juste assez grand pour contenir l'image
+ * doit etre declare array[50][100] (et non pas array[100][50])
+ *                   array[NAXIS2][NAXIS1]
+ */
+/*!
+Read image into a TMatrix<uint_2>
+\warning TMatrix data(Naxis2,Naxis1)
+*/
+long FitsImg2DRd::Read(TMatrix<uint_2>& data)
+{
+ int sta=0;
+ uint_2* arr = new uint_2[Naxis[0]];
+ data.ReSize(Naxis[1],Naxis[0]);
+
+ for(int j=0;j<Naxis[1];j++) {
+   long deb = j*Naxis[0]+1, nel = Naxis[0];
+   fits_read_img(FitsPtr,TUSHORT,deb,nel,&NulVal,arr,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Read(TMatrix<uint_2>): Error Reading Fits file\n");
+   }
+   for(int i=0;i<Naxis[0];i++) data(j,i) = arr[i];
+ }
+
+ delete [] arr;
+ return Naxis[0]*Naxis[1];
+ }
+
+/*! Read image into a TMatrix<int_4> */
+long FitsImg2DRd::Read(TMatrix<int_4>& data)
+{
+ int sta=0;
+ int_4* arr = new int_4[Naxis[0]];
+ data.ReSize(Naxis[1],Naxis[0]);
+ int T = (sizeof(long)==4) ? TLONG: TINT;
+
+ for(int j=0;j<Naxis[1];j++) {
+   long deb = j*Naxis[0]+1, nel = Naxis[0];
+   fits_read_img(FitsPtr,T,deb,nel,&NulVal,arr,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Read(TMatrix<int_4>): Error Reading Fits file\n");
+   }
+   for(int i=0;i<Naxis[0];i++) data(j,i) = arr[i];
+ }
+
+ delete [] arr;
+ return Naxis[0]*Naxis[1];
+ }
+
+/*! Read image into a TMatrix<int_8> */
+long FitsImg2DRd::Read(TMatrix<int_8>& data)
+{
+ int sta=0;
+ int_8* arr = new int_8[Naxis[0]];
+ data.ReSize(Naxis[1],Naxis[0]);
+
+ for(int j=0;j<Naxis[1];j++) {
+   long deb = j*Naxis[0]+1, nel = Naxis[0];
+   fits_read_img(FitsPtr,TLONGLONG,deb,nel,&NulVal,arr,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Read(TMatrix<int_8>): Error Reading Fits file\n");
+   }
+   for(int i=0;i<Naxis[0];i++) data(j,i) = arr[i];
+ }
+
+ delete [] arr;
+ return Naxis[0]*Naxis[1];
+ }
+
+/*! Read image into a TMatrix<float> */
+long FitsImg2DRd::Read(TMatrix<float>& data)
+{
+ int sta=0;
+ float* arr = new float[Naxis[0]];
+ data.ReSize(Naxis[1],Naxis[0]);
+
+ for(int j=0;j<Naxis[1];j++) {
+   long deb = j*Naxis[0]+1, nel = Naxis[0];
+   fits_read_img(FitsPtr,TFLOAT,deb,nel,&NulVal,arr,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Read(TMatrix<float>): Error Reading Fits file\n");
+   }
+   for(int i=0;i<Naxis[0];i++) data(j,i) = arr[i];
+ }
+
+ delete [] arr;
+ return Naxis[0]*Naxis[1];
+ }
+
+/*! Read image into a TMatrix<double> */
+long FitsImg2DRd::Read(TMatrix<double>& data)
+{
+ int sta=0;
+ double* arr = new double[Naxis[0]];
+ data.ReSize(Naxis[1],Naxis[0]);
+
+ for(int j=0;j<Naxis[1];j++) {
+   long deb = j*Naxis[0]+1, nel = Naxis[0];
+   fits_read_img(FitsPtr,TDOUBLE,deb,nel,&NulVal,arr,NULL,&sta);
+   if(sta) {
+     FitsOpenFile::printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Read(TMatrix<double>): Error Reading Fits file\n");
+   }
+   for(int i=0;i<Naxis[0];i++) data(j,i) = arr[i];
+ }
+
+ delete [] arr;
+ return Naxis[0]*Naxis[1];
+ }
Index: trunk/SophyaExt/FitsIOServer/fabtcolread.h
===================================================================
--- trunk/SophyaExt/FitsIOServer/fabtcolread.h	(revision 2451)
+++ trunk/SophyaExt/FitsIOServer/fabtcolread.h	(revision 2453)
@@ -28,8 +28,12 @@
   inline fitsfile* GetFitsPtr() {return FitsPtr;}
 
+  static double ReadKey(fitsfile *fitsptr,char *keyname);
+  static long   ReadKeyL(fitsfile *fitsptr,char *keyname);
+  static string ReadKeyS(fitsfile *fitsptr,char *keyname);
+  static void   printerror(int sta);
+
 protected:
   void Init(const char *cfname);
   void Delete(void);
-  void printerror(int sta) const;
 
   string FitsFN;
@@ -121,5 +125,4 @@
            ,int ihdu,long blen,long bsens,int lp);
   void Delete(void);
-  void printerror(int sta) const;
 
   string FitsFN,ColLabel,ColTUnit,ColTForm;
@@ -158,2 +161,50 @@
 } // namespace SOPHYA
 #endif    /* FABTCOLREAD_H_SEEN */
+
+///////////////////////////////////////////////////////////////////
+//! Class for reading a 2D image from a FITS file
+class FitsImg2DRd : public AnyDataObj {
+public:
+  FitsImg2DRd(FitsOpenFile* fof,int ihdu=0,int lp=0);
+  FitsImg2DRd(FitsImg2DRd& fbt);
+  FitsImg2DRd();
+  virtual ~FitsImg2DRd();
+
+  double ReadKey(char *keyname);
+  long   ReadKeyL(char *keyname);
+  string ReadKeyS(char *keyname);
+
+  long   Read(TMatrix<uint_2>& data);
+  long   Read(TMatrix<int_4>& data);
+  long   Read(TMatrix<int_8>& data);
+  long   Read(TMatrix<float>& data);
+  long   Read(TMatrix<double>& data);
+
+  //! Set debug level
+  inline void    SetDebug(int lp=0) {DbgLevel = (unsigned short) lp;}
+  //! Set null value to be return when reading null data (0=return the data)
+  inline void    SetNulVal(double nulval=0.) {NulVal = nulval;}
+  //! Get the pointer to FitsOpenFile
+  inline FitsOpenFile* GetFitsOpenFile(void) {return FitsOF;}
+  //! Get the number of the HDU read
+  inline int     GetHDU(void) {return IHdu;}
+  //! Get the HDU type
+  inline int     GetHDUType(void) {return HduType;}
+  //! Get NAXIS1
+  inline long    GetNaxis1(void) {return Naxis[0];}
+  //! Get NAXIS2
+  inline long    GetNaxis2(void) {return Naxis[1];}
+
+protected:
+  void Init(FitsOpenFile* fof,int ihdu,int lp);
+
+  string FitsFN;
+  int IHdu,NHdu,HduType;
+  long Naxis[2];
+
+  double NulVal;
+  unsigned short DbgLevel;
+
+  FitsOpenFile* FitsOF;
+  fitsfile* FitsPtr;
+};
Index: trunk/SophyaExt/FitsIOServer/fabtwriter.cc
===================================================================
--- trunk/SophyaExt/FitsIOServer/fabtwriter.cc	(revision 2451)
+++ trunk/SophyaExt/FitsIOServer/fabtwriter.cc	(revision 2453)
@@ -6,4 +6,189 @@
 #include "fabtwriter.h"
 
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::FitsWriter
+  \ingroup FitsIOServer
+  Class for writing into a FITS file (DO NOT USE)
+*/
+
+/*! Constructor  (DO NOT USE). */
+FitsWriter::FitsWriter(string fname,int lp)
+{
+  cr_or_upd_fits(fname.c_str(),false,lp);
+}
+
+/*! Constructor (DO NOT USE). */
+FitsWriter::FitsWriter(const char* cfname,int lp)
+{
+  cr_or_upd_fits(cfname,false,lp);
+}
+
+/*! Constructor (DO NOT USE). */
+FitsWriter::FitsWriter(string fname,bool update,int lp)
+{
+  cr_or_upd_fits(fname.c_str(),update,lp);
+}
+
+/*! Constructor (DO NOT USE). */
+FitsWriter::FitsWriter(const char* cfname,bool update,int lp)
+{
+  cr_or_upd_fits(cfname,update,lp);
+}
+
+/*! See FitsWriter() */
+void FitsWriter::cr_or_upd_fits(const char *cfname,bool update,int lp)
+{
+ FitsPtr = NULL;
+ HduType = 0;
+ SetDebug(lp);
+ FitsFN = cfname;
+ NOverFlow = 0;
+ Update = update;
+ // Init key structure
+ DoubleKey.resize(0);
+ LongKey.resize(0);
+ StringKey.resize(0);
+
+ if(DbgLevel)
+   cout<<"FitsWriter::cr_or_upd_fits FitsFN="<<FitsFN<<endl;
+
+ if(FitsFN.size() <= 0 )
+   throw ParmError("FitsWriter::cr_or_upd_fits: Fits file name error\n");
+
+ // create or update FITS file
+ int sta=0;
+ if(Update) {
+   if(fits_open_file(&FitsPtr,FitsFN.c_str(),READWRITE,&sta)) {
+     printerror(sta);
+     throw NullPtrError("FitsWriter::cr_or_upd_fits: Error opening Fits file for update\n");
+   }
+   if(DbgLevel) cout<<"FitsWriter::cr_or_upd_fits: fits file has been opened for update"<<endl;
+ } else {
+   if(fits_create_file(&FitsPtr,FitsFN.c_str(),&sta)) {
+     printerror(sta);
+     throw NullPtrError("FitsWriter::cr_or_upd_fits: Error creating new Fits file\n");
+   }
+   if(DbgLevel) cout<<"FitsWriter::cr_or_upd_fits: a new fits file has been created"<<endl;
+ }
+
+ // create d'un Primary HDU
+ //long naxes[1] = {0};
+ //if(fits_create_img(FitsPtr,BYTE_IMG,0,naxes,&sta)) {
+ //  printerror(sta);
+ //  throw NullPtrError("FitsWriter::cr_or_upd_fits: Error creating Primary extension\n");
+ //}
+}
+
+/*! Destructor */
+FitsWriter::~FitsWriter()
+{
+ int sta = 0;
+ writekeys();
+ if(fits_close_file(FitsPtr,&sta)) printerror(sta);
+ FitsPtr = NULL;
+}
+
+/*! Flush the FitsIO buffer to set good Fits file in case of problems */
+void FitsWriter::Flush(void)
+{
+ if(FitsPtr==NULL) return;
+ int sta = 0;
+ if(fits_flush_file(FitsPtr,&sta)) printerror(sta);
+}
+
+
+/*! Write a double value into Fits Header */
+void FitsWriter::WriteKey(const char *keyname,double val,char* comment)
+{
+ if(keyname==NULL || strlen(keyname)<=0) return;
+ KeyDouble k;
+ k.keyname=keyname;
+ k.val=val;
+ if(comment) k.comment=comment; else k.comment="";
+ DoubleKey.push_back(k);
+}
+
+/*! Write a long value into Fits Header */
+void FitsWriter::WriteKey(const char *keyname,long val,char* comment)
+{
+ if(keyname==NULL || strlen(keyname)<=0) return;
+ KeyLong k;
+ k.keyname=keyname;
+ k.val=val;
+ if(comment) k.comment=comment; else k.comment="";
+ LongKey.push_back(k);
+}
+
+/*! Write a string value into Fits Header */
+void FitsWriter::WriteKey(const char *keyname,string val,char* comment)
+{
+ if(keyname==NULL || strlen(keyname)<=0) return;
+ KeyString k;
+ k.keyname=keyname;
+ k.val=val;
+ if(comment) k.comment=comment; else k.comment="";
+ StringKey.push_back(k);
+}
+
+void FitsWriter::writekeys(void)
+// Ecriture effective des clefs
+{
+ if(FitsPtr==NULL) return;
+ int sta=0;
+ if(DoubleKey.size()>0)
+   for(unsigned int i=0;i<DoubleKey.size();i++) {
+     char* key = const_cast<char*>(DoubleKey[i].keyname.c_str());
+     char* com = const_cast<char*>(DoubleKey[i].comment.c_str());
+     double val = DoubleKey[i].val;
+     if(fits_update_key(FitsPtr,TDOUBLE,key,&val,com,&sta))
+       printerror(sta);
+   }
+ if(LongKey.size()>0)
+   for(unsigned int i=0;i<LongKey.size();i++) {
+     char* key = const_cast<char*>(LongKey[i].keyname.c_str());
+     char* com = const_cast<char*>(LongKey[i].comment.c_str());
+     long val = LongKey[i].val;
+     if(fits_update_key(FitsPtr,TLONG,key,&val,com,&sta))
+       printerror(sta);
+   }
+ if(StringKey.size()>0)
+   for(unsigned int i=0;i<StringKey.size();i++) {
+     char* key = const_cast<char*>(StringKey[i].keyname.c_str());
+     char* com = const_cast<char*>(StringKey[i].comment.c_str());
+     char* val = const_cast<char*>(StringKey[i].val.c_str());
+     if(fits_update_key(FitsPtr,TSTRING,key,val,com,&sta))
+       printerror(sta);
+   }
+ DoubleKey.resize(0);
+ LongKey.resize(0);
+ StringKey.resize(0);
+}
+
+void FitsWriter::printerrorwrite(const char* type,int col,long row,int sta)
+{
+ if(sta==NUM_OVERFLOW) {NOverFlow++; return;}
+ printerror(sta);
+ char str[256];
+ sprintf(str,"FitsWriter::Write_%s: Error Writing Fits c=%d r=%ld sta=%d"
+        ,type,col,row,sta);
+ throw NotAvailableOperation(str);
+}
+
+void FitsWriter::printerror(int sta) const
+{
+ int stat = sta;
+ fits_report_error(stdout,stat);
+ fflush(stdout);
+ return;
+}
+
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
 /*!
   \class SOPHYA::FitsABTWriter
@@ -117,6 +302,11 @@
 */
 FitsABTWriter::FitsABTWriter(string fname,int hdutype,int lp)
-{
-  cr_or_upd_fits(fname.c_str(),false,hdutype,lp);
+: FitsWriter(fname,lp)
+{
+ FirstTime = true;
+ HduType = hdutype;
+ if(HduType!=BINARY_TBL && HduType!=ASCII_TBL)
+   throw
+     TypeMismatchExc("FitsABTWriter::FitsABTWriter: Only BINARY or ASCII table permitted\n");
 }
 
@@ -128,6 +318,11 @@
 */
 FitsABTWriter::FitsABTWriter(const char* cfname,int hdutype,int lp)
-{
-  cr_or_upd_fits(cfname,false,hdutype,lp);
+: FitsWriter(cfname,lp)
+{
+ FirstTime = true;
+ HduType = hdutype;
+ if(HduType!=BINARY_TBL && HduType!=ASCII_TBL)
+   throw
+     TypeMismatchExc("FitsABTWriter::FitsABTWriter: Only BINARY or ASCII table permitted\n");
 }
 
@@ -140,6 +335,11 @@
 */
 FitsABTWriter::FitsABTWriter(string fname,bool update,int hdutype,int lp)
-{
-  cr_or_upd_fits(fname.c_str(),update,hdutype,lp);
+: FitsWriter(fname,update,lp)
+{
+ FirstTime = true;
+ HduType = hdutype;
+ if(HduType!=BINARY_TBL && HduType!=ASCII_TBL)
+   throw
+     TypeMismatchExc("FitsABTWriter::FitsABTWriter: Only BINARY or ASCII table permitted\n");
 }
 
@@ -152,52 +352,11 @@
 */
 FitsABTWriter::FitsABTWriter(const char* cfname,bool update,int hdutype,int lp)
-{
-  cr_or_upd_fits(cfname,update,hdutype,lp);
-}
-
-/*! See FitsABTWriter() */
-void FitsABTWriter::cr_or_upd_fits(const char *cfname,bool update,int hdutype,int lp)
+: FitsWriter(cfname,update,lp)
 {
  FirstTime = true;
- FitsPtr = NULL;
  HduType = hdutype;
- SetDebug(lp);
- FitsFN = cfname;
- NOverFlow = 0;
- Update = update;
-
- if(DbgLevel)
-   cout<<"FitsABTWriter::cr_or_upd_fits FitsFN="<<FitsFN
-       <<" HduType="<<HduType<<endl;
-
- if(FitsFN.size() <= 0 )
-   throw ParmError("FitsABTWriter::cr_or_upd_fits: Fits file name error\n");
-
  if(HduType!=BINARY_TBL && HduType!=ASCII_TBL)
-   throw TypeMismatchExc("FitsABTWriter::cr_or_upd_fits: Only BINARY or ASCII table permitted\n");
-
- // create or update FITS file
- int sta=0;
- if(Update) {
-   if(fits_open_file(&FitsPtr,FitsFN.c_str(),READWRITE,&sta)) {
-     printerror(sta);
-     throw NullPtrError("FitsABTWriter::cr_or_upd_fits: Error opening Fits file for update\n");
-   }
-   if(DbgLevel) cout<<"FitsABTWriter::cr_or_upd_fits: fits file has been opened for update"<<endl;
- } else {
-   if(fits_create_file(&FitsPtr,FitsFN.c_str(),&sta)) {
-     printerror(sta);
-     throw NullPtrError("FitsABTWriter::cr_or_upd_fits: Error creating new Fits file\n");
-   }
-   if(DbgLevel) cout<<"FitsABTWriter::cr_or_upd_fits: a new fits file has been created"<<endl;
- }
-
- // create d'un Primary HDU
- //long naxes[1] = {0};
- //if(fits_create_img(FitsPtr,BYTE_IMG,0,naxes,&sta)) {
- //  printerror(sta);
- //  throw NullPtrError("FitsABTWriter::cr_or_upd_fits: Error creating Primary extension\n");
- //}
-
+   throw
+     TypeMismatchExc("FitsABTWriter::FitsABTWriter: Only BINARY or ASCII table permitted\n");
 }
 
@@ -205,83 +364,4 @@
 FitsABTWriter::~FitsABTWriter()
 {
- int sta = 0;
- writekeys();
- if(fits_close_file(FitsPtr,&sta)) printerror(sta);
- FitsPtr = NULL;
-}
-
-/*! Flush the FitsIO buffer to set good Fits file in case of problems */
-void FitsABTWriter::Flush(void)
-{
- if(FitsPtr==NULL) return;
- int sta = 0;
- if(fits_flush_file(FitsPtr,&sta)) printerror(sta);
-}
-
-/*! Write a double value into Fits Header */
-void FitsABTWriter::WriteKey(const char *keyname,double val,char* comment)
-{
- if(keyname==NULL || strlen(keyname)<=0) return;
- KeyDouble k;
- k.keyname=keyname;
- k.val=val;
- if(comment) k.comment=comment; else k.comment="";
- DoubleKey.push_back(k);
-}
-
-/*! Write a long value into Fits Header */
-void FitsABTWriter::WriteKey(const char *keyname,long val,char* comment)
-{
- if(keyname==NULL || strlen(keyname)<=0) return;
- KeyLong k;
- k.keyname=keyname;
- k.val=val;
- if(comment) k.comment=comment; else k.comment="";
- LongKey.push_back(k);
-}
-
-/*! Write a string value into Fits Header */
-void FitsABTWriter::WriteKey(const char *keyname,string val,char* comment)
-{
- if(keyname==NULL || strlen(keyname)<=0) return;
- KeyString k;
- k.keyname=keyname;
- k.val=val;
- if(comment) k.comment=comment; else k.comment="";
- StringKey.push_back(k);
-}
-
-void FitsABTWriter::writekeys(void)
-// Ecriture effective des clefs
-{
- if(FitsPtr==NULL) return;
- int sta=0;
- if(DoubleKey.size()>0)
-   for(unsigned int i=0;i<DoubleKey.size();i++) {
-     char* key = const_cast<char*>(DoubleKey[i].keyname.c_str());
-     char* com = const_cast<char*>(DoubleKey[i].comment.c_str());
-     double val = DoubleKey[i].val;
-     if(fits_update_key(FitsPtr,TDOUBLE,key,&val,com,&sta))
-       printerror(sta);
-   }
- if(LongKey.size()>0)
-   for(unsigned int i=0;i<LongKey.size();i++) {
-     char* key = const_cast<char*>(LongKey[i].keyname.c_str());
-     char* com = const_cast<char*>(LongKey[i].comment.c_str());
-     long val = LongKey[i].val;
-     if(fits_update_key(FitsPtr,TLONG,key,&val,com,&sta))
-       printerror(sta);
-   }
- if(StringKey.size()>0)
-   for(unsigned int i=0;i<StringKey.size();i++) {
-     char* key = const_cast<char*>(StringKey[i].keyname.c_str());
-     char* com = const_cast<char*>(StringKey[i].comment.c_str());
-     char* val = const_cast<char*>(StringKey[i].val.c_str());
-     if(fits_update_key(FitsPtr,TSTRING,key,val,com,&sta))
-       printerror(sta);
-   }
- DoubleKey.resize(0);
- LongKey.resize(0);
- StringKey.resize(0);
 }
 
@@ -303,6 +383,6 @@
                          ,const char* tunit,int datatype)
 {
-  if(!FirstTime)
-    throw AllocationError("FitsABTWriter::addcol: table already created\n");
+ if(!FirstTime)
+   throw AllocationError("FitsABTWriter::addcol: table already created\n");
  
  // Gestion auto du tform pour les tables binaires avec le datatype (si non-definie)
@@ -402,7 +482,4 @@
  }
 
- // Append Fits key
- writekeys();
-
  // menage
  if(extname) delete [] extname;
@@ -591,24 +668,4 @@
 }
 
-//////////////////////////////////////////////////////////////
-void FitsABTWriter::printerrorwrite(const char* type,int col,long row,int sta)
-{
- if(sta==NUM_OVERFLOW) {NOverFlow++; return;}
- printerror(sta);
- char str[256];
- sprintf(str,"FitsABTWriter::Write_%s: Error Writing Fits c=%d r=%ld sta=%d"
-        ,type,col,row,sta);
- throw NotAvailableOperation(str);
-}
-
-/////////////////////////////////////////////////
-void FitsABTWriter::printerror(int sta) const
-{
- int stat = sta;
- fits_report_error(stdout,stat);
- fflush(stdout);
- return;
-}
-
 /////////////////////////////////////////////////
 void FitsABTWriter::Print(ostream& os,int lp) const
@@ -621,2 +678,188 @@
     os<<i<<"... Label="<<Label[i]<<" TForm="<<TForm[i]<<" TUnit="<<TUnit[i]<<endl;
 }
+
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::FitsImg2DWriter
+  \ingroup FitsIOServer
+  Class for writing an image into FITS file
+*/
+
+/*!
+  Constructor.
+  \param fname : FITS file name to be written (a new fits file is created)
+  \param bitpix : image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg2DWriter::FitsImg2DWriter(string fname,int bitpix,int lp)
+: FitsWriter(fname,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = 0;
+}
+
+/*!
+  Constructor.
+  \param cfname : FITS file name to be written (a new fits file is created)
+  \param bitpix : image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg2DWriter::FitsImg2DWriter(const char* cfname,int bitpix,int lp)
+: FitsWriter(cfname,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = 0;
+}
+
+/*!
+  Constructor.
+  \param fname : FITS file name to be written (created or updated)
+  \param update : file is created if FALSE, open for update if TRUE
+  \param bitpix : image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg2DWriter::FitsImg2DWriter(string fname,bool update,int bitpix,int lp)
+: FitsWriter(fname,update,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = 0;
+}
+
+/*!
+  Constructor.
+  \param cfname : FITS file name to be written (created or updated)
+  \param update : file is created if FALSE, open for update if TRUE
+  \param bitpix : image type (BYTE_IMG,USHORT_IMG,SHORT_IMG,LONG_IMG,FLOAT_IMG,DOUBLE_IMG)
+  \param lp : debug level
+*/
+FitsImg2DWriter::FitsImg2DWriter(const char* cfname,bool update,int bitpix,int lp)
+: FitsWriter(cfname,update,lp)
+{
+ BitPix = bitpix;
+ HduType = IMAGE_HDU;
+ FirstTime = true;
+ Naxis[0] = Naxis[1] = 0;
+}
+
+/*! Destructor */
+FitsImg2DWriter::~FitsImg2DWriter()
+{
+}
+
+/*! Create the image. Done at the first write request. */
+void FitsImg2DWriter::createimg(void)
+{
+ if(!FirstTime)
+   throw NotAvailableOperation("FitsImg2DWriter::createimg: already created image\n");
+ if(Naxis[0]<=0 || Naxis[1]<=0)
+   throw ParmError("FitsImg2DWriter::createimg: bad Naxis 1 or 2 value\n");
+
+ int sta=0;
+ if(fits_create_img(FitsPtr,BitPix,2,Naxis,&sta)) {
+   printerror(sta);
+   throw NullPtrError("FitsImg2DWriter::createimg: Error creating image extension\n");
+ }
+
+ FirstTime = false;
+}
+
+/*!
+  Write an image to FITS file.
+  \warning TMatrix data(Naxis2,Naxis1)
+*/
+void FitsImg2DWriter::Write(TMatrix<uint_2>& data)
+{
+ Naxis[0]=data.NCols(); Naxis[1]=data.NRows(); createimg();
+ uint_2* arr = new uint_2[Naxis[0]];
+
+ for(int j=0;j<Naxis[1];j++) {
+   for(int i=0;i<Naxis[0];i++) arr[i] = data(j,i);
+   long deb = j*Naxis[0]+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,TUSHORT,deb,nel,arr,&sta);
+   if(sta) {
+     printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Write(TMatrix<uint_2>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Write an image to FITS file. */
+void FitsImg2DWriter::Write(TMatrix<int_4>& data)
+{
+ int T = (sizeof(long)==4) ? TLONG: TINT;
+ Naxis[0]=data.NCols(); Naxis[1]=data.NRows(); createimg();
+ int_4* arr = new int_4[Naxis[0]];
+
+ for(int j=0;j<Naxis[1];j++) {
+   for(int i=0;i<Naxis[0];i++) arr[i] = data(j,i);
+   long deb = j*Naxis[0]+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,T,deb,nel,arr,&sta);
+   if(sta) {
+     printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Write(TMatrix<int_4>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Write an image to FITS file. */
+void FitsImg2DWriter::Write(TMatrix<float>& data)
+{
+ Naxis[0]=data.NCols(); Naxis[1]=data.NRows(); createimg();
+ float* arr = new float[Naxis[0]];
+
+ for(int j=0;j<Naxis[1];j++) {
+   for(int i=0;i<Naxis[0];i++) arr[i] = data(j,i);
+   long deb = j*Naxis[0]+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,TFLOAT,deb,nel,arr,&sta);
+   if(sta) {
+     printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Write(TMatrix<float>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Write an image to FITS file. */
+void FitsImg2DWriter::Write(TMatrix<double>& data)
+{
+ Naxis[0]=data.NCols(); Naxis[1]=data.NRows(); createimg();
+ double* arr = new double[Naxis[0]];
+
+ for(int j=0;j<Naxis[1];j++) {
+   for(int i=0;i<Naxis[0];i++) arr[i] = data(j,i);
+   long deb = j*Naxis[0]+1, nel = Naxis[0]; int sta=0;
+   fits_write_img(FitsPtr,TDOUBLE,deb,nel,arr,&sta);
+   if(sta) {
+     printerror(sta); delete [] arr;
+     throw
+       NotAvailableOperation("FitsImg2DRd::Write(TMatrix<double>): Error Writing Fits file\n");
+   }
+ }
+
+ delete [] arr;
+}
+
+/*! Print infos. */
+void FitsImg2DWriter::Print(ostream& os) const
+{
+os<<"FitsImg2DWriter::Print: FitsFN "<<FitsFN<<endl
+  <<"  HduType "<<HduType<<"  NOverFlow "<<NOverFlow<<"  BitPix "<<BitPix
+  <<"  Naxis1 "<<Naxis[0]<<"  Naxis2 "<<Naxis[1]<<endl;
+}
Index: trunk/SophyaExt/FitsIOServer/fabtwriter.h
===================================================================
--- trunk/SophyaExt/FitsIOServer/fabtwriter.h	(revision 2451)
+++ trunk/SophyaExt/FitsIOServer/fabtwriter.h	(revision 2453)
@@ -16,13 +16,16 @@
 namespace SOPHYA {
 
-//! Class for writing a FITS ASCII or BINARY table
-class FitsABTWriter : public AnyDataObj {
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+//! Class for writing into a FITS file (DO NOT USE)
+class FitsWriter : public AnyDataObj {
+protected:
+  FitsWriter(string fname,int lp=0);
+  FitsWriter(const char* cfname,int lp=0);
+  FitsWriter(string fname,bool update,int lp=0);
+  FitsWriter(const char* cfname,bool update,int lp=0);
+  virtual ~FitsWriter();
+
 public:
-  FitsABTWriter(string fname,int hdutype=BINARY_TBL,int lp=0);
-  FitsABTWriter(const char* cfname,int hdutype=BINARY_TBL,int lp=0);
-  FitsABTWriter(string fname,bool update,int hdutype=BINARY_TBL,int lp=0);
-  FitsABTWriter(const char* cfname,bool update,int hdutype=BINARY_TBL,int lp=0);
-  virtual ~FitsABTWriter();
-
   void Flush(void);
 
@@ -36,4 +39,48 @@
   inline void WriteKey(const char *keyname,char* val,char* comment=NULL)
                       {string dum=val; WriteKey(keyname,dum,comment);}
+  //! Set debug level
+  inline void SetDebug(int lp=0) {DbgLevel = (unsigned short) lp;}
+
+  //! Return the number of overflows managed by cfitsio
+  inline unsigned long GetNOverFlow(void) {return NOverFlow;}
+
+protected:
+  struct KeyDouble {string keyname; double val; string comment;};
+  struct KeyLong   {string keyname; long   val; string comment;};
+  struct KeyString {string keyname; string val; string comment;};
+
+  void cr_or_upd_fits(const char *cfname,bool update,int lp);
+
+  void writekeys(void);
+  void printerrorwrite(const char* type,int col,long row,int sta);
+  void printerror(int sta) const;
+
+  string FitsFN,ExtName;
+  bool Update;
+  int HduType;
+  unsigned short DbgLevel;
+  fitsfile *FitsPtr;
+  unsigned long NOverFlow;
+
+  vector<struct KeyDouble> DoubleKey;
+  vector<struct KeyLong>   LongKey;
+  vector<struct KeyString> StringKey;
+};
+
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+//! Class for writing a FITS ASCII or BINARY table
+class FitsABTWriter : public FitsWriter {
+public:
+  FitsABTWriter(string fname,int hdutype=BINARY_TBL,int lp=0);
+  FitsABTWriter(const char* cfname,int hdutype=BINARY_TBL,int lp=0);
+  FitsABTWriter(string fname,bool update,int hdutype=BINARY_TBL,int lp=0);
+  FitsABTWriter(const char* cfname,bool update,int hdutype=BINARY_TBL,int lp=0);
+  virtual ~FitsABTWriter();
+
+  //! Set the FITS table extension name
+  inline void SetExtName(string extname=string("")) {ExtName = extname;}
+  //! Set the FITS table extension name
+  inline void SetExtName(char* extname="") {ExtName = extname;}
 
   //! Add a new column to the FITS table and return its number (see addcol).
@@ -45,11 +92,4 @@
                    ,const char* tunit="",int datatype=TDOUBLE)
      {return addcol(label,tform,tunit,datatype);}
-
-  //! Set the FITS table extension name
-  inline void SetExtName(string extname=string("")) {ExtName = extname;}
-  //! Set the FITS table extension name
-  inline void SetExtName(char* extname="") {ExtName = extname;}
-  //! Set debug level
-  inline void SetDebug(int lp=0) {DbgLevel = (unsigned short) lp;}
 
   void Write(int col,long row,uint_1 val);
@@ -66,6 +106,4 @@
   long Write(int col,long row,TVector<float>& val);
   long Write(int col,long row,TVector<double>& val);
-  //! Return the number of overflows managed by cfitsio
-  inline unsigned long GetNOverFlow(void) {return NOverFlow;}
 
   //! Return the number of created columns
@@ -78,30 +116,40 @@
 
 protected:
-  struct KeyDouble {string keyname; double val; string comment;};
-  struct KeyLong   {string keyname; long   val; string comment;};
-  struct KeyString {string keyname; string val; string comment;};
+  int addcol(const char* label,const char* tform,const char* tunit,int datatype);
+  void createtbl(void);
 
-  void cr_or_upd_fits(const char *cfname,bool update,int hdutype,int lp);
-  int addcol(const char* label,const char* tform
-            ,const char* tunit,int datatype);
-  void createtbl(void);
-  void writekeys(void);
-  void printerrorwrite(const char* type,int col,long row,int sta);
-  void printerror(int sta) const;
-
-  string FitsFN,ExtName;
-  bool Update;
-  int HduType;
-  unsigned short DbgLevel;
-  fitsfile *FitsPtr;
   bool FirstTime;
   vector<string> Label;
   vector<string> TForm;
   vector<string> TUnit;
-  unsigned long NOverFlow;
+};
 
-  vector<struct KeyDouble> DoubleKey;
-  vector<struct KeyLong>   LongKey;
-  vector<struct KeyString> StringKey;
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+//! Class for writing a FITS Image
+class FitsImg2DWriter : public FitsWriter {
+public:
+  FitsImg2DWriter(string fname,int bitpix=FLOAT_IMG,int lp=0);
+  FitsImg2DWriter(const char* cfname,int bitpix=FLOAT_IMG,int lp=0);
+  FitsImg2DWriter(string fname,bool update,int bitpix=FLOAT_IMG,int lp=0);
+  FitsImg2DWriter(const char* cfname,bool update,int bitpix=FLOAT_IMG,int lp=0);
+  virtual ~FitsImg2DWriter();
+
+  void Write(TMatrix<uint_2>& data);
+  void Write(TMatrix<int_4>& data);
+  void Write(TMatrix<float>& data);
+  void Write(TMatrix<double>& data);
+
+  //! Print to os
+  virtual void   Print(ostream& os) const;
+  //! Print to stdout
+  inline  void   Print(void) const {Print(cout);}
+
+protected:
+  void createimg(void);
+
+  int BitPix;
+  long Naxis[2];
+  bool FirstTime;
 };
 
