File: gdcmImageFragmentSplitter.cxx

package info (click to toggle)
gdcm 2.4.4-3%2Bdeb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 32,912 kB
  • ctags: 52,166
  • sloc: cpp: 188,527; ansic: 124,526; xml: 41,799; sh: 7,162; python: 3,667; cs: 2,128; java: 1,344; lex: 1,290; tcl: 677; php: 128; makefile: 116
file content (113 lines) | stat: -rw-r--r-- 3,240 bytes parent folder | download | duplicates (11)
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