// Module PI : Peida Interactive     PIPixmap
// Classes utilitaires pour representation de pixels et couleurs RGB pour PI
//                             R. Ansari  09/2008
// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;

#include "pipixutils.h"

//++
// Class	PIPixColIdx
// Lib		PI
// include	pipixmapgen.h
//
//   	Classe auxiliaire de gestion d'index de couleurs pour les pixmap,
//	organise en interne en byte ou short.
//--

PIPixColIdx::PIPixColIdx()
{
  pix8 = NULL;
  pix16 = NULL;
  sx_ = sy_ = 0;
}

PIPixColIdx::~PIPixColIdx()
{
  if (pix8)  delete[] pix8;
  if (pix16)  delete[] pix16;
}

void PIPixColIdx::AllocateByte(int sx, int sy)
{
  size_t osz = sx_*sy_;
  if (sx<=0)  sx=sy=0;
  else if (sy<=0)  sx=sy=0;
  sx_ = sx; sy_ = sy; 
  if (pix16)  delete[] pix16;
  pix16 = NULL;
  size_t nsz = sx_*sy_;
  if (pix8) {
    if (osz == nsz) return;
    delete[] pix8;   pix8 = NULL;
  }
  if ((nsz > 0)&&(pix8==NULL)) {
    pix8 = new unsigned char[nsz];
  }
}

void PIPixColIdx::AllocateShort(int sx, int sy)
{
  size_t osz = sx_*sy_;
  if (sx<=0)  sx=sy=0;
  else if (sy<=0)  sx=sy=0;
  sx_ = sx; sy_ = sy; 
  if (pix8)  delete[] pix8;
  pix8 = NULL;
  size_t nsz = sx_*sy_;
  if (pix16) {
    if (osz == nsz) return;
    delete[] pix16;   pix16 = NULL;
  }
  if ((nsz > 0)&&(pix16==NULL)) 
    pix16 = new unsigned short[nsz];
}


//++
// Class	PIPixRGBArray
// Lib		PI
// include	pipixmapgen.h
//
//   	Classe auxiliaire de gestion tableau representant des pixels RGB,
//	chaque composante codee en 8 bits (unsigned char)
//--

PIPixRGBArray::PIPixRGBArray(int sx, int sy)
{
  sx_ = sy_  = 0;
  rgbpix_ = NULL; 
  SetSize(sx, sy);
}

PIPixRGBArray::PIPixRGBArray(const char * filename)
{
  sx_ = sy_ = 0;
  rgbpix_ = NULL; 
  ReadFrFile(filename); 	
}

PIPixRGBArray::~PIPixRGBArray()
{
  if (rgbpix_) delete[] rgbpix_;	
}

void PIPixRGBArray::SetSize(int sx, int sy)
{
  if ((sx == sx_)&&(sy == sy_)) return;
  if (sx < 0) sx = 0;
  if (sy < 0) sy = 0;
  if (rgbpix_)  delete[] rgbpix_;
  sx_ = sx;  sy_ = sy;	
  size_t sz = sx_*sy_;
  if (sz>0) rgbpix_ = new PIPixRGB[sz];
  else rgbpix_ = NULL;  
}

int PIPixRGBArray::SaveToFile(const char * filename)   const 
{
  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;	  
}

