1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 /*=========================================================================
19  *
20  *  Portions of this file are subject to the VTK Toolkit Version 3 copyright.
21  *
22  *  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
23  *
24  *  For complete copyright, license and disclaimer of warranty information
25  *  please refer to the NOTICE file at the top of the ITK source tree.
26  *
27  *=========================================================================*/
28 #include "itkTemporalDataObject.h"
29 
30 
31 namespace itk
32 {
33 
34 //----------------------------------------------------------------------------
TemporalDataObject()35 TemporalDataObject::TemporalDataObject()
36   : m_LargestPossibleTemporalRegion(),
37     m_RequestedTemporalRegion(),
38     m_BufferedTemporalRegion()
39 
40 {
41   m_DataObjectBuffer = BufferType::New();
42 }
43 
44 //----------------------------------------------------------------------------
45 TemporalDataObject
46 ::~TemporalDataObject() = default;
47 
48 //----------------------------------------------------------------------------
49 TemporalDataObject::TemporalUnitType
50 TemporalDataObject
GetTemporalUnit() const51 ::GetTemporalUnit() const
52 {
53   return m_TemporalUnit;
54 }
55 
56 //----------------------------------------------------------------------------
57 void
58 TemporalDataObject
SetTemporalUnitToFrame()59 ::SetTemporalUnitToFrame()
60 {
61   m_TemporalUnit = Frame;
62 }
63 
64 //----------------------------------------------------------------------------
65 void
66 TemporalDataObject
SetTemporalUnitToRealTime()67 ::SetTemporalUnitToRealTime()
68 {
69   m_TemporalUnit = RealTime;
70 }
71 
72 //----------------------------------------------------------------------------
73 void
74 TemporalDataObject
SetTemporalUnitToFrameAndRealTime()75 ::SetTemporalUnitToFrameAndRealTime()
76 {
77   m_TemporalUnit = FrameAndRealTime;
78 }
79 
80 //----------------------------------------------------------------------------
81 SizeValueType
82 TemporalDataObject
GetNumberOfBuffers()83 ::GetNumberOfBuffers()
84 {
85   return m_DataObjectBuffer->GetNumberOfBuffers();
86 }
87 
88 //----------------------------------------------------------------------------
89 void
90 TemporalDataObject
SetNumberOfBuffers(SizeValueType num)91 ::SetNumberOfBuffers(SizeValueType num)
92 {
93   m_DataObjectBuffer->SetNumberOfBuffers(num);
94 }
95 
96 //----------------------------------------------------------------------------
97 void
98 TemporalDataObject::
SetLargestPossibleTemporalRegion(const TemporalRegionType & region)99 SetLargestPossibleTemporalRegion( const TemporalRegionType & region)
100 {
101   m_LargestPossibleTemporalRegion = region;
102   this->Modified();
103 }
104 
105 //----------------------------------------------------------------------------
106 const TemporalDataObject::TemporalRegionType&
107 TemporalDataObject
GetLargestPossibleTemporalRegion() const108 ::GetLargestPossibleTemporalRegion() const
109 {
110   return m_LargestPossibleTemporalRegion;
111 }
112 
113 //----------------------------------------------------------------------------
114 void
115 TemporalDataObject
SetBufferedTemporalRegion(const TemporalRegionType & region)116 ::SetBufferedTemporalRegion(const TemporalRegionType & region)
117 {
118   m_BufferedTemporalRegion = region;
119   this->Modified();
120 }
121 
122 //----------------------------------------------------------------------------
123 const TemporalDataObject::TemporalRegionType&
124 TemporalDataObject
GetBufferedTemporalRegion() const125 ::GetBufferedTemporalRegion() const
126 {
127   return m_BufferedTemporalRegion;
128 }
129 
130 //----------------------------------------------------------------------------
131 void
132 TemporalDataObject
SetRequestedTemporalRegion(const TemporalRegionType & region)133 ::SetRequestedTemporalRegion(const TemporalRegionType & region)
134 {
135   m_RequestedTemporalRegion = region;
136   this->Modified();
137 }
138 
139 //----------------------------------------------------------------------------
140 const TemporalDataObject::TemporalRegionType &
141 TemporalDataObject
GetRequestedTemporalRegion() const142 ::GetRequestedTemporalRegion() const
143 {
144   return m_RequestedTemporalRegion;
145 }
146 
147 //----------------------------------------------------------------------------
148 const TemporalDataObject::TemporalRegionType
149 TemporalDataObject
GetUnbufferedRequestedTemporalRegion()150 ::GetUnbufferedRequestedTemporalRegion()
151 {
152   // If nothing is buffered or nothing is requested, just return the entire request
153   if (m_BufferedTemporalRegion.GetFrameDuration() == 0 ||
154       m_RequestedTemporalRegion.GetFrameDuration() == 0)
155     {
156     return m_RequestedTemporalRegion;
157     }
158 
159   // Get the start and end of the buffered and requested temporal regions
160   SizeValueType reqStart = m_RequestedTemporalRegion.GetFrameStart();
161   SizeValueType reqEnd = m_RequestedTemporalRegion.GetFrameStart() +
162                           m_RequestedTemporalRegion.GetFrameDuration() - 1;
163 
164   SizeValueType bufStart = m_BufferedTemporalRegion.GetFrameStart();
165   SizeValueType bufEnd = m_BufferedTemporalRegion.GetFrameStart() +
166                           m_BufferedTemporalRegion.GetFrameDuration() - 1;
167 
168   // If the request starts after the buffered region, return the whole request
169   if (reqStart > bufEnd)
170     {
171     return m_RequestedTemporalRegion;
172     }
173 
174   // Handle case with unbuffered frames at beginning and end
175   if (reqStart < bufStart && reqEnd > bufEnd)
176     {
177     itkDebugMacro(<< "Unbuffered frames at beginning and end. Returning entire "
178                   << "requested region as unbuffered");
179     return this->m_RequestedTemporalRegion;
180     }
181 
182   // Handle case with unbuffered frames at end -- TODO: FIX FOR REAL TIME!!!!!
183   else if(reqEnd > bufEnd)
184     {
185     TemporalRegionType out;
186     out.SetFrameStart(bufEnd + 1);
187     out.SetFrameDuration(reqEnd - bufEnd);
188     return out;
189     }
190 
191   // Handle case with unbuffered frames at beginning -- TODO: FIX FOR REAL TIME!!!!!
192   else if(reqStart < bufStart)
193     {
194     TemporalRegionType out;
195     out.SetFrameStart(reqStart);
196     out.SetFrameDuration(bufStart - reqStart);
197     return out;
198     }
199 
200   // Otherwise, nothing unbuffered
201   else
202     {
203     TemporalRegionType out;
204     out.SetFrameStart(0);
205     out.SetFrameDuration(0);
206     return out;
207     }
208 
209 }
210 
211 //----------------------------------------------------------------------------
212 void
213 TemporalDataObject
SetRequestedRegionToLargestPossibleRegion()214 ::SetRequestedRegionToLargestPossibleRegion()
215 {
216   this->SetRequestedTemporalRegion( this->GetLargestPossibleTemporalRegion() );
217 }
218 
219 //----------------------------------------------------------------------------
220 bool
221 TemporalDataObject
RequestedRegionIsOutsideOfTheBufferedRegion()222 ::RequestedRegionIsOutsideOfTheBufferedRegion()
223 {
224   bool frameFlag = m_RequestedTemporalRegion.GetFrameStart() <
225     m_BufferedTemporalRegion.GetFrameStart();
226   frameFlag |= m_RequestedTemporalRegion.GetFrameDuration() + m_RequestedTemporalRegion.GetFrameStart() >
227     m_BufferedTemporalRegion.GetFrameDuration() + m_BufferedTemporalRegion.GetFrameStart();
228   bool realTimeFlag = m_RequestedTemporalRegion.GetRealStart() <
229     m_BufferedTemporalRegion.GetRealStart();
230   realTimeFlag |= m_RequestedTemporalRegion.GetRealStart() + m_RequestedTemporalRegion.GetRealDuration() >
231     m_BufferedTemporalRegion.GetRealStart() + m_BufferedTemporalRegion.GetRealDuration();
232 
233   switch( m_TemporalUnit )
234     {
235     case Frame:
236       {
237       return frameFlag;
238       }
239     case RealTime:
240       {
241       return realTimeFlag;
242       }
243     case FrameAndRealTime:
244       {
245       return frameFlag || realTimeFlag;
246       }
247     default:
248       itkExceptionMacro( << "itk::TemporalDataObject::"
249                          << "RequestedRegionIsOutsideOfTheBufferedRegion() "
250                          << "Invalid Temporal Unit" );
251     }
252 }
253 
254 //----------------------------------------------------------------------------
255 bool
256 TemporalDataObject
VerifyRequestedRegion()257 ::VerifyRequestedRegion()
258 {
259   bool frameFlag = m_RequestedTemporalRegion.GetFrameStart() >=
260     m_LargestPossibleTemporalRegion.GetFrameStart();
261   frameFlag &= m_RequestedTemporalRegion.GetFrameDuration() <=
262     m_LargestPossibleTemporalRegion.GetFrameDuration();
263   bool realTimeFlag = m_RequestedTemporalRegion.GetRealStart() >=
264     m_LargestPossibleTemporalRegion.GetRealStart();
265   realTimeFlag &= m_RequestedTemporalRegion.GetRealDuration() <=
266     m_LargestPossibleTemporalRegion.GetRealDuration();
267   switch( m_TemporalUnit )
268     {
269     case Frame:
270       {
271       return frameFlag;
272       }
273     case RealTime:
274       {
275       return realTimeFlag;
276       }
277     case FrameAndRealTime:
278       {
279       return frameFlag && realTimeFlag;
280       }
281     default:
282       itkExceptionMacro( << "itk::TemporalDataObject::VerifyRequestedRegion() "
283                          << "Invalid Temporal Unit" );
284     }
285 }
286 
287 //----------------------------------------------------------------------------
288 void
289 TemporalDataObject
CopyInformation(const DataObject * data)290 ::CopyInformation(const DataObject *data)
291 {
292   // Standard call to the superclass' method
293   Superclass::CopyInformation(data);
294 
295   const TemporalDataObject* temporalData;
296   temporalData = dynamic_cast< const TemporalDataObject* >( data );
297 
298   if ( temporalData )
299     {
300     // Copy the meta data for this data type
301     this->SetLargestPossibleTemporalRegion(
302       temporalData->GetLargestPossibleTemporalRegion() );
303     for( unsigned int i = 0;
304          i < this->m_DataObjectBuffer->GetNumberOfBuffers();
305          ++i )
306       {
307       if( this->m_DataObjectBuffer->BufferIsFull(i) )
308         {
309         m_DataObjectBuffer->GetBufferContents(i)->CopyInformation(
310           temporalData->m_DataObjectBuffer->GetBufferContents(i) );
311         }
312       }
313     }
314   else
315     {
316     // pointer could not be cast back down
317     itkExceptionMacro( << "itk::TemporalDataObject::CopyInformation() "
318                        << "cannot cast " << typeid( data ).name() << " to "
319                        << typeid( const TemporalDataObject* ).name() );
320     }
321 }
322 
323 //----------------------------------------------------------------------------
324 void
325 TemporalDataObject
Graft(const DataObject * data)326 ::Graft(const DataObject *data)
327 {
328   const TemporalDataObject* temporalData;
329 
330   temporalData = dynamic_cast< const TemporalDataObject* >( data );
331 
332   if( temporalData )
333     {
334     // Copy the meta-information
335     this->CopyInformation( temporalData );
336 
337     this->SetBufferedTemporalRegion(
338       temporalData->GetBufferedTemporalRegion() );
339     this->SetRequestedTemporalRegion(
340       temporalData->GetRequestedTemporalRegion() );
341 
342     for( unsigned int i = 0;
343          i < this->m_DataObjectBuffer->GetNumberOfBuffers();
344          ++i )
345       {
346       if( this->m_DataObjectBuffer->BufferIsFull(i) )
347         {
348         m_DataObjectBuffer->GetBufferContents(i)->Graft(
349           temporalData->m_DataObjectBuffer->GetBufferContents(i) );
350         }
351       }
352     }
353   else
354     {
355     // pointer could not be cast back down
356     itkExceptionMacro( << "itk::TemporalDataObject::Graft() "
357                        << "cannot cast " << typeid( data ).name() << " to "
358                        << typeid( const TemporalDataObject* ).name() );
359     }
360 }
361 
362 //----------------------------------------------------------------------------
363 void
364 TemporalDataObject
SetRequestedRegion(const DataObject * data)365 ::SetRequestedRegion(const DataObject *data)
366 {
367   const TemporalDataObject *temporalData;
368 
369   temporalData = dynamic_cast< const TemporalDataObject * >( data );
370 
371   if ( temporalData )
372     {
373     // only copy the RequestedTemporalRegion if the parameter object is
374     // a temporal data object
375     this->SetRequestedTemporalRegion(
376       temporalData->GetRequestedTemporalRegion() );
377     for( unsigned int i = 0;
378          i < this->m_DataObjectBuffer->GetNumberOfBuffers();
379          ++i )
380       {
381       if( this->m_DataObjectBuffer->BufferIsFull(i) )
382         {
383         m_DataObjectBuffer->GetBufferContents(i)->SetRequestedRegion(
384           temporalData->m_DataObjectBuffer->GetBufferContents(i) );
385         }
386       }
387     }
388   else
389     {
390     // pointer could not be cast back down
391     itkExceptionMacro( << "itk::TemporalDataObject:SetRequestedRegion() "
392                        << "cannot cast " << typeid( data ).name() << " to "
393                        << typeid( const TemporalDataObject* ).name() );
394     }
395 }
396 
397 //----------------------------------------------------------------------------
398 void
399 TemporalDataObject
PrintSelf(std::ostream & os,Indent indent) const400 ::PrintSelf(std::ostream & os, Indent indent) const
401 {
402   Superclass::PrintSelf(os, indent);
403   os << indent << "Data Object Buffer: " << m_DataObjectBuffer.GetPointer()
404      << std::endl;
405   os << indent << "LargestPossibleTemporalRegion: " << std::endl;
406   this->GetLargestPossibleTemporalRegion().Print( os,
407                                                   indent.GetNextIndent() );
408 
409   os << indent << "BufferedTemporalRegion: " << std::endl;
410   this->GetBufferedTemporalRegion().Print( os, indent.GetNextIndent() );
411 
412   os << indent << "RequestedTemporalRegion: " << std::endl;
413   this->GetRequestedTemporalRegion().Print( os, indent.GetNextIndent() );
414 }
415 
416 } // end namespace itk
417