//-----------------------------------------------------------------------------
//
// IRISReader.h
//
// Sean Ho
// Mar2000
//
// Superclass of various image format file readers.
// Overrides vtkImageReader's OpenFile() method to do uncompression.
//-----------------------------------------------------------------------------

#ifndef IRIS_IRISREADER_H
#define IRIS_IRISREADER_H

#include <vtkImageData.h>
#include <vtkByteSwap.h>

#include <fstream.h>
#ifdef PIPE_UNCOMPRESS
#  include <pfstream.h>
#endif

#include "IrisTypes.h"

class IRISReader : public vtkObject {
protected:
  IRISReader() {};
  ~IRISReader() {};
  IRISReader(const IRISReader&) {};
  void operator=(const IRISReader&) {};

  ifstream *Input;

  int DataType;
  int BigEndian;
  int SwapBytes;
  int HeaderSize;
  int Dimensions[3];
  float PixDims[3];
  int Flip[3];
  int NeedHeader;

  void SetDefaults();

public:

  enum dimtype { X, Y, Z };

  vtkTypeMacro(IRISReader, vtkObject);
  void OpenFile(const char *filename);
  static IRISReader *New(ifstream *in);
  static IRISReader *New(const char *filename);

  // The header accessor functions are valid only after ReadHeader() is called.
  // Subclasses will want to override this method.
  virtual int ReadHeader();

  // GetImageData() is valid only after ReadData() is called.
  virtual int ReadData(vtkImageData *ImageData);

  // DataType is 1 for unsigned char, 2 for unsigned short, 4 for unsigned int
  // Not coincidentally, it's the length in bytes of the type
  vtkSetMacro(DataType, int);
  vtkGetMacro(DataType, int);

  // Nonzero iff the ifstream data is big-endian.
  void SetBigEndian(int b);
  vtkGetMacro(BigEndian, int);

  // How many bytes to skip for the header
  vtkSetMacro(HeaderSize, int);
  vtkGetMacro(HeaderSize, int);

  // Extents of the image, e.g. 256x256x94
  vtkSetVector3Macro(Dimensions, int);
  vtkGetVector3Macro(Dimensions, int);
  void SetDimensions(Coord3i c) { this->SetDimensions(c[0], c[1], c[2]); }

  // Dimensions of an individual pixel/voxel, in world size (e.g. mm^3)
  vtkSetVector3Macro(PixDims, float);
  vtkGetVector3Macro(PixDims, float);
  void SetPixDims(Coord3f c) { this->SetPixDims(c[0], c[1], c[2]); }

  // A nonzero dimension asks for a flip in that dimension
  // As is consistent in VoxData and GUI, (0,0,0) means left-bottom-back,
  // but the default orientation is (0,1,1): left-top-front
  vtkSetVector3Macro(Flip, int);
  vtkGetVector3Macro(Flip, int);
  void SetFlip(Coord3i c) { this->SetFlip(c[0], c[1], c[2]); }
};

#endif /* IRIS_IRISREADER_H */
