/*=========================================================================

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/VolViewCopyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkPICReader.h"
#include <stdio.h>
#include "vtkObjectFactory.h"



//----------------------------------------------------------------------------
vtkStandardNewMacro(vtkPICReader);
vtkCxxRevisionMacro(vtkPICReader, "$Revision: 1.9 $");

void vtkPICReader::ExecuteInformation()
{
  unsigned char header[76];
  FILE *fp;
  this->Error = 1;
  
  if (!this->FileName && !this->FilePattern)
    {
    vtkErrorMacro(<<"Either a FileName or FilePattern must be specified.");
    return;
    }
  // Allocate the space for the filename
  this->ComputeInternalFileName(this->DataExtent[4]);
  
  // read in the header
  fp = fopen(this->InternalFileName,"rb");
  if (!fp)
    {
    vtkErrorMacro("Unable to open file " << this->InternalFileName);
    return;
    }
  fread(header,1,76,fp);
  fclose(fp);
  
  int xsize, ysize, zsize, psize, magic;
  
  xsize = header[0] + header[1]*256;
  ysize = header[2] + header[3]*256;
  zsize = header[4] + header[5]*256;
  psize = header[14] + header[15]*256;
  magic = header[54] + header[55]*256;
  
  if (magic != 12345)
    {
    vtkErrorMacro(<<"Unknown file type! Not a standard PIC file");
    return;
    }
  
  // Set the header size now that we have parsed it
  this->SetHeaderSize(76);

  // if the user has set the VOI, just make sure its valid
  if (this->DataVOI[0] || this->DataVOI[1] || 
      this->DataVOI[2] || this->DataVOI[3] ||
      this->DataVOI[4] || this->DataVOI[5])
    { 
    if ((this->DataVOI[0] < 0) ||
        (this->DataVOI[1] >= xsize) ||
        (this->DataVOI[2] < 0) ||
        (this->DataVOI[3] >= ysize) ||
        (this->DataVOI[4] < 0) ||
        (this->DataVOI[5] >= zsize))
      {
      vtkWarningMacro("The requested VOI is larger than the file's (" << this->InternalFileName << ") extent ");
      this->DataVOI[0] = 0;
      this->DataVOI[1] = xsize - 1;
      this->DataVOI[2] = 0;
      this->DataVOI[3] = ysize - 1;
      this->DataVOI[4] = 0;
      this->DataVOI[5] = zsize - 1;
      }
    }

  this->DataExtent[0] = 0;
  this->DataExtent[1] = xsize - 1;
  this->DataExtent[2] = 0;
  this->DataExtent[3] = ysize - 1;
  this->DataExtent[4] = 0;
  this->DataExtent[5] = zsize - 1;
  
  if (psize)
    {
    this->SetDataScalarTypeToUnsignedChar();
    }
  else
    {
    this->SetDataScalarTypeToUnsignedShort();
    }
  this->SetNumberOfScalarComponents(1);
  this->SetFileDimensionality(3);
  
  this->vtkImageReader::ExecuteInformation();
  this->Error = 0;
}



int vtkPICReader::CanReadFile(const char* fname)
{
  unsigned char header[76];
  FILE *fp;
  // read in the header
  fp = fopen(fname,"rb");
  if (!fp)
    {
    return 0;
    }
  fread(header,1,76,fp);
  fclose(fp);
  
  int magic;
  
  magic = header[54] + header[55]*256;
  
  if (magic != 12345)
    {
    return 0;
    }

  // since this is a weak header test (e.g. one in 65556 chance of being
  // wrong) determine the return type also based on file extension
  if (!strcmp(fname+strlen(fname)-3,"pic"))
    {
    return 3;
    }
  if (!strcmp(fname+strlen(fname)-3,"PIC"))
    {
    return 3;
    }
  return 2;
}

void vtkPICReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  
  os << indent << "Error: " << this->Error << endl;
}

