Commit 753dcc6d authored by Morten Ofstad's avatar Morten Ofstad
Browse files

Creating metadata for survey coordinate system and original SEG-Y headers....

Creating metadata for survey coordinate system and original SEG-Y headers. Changed vector class to have X/Y/Z/T members and proper constructors. Added GlobalMetadataCommon.h and used definitions from there to get correct names. Fixed some previously incorrect names. Replaced to_hexstring() with fmt::format().
parent 4077b8ea
/****************************************************************************
** Copyright 2019 The Open Group
** Copyright 2019 Bluware, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
****************************************************************************/
#ifndef HUE_GLOBALMETADATACORE_H_INCLUDED
#define HUE_GLOBALMETADATACORE_H_INCLUDED
////////////////////////////////////////////////////////////////////////////////
// <copyright>
// Copyright (c) 2019 Hue AS. All rights reserved.
//
// All rights are reserved. Reproduction or transmission in whole or in part, in
// any form or by any means, electronic, mechanical or otherwise, is prohibited
// without the prior written permission of the copyright owner.
// </copyright>
////////////////////////////////////////////////////////////////////////////////
#include "KnownMetadata.h"
// Standard names for common dimensions
#define VDS_DIMENSION_INLINE_NAME KNOWNMETADATA_SURVEYCOORDINATE_INLINECROSSLINE_AXISNAME_INLINE
#define VDS_DIMENSION_CROSSLINE_NAME KNOWNMETADATA_SURVEYCOORDINATE_INLINECROSSLINE_AXISNAME_CROSSLINE
#define VDS_DIMENSION_CDP_NAME "CDP"
#define VDS_DIMENSION_GATHER_NAME "Gather"
#define VDS_DIMENSION_BARE_TRACE_NAME "Trace" // use VDS_DIMENSION_TRACE_NAME instead
#define VDS_DIMENSION_TRACE_NAME(sortOrder) VDS_DIMENSION_BARE_TRACE_NAME " (" sortOrder ")"
#define VDS_DIMENSION_SAMPLE_NAME KNOWNMETADATA_SURVEYCOORDINATE_INLINECROSSLINE_AXISNAME_SAMPLE
#define VDS_DIMENSION_CABLE_NAME "Cable"
#define VDS_DIMENSION_SHOT_NAME "Shot"
#define VDS_DIMENSION_RECEIVER_NAME "Receiver"
#define VDS_DIMENSION_FREQUENCY_NAME "Frequency"
#define VDS_DIMENSION_X_NAME "X"
#define VDS_DIMENSION_Y_NAME "Y"
#define VDS_DIMENSION_Z_NAME "Z"
#define VDS_DIMENSION_TIME_NAME KNOWNMETADATA_SURVEYCOORDINATE_INLINECROSSLINE_AXISNAME_TIME
#define VDS_DIMENSION_DEPTH_NAME KNOWNMETADATA_SURVEYCOORDINATE_INLINECROSSLINE_AXISNAME_DEPTH
#define VDS_DIMENSION_VELOCITY_NAME "Velocity"
#define VDS_DIMENSION_EASTING_NAME "Easting"
#define VDS_DIMENSION_NORTHING_NAME "Northing"
#define VDS_DIMENSION_RMO_NAME "RMO Parameter"
// Attributes' names
#define DEFAULT_ATTRIBUTE_NAME "Attribute"
#define Z_ATTRIBUTE_NAME VDS_DIMENSION_Z_NAME
#define TIME_ATTRIBUTE_NAME VDS_DIMENSION_TIME_NAME
#define DEPTH_ATTRIBUTE_NAME VDS_DIMENSION_DEPTH_NAME
#define AMPLITUDE_ATTRIBUTE_NAME "Amplitude"
#define INTECEPT_ATTRIBUTE_NAME "Intercept"
#define GRADIENT_ATTRIBUTE_NAME "Gradient"
#define ANGLE_ATTRIBUTE_NAME "Angle"
#define AZIMUTH_ATTRIBUTE_NAME "Azimuth"
#define RMS_VELOCITY_ATTRIBUTE_NAME "Vrms"
#define INTERVAL_VELOCITY_ATTRIBUTE_NAME "Vint"
#define AVERAGE_VELOCITY_ATTRIBUTE_NAME "Vavg"
#define AVERAGE_VELOCITY_BELOW_DATUM_ATTRIBUTE_NAME "Vavg (below datum)"
#define OFFSET_ATTRIBUTE_NAME "Offset"
#define ETA_ATTRIBUTE_NAME "Eta"
#define PROBABILITY_ATTRIBUTE_NAME "Probability"
// Sort orders for the trace dimension; pass as the parameter to VDS_DIMENSION_TRACE_NAME (case sensitive)
#define VDS_DIMENSION_TRACE_SORT_OFFSET "offset"
#define VDS_DIMENSION_TRACE_SORT_OFFSET_BY_CABLE "offset by cable"
#define VDS_DIMENSION_TRACE_SORT_ANGLE "angle"
#define VDS_DIMENSION_TRACE_SORT_ANGLE_BY_CABLE "angle by cable"
#define VDS_DIMENSION_TRACE_SORT_AZIMUTH "azimuth"
#define VDS_DIMENSION_TRACE_SORT_AZIMUTH_BY_CABLE "azimuth by cable"
//
// Global metadata section
//
// SurveyCoordinateSystem category of global metadata that contains information for locating the seismic in XY space.
#define LATTICE_CATEGORY KNOWNMETADATA_SURVEYCOORDINATESYSTEM
// Display lattice information for use in GetVDSCoordinateSystem
#define LATTICE_ORIGIN KNOWNMETADATA_SURVEYCOORDINATE_INLINECROSSLINE_ORIGIN
#define LATTICE_INLINE_SPACING KNOWNMETADATA_SURVEYCOORDINATE_INLINECROSSLINE_INLINESPACING
#define LATTICE_CROSSLINE_SPACING KNOWNMETADATA_SURVEYCOORDINATE_INLINECROSSLINE_CROSSLINESPACING
#define LATTICE_UNIT "Unit"
// Original / source lattice
#define LATTICE_ORIGIN_ORIGINAL "Original" LATTICE_ORIGIN
#define LATTICE_INLINE_SPACING_ORIGINAL "Original" LATTICE_INLINE_SPACING
#define LATTICE_CROSSLINE_SPACING_ORIGINAL "Original" LATTICE_CROSSLINE_SPACING
// Source CRS 4 strings
#define CRS_WKT "CRSWkt" //The well-known text in this coordinate system
// 2D trace positions
#define TRACE_COORDINATES_2D_CATEGORY KNOWNMETADATA_TRACECOORDINATES
#define TRACE_POSITIONS_2D KNOWNMETADATA_TRACEPOSITIONS
#define TRACE_POSITIONS_2D_ORIGINAL "TracePositionsOriginal"
#define TRACE_START_TIMES_2D KNOWNMETADATA_TRACEVERTICALOFFSETS
#endif // HUE_GLOBALMETADATACORE_H_INCLUDED
......@@ -21,41 +21,82 @@
namespace OpenVDS
{
template<typename T, size_t N>
struct Vector
template<typename T>
struct Vector2
{
T d[N];
inline T & operator[] (size_t n) { return d[n]; }
inline const T &operator[] (size_t n) const { return d[n]; }
typedef T element_type;
enum { element_count = 2 };
union
{
struct
{
T X, Y;
};
T data[2];
};
Vector2() : X(), Y() {}
Vector2(T X, T Y) : X(X), Y(Y) {}
inline T &operator[] (size_t n) { return data[n]; }
inline const T &operator[] (size_t n) const { return data[n]; }
};
template<typename T, size_t N>
static inline Vector<T, N> Add(const Vector<T, N> &a, const Vector<T, N> &b)
template<typename T>
struct Vector3
{
Vector<T,N> ret;
for (int i = 0; i < N; i++)
ret[i] = a[i] + b[i];
return ret;
}
typedef T element_type;
enum { element_count = 3 };
union
{
struct
{
T X, Y, Z;
};
T data[3];
};
Vector3() : X(), Y(), Z() {}
Vector3(T X, T Y, T Z) : X(X), Y(Y), Z(Z) {}
inline T &operator[] (size_t n) { return data[n]; }
inline const T &operator[] (size_t n) const { return data[n]; }
};
template<typename T, size_t N>
static inline Vector<T, N> Subtract(const Vector<T, N> &a, const Vector<T, N> &b)
template<typename TYPE>
struct Vector4
{
Vector<T,N> ret;
for (int i = 0; i < N; i++)
ret[i] = a[i] - b[i];
return ret;
}
typedef TYPE element_type;
enum { element_count = 4 };
union
{
struct
{
TYPE X, Y, Z, T;
};
TYPE data[4];
};
Vector4() : X(), Y(), Z(), T() {}
Vector4(TYPE X, TYPE Y, TYPE Z, TYPE T) : X(X), Y(Y), Z(Z), T(T) {}
inline TYPE &operator[] (size_t n) { return data[n]; }
inline const TYPE &operator[] (size_t n) const { return data[n]; }
};
/*
template<typename T, size_t N>
static inline Vector<T, N> Multiply(const Vector<T, N> &a, const Vector<T, N> &b)
struct Vector
{
Vector<T,N> ret;
for (int i = 0; i < N; i++)
ret[i] = a[i] * b[i];
return ret;
}
T d[N];
inline T & operator[] (size_t n) { return d[n]; }
inline const T &operator[] (size_t n) const { return d[n]; }
};
*/
/*
template<typename T, size_t N>
static inline bool operator==(const Vector<T, N> &a, const Vector<T, N> &b)
{
......@@ -75,14 +116,7 @@ bool operator!=(const Vector<T, N> &a, const Vector<T, N> &b)
return true;
}
template<typename T>
using Vector2 = Vector<T, 2>;
template<typename T>
using Vector3 = Vector<T, 3>;
template<typename T>
using Vector4 = Vector<T, 4>;
*/
using IntVector2 = Vector2<int>;
using IntVector3 = Vector3<int>;
using IntVector4 = Vector4<int>;
......
......@@ -23,6 +23,7 @@
#include <climits>
#include <json/json.h>
#include <assert.h>
#include <fmt/format.h>
Json::Value
serializeSEGYBinInfo(SEGYBinInfo const &binInfo)
......@@ -91,20 +92,13 @@ serializeSEGYHeaderField(SEGY::HeaderField const &headerField)
return jsonHeaderField;
}
std::string to_hexstring(uint64_t value)
{
char buffer[sizeof(value) * 2 + 1];
snprintf(buffer, sizeof(buffer), "%llX", value);
return std::string(buffer);
}
Json::Value
serializeSEGYFileInfo(SEGYFileInfo const &fileInfo)
{
Json::Value
jsonFileInfo;
jsonFileInfo["persistentID"] = to_hexstring(fileInfo.m_persistentID);
jsonFileInfo["persistentID"] = fmt::format("{:X}", fileInfo.m_persistentID);
jsonFileInfo["headerEndianness"] = to_string(fileInfo.m_headerEndianness);
jsonFileInfo["dataSampleFormatCode"] = (int)fileInfo.m_dataSampleFormatCode;
jsonFileInfo["sampleCount"] = fileInfo.m_sampleCount;
......
......@@ -26,6 +26,7 @@
#include <OpenVDS/VolumeDataAccess.h>
#include <OpenVDS/Range.h>
#include <OpenVDS/VolumeDataLayout.h>
#include <OpenVDS/GlobalMetadataCommon.h>
#include "cxxopts.hpp"
......@@ -248,6 +249,127 @@ analyzeSegment(OpenVDS::File const &file, SEGYFileInfo const &fileInfo, SEGYSegm
return true;
}
bool
createSEGYHeadersMetadata(OpenVDS::File const &file, OpenVDS::MetadataContainer &metadataContainer, OpenVDS::IOError &error)
{
std::vector<uint8_t> textHeader(SEGY::TextualFileHeaderSize);
std::vector<uint8_t> binaryHeader(SEGY::BinaryFileHeaderSize);
// Read headers
bool success = file.read( textHeader.data(), 0, SEGY::TextualFileHeaderSize, error) &&
file.read(binaryHeader.data(), SEGY::TextualFileHeaderSize, SEGY::BinaryFileHeaderSize, error);
if(!success) return false;
// Create metadata
{
OpenVDS::MetadataKey key = { OpenVDS::MetadataType::BLOB, "SEGY", "TextHeader" };
metadataContainer.blobData[key] = textHeader;
metadataContainer.keys.push_back(key);
}
{
OpenVDS::MetadataKey key = { OpenVDS::MetadataType::BLOB, "SEGY", "BinaryHeader" };
metadataContainer.blobData[key] = binaryHeader;
metadataContainer.keys.push_back(key);
}
return success;
}
void
createSurveyCoordinateSystemMetadata(SEGYFileInfo const &fileInfo, OpenVDS::MetadataContainer &metadataContainer)
{
if(fileInfo.m_segmentInfo.empty()) return;
double inlineSpacing[2] = {0, 0};
double crosslineSpacing[2] = {0, 0};
// Determine crossline spacing
int countedCrosslineSpacings = 0;
for(auto const &segmentInfo : fileInfo.m_segmentInfo)
{
int crosslineCount = segmentInfo.m_binInfoStop.m_crosslineNumber - segmentInfo.m_binInfoStart.m_crosslineNumber;
if(crosslineCount == 0 || segmentInfo.m_binInfoStart.m_inlineNumber != segmentInfo.m_binInfoStop.m_inlineNumber) continue;
double segmentCrosslineSpacing[3];
segmentCrosslineSpacing[0] = (segmentInfo.m_binInfoStop.m_ensembleXCoordinate - segmentInfo.m_binInfoStart.m_ensembleXCoordinate) / crosslineCount;
segmentCrosslineSpacing[1] = (segmentInfo.m_binInfoStop.m_ensembleYCoordinate - segmentInfo.m_binInfoStart.m_ensembleYCoordinate) / crosslineCount;
crosslineSpacing[0] += segmentCrosslineSpacing[0];
crosslineSpacing[1] += segmentCrosslineSpacing[1];
countedCrosslineSpacings++;
}
if(countedCrosslineSpacings > 0)
{
crosslineSpacing[0] /= countedCrosslineSpacings;
crosslineSpacing[1] /= countedCrosslineSpacings;
}
else
{
crosslineSpacing[0] = 0;
crosslineSpacing[1] = 1;
}
// Determine inline spacing
SEGYSegmentInfo const &firstSegmentInfo = fileInfo.m_segmentInfo.front();
SEGYSegmentInfo const &lastSegmentInfo = fileInfo.m_segmentInfo.back();
if(firstSegmentInfo.m_binInfoStart.m_inlineNumber != lastSegmentInfo.m_binInfoStart.m_inlineNumber)
{
int inlineNunberDelta = lastSegmentInfo.m_binInfoStart.m_inlineNumber - firstSegmentInfo.m_binInfoStart.m_inlineNumber;
int crosslineNunberDelta = lastSegmentInfo.m_binInfoStart.m_crosslineNumber - firstSegmentInfo.m_binInfoStart.m_crosslineNumber;
double offset[2] = { crosslineSpacing[0] * crosslineNunberDelta,
crosslineSpacing[1] * crosslineNunberDelta };
inlineSpacing[0] = (lastSegmentInfo.m_binInfoStart.m_ensembleXCoordinate - firstSegmentInfo.m_binInfoStart.m_ensembleXCoordinate - offset[0]) / inlineNunberDelta;
inlineSpacing[1] = (lastSegmentInfo.m_binInfoStart.m_ensembleYCoordinate - firstSegmentInfo.m_binInfoStart.m_ensembleYCoordinate - offset[1]) / inlineNunberDelta;
}
else
{
// make square voxels
inlineSpacing[0] = crosslineSpacing[1];
inlineSpacing[1] = -crosslineSpacing[0];
}
// Determine origin
double origin[2];
origin[0] = firstSegmentInfo.m_binInfoStart.m_ensembleXCoordinate;
origin[1] = firstSegmentInfo.m_binInfoStart.m_ensembleYCoordinate;
origin[0] -= inlineSpacing[0] * firstSegmentInfo.m_binInfoStart.m_inlineNumber;
origin[1] -= inlineSpacing[1] * firstSegmentInfo.m_binInfoStart.m_inlineNumber;
origin[0] -= crosslineSpacing[0] * firstSegmentInfo.m_binInfoStart.m_crosslineNumber;
origin[1] -= crosslineSpacing[1] * firstSegmentInfo.m_binInfoStart.m_crosslineNumber;
// Set coordinate system
{
OpenVDS::MetadataKey key = { OpenVDS::MetadataType::DoubleVector2, LATTICE_CATEGORY, LATTICE_ORIGIN };
metadataContainer.doubleVector2Data[key] = OpenVDS::DoubleVector2(origin[0], origin[1]);
metadataContainer.keys.push_back(key);
}
{
OpenVDS::MetadataKey key = { OpenVDS::MetadataType::DoubleVector2, LATTICE_CATEGORY, LATTICE_INLINE_SPACING };
metadataContainer.doubleVector2Data[key] = OpenVDS::DoubleVector2(crosslineSpacing[0], crosslineSpacing[1]);
metadataContainer.keys.push_back(key);
}
{
OpenVDS::MetadataKey key = { OpenVDS::MetadataType::DoubleVector2, LATTICE_CATEGORY, LATTICE_CROSSLINE_SPACING };
metadataContainer.doubleVector2Data[key] = OpenVDS::DoubleVector2(inlineSpacing[0], inlineSpacing[1]);
metadataContainer.keys.push_back(key);
}
}
bool
parseSEGYFileInfoFile(OpenVDS::File const &file, SEGYFileInfo &fileInfo)
{
......@@ -365,24 +487,17 @@ createChannelDescriptors(SEGYFileInfo const &fileInfo, OpenVDS::FloatRange const
channelDescriptors;
// Primary channel
channelDescriptors.push_back(OpenVDS::VolumeDataChannelDescriptor(OpenVDS::VolumeDataChannelDescriptor::Format_R32, OpenVDS::VolumeDataChannelDescriptor::Components_1, "Amplitude", "", valueRange.min, valueRange.max));
channelDescriptors.push_back(OpenVDS::VolumeDataChannelDescriptor(OpenVDS::VolumeDataChannelDescriptor::Format_R32, OpenVDS::VolumeDataChannelDescriptor::Components_1, AMPLITUDE_ATTRIBUTE_NAME, "", valueRange.min, valueRange.max));
// Trace defined flag
channelDescriptors.push_back(OpenVDS::VolumeDataChannelDescriptor(OpenVDS::VolumeDataChannelDescriptor::Format_U8, OpenVDS::VolumeDataChannelDescriptor::Components_1, "Trace", "", 0, 1, OpenVDS::VolumeDataMapping::PerTrace));
channelDescriptors.push_back(OpenVDS::VolumeDataChannelDescriptor(OpenVDS::VolumeDataChannelDescriptor::Format_U8, OpenVDS::VolumeDataChannelDescriptor::Components_1, "Trace", "", 0, 1, OpenVDS::VolumeDataMapping::PerTrace, OpenVDS::VolumeDataChannelDescriptor::DiscreteData));
// SEG-Y trace headers
channelDescriptors.push_back(OpenVDS::VolumeDataChannelDescriptor(OpenVDS::VolumeDataChannelDescriptor::Format_U8, OpenVDS::VolumeDataChannelDescriptor::Components_1, "SEGYTraceHeaders", "", 0, 255, OpenVDS::VolumeDataMapping::PerTrace, SEGY::TraceHeaderSize, OpenVDS::VolumeDataChannelDescriptor::Flags::Default, 1.0f, 0.0f));
channelDescriptors.push_back(OpenVDS::VolumeDataChannelDescriptor(OpenVDS::VolumeDataChannelDescriptor::Format_U8, OpenVDS::VolumeDataChannelDescriptor::Components_1, "SEGYTraceHeader", "", 0, 255, OpenVDS::VolumeDataMapping::PerTrace, SEGY::TraceHeaderSize, OpenVDS::VolumeDataChannelDescriptor::DiscreteData, 1.0f, 0.0f));
return channelDescriptors;
}
std::string to_hexstring(uint64_t value)
{
char buffer[sizeof(value) * 2 + 1];
snprintf(buffer, sizeof(buffer), "%llX", value);
return std::string(buffer);
}
class FileViewManager
{
typedef std::map<std::pair<int64_t, int64_t>, OpenVDS::FileView *> FileViewMap;
......@@ -659,7 +774,7 @@ main(int argc, char *argv[])
if(persistentID.empty())
{
persistentID = to_hexstring(fileInfo.m_persistentID);
persistentID = fmt::format("{:X}", fileInfo.m_persistentID);
}
OpenVDS::File
......@@ -725,6 +840,17 @@ main(int argc, char *argv[])
OpenVDS::MetadataContainer
metadataContainer;
createSEGYHeadersMetadata(file, metadataContainer, error);
if(error.code != 0)
{
std::cerr << error.string;
return EXIT_FAILURE;
}
createSurveyCoordinateSystemMetadata(fileInfo, metadataContainer);
// Create the VDS
OpenVDS::Error
createError;
......@@ -881,7 +1007,7 @@ main(int argc, char *argv[])
amplitudeAccessor->commit();
traceFlagAccessor->commit();
segyTraceHeaderAccessor->commit();
fmt::print("\r100% done.\n");
fileView.reset();
......
......@@ -841,15 +841,15 @@ Json::Value serializeChannelDescriptor(VolumeDataChannelDescriptor const &channe
return channelDescriptorJson;
}
template<typename T, size_t N>
Json::Value serializeVector(Vector<T, N> const &vector)
template<typename T>
Json::Value serializeVector(T const &vector)
{
static_assert(N > 1 && N <= 4, "Only vectors with 2, 3 or 4 elements are supported");
static_assert(T::element_count > 1 && T::element_count <= 4, "Only vectors with 2, 3 or 4 elements are supported");
Json::Value vectorJson(Json::arrayValue);
int i = 0;
switch(N)
switch(T::element_count)
{
case 4: vectorJson.append(vector[i++]);
case 3: vectorJson.append(vector[i++]);
......
......@@ -27,7 +27,6 @@
namespace OpenVDS
{
template <typename INDEX> INDEX ndPosToVector(const int (&pos)[Dimensionality_Max]){ assert(false); } ;
template <> IntVector2 ndPosToVector<IntVector2>(const int (&pos)[Dimensionality_Max]) { return { pos[1], pos[0]}; }
......
......@@ -347,75 +347,6 @@ float VolumeDataLayer::getIntegerOffset() const
return m_volumeDataLayout->getChannelIntegerOffset(m_channel);
}
FloatVector2 VolumeDataLayer::getQuantizingScaleOffset(VolumeDataChannelDescriptor::Format format) const
{
VolumeDataChannelDescriptor::Format layerFormat = getFormat();
FloatVector2 scaleAndOffset = {getIntegerScale(), getIntegerOffset()};
if (format == VolumeDataChannelDescriptor::Format_U8 || format == VolumeDataChannelDescriptor::Format_U16)
{
if ((layerFormat != VolumeDataChannelDescriptor::Format_U8 && layerFormat != VolumeDataChannelDescriptor::Format_U16) ||
(layerFormat == VolumeDataChannelDescriptor::Format_U16 && format == VolumeDataChannelDescriptor::Format_U8))
{
if (format == VolumeDataChannelDescriptor::Format_U8)
{
scaleAndOffset[0] = rangeSize(getValueRange()) / (isUseNoValue() ? 254.0f : 255.0f);
}
else
{
scaleAndOffset[0] = rangeSize(getValueRange()) / (isUseNoValue() ? 65534.0f : 65535.0f);
}
scaleAndOffset[1] = getValueRange().min;
}
}
return scaleAndOffset;
}
FloatVector2 VolumeDataLayer::getTextureScaleOffset(VolumeDataChannelDescriptor::Format eDataBlockFormat) const
{
return staticGetTextureScaleOffset(getValueRange(), getIntegerScale(), getIntegerOffset(), isUseNoValue(), getFormat(), eDataBlockFormat);
}
FloatVector2 VolumeDataLayer::staticGetTextureScaleOffset(const FloatRange &valueRange, float integerScale, float integerOffset, bool isUseNoValue, VolumeDataChannelDescriptor::Format originalFormat, VolumeDataChannelDescriptor::Format dataBlockFormat)
{
FloatVector2 scaleAndOffset= {1.0f, 0.0f};
if (dataBlockFormat == VolumeDataChannelDescriptor::Format_U8 || dataBlockFormat == VolumeDataChannelDescriptor::Format_U16)
{
if (originalFormat == VolumeDataChannelDescriptor::Format_U8)
{
scaleAndOffset[0] = integerScale * 255.0f;
scaleAndOffset[1] = integerOffset;
}
else if (originalFormat == VolumeDataChannelDescriptor::Format_U16 && dataBlockFormat != VolumeDataChannelDescriptor::Format_U8)
{
scaleAndOffset[0] = integerScale * 65535.0f;
scaleAndOffset[1] = integerOffset;
}
else
{
scaleAndOffset[0] = rangeSize(valueRange);
scaleAndOffset[1] = valueRange.min;
if (isUseNoValue)
{
if (dataBlockFormat == VolumeDataChannelDescriptor::Format_U8)
{
scaleAndOffset[0] = scaleAndOffset[0] * 255.0f / 254.0f;
}
else if (dataBlockFormat == VolumeDataChannelDescriptor::Format_U16)
{
scaleAndOffset[0] = scaleAndOffset[0] * 65535.0f / 65534.0f;
}
}
}
}
return scaleAndOffset;
}
void VolumeDataLayer::setProduceStatus(ProduceStatus produceStatus)
{
m_produceStatus = produceStatus;
......
......@@ -214,14 +214,7 @@ public:
float getIntegerOffset() const;
// in cases where we have an integer data block for a non-integer layer, use this scale/offset to get back to the original values
FloatVector2 getQuantizingScaleOffset(VolumeDataChannelDescriptor::Format dataBlockFormat) const;
FloatVector2 getTextureScaleOffset(VolumeDataChannelDescriptor::Format dataBlockFormat) const;
void setProduceStatus(ProduceStatus produceStatus);
static FloatVector2 staticGetTextureScaleOffset(const FloatRange &valueRange, float integerScale, float integerOffset, bool isUseNoValue, VolumeDataChannelDescriptor::Format originalFormat, VolumeDataChannelDescriptor::Format dataBlockFormat);
};
}
#endif //VOLUMEDATALAYER_H
......@@ -269,7 +269,9 @@ static void createTransformData(Wavelet_TransformData (&transformData)[TRANSFORM
else endWrite[2] = bandSize[i + 1][2];
IntVector3 delta = Subtract(endWrite, startWrite);
IntVector3 delta = IntVector3(endWrite.X - startWrite.X,
endWrite.Y - startWrite.Y,
endWrite.Z - startWrite.Z);
if (currentTransformMask & 1) delta[0] *= 2;
if (currentTransformMask & 2) delta[1] *= 2;
......@@ -314,7 +316,9 @@ static void createTransformData(Wavelet_TransformData (&transformData)[TRANSFORM
// Are there some places we need to create 3 children along one axis?
endRead = Subtract(endRead, startRead);
endRead = IntVector3(endRead.X - startRead.X,
endRead.Y - startRead.Y,
endRead.Z - startRead.Z);