Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mitkCompressedImageContainer.h"
00019 #include "itkSmartPointerForwardReference.txx"
00020
00021 #include "itk_zlib.h"
00022
00023 #include <stdlib.h>
00024
00025 mitk::CompressedImageContainer::CompressedImageContainer()
00026 {
00027 }
00028
00029 mitk::CompressedImageContainer::~CompressedImageContainer()
00030 {
00031 for (std::vector< std::pair<unsigned char*, unsigned long> >::iterator iter = m_ByteBuffers.begin();
00032 iter != m_ByteBuffers.end();
00033 ++iter)
00034 {
00035 free( iter->first );
00036 }
00037 }
00038
00039 void mitk::CompressedImageContainer::SetImage( Image* image )
00040 {
00041 for (std::vector< std::pair<unsigned char*, unsigned long> >::iterator iter = m_ByteBuffers.begin();
00042 iter != m_ByteBuffers.end();
00043 ++iter)
00044 {
00045 free( iter->first );
00046 }
00047
00048 m_ByteBuffers.clear();
00049
00050
00051
00052 m_ImageDimension = image->GetDimension();
00053 m_ImageDimensions.clear();
00054 m_PixelType = image->GetPixelType();
00055 m_OneTimeStepImageSizeInBytes = m_PixelType.GetBpe() >> 3;
00056 for (unsigned int i = 0; i < m_ImageDimension; ++i)
00057 {
00058 unsigned int currentImageDimension = image->GetDimension(i);
00059 m_ImageDimensions.push_back( currentImageDimension );
00060 if (i < 3)
00061 {
00062 m_OneTimeStepImageSizeInBytes *= currentImageDimension;
00063 }
00064 }
00065
00066 m_ImageGeometry = image->GetGeometry();
00067
00068 m_NumberOfTimeSteps = 1;
00069 if (m_ImageDimension > 3)
00070 {
00071 m_NumberOfTimeSteps = image->GetDimension(3);
00072 }
00073
00074 for (unsigned int timestep = 0; timestep < m_NumberOfTimeSteps; ++timestep)
00075 {
00076
00077 unsigned long bufferSize = m_OneTimeStepImageSizeInBytes + static_cast<unsigned long>(m_OneTimeStepImageSizeInBytes * 0.2) + 12;
00078 unsigned char* byteBuffer = (unsigned char*) malloc(bufferSize);
00079
00080 if (itk::Object::GetDebug())
00081 {
00082
00083 MITK_INFO << "Using ZLib version: '" << zlibVersion() << "'" << std::endl
00084 << "Attempting to compress " << m_OneTimeStepImageSizeInBytes << " image bytes into a buffer of size " << bufferSize << std::endl;
00085 }
00086
00087 ::Bytef* dest(byteBuffer);
00088 ::uLongf destLen(bufferSize);
00089 ::Bytef* source( static_cast<unsigned char*>(image->GetVolumeData(timestep)->GetData()) );
00090 ::uLongf sourceLen( m_OneTimeStepImageSizeInBytes );
00091 int zlibRetVal = ::compress(dest, &destLen, source, sourceLen);
00092 if (itk::Object::GetDebug())
00093 {
00094 if (zlibRetVal == Z_OK)
00095 {
00096 MITK_INFO << "Success, using " << destLen << " bytes of the buffer (ratio " << ((double)destLen / (double)sourceLen) << ")" << std::endl;
00097 }
00098 else
00099 {
00100 switch ( zlibRetVal )
00101 {
00102 case Z_MEM_ERROR:
00103 MITK_ERROR << "not enough memory" << std::endl;
00104 break;
00105 case Z_BUF_ERROR:
00106 MITK_ERROR << "output buffer too small" << std::endl;
00107 break;
00108 default:
00109 MITK_ERROR << "other, unspecified error" << std::endl;
00110 break;
00111 }
00112 }
00113 }
00114
00115
00116 byteBuffer = (unsigned char*) realloc( byteBuffer, destLen );
00117 bufferSize = destLen;
00118
00119
00120 m_ByteBuffers.push_back( std::pair<unsigned char*, unsigned long>( byteBuffer, bufferSize ) );
00121 }
00122 }
00123
00124 mitk::Image::Pointer mitk::CompressedImageContainer::GetImage()
00125 {
00126 if (m_ByteBuffers.empty()) return NULL;
00127
00128
00129 Image::Pointer image = Image::New();
00130 unsigned int dims[20];
00131 for (unsigned int dim = 0; dim < m_ImageDimension; ++dim)
00132 dims[dim] = m_ImageDimensions[dim];
00133
00134 image->Initialize( m_PixelType, m_ImageDimension, dims );
00135
00136 unsigned int timeStep(0);
00137 for (std::vector< std::pair<unsigned char*, unsigned long> >::iterator iter = m_ByteBuffers.begin();
00138 iter != m_ByteBuffers.end();
00139 ++iter, ++timeStep)
00140 {
00141 ::Bytef* dest( static_cast<unsigned char*>(image->GetVolumeData(timeStep)->GetData()) );
00142 ::uLongf destLen(m_OneTimeStepImageSizeInBytes);
00143 ::Bytef* source( iter->first );
00144 ::uLongf sourceLen( iter->second );
00145 int zlibRetVal = ::uncompress(dest, &destLen, source, sourceLen);
00146 if (itk::Object::GetDebug())
00147 {
00148 if (zlibRetVal == Z_OK)
00149 {
00150 MITK_INFO << "Success, destLen now " << destLen << " bytes" << std::endl;
00151 }
00152 else
00153 {
00154 switch ( zlibRetVal )
00155 {
00156 case Z_DATA_ERROR:
00157 MITK_ERROR << "compressed data corrupted" << std::endl;
00158 break;
00159 case Z_MEM_ERROR:
00160 MITK_ERROR << "not enough memory" << std::endl;
00161 break;
00162 case Z_BUF_ERROR:
00163 MITK_ERROR << "output buffer too small" << std::endl;
00164 break;
00165 default:
00166 MITK_ERROR << "other, unspecified error" << std::endl;
00167 break;
00168 }
00169 }
00170 }
00171 }
00172
00173 image->SetGeometry( m_ImageGeometry );
00174 image->Modified();
00175
00176 return image;
00177 }
00178