/*========================================================================= Program: Visualization Toolkit Module: vtkBMPWriter.cxx 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 "vtkBMPWriter.h" #include "vtkImageData.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include "vtkUnsignedCharArray.h" #include vtkStandardNewMacro(vtkBMPWriter); vtkCxxSetObjectMacro(vtkBMPWriter,Result,vtkUnsignedCharArray); vtkBMPWriter::vtkBMPWriter() { this->FileLowerLeft = 1; this->Result = nullptr; } vtkBMPWriter::~vtkBMPWriter() { if (this->Result) { this->Result->Delete(); this->Result = nullptr; } } void vtkBMPWriter::WriteFileHeader(ostream *file, vtkImageData *, int wExt[6]) { long temp; int width, height, dataWidth; int row; // Find the length of the rows to write. width = (wExt[1] - wExt[0] + 1); height = (wExt[3] - wExt[2] + 1); dataWidth = ((width*3+3)/4)*4; // spit out the BMP header file->put((char)66); file->put((char)77); temp = (long)(dataWidth*height) + 54L; file->put((char)(temp%256)); file->put((char)((temp%65536L)/256)); file->put((char)(temp/65536L)); for (row = 0; row < 5; row++) { file->put((char)0); } file->put((char)54); file->put((char)0); file->put((char)0); file->put((char)0); // info header file->put((char)40); file->put((char)0); file->put((char)0); file->put((char)0); file->put((char)(width%256)); file->put((char)(width/256)); file->put((char)0); file->put((char)0); file->put((char)(height%256)); file->put((char)(height/256)); file->put((char)0); file->put((char)0); file->put((char)1); file->put((char)0); file->put((char)24); for (row = 0; row < 25; row++) { file->put((char)0); } } void vtkBMPWriter::WriteFile(ostream *file, vtkImageData *data, int extent[6], int wExtent[6]) { int idx1, idx2; int rowLength, rowAdder, i; // in bytes unsigned char *ptr; int bpp; unsigned long count = 0; unsigned long target; float progress = this->Progress; float area; bpp = data->GetNumberOfScalarComponents(); // Make sure we actually have data. if ( !data->GetPointData()->GetScalars()) { vtkErrorMacro(<< "Could not get data from input."); return; } // take into consideration the scalar type if (data->GetScalarType() != VTK_UNSIGNED_CHAR) { vtkErrorMacro("BMPWriter only accepts unsigned char scalars!"); return; } // Row length of x axis rowLength = extent[1] - extent[0] + 1; rowAdder = (4 - ((extent[1]-extent[0] + 1)*3)%4)%4; area = ((extent[5] - extent[4] + 1)*(extent[3] - extent[2] + 1)* (extent[1] - extent[0] + 1)) / ((wExtent[5] -wExtent[4] + 1)*(wExtent[3] -wExtent[2] + 1)* (wExtent[1] -wExtent[0] + 1)); target = (unsigned long)((extent[5]-extent[4]+1)* (extent[3]-extent[2]+1)/(50.0*area)); target++; for (idx2 = extent[4]; idx2 <= extent[5]; ++idx2) { for (idx1 = extent[2]; idx1 <= extent[3]; idx1++) { if (!(count%target)) { this->UpdateProgress(progress + count/(50.0*target)); } count++; ptr = (unsigned char *)data->GetScalarPointer(extent[0], idx1, idx2); if (bpp == 1) { for (i = 0; i < rowLength; i++) { file->put(ptr[i]); file->put(ptr[i]); file->put(ptr[i]); } } if (bpp == 2) { for (i = 0; i < rowLength; i++) { file->put(ptr[i*2]); file->put(ptr[i*2]); file->put(ptr[i*2]); } } if (bpp == 3) { for (i = 0; i < rowLength; i++) { file->put(ptr[i*3 + 2]); file->put(ptr[i*3 + 1]); file->put(ptr[i*3]); } } if (bpp == 4) { for (i = 0; i < rowLength; i++) { file->put(ptr[i*4 + 2]); file->put(ptr[i*4 + 1]); file->put(ptr[i*4]); } } for (i = 0; i < rowAdder; i++) { file->put((char)0); } } } } void vtkBMPWriter::MemoryWrite( int dim, vtkImageData *input, int wExt[6], vtkInformation*inInfo) { std::ostringstream *oss; oss = new std::ostringstream(); this->WriteFileHeader(oss, input, wExt); this->RecursiveWrite(dim, input, inInfo, oss); vtkUnsignedCharArray *r = vtkUnsignedCharArray::New(); r->SetNumberOfComponents(1); size_t alen = oss->str().length(); r->SetNumberOfTuples(static_cast(alen)); unsigned char *buff = static_cast(r->GetVoidPointer(0)); memcpy(buff, oss->str().data(), alen); this->SetResult(r); r->Delete(); delete oss; } //---------------------------------------------------------------------------- void vtkBMPWriter::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os,indent); os << indent << "Result: " << this->Result << "\n"; }