/*========================================================================= Program: Visualization Toolkit Module: vtkQImageToImageSource.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 "vtkQImageToImageSource.h" #include "vtkImageData.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include "vtkStreamingDemandDrivenPipeline.h" #include "vtkUnsignedCharArray.h" #include #include #include #include "vtkSmartPointer.h" #define VTK_CREATE(type, name) vtkSmartPointer name = vtkSmartPointer::New() vtkStandardNewMacro(vtkQImageToImageSource); //------------------------------------------------------------------------------ vtkQImageToImageSource::vtkQImageToImageSource() { this->QtImage = nullptr; this->SetNumberOfInputPorts(0); this->DataExtent[0] = 0; this->DataExtent[1] = 0; this->DataExtent[2] = 0; this->DataExtent[3] = 0; this->DataExtent[4] = 0; this->DataExtent[5] = 0; } //------------------------------------------------------------------------------ int vtkQImageToImageSource::RequestData(vtkInformation* vtkNotUsed(request), vtkInformationVector** vtkNotUsed(inputVector), vtkInformationVector* outputVector) { if (!QApplication::instance()) { vtkErrorMacro("You must initialize QApplication before using this filter."); return 0; } // get the info objects vtkInformation* outInfo = outputVector->GetInformationObject(0); vtkImageData* output = vtkImageData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); if (this->QtImage == nullptr) { vtkErrorMacro("Qt Image was not set."); return 0; } QImage newImage = this->QtImage->convertToFormat(QImage::Format_ARGB32); QSize size = newImage.size(); int width = size.width(); int height = size.height(); const unsigned char* data2 = newImage.bits(); unsigned char* data = new unsigned char[4 * width * height]; memcpy(data, data2, 4 * width * height); output->SetExtent(this->DataExtent); output->AllocateScalars(VTK_UNSIGNED_CHAR, 4); vtkUnsignedCharArray* array = vtkArrayDownCast(output->GetPointData()->GetScalars()); int i, j; unsigned char temp[4]; for (i = 0; i < height / 2; i++) { for (j = 0; j < width; j++) { int bottom_address = ((((height - 1) - i) * width) + j); int top_address = (i * width) + j; temp[0] = data[(4 * bottom_address) + 0]; temp[1] = data[(4 * bottom_address) + 1]; temp[2] = data[(4 * bottom_address) + 2]; temp[3] = data[(4 * bottom_address) + 3]; data[(4 * bottom_address) + 2] = data[(4 * top_address) + 0]; // B data[(4 * bottom_address) + 1] = data[(4 * top_address) + 1]; // G data[(4 * bottom_address) + 0] = data[(4 * top_address) + 2]; // R data[(4 * bottom_address) + 3] = data[(4 * top_address) + 3]; // A data[(4 * top_address) + 2] = temp[0]; // B data[(4 * top_address) + 1] = temp[1]; // G data[(4 * top_address) + 0] = temp[2]; // R data[(4 * top_address) + 3] = temp[3]; // A } } if (height % 2) { for (j = 0; j < width; j++) { int address = (i * width) + j; unsigned char temp1 = data[(4 * address) + 0]; data[(4 * address) + 0] = data[(4 * address) + 2]; data[(4 * address) + 2] = temp1; } } array->SetVoidArray(data, 4 * width * height, 0, vtkUnsignedCharArray::VTK_DATA_ARRAY_DELETE); return 1; } //------------------------------------------------------------------------------ int vtkQImageToImageSource::RequestInformation(vtkInformation* vtkNotUsed(request), vtkInformationVector** vtkNotUsed(inputVector), vtkInformationVector* outputVector) { // get the info objects vtkInformation* outInfo = outputVector->GetInformationObject(0); if (this->QtImage == nullptr) { vtkErrorMacro("Qt Image was not set."); return 0; } QSize size = this->QtImage->size(); this->DataExtent[1] = size.width() - 1; this->DataExtent[3] = size.height() - 1; outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), this->DataExtent, 6); return 1; } //------------------------------------------------------------------------------ void vtkQImageToImageSource::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); }