1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
/*=========================================================================
Program: GDCM (Grassroots DICOM). A DICOM library
Copyright (c) 2006-2011 Mathieu Malaterre
All rights reserved.
See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html 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 "gdcmImageFragmentSplitter.h"
#include "gdcmSequenceOfFragments.h"
namespace gdcm
{
bool ImageFragmentSplitter::Split()
{
Output = Input;
const Bitmap &image = *Input;
const unsigned int *dims = image.GetDimensions();
if( dims[2] != 1 )
{
gdcmDebugMacro( "Cannot split a 3D image" );
return false;
}
const DataElement& pixeldata = image.GetDataElement();
const SequenceOfFragments *sqf = pixeldata.GetSequenceOfFragments();
if( !sqf )
{
gdcmDebugMacro( "Cannot split a non-encapsulated syntax" );
return false;
}
if ( sqf->GetNumberOfFragments() != 1 )
{
gdcmDebugMacro( "Case not handled (for now)" );
return false;
}
//assert( sqf->GetNumberOfFragments() == 1 );
// WARNING do not keep the same Basic Offset Table...
const Fragment& frag = sqf->GetFragment(0);
const ByteValue *bv = frag.GetByteValue();
const char *p = bv->GetPointer();
unsigned long len = bv->GetLength();
if( FragmentSizeMax > len && !Force )
{
// I think it is ok
return true;
}
// prevent zero division
if( FragmentSizeMax == 0 )
{
gdcmDebugMacro( "Need to set a real value for fragment size" );
return false; // seriously...
}
unsigned long nfrags = len / FragmentSizeMax;
unsigned long lastfrag = len % FragmentSizeMax;
SmartPointer<SequenceOfFragments> sq = new SequenceOfFragments;
// Let's do all complete frag:
for(unsigned long i = 0; i < nfrags; ++i)
{
Fragment splitfrag;
splitfrag.SetByteValue( p + i * FragmentSizeMax, FragmentSizeMax);
sq->AddFragment( splitfrag );
}
// Last (incomplete one):
if( lastfrag )
{
Fragment splitfrag;
splitfrag.SetByteValue( p + nfrags * FragmentSizeMax, (uint32_t)lastfrag );
assert( nfrags * FragmentSizeMax + lastfrag == len );
sq->AddFragment( splitfrag );
}
Output->GetDataElement().SetValue( *sq );
bool success = true;
return success;
}
void ImageFragmentSplitter::SetFragmentSizeMax(unsigned int fragsize)
{
/*
* A.4 TRANSFER SYNTAXES FOR ENCAPSULATION OF ENCODED PIXEL DATA
*
* All items containing an encoded fragment shall be made of an even number of bytes
* greater or equal to two. The last fragment of a frame may be padded, if necessary,
* to meet the sequence item format requirements of the DICOM Standard.
*/
FragmentSizeMax = fragsize;
if( fragsize % 2 )
{
// what if FragmentSizeMax == 0 ...
FragmentSizeMax--;
}
// How do I handle this one...
if( fragsize < 2 )
{
FragmentSizeMax = 2;
}
// \postcondition:
assert( FragmentSizeMax >= 2 && (FragmentSizeMax % 2) == 0 );
}
} // end namespace gdcm
|