Cloned library of VTK-5.0.0 with extra build files for internal package management.
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.
 
 
 
 
 
 

301 lines
8.6 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkTIFFWriter.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 "vtkTIFFWriter.h"
#include "vtkErrorCode.h"
#include "vtkImageData.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtk_tiff.h"
vtkCxxRevisionMacro(vtkTIFFWriter, "$Revision: 1.39.6.1 $");
vtkStandardNewMacro(vtkTIFFWriter);
//----------------------------------------------------------------------------
vtkTIFFWriter::vtkTIFFWriter()
{
this->TIFFPtr = 0;
this->Compression = vtkTIFFWriter::PackBits;
};
class vtkTIFFWriterIO
{
public:
// Writing file no reading
static tsize_t TIFFRead(thandle_t, tdata_t, tsize_t) { return 0; }
// Write data
static tsize_t TIFFWrite(thandle_t fd, tdata_t buf, tsize_t size)
{
ostream *out = reinterpret_cast<ostream *>(fd);
out->write(static_cast<char *>(buf), size);
return out->fail() ? static_cast<tsize_t>(0) : size;
}
static toff_t TIFFSeek(thandle_t fd, toff_t off, int whence)
{
ostream *out = reinterpret_cast<ostream *>(fd);
switch (whence)
{
case SEEK_SET:
out->seekp(off, ios::beg);
break;
case SEEK_END:
out->seekp(off, ios::end);
break;
case SEEK_CUR:
out->seekp(off, ios::cur);
break;
default:
return out->tellp();
}
return out->tellp();
}
// File will be closed by the superclass
static int TIFFClose(thandle_t) { return 1; }
static toff_t TIFFSize(thandle_t fd)
{
ostream *out = reinterpret_cast<ostream *>(fd);
out->seekp(0, ios::end);
return out->tellp();
}
static int TIFFMapFile(thandle_t, tdata_t*, toff_t*) { return (0); }
static void TIFFUnmapFile(thandle_t, tdata_t, toff_t) {}
};
//----------------------------------------------------------------------------
void vtkTIFFWriter::WriteFileHeader(ofstream *file, vtkImageData *data)
{
int dims[3];
int width, height;
data->GetDimensions(dims);
int scomponents = data->GetNumberOfScalarComponents();
int stype = data->GetScalarType();
double resolution = -1;
uint32 rowsperstrip = (uint32) -1;
int min0, min1, max0, max1, min2, max2;
int bps;
switch (stype)
{
case VTK_CHAR:
case VTK_SIGNED_CHAR:
case VTK_UNSIGNED_CHAR:
bps = 8;
break;
case VTK_SHORT:
case VTK_UNSIGNED_SHORT:
bps = 16;
break;
case VTK_FLOAT:
bps = 32;
break;
default:
vtkErrorMacro(<< "Unsupported data type: " << data->GetScalarTypeAsString());
this->SetErrorCode(vtkErrorCode::FileFormatError);
return;
}
int predictor;
ostream* ost = file;
// Find the length of the rows to write.
data->GetWholeExtent(min0, max0, min1, max1, min2, max2);
width = (max0 - min0 + 1);
height = (max1 - min1 + 1);
TIFF* tif = TIFFClientOpen(this->GetFileName(), "w",
(thandle_t) ost,
reinterpret_cast<TIFFReadWriteProc>(vtkTIFFWriterIO::TIFFRead),
reinterpret_cast<TIFFReadWriteProc>(vtkTIFFWriterIO::TIFFWrite),
reinterpret_cast<TIFFSeekProc>(vtkTIFFWriterIO::TIFFSeek),
reinterpret_cast<TIFFCloseProc>(vtkTIFFWriterIO::TIFFClose),
reinterpret_cast<TIFFSizeProc>(vtkTIFFWriterIO::TIFFSize),
reinterpret_cast<TIFFMapFileProc>(vtkTIFFWriterIO::TIFFMapFile),
reinterpret_cast<TIFFUnmapFileProc>(vtkTIFFWriterIO::TIFFUnmapFile)
);
if ( !tif )
{
this->TIFFPtr = 0;
return;
}
this->TIFFPtr = tif;
uint32 w = width;
uint32 h = height;
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, w);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, h);
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, scomponents);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); // Fix for stype
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
if(stype == VTK_FLOAT)
{
TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
}
if ( scomponents > 3 )
{
// if number of scalar components is greater than 3, that means we assume
// there is alpha.
uint16 extra_samples = scomponents-3;
uint16 *sample_info = new uint16[scomponents-3];
sample_info[0]=EXTRASAMPLE_ASSOCALPHA;
int cc;
for ( cc = 1; cc < scomponents-3; cc ++ )
{
sample_info[cc] = EXTRASAMPLE_UNSPECIFIED;
}
TIFFSetField(tif,TIFFTAG_EXTRASAMPLES,extra_samples,
sample_info);
delete [] sample_info;
}
int compression;
switch ( this->Compression )
{
case vtkTIFFWriter::PackBits: compression = COMPRESSION_PACKBITS; break;
case vtkTIFFWriter::JPEG: compression = COMPRESSION_JPEG; break;
case vtkTIFFWriter::Deflate: compression = COMPRESSION_DEFLATE; break;
case vtkTIFFWriter::LZW: compression = COMPRESSION_LZW; break;
default: compression = COMPRESSION_NONE;
}
//compression = COMPRESSION_JPEG;
TIFFSetField(tif, TIFFTAG_COMPRESSION, compression); // Fix for compression
uint16 photometric =
(scomponents == 1 ? PHOTOMETRIC_MINISBLACK : PHOTOMETRIC_RGB);
if ( compression == COMPRESSION_JPEG )
{
TIFFSetField(tif, TIFFTAG_JPEGQUALITY, 75); // Parameter
TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
photometric = PHOTOMETRIC_YCBCR;
}
else if ( compression == COMPRESSION_LZW )
{
predictor = 2;
TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor);
vtkErrorMacro("LZW compression is patented outside US so it is disabled");
}
else if ( compression == COMPRESSION_DEFLATE )
{
predictor = 2;
TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor);
}
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric); // Fix for scomponents
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP,
TIFFDefaultStripSize(tif, rowsperstrip));
if (resolution > 0)
{
TIFFSetField(tif, TIFFTAG_XRESOLUTION, resolution);
TIFFSetField(tif, TIFFTAG_YRESOLUTION, resolution);
TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
}
}
//----------------------------------------------------------------------------
void vtkTIFFWriter::WriteFile(ofstream *, vtkImageData *data,
int extent[6])
{
int idx1, idx2;
void *ptr;
// Make sure we actually have data.
if ( !data->GetPointData()->GetScalars())
{
vtkErrorMacro(<< "Could not get data from input.");
return;
}
TIFF* tif = reinterpret_cast<TIFF*>(this->TIFFPtr);
if ( !tif )
{
vtkErrorMacro("Problem writting trailer.");
this->SetErrorCode(vtkErrorCode::FileFormatError);
return;
}
// take into consideration the scalar type
if( data->GetScalarType() != VTK_UNSIGNED_CHAR
&& data->GetScalarType() != VTK_UNSIGNED_SHORT
&& data->GetScalarType() != VTK_FLOAT
)
{
vtkErrorMacro("TIFFWriter only accepts unsigned char/short or float scalars!");
return;
}
int row = 0;
for (idx2 = extent[4]; idx2 <= extent[5]; ++idx2)
{
for (idx1 = extent[3]; idx1 >= extent[2]; idx1--)
{
ptr = data->GetScalarPointer(extent[0], idx1, idx2);
if ( TIFFWriteScanline(tif, static_cast<unsigned char*>(ptr), row, 0) < 0)
{
this->SetErrorCode(vtkErrorCode::OutOfDiskSpaceError);
break;
}
row ++;
}
}
}
//----------------------------------------------------------------------------
void vtkTIFFWriter::WriteFileTrailer(ofstream *, vtkImageData *)
{
TIFF* tif = reinterpret_cast<TIFF*>(this->TIFFPtr);
if ( !tif )
{
vtkErrorMacro("Problem writting trailer.");
this->SetErrorCode(vtkErrorCode::FileFormatError);
}
TIFFClose(tif);
this->TIFFPtr = 0;
}
//----------------------------------------------------------------------------
void vtkTIFFWriter::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Compression: ";
if ( this->Compression == vtkTIFFWriter::PackBits )
{
os << "Pack Bits\n";
}
else if ( this->Compression == vtkTIFFWriter::JPEG )
{
os << "JPEG\n";
}
else if ( this->Compression == vtkTIFFWriter::Deflate )
{
os << "Deflate\n";
}
else if ( this->Compression == vtkTIFFWriter::LZW )
{
os << "LZW\n";
}
else //if ( this->Compression == vtkTIFFWriter::NoCompression )
{
os << "No Compression\n";
}
}