You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
233 lines
5.3 KiB
233 lines
5.3 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkPNMReader.cxx,v $
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.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 "vtkPNMReader.h"
|
|
|
|
#include "vtkImageData.h"
|
|
#include "vtkObjectFactory.h"
|
|
|
|
vtkCxxRevisionMacro(vtkPNMReader, "$Revision: 1.32 $");
|
|
vtkStandardNewMacro(vtkPNMReader);
|
|
|
|
char vtkPNMReaderGetChar(FILE *fp)
|
|
{
|
|
char c;
|
|
int result;
|
|
|
|
if ((result = getc(fp)) == EOF )
|
|
{
|
|
return '\0';
|
|
}
|
|
|
|
c = (char)result;
|
|
if (c == '#')
|
|
{
|
|
do
|
|
{
|
|
if ((result = getc(fp)) == EOF )
|
|
{
|
|
return '\0';
|
|
}
|
|
c = (char)result;
|
|
}
|
|
while (c != '\n');
|
|
}
|
|
|
|
return c;
|
|
}
|
|
|
|
int vtkPNMReaderGetInt(FILE *fp)
|
|
{
|
|
char c;
|
|
int result = 0;
|
|
|
|
do
|
|
{
|
|
c = vtkPNMReaderGetChar(fp);
|
|
}
|
|
while ((c < '1')||(c > '9'));
|
|
do
|
|
{
|
|
result = result * 10 + (c - '0');
|
|
c = vtkPNMReaderGetChar(fp);
|
|
}
|
|
while ((c >= '0')&&(c <= '9'));
|
|
|
|
// put the CR/LF or whitespace back.....
|
|
ungetc(c, fp);
|
|
return result;
|
|
}
|
|
|
|
|
|
void vtkPNMReader::ExecuteInformation()
|
|
{
|
|
int xsize, ysize, comp;
|
|
char magic[80];
|
|
char c;
|
|
FILE *fp;
|
|
|
|
// if the user has not set the extent, but has set the VOI
|
|
// set the zaxis extent to the VOI z axis
|
|
if (this->DataExtent[4]==0 && this->DataExtent[5] == 0 &&
|
|
(this->DataVOI[4] || this->DataVOI[5]))
|
|
{
|
|
this->DataExtent[4] = this->DataVOI[4];
|
|
this->DataExtent[5] = this->DataVOI[5];
|
|
}
|
|
|
|
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]);
|
|
|
|
// get the magic number by reading in a file
|
|
fp = fopen(this->InternalFileName,"rb");
|
|
if (!fp)
|
|
{
|
|
vtkErrorMacro("Unable to open file " << this->InternalFileName);
|
|
return;
|
|
}
|
|
|
|
do
|
|
{
|
|
c = vtkPNMReaderGetChar(fp);
|
|
if (c == '\0')
|
|
{ // Bad file.
|
|
this->GetOutput()->SetWholeExtent(0, -1, 0, -1, 0, -1);
|
|
fclose(fp);
|
|
return;
|
|
}
|
|
}
|
|
while (c != 'P');
|
|
magic[0] = c;
|
|
magic[1] = vtkPNMReaderGetChar(fp);
|
|
magic[2] = '\0';
|
|
|
|
// now get the dimensions
|
|
xsize = vtkPNMReaderGetInt(fp);
|
|
ysize = vtkPNMReaderGetInt(fp);
|
|
|
|
// read max pixel value into comp for now
|
|
vtkPNMReaderGetInt(fp);
|
|
// if file is ascii, any amount of whitespace may follow.
|
|
// if file is binary, a single whitespace character will follow.
|
|
// We only support binary ppm and pgm files right now. So the next
|
|
// character IS always ignored.
|
|
c = getc(fp);
|
|
|
|
// if this file was "written" on the PC, then a CR will have been
|
|
// written as a CR/LF combination. So, if this single whitespace
|
|
// character is a CR and it is followed by a LF, then swallow the
|
|
// linefeed character as well. (Not part of the PPM standard, but a
|
|
// a hard fact of life.
|
|
if ( c == 0x0d )
|
|
{
|
|
c = getc(fp);
|
|
if ( c != 0x0a )
|
|
{
|
|
ungetc( c, fp );
|
|
}
|
|
}
|
|
|
|
// Set the header size now that we have parsed it
|
|
this->SetHeaderSize(ftell(fp));
|
|
|
|
fclose(fp);
|
|
|
|
// compare magic number to determine file type
|
|
if ( ! strcmp(magic,"P5") )
|
|
{
|
|
comp = 1;
|
|
}
|
|
else if ( ! strcmp(magic,"P6") )
|
|
{
|
|
comp = 3;
|
|
}
|
|
else
|
|
{
|
|
vtkErrorMacro(<<"Unknown file type! " << this->InternalFileName
|
|
<<" is not a binary PGM or PPM!");
|
|
return;
|
|
}
|
|
|
|
// 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))
|
|
{
|
|
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->DataExtent[0] = 0;
|
|
this->DataExtent[1] = xsize - 1;
|
|
this->DataExtent[2] = 0;
|
|
this->DataExtent[3] = ysize - 1;
|
|
|
|
this->SetDataScalarTypeToUnsignedChar();
|
|
this->SetNumberOfScalarComponents(comp);
|
|
|
|
this->vtkImageReader::ExecuteInformation();
|
|
}
|
|
|
|
|
|
inline int iseol(int c)
|
|
{
|
|
return c == 10 || c == 13;
|
|
}
|
|
|
|
|
|
|
|
int vtkPNMReader::CanReadFile(const char* fname)
|
|
{
|
|
FILE *fp = fopen(fname, "rb");
|
|
if(!fp)
|
|
{
|
|
return 0;
|
|
}
|
|
unsigned char magic[3];
|
|
if(fread(magic, 1, 3, fp) != 3)
|
|
{
|
|
fclose(fp);
|
|
return 0;
|
|
}
|
|
int ok = ((magic[0] == 'P') &&
|
|
iseol(magic[2]) &&
|
|
(magic[1] >= '1' && magic[1] <= '6'));
|
|
fclose(fp);
|
|
if (ok)
|
|
{
|
|
return 3;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPNMReader::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
}
|
|
|