00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #pragma once
00026
00027 #include <LDM/compressors/SoDataCompressor.h>
00028
00062 class SoJp3dDataCompressor : public SoDataCompressor
00063 {
00064 SO_TYPED_CLASS_HEADER();
00065
00066 public:
00070 SoJp3dDataCompressor();
00071
00075 virtual ~SoJp3dDataCompressor();
00076
00084 virtual SbString getCompressionFormatName() const;
00085
00090 virtual bool isLossless();
00091
00101 virtual size_t compress( void* src, size_t srcLen, const TileInfo& tileInfo );
00102
00112 virtual size_t uncompress( void* dst, size_t dstLen, const TileInfo& tileInfo );
00113
00114
00115 private:
00127 template<typename T, typename MappingType>
00128 static void map( T* src, MappingType* dst, size_t sampleCount, const SbVec2d& range );
00129
00141 template <typename T, typename MappingType>
00142 static void unmap( MappingType* src, T* dst, size_t sampleCount, const SbVec2d& range );
00143
00149 size_t uncompressRaw( void* dst, size_t dstLen, const TileInfo& tileInfo );
00150
00156 template <typename T>
00157 size_t uncompressAndUnmap( void* dst, size_t dstLen, const TileInfo& tileInfo );
00158 };
00159
00160
00161 template<typename T, typename MappingType>
00162 void
00163 SoJp3dDataCompressor::map( T* src, MappingType* dst, size_t sampleCount, const SbVec2d& range )
00164 {
00165 double rangeOffset = range[0];
00166 double rangeMax = range[1] - range[0];
00167 double ratio = 0.0;
00168
00169 for ( size_t i = 0; i < sampleCount; ++i )
00170 {
00171 ratio = ( static_cast<double>( src[i] ) - rangeOffset ) / rangeMax;
00172 dst[i] = static_cast<MappingType>( ratio * std::numeric_limits<uint16_t>::max() );
00173 }
00174 }
00175
00176
00177 template <typename T, typename MappingType>
00178 void
00179 SoJp3dDataCompressor::unmap( MappingType* src, T* dst, size_t sampleCount, const SbVec2d& range )
00180 {
00181 double rangeMin = range[0];
00182 double rangeMax = range[1];
00183 double mappingRange = rangeMax - rangeMin;
00184 double ratio = 0.0;
00185
00186 for ( size_t i = 0; i < sampleCount; ++i )
00187 {
00188 ratio = static_cast<double>( src[i] ) / std::numeric_limits<MappingType>::max();
00189 dst[i] = static_cast<T>( rangeMin + ratio*mappingRange );
00190 }
00191 }
00192
00193
00194 template <typename T>
00195 size_t
00196 SoJp3dDataCompressor::uncompressAndUnmap( void* dst, size_t dstLen, const TileInfo& tileInfo )
00197 {
00198 T* dstBuffer = reinterpret_cast<T*>( dst );
00199
00200 size_t sampleCount = tileInfo.dims[0];
00201 sampleCount *= tileInfo.dims[1];
00202 sampleCount *= tileInfo.dims[2];
00203
00204 size_t dstSampleCount = dstLen / sizeof( T );
00205
00206 if ( sampleCount > dstSampleCount )
00207 {
00208 SoDebugError::post(
00209 "SoJp3dDataCompressor::uncompressAndUnmap",
00210 "%ld samples to uncompress, only space for %ld samples in destination.", sampleCount, dstSampleCount
00211 );
00212
00213 return 0;
00214 }
00215
00216 std::vector<uint16_t> mapBuffer( sampleCount );
00217 size_t uncompressedBytes = uncompressRaw( &mapBuffer[0], mapBuffer.size() * sizeof( uint16_t ), tileInfo );
00218 size_t uncompressedSamples = uncompressedBytes / sizeof( uint16_t );
00219
00220 if ( uncompressedSamples != sampleCount )
00221 {
00222 SoDebugError::post(
00223 "SoJp3dDataCompressor::uncompressAndUnmap",
00224 "incorrect sample count, %ld sampled decoded on %ld.", uncompressedSamples, sampleCount
00225 );
00226
00227 return 0;
00228 }
00229
00230 unmap( &mapBuffer[0], dstBuffer, mapBuffer.size(), tileInfo.range );
00231
00232 return mapBuffer.size() * sizeof( T );
00233 }
00234