void VolumeSlice::process() { auto vol = inport_.getData(); const ivec3 dims(vol->getDimensions()); switch (static_cast<CartesianCoordinateAxis>(sliceAlongAxis_.get())) { case CartesianCoordinateAxis::X: if (dims.x != sliceNumber_.getMaxValue()) { sliceNumber_.setMaxValue(dims.x); sliceNumber_.set(dims.x / 2); sliceNumber_.setCurrentStateAsDefault(); } break; case CartesianCoordinateAxis::Y: if (dims.y != sliceNumber_.getMaxValue()) { sliceNumber_.setMaxValue(dims.y); sliceNumber_.set(dims.y / 2); } break; case CartesianCoordinateAxis::Z: if (dims.z != sliceNumber_.getMaxValue()) { sliceNumber_.setMaxValue(dims.z); sliceNumber_.set(dims.z / 2); } break; } VolumeSliceDispatcher disp; image_ = vol->getDataFormat()->dispatch( disp, *vol, static_cast<CartesianCoordinateAxis>(sliceAlongAxis_.get()), static_cast<size_t>(sliceNumber_.get() - 1), image_); outport_.setData(image_); }
void PixelToBufferProcessor::inportChanged() { if (!inport_.hasData()) return; auto data = inport_.getData(); fromPixel_.setMaxValue(ivec2(data->getDimensions()) - 1); channel_.setMaxValue(static_cast<int>(data->getDataFormat()->components()) - 1); }
bool GraphicsContext3D::packPixels(const uint8_t* sourceData, DataFormat sourceDataFormat, unsigned width, unsigned height, unsigned sourceUnpackAlignment, unsigned destinationFormat, unsigned destinationType, AlphaOp alphaOp, void* destinationData, bool flipY) { int validSrc = width * TexelBytesForFormat(sourceDataFormat); int remainder = sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) : 0; int srcStride = remainder ? (validSrc + sourceUnpackAlignment - remainder) : validSrc; DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType); int dstStride = width * TexelBytesForFormat(dstDataFormat); if (flipY) { destinationData = static_cast<uint8_t*>(destinationData) + dstStride*(height - 1); dstStride = -dstStride; } if (!hasAlpha(sourceDataFormat) || !hasColor(sourceDataFormat) || !hasColor(dstDataFormat)) alphaOp = AlphaDoNothing; if (sourceDataFormat == dstDataFormat && alphaOp == AlphaDoNothing) { const uint8_t* ptr = sourceData; const uint8_t* ptrEnd = sourceData + srcStride * height; unsigned rowSize = (dstStride > 0) ? dstStride: -dstStride; uint8_t* dst = static_cast<uint8_t*>(destinationData); while (ptr < ptrEnd) { memcpy(dst, ptr, rowSize); ptr += srcStride; dst += dstStride; } return true; } FormatConverter converter(width, height, sourceData, destinationData, srcStride, dstStride); converter.convert(sourceDataFormat, dstDataFormat, alphaOp); if (!converter.success()) return false; return true; }
void VolumeLaplacian::process() { auto volume = inport_.getData(); VolumeLaplacian::Dispatcher disp; Volume* res = volume->getDataFormat()->dispatch(disp, volume.get()); outport_.setData(res); }
void TMIP::process() { auto volumes = inport_.getData(); if (volumes->empty()) { return; } auto firstVol = volumes->at(0); if (inport_.isChanged()) { const DataFormatBase* format = firstVol->getDataFormat(); volume0_ = std::make_shared<Volume>(firstVol->getDimensions(), format); volume0_->setModelMatrix(firstVol->getModelMatrix()); volume0_->setWorldMatrix(firstVol->getWorldMatrix()); // pass on metadata volume0_->copyMetaDataFrom(*firstVol); volume0_->dataMap_ = firstVol->dataMap_; volume1_ = std::shared_ptr<Volume>(volume0_->clone()); } int iterations = static_cast<int>(std::ceil(volumes->size() / static_cast<float>(maxSamplers_))); LogInfo(iterations); std::shared_ptr<Volume> readVol = volume0_; std::shared_ptr<Volume> writeVol = volume1_; int offset = 0; for (int i = 0; i < iterations; i++) { bool firstIT = i == 0; bool lastIT = i != 0 && iterations; auto startVolIT = volumes->begin() + offset + 1; if (firstIT) { auto endVolIT = volumes->begin() + offset + maxSamplers_; iteration(shader_, volumes->at(0), writeVol, startVolIT, endVolIT); } else if (!lastIT) { auto endVolIT = volumes->begin() + offset + maxSamplers_; iteration(shader_, readVol, writeVol, startVolIT, endVolIT); } else { iteration(shaderLast_, readVol, writeVol, startVolIT, volumes->end()); } std::swap(readVol, writeVol); offset += maxSamplers_; } outport_.setData(readVol); }
void ImageCL::update(bool editable) { // TODO: Convert more then just first color layer layerCL_ = nullptr; auto owner = static_cast<Image*>(this->getOwner()); if (editable) { layerCL_ = owner->getColorLayer()->getEditableRepresentation<LayerCL>(); } else { layerCL_ = const_cast<LayerCL*>(owner->getColorLayer()->getRepresentation<LayerCL>()); } if (layerCL_->getDataFormat() != owner->getDataFormat()) { owner->getColorLayer()->setDataFormat(layerCL_->getDataFormat()); owner->getColorLayer()->setDimensions(layerCL_->getDimensions()); } }
bool GraphicsContext3D::extractTextureData(unsigned int width, unsigned int height, GC3Denum format, GC3Denum type, unsigned int unpackAlignment, bool flipY, bool premultiplyAlpha, const void* pixels, Vector<uint8_t>& data) { // Assumes format, type, etc. have already been validated. DataFormat sourceDataFormat = getDataFormat(format, type); // Resize the output buffer. unsigned int componentsPerPixel, bytesPerComponent; if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent)) return false; unsigned int bytesPerPixel = componentsPerPixel * bytesPerComponent; data.resize(width * height * bytesPerPixel); if (!packPixels(static_cast<const uint8_t*>(pixels), sourceDataFormat, width, height, unpackAlignment, format, type, (premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing), data.data(), flipY)) return false; return true; }
/** * Creates a ImageDisk representation if there isn't an object already defined. **/ void ImageSourceSeries::process() { if (fileList_.empty()) return; std::string basePath{imageFileDirectory_.get()}; long currentIndex = currentImageIndex_.get() - 1; if ((currentIndex < 0) || (currentIndex >= static_cast<long>(fileList_.size()))) { LogError("Invalid image index. Exceeded number of files."); return; } std::string currentFileName{basePath + "/" + fileList_[currentIndex]}; imageFileName_.set(fileList_[currentIndex]); std::string fileExtension = filesystem::getFileExtension(currentFileName); auto factory = getNetwork()->getApplication()->getDataReaderFactory(); if (auto reader = factory->getReaderForTypeAndExtension<Layer>(fileExtension)) { try { auto outLayer = reader->readData(currentFileName); // Call getRepresentation here to force read a ram representation. // Otherwise the default image size, i.e. 256x265, will be reported // until you do the conversion. Since the LayerDisk does not have any metadata. auto ram = outLayer->getRepresentation<LayerRAM>(); // Hack needs to set format here since LayerDisk does not have a format. outLayer->setDataFormat(ram->getDataFormat()); auto outImage = std::make_shared<Image>(outLayer); outImage->getRepresentation<ImageRAM>(); outport_.setData(outImage); } catch (DataReaderException const& e) { util::log(e.getContext(), "Could not load data: " + imageFileName_.get() + ", " + e.getMessage(), LogLevel::Error); } } else { LogWarn("Could not find a data reader for file: " << currentFileName); // remove file from list fileList_.erase(fileList_.begin() + currentIndex); // adjust index property updateProperties(); } }
std::string Volume::getDataInfo() const { using P = Document::PathComponent; using H = utildoc::TableBuilder::Header; Document doc; doc.append("b", "Volume", { {"style", "color:white;"} }); utildoc::TableBuilder tb(doc.handle(), P::end()); tb(H("Format"), getDataFormat()->getString()); tb(H("Dimension"), getDimensions()); tb(H("Data Range"), dataMap_.dataRange); tb(H("Value Range"), dataMap_.valueRange); tb(H("Unit"), dataMap_.valueUnit); if (hasRepresentation<VolumeRAM>()) { auto volumeRAM = getRepresentation<VolumeRAM>(); if (volumeRAM->hasHistograms()) { auto histograms = volumeRAM->getHistograms(); for (size_t i = 0; i < histograms->size(); ++i) { std::stringstream ss; ss << "Channel " << i << " Min: " << (*histograms)[i].stats_.min << " Mean: " << (*histograms)[i].stats_.mean << " Max: " << (*histograms)[i].stats_.max << " Std: " << (*histograms)[i].stats_.standardDeviation; tb(H("Stats"), ss.str()); std::stringstream ss2; ss2 << "(1: " << (*histograms)[i].stats_.percentiles[1] << ", 25: " << (*histograms)[i].stats_.percentiles[25] << ", 50: " << (*histograms)[i].stats_.percentiles[50] << ", 75: " << (*histograms)[i].stats_.percentiles[75] << ", 99: " << (*histograms)[i].stats_.percentiles[99] << ")"; tb(H("Percentiles"), ss2.str()); } } } return doc; }
std::shared_ptr<VolumeRepresentation> Volume::createDefaultRepresentation() const { return createVolumeRAM(getDimensions(), getDataFormat()); }
void HeightFieldMapper::process() { if (!inport_.isReady()) return; auto srcImg = inport_.getData(); if (!srcImg) { LogWarn("No valid input image given"); return; } // check the number of channels const DataFormatBase *format = srcImg->getDataFormat(); std::size_t numInputChannels = format->getComponents(); size2_t dim = srcImg->getDimensions(); Image *outImg = nullptr; // check format of output image if (!outImg || (outImg->getDataFormat()->getId() != DataFormatId::Float32)) { // replace with new floating point image Image *img = new Image(dim, DataFloat32::get()); outport_.setData(img); outImg = img; } else if (outImg->getDimensions() != dim) { // adjust dimensions of output image outImg->setDimensions(dim); } LayerRAM *dstLayer = outImg->getColorLayer(0)->getEditableRepresentation<LayerRAM>(); float *data = static_cast<float *>(dstLayer->getData()); // convert input image to float image const LayerRAM *srcLayer = srcImg->getColorLayer(0)->getRepresentation<LayerRAM>(); // special case: input image is already FLOAT32 with 1 channel if ((numInputChannels == 1) && (format->getId() == DataFormatId::Float32)) { const float *srcData = static_cast<const float *>(srcLayer->getData()); std::copy(srcData, srcData + dim.x * dim.y, data); } else { switch (numInputChannels) { case 2: for (unsigned int y = 0; y < dim.y; ++y) { for (unsigned int x = 0; x < dim.x; ++x) { data[y * dim.x + x] = static_cast<float>(srcLayer->getValueAsVec2Double(glm::uvec2(x, y)).r); } } break; case 3: for (unsigned int y = 0; y < dim.y; ++y) { for (unsigned int x = 0; x < dim.x; ++x) { data[y * dim.x + x] = static_cast<float>(srcLayer->getValueAsVec3Double(glm::uvec2(x, y)).r); } } break; case 4: for (unsigned int y = 0; y < dim.y; ++y) { for (unsigned int x = 0; x < dim.x; ++x) { data[y * dim.x + x] = static_cast<float>(srcLayer->getValueAsVec4Double(glm::uvec2(x, y)).r); } } break; case 1: default: for (unsigned int y = 0; y < dim.y; ++y) { for (unsigned int x = 0; x < dim.x; ++x) { data[y * dim.x + x] = static_cast<float>(srcLayer->getValueAsSingleDouble(glm::uvec2(x, y))); } } break; } } // rescale data set std::size_t numValues = dim.x * dim.y; // determine min/max values float minVal = *std::min_element(data, data + numValues); float maxVal = *std::max_element(data, data + numValues); switch (scalingModeProp_.get()) { case HeightFieldScaling::SeaLevel: { // scale heightfield based on sea level and min/max height float sealevel = seaLevel_.get(); float aboveSea = maxVal - sealevel; float belowSea = minVal - sealevel; float factor = maxHeight_.get() / std::max(aboveSea, std::abs(belowSea)); for (std::size_t i = 0; i < numValues; ++i) { data[i] = (data[i] - sealevel) * factor; } } break; case HeightFieldScaling::DataRange: { // scale data to [heightRange_.min : heightRange_.max] glm::vec2 range(heightRange_.get()); float factor = (range.y - range.x) / (maxVal - minVal); for (std::size_t i = 0; i < numValues; ++i) { data[i] = (data[i] - minVal) * factor + range.x; } } break; case HeightFieldScaling::FixedRange: default: { // scale data to [0:1] range float delta = 1.0f / (maxVal - minVal); for (std::size_t i = 0; i < numValues; ++i) { data[i] = (data[i] - minVal) * delta; } } break; } }
std::shared_ptr<LayerRepresentation> Layer::createDefaultRepresentation() const { return createLayerRAM(getDimensions(), getLayerType(), getDataFormat()); }