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 #ifndef itkVideoStream_hxx
19 #define itkVideoStream_hxx
20
21 #include "itkVideoStream.h"
22
23 namespace itk
24 {
25
26 template<typename TFrameType>
27 void
28 VideoStream<TFrameType>
SetFrameLargestPossibleSpatialRegion(SizeValueType frameNumber,typename TFrameType::RegionType region)29 ::SetFrameLargestPossibleSpatialRegion(SizeValueType frameNumber, typename TFrameType::RegionType region)
30 {
31 m_LargestPossibleSpatialRegionCache[frameNumber] = region;
32
33 // If the frame is currently buffered, set the actual frame's region
34 SizeValueType bufStart = m_BufferedTemporalRegion.GetFrameStart();
35 SizeValueType bufDur = m_BufferedTemporalRegion.GetFrameDuration();
36 if (frameNumber >= bufStart && frameNumber < bufStart + bufDur)
37 {
38 FrameType* frame = this->GetFrame(frameNumber);
39 frame->SetLargestPossibleRegion(region);
40 }
41 }
42
43
44 template<typename TFrameType>
45 const typename TFrameType::RegionType &
46 VideoStream<TFrameType>
GetFrameLargestPossibleSpatialRegion(SizeValueType frameNumber) const47 ::GetFrameLargestPossibleSpatialRegion(SizeValueType frameNumber) const
48 {
49 // It seems that std::map's [] operator isn't const correct, so we need to
50 // access this member from an non-const version of ourselves
51 return const_cast<Self*>(this)->m_LargestPossibleSpatialRegionCache[frameNumber];
52 }
53
54
55 template<typename TFrameType>
56 void
57 VideoStream<TFrameType>
SetFrameRequestedSpatialRegion(SizeValueType frameNumber,typename TFrameType::RegionType region)58 ::SetFrameRequestedSpatialRegion(SizeValueType frameNumber, typename TFrameType::RegionType region)
59 {
60 m_RequestedSpatialRegionCache[frameNumber] = region;
61
62 // If the frame is currently buffered, set the actual frame's region
63 SizeValueType bufStart = m_BufferedTemporalRegion.GetFrameStart();
64 SizeValueType bufDur = m_BufferedTemporalRegion.GetFrameDuration();
65 if (frameNumber >= bufStart && frameNumber < bufStart + bufDur)
66 {
67 FrameType* frame = this->GetFrame(frameNumber);
68 frame->SetRequestedRegion(region);
69 }
70 }
71
72
73 template<typename TFrameType>
74 const typename TFrameType::RegionType &
75 VideoStream<TFrameType>
GetFrameRequestedSpatialRegion(SizeValueType frameNumber) const76 ::GetFrameRequestedSpatialRegion(SizeValueType frameNumber) const
77 {
78 // It seems that std::map's [] operator isn't const correct, so we need to
79 // access this member from an non-const version of ourselves
80 return const_cast<Self*>(this)->m_RequestedSpatialRegionCache[frameNumber];
81 }
82
83
84 template<typename TFrameType>
85 void
86 VideoStream<TFrameType>
SetFrameBufferedSpatialRegion(SizeValueType frameNumber,typename TFrameType::RegionType region)87 ::SetFrameBufferedSpatialRegion(SizeValueType frameNumber, typename TFrameType::RegionType region)
88 {
89 m_BufferedSpatialRegionCache[frameNumber] = region;
90
91 // If the frame is currently buffered, set the actual frame's region
92 SizeValueType bufStart = m_BufferedTemporalRegion.GetFrameStart();
93 SizeValueType bufDur = m_BufferedTemporalRegion.GetFrameDuration();
94 if (frameNumber >= bufStart && frameNumber < bufStart + bufDur)
95 {
96 FrameType* frame = this->GetFrame(frameNumber);
97 frame->SetBufferedRegion(region);
98 }
99 }
100
101
102 template<typename TFrameType>
103 const typename TFrameType::RegionType &
104 VideoStream<TFrameType>
GetFrameBufferedSpatialRegion(SizeValueType frameNumber) const105 ::GetFrameBufferedSpatialRegion(SizeValueType frameNumber) const
106 {
107 // It seems that std::map's [] operator isn't const correct, so we need to
108 // access this member from an non-const version of ourselves
109 return const_cast<Self*>(this)->m_BufferedSpatialRegionCache[frameNumber];
110 }
111
112
113 template<typename TFrameType>
114 void
115 VideoStream<TFrameType>
SetFrameSpacing(SizeValueType frameNumber,typename TFrameType::SpacingType spacing)116 ::SetFrameSpacing(SizeValueType frameNumber, typename TFrameType::SpacingType spacing)
117 {
118 // Make sure spacing is non-zero
119 for (unsigned int i = 0; i < FrameType::ImageDimension; ++i)
120 {
121 if (spacing[i] == 0.0)
122 {
123 itkExceptionMacro("Zero spacing is not allowed for any dimension: Spacing is " << spacing);
124 }
125 }
126
127 m_SpacingCache[frameNumber] = spacing;
128
129 // If the frame is currently buffered, set the actual frame's spacing
130 SizeValueType bufStart = m_BufferedTemporalRegion.GetFrameStart();
131 SizeValueType bufDur = m_BufferedTemporalRegion.GetFrameDuration();
132 if (frameNumber >= bufStart && frameNumber < bufStart + bufDur)
133 {
134 FrameType* frame = this->GetFrame(frameNumber);
135 frame->SetSpacing(spacing);
136 }
137 }
138
139
140 template<typename TFrameType>
141 const typename TFrameType::SpacingType &
142 VideoStream<TFrameType>
GetFrameSpacing(SizeValueType frameNumber) const143 ::GetFrameSpacing(SizeValueType frameNumber) const
144 {
145 // It seems that std::map's [] operator isn't const correct, so we need to
146 // access this member from an non-const version of ourselves
147 return const_cast<Self*>(this)->m_SpacingCache[frameNumber];
148 }
149
150
151 template<typename TFrameType>
152 void
153 VideoStream<TFrameType>
SetFrameOrigin(SizeValueType frameNumber,typename TFrameType::PointType origin)154 ::SetFrameOrigin(SizeValueType frameNumber, typename TFrameType::PointType origin)
155 {
156 m_OriginCache[frameNumber] = origin;
157
158 // If the frame is currently buffered, set the actual frame's spacing
159 SizeValueType bufStart = m_BufferedTemporalRegion.GetFrameStart();
160 SizeValueType bufDur = m_BufferedTemporalRegion.GetFrameDuration();
161 if (frameNumber >= bufStart && frameNumber < bufStart + bufDur)
162 {
163 FrameType* frame = this->GetFrame(frameNumber);
164 frame->SetOrigin(origin);
165 }
166 }
167
168
169 template<typename TFrameType>
170 const typename TFrameType::PointType &
171 VideoStream<TFrameType>
GetFrameOrigin(SizeValueType frameNumber) const172 ::GetFrameOrigin(SizeValueType frameNumber) const
173 {
174 // It seems that std::map's [] operator isn't const correct, so we need to
175 // access this member from an non-const version of ourselves
176 return const_cast<Self*>(this)->m_OriginCache[frameNumber];
177 }
178
179
180 template<typename TFrameType>
181 void
182 VideoStream<TFrameType>
SetFrameDirection(SizeValueType frameNumber,typename TFrameType::DirectionType direction)183 ::SetFrameDirection(SizeValueType frameNumber, typename TFrameType::DirectionType direction)
184 {
185 // Determinant is non-zero
186 if (itk::Math::abs(vnl_determinant(direction.GetVnlMatrix())) <= itk::Math::eps)
187 {
188 itkExceptionMacro("Bad direction, determinant is 0. Direction is " << direction);
189 }
190
191 m_DirectionCache[frameNumber] = direction;
192
193 // If the frame is currently buffered, set the actual frame's spacing
194 SizeValueType bufStart = m_BufferedTemporalRegion.GetFrameStart();
195 SizeValueType bufDur = m_BufferedTemporalRegion.GetFrameDuration();
196 if (frameNumber >= bufStart && frameNumber < bufStart + bufDur)
197 {
198 FrameType* frame = this->GetFrame(frameNumber);
199 frame->SetDirection(direction);
200 }
201 }
202
203
204 template<typename TFrameType>
205 const typename TFrameType::DirectionType &
206 VideoStream<TFrameType>
GetFrameDirection(SizeValueType frameNumber) const207 ::GetFrameDirection(SizeValueType frameNumber) const
208 {
209 // It seems that std::map's [] operator isn't const correct, so we need to
210 // access this member from an non-const version of ourselves
211 return const_cast<Self*>(this)->m_DirectionCache[frameNumber];
212 }
213
214
215 template<typename TFrameType>
216 void
217 VideoStream<TFrameType>
SetFrameBuffer(typename VideoStream<TFrameType>::BufferType * buffer)218 ::SetFrameBuffer(typename VideoStream<TFrameType>::BufferType* buffer)
219 {
220 // We reinterpret the buffer to match TemporalDataObject's buffer type. We
221 // assume that any tampering with the internal buffer will use our BufferType
222 // so this will be safe.
223 auto * castBuffer = reinterpret_cast<TemporalDataObject::BufferType*>(buffer);
224
225 if (m_DataObjectBuffer != castBuffer)
226 {
227 m_DataObjectBuffer = castBuffer;
228 this->Modified();
229 }
230 }
231
232
233 template<typename TFrameType>
234 void
235 VideoStream<TFrameType>
SetMinimumBufferSize(SizeValueType minimumNumberOfFrames)236 ::SetMinimumBufferSize(SizeValueType minimumNumberOfFrames)
237 {
238 // If we don't have enough buffer space to handle the number of requested
239 // frames, we need to resize the ring buffer. Just resizing can cause data to
240 // be in the wrong place. For example if the head of the buffer is at index 0
241 // and the buffer has 3 slots, setting frame number 3 will actually place the
242 // data into slot 0. If we then resize the buffer to have 4 slots, the data
243 // for frame 3 will live in slot 0 even though a request for frame 3 will
244 // return the data from the newly created slot 3. To circumvent this problem,
245 // we move the buffered data to the proper indices in the ring buffer after
246 // resizing.
247 if (m_DataObjectBuffer->GetNumberOfBuffers() < minimumNumberOfFrames)
248 {
249 // Save the indices of all frames in the currently buffered region
250 const SizeValueType bufferedStart = m_BufferedTemporalRegion.GetFrameStart();
251 const SizeValueType bufferedDuration = m_BufferedTemporalRegion.GetFrameDuration();
252 std::vector< DataObject * > frames( bufferedDuration - bufferedStart, nullptr );
253 for (SizeValueType i = bufferedStart; i < bufferedStart + bufferedDuration; ++i)
254 {
255 frames[i - bufferedStart] = m_DataObjectBuffer->GetBufferContents(i);
256 }
257
258 // Resize the ring buffer
259 m_DataObjectBuffer->SetNumberOfBuffers(minimumNumberOfFrames);
260
261 // Move previously buffered data to the locations where their frame numbers now map
262 for (SizeValueType i = bufferedStart; i < bufferedStart + bufferedDuration; ++i)
263 {
264 m_DataObjectBuffer->SetBufferContents(i, frames[i - bufferedStart]);
265 }
266 }
267 }
268
269
270 template<typename TFrameType>
271 void
272 VideoStream<TFrameType>
InitializeEmptyFrames()273 ::InitializeEmptyFrames()
274 {
275 // If we don't have any frames requested, just return
276 SizeValueType numFrames = m_RequestedTemporalRegion.GetFrameDuration();
277 if (numFrames == 0)
278 {
279 return;
280 }
281
282
283 // Safely expand the ring buffer if necessary
284 this->SetMinimumBufferSize(numFrames);
285
286 // Go through the number of required frames and make sure none are empty
287 SizeValueType startFrame = m_RequestedTemporalRegion.GetFrameStart();
288 for (SizeValueType i = startFrame; i < startFrame + numFrames; ++i)
289 {
290 if (!m_DataObjectBuffer->BufferIsFull(i))
291 {
292 FramePointer newFrame = FrameType::New();
293 FrameType* newFrameRawPointer = newFrame.GetPointer();
294 typename BufferType::ElementPointer element =
295 dynamic_cast<typename BufferType::ElementType*>(newFrameRawPointer);
296 m_DataObjectBuffer->SetBufferContents(i, element);
297 }
298
299 // Check to see if any cached meta data exists and if it does, assign it
300 if (m_LargestPossibleSpatialRegionCache.find(i) !=
301 m_LargestPossibleSpatialRegionCache.end())
302 {
303 this->GetFrame(i)->SetLargestPossibleRegion(m_LargestPossibleSpatialRegionCache[i]);
304 }
305 if (m_RequestedSpatialRegionCache.find(i) !=
306 m_RequestedSpatialRegionCache.end())
307 {
308 this->GetFrame(i)->SetRequestedRegion(m_RequestedSpatialRegionCache[i]);
309 }
310 if (m_BufferedSpatialRegionCache.find(i) !=
311 m_BufferedSpatialRegionCache.end())
312 {
313 this->GetFrame(i)->SetBufferedRegion(m_BufferedSpatialRegionCache[i]);
314 }
315 if (m_SpacingCache.find(i) != m_SpacingCache.end())
316 {
317 this->GetFrame(i)->SetSpacing(m_SpacingCache[i]);
318 }
319 if (m_OriginCache.find(i) != m_OriginCache.end())
320 {
321 this->GetFrame(i)->SetOrigin(m_OriginCache[i]);
322 }
323 if (m_DirectionCache.find(i) != m_DirectionCache.end())
324 {
325 this->GetFrame(i)->SetDirection(m_DirectionCache[i]);
326 }
327 }
328 }
329
330
331 template<typename TFrameType>
332 void
333 VideoStream<TFrameType>
SetFrame(SizeValueType frameNumber,FramePointer frame)334 ::SetFrame(SizeValueType frameNumber, FramePointer frame)
335 {
336 auto * dataObjectRawPointer = dynamic_cast<typename BufferType::ElementType*>(frame.GetPointer());
337 typename BufferType::ElementPointer dataObject = dataObjectRawPointer;
338 m_DataObjectBuffer->SetBufferContents(frameNumber,dataObject);
339
340 // Cache the meta data
341 m_LargestPossibleSpatialRegionCache[frameNumber] = frame->GetLargestPossibleRegion();
342 m_RequestedSpatialRegionCache[frameNumber] = frame->GetRequestedRegion();
343 m_BufferedSpatialRegionCache[frameNumber] = frame->GetBufferedRegion();
344 m_SpacingCache[frameNumber] = frame->GetSpacing();
345 m_OriginCache[frameNumber] = frame->GetOrigin();
346 m_DirectionCache[frameNumber] = frame->GetDirection();
347 }
348
349
350 template<typename TFrameType>
351 typename VideoStream<TFrameType>::FramePointer
352 VideoStream<TFrameType>
GetFrame(SizeValueType frameNumber)353 ::GetFrame(SizeValueType frameNumber)
354 {
355
356 // Fetch the frame
357 typename BufferType::ElementPointer element =
358 m_DataObjectBuffer->GetBufferContents(frameNumber);
359 FramePointer frame = dynamic_cast<FrameType*>(element.GetPointer());
360 return frame;
361 }
362
363
364 template<typename TFrameType>
365 typename VideoStream<TFrameType>::FrameConstPointer
366 VideoStream<TFrameType>
GetFrame(SizeValueType frameNumber) const367 ::GetFrame(SizeValueType frameNumber) const
368 {
369 typename BufferType::ElementPointer element =
370 m_DataObjectBuffer->GetBufferContents(frameNumber);
371 FrameConstPointer frame = dynamic_cast<FrameType*>(element.GetPointer());
372 return frame;
373 }
374
375
376 template<typename TFrameType>
377 void
378 VideoStream<TFrameType>
Graft(const DataObject * data)379 ::Graft(const DataObject* data)
380 {
381 // Call TemporalDataObject's Graft implementation
382 Superclass::Graft(data);
383
384 if (data)
385 {
386 // Attempt to cast to a VideoStream
387 const auto * videoData = dynamic_cast< const Self* >(data);
388 if (!videoData)
389 {
390 itkExceptionMacro( << "itk::VideoStream::Graft() cannot cast "
391 << typeid( data ).name() << " to "
392 << typeid( const Self* ).name() );
393 }
394
395 // Copy the meta data caches
396 this->SetLargestPossibleSpatialRegionCache(
397 videoData->GetLargestPossibleSpatialRegionCache());
398 this->SetRequestedSpatialRegionCache(
399 videoData->GetRequestedSpatialRegionCache());
400 this->SetBufferedSpatialRegionCache(
401 videoData->GetBufferedSpatialRegionCache());
402 this->SetSpacingCache(videoData->GetSpacingCache());
403 this->SetOriginCache(videoData->GetOriginCache());
404 this->SetDirectionCache(videoData->GetDirectionCache());
405
406 // Copy the frame buffer
407 this->SetFrameBuffer(const_cast< BufferType* >(videoData->GetFrameBuffer()));
408 }
409 }
410
411
412 template<typename TFrameType>
413 void
414 VideoStream<TFrameType>
SetAllLargestPossibleSpatialRegions(typename TFrameType::RegionType region)415 ::SetAllLargestPossibleSpatialRegions(typename TFrameType::RegionType region)
416 {
417 SizeValueType numFrames = m_LargestPossibleTemporalRegion.GetFrameDuration();
418 SizeValueType startFrame = m_LargestPossibleTemporalRegion.GetFrameStart();
419
420 // If the largest region is infinite, use the largest of the requested or
421 // buffered region
422 if (numFrames == ITK_INFINITE_FRAME_DURATION)
423 {
424 SizeValueType bufEnd = m_BufferedTemporalRegion.GetFrameStart() +
425 m_BufferedTemporalRegion.GetFrameDuration();
426 SizeValueType reqEnd = m_RequestedTemporalRegion.GetFrameStart() +
427 m_RequestedTemporalRegion.GetFrameDuration();
428 (bufEnd > reqEnd) ? (numFrames = bufEnd) : (numFrames = reqEnd);
429 }
430
431 // Go through the number of required frames, making sure none are empty and
432 // setting the region
433 for (SizeValueType i = startFrame; i < startFrame + numFrames; ++i)
434 {
435 this->SetFrameLargestPossibleSpatialRegion(i, region);
436 }
437 }
438
439
440 template<typename TFrameType>
441 void
442 VideoStream<TFrameType>
SetAllRequestedSpatialRegions(typename TFrameType::RegionType region)443 ::SetAllRequestedSpatialRegions(typename TFrameType::RegionType region)
444 {
445 SizeValueType numFrames = m_LargestPossibleTemporalRegion.GetFrameDuration();
446 SizeValueType startFrame = m_LargestPossibleTemporalRegion.GetFrameStart();
447
448 // If the largest region is infinite, use the largest of the requested or
449 // buffered region
450 if (numFrames == ITK_INFINITE_FRAME_DURATION)
451 {
452 SizeValueType bufEnd = m_BufferedTemporalRegion.GetFrameStart() +
453 m_BufferedTemporalRegion.GetFrameDuration();
454 SizeValueType reqEnd = m_RequestedTemporalRegion.GetFrameStart() +
455 m_RequestedTemporalRegion.GetFrameDuration();
456 (bufEnd > reqEnd) ? (numFrames = bufEnd) : (numFrames = reqEnd);
457 }
458
459 // Go through the number of required frames, making sure none are empty and
460 // setting the region
461 for (SizeValueType i = startFrame; i < startFrame + numFrames; ++i)
462 {
463 this->SetFrameRequestedSpatialRegion(i, region);
464 }
465 }
466
467
468 template<typename TFrameType>
469 void
470 VideoStream<TFrameType>
SetAllBufferedSpatialRegions(typename TFrameType::RegionType region)471 ::SetAllBufferedSpatialRegions(typename TFrameType::RegionType region)
472 {
473 SizeValueType numFrames = m_LargestPossibleTemporalRegion.GetFrameDuration();
474 SizeValueType startFrame = m_LargestPossibleTemporalRegion.GetFrameStart();
475
476 // If the largest region is infinite, use the largest of the requested or
477 // buffered region
478 if (numFrames == ITK_INFINITE_FRAME_DURATION)
479 {
480 SizeValueType bufEnd = m_BufferedTemporalRegion.GetFrameStart() +
481 m_BufferedTemporalRegion.GetFrameDuration();
482 SizeValueType reqEnd = m_RequestedTemporalRegion.GetFrameStart() +
483 m_RequestedTemporalRegion.GetFrameDuration();
484 (bufEnd > reqEnd) ? (numFrames = bufEnd) : (numFrames = reqEnd);
485 }
486
487 // Go through the number of required frames, making sure none are empty and
488 // setting the region
489 for (SizeValueType i = startFrame; i < startFrame + numFrames; ++i)
490 {
491 this->SetFrameBufferedSpatialRegion(i, region);
492 }
493 }
494
495
496 template<typename TFrameType>
497 void
498 VideoStream<TFrameType>
SetAllFramesSpacing(typename TFrameType::SpacingType spacing)499 ::SetAllFramesSpacing(typename TFrameType::SpacingType spacing)
500 {
501 SizeValueType numFrames = m_LargestPossibleTemporalRegion.GetFrameDuration();
502 SizeValueType startFrame = m_LargestPossibleTemporalRegion.GetFrameStart();
503
504 // If the largest region is infinite, use the largest of the requested or
505 // buffered region
506 if (numFrames == ITK_INFINITE_FRAME_DURATION)
507 {
508 SizeValueType bufEnd = m_BufferedTemporalRegion.GetFrameStart() +
509 m_BufferedTemporalRegion.GetFrameDuration();
510 SizeValueType reqEnd = m_RequestedTemporalRegion.GetFrameStart() +
511 m_RequestedTemporalRegion.GetFrameDuration();
512 (bufEnd > reqEnd) ? (numFrames = bufEnd) : (numFrames = reqEnd);
513 }
514
515 // Go through the number of required frames, making sure none are empty and
516 // setting the region
517 for (SizeValueType i = startFrame; i < startFrame + numFrames; ++i)
518 {
519 this->SetFrameSpacing(i, spacing);
520 }
521 }
522
523
524 template<typename TFrameType>
525 void
526 VideoStream<TFrameType>
SetAllFramesOrigin(typename TFrameType::PointType origin)527 ::SetAllFramesOrigin(typename TFrameType::PointType origin)
528 {
529 SizeValueType numFrames = m_LargestPossibleTemporalRegion.GetFrameDuration();
530 SizeValueType startFrame = m_LargestPossibleTemporalRegion.GetFrameStart();
531
532 // If the largest region is infinite, use the largest of the requested or
533 // buffered region
534 if (numFrames == ITK_INFINITE_FRAME_DURATION)
535 {
536 SizeValueType bufEnd = m_BufferedTemporalRegion.GetFrameStart() +
537 m_BufferedTemporalRegion.GetFrameDuration();
538 SizeValueType reqEnd = m_RequestedTemporalRegion.GetFrameStart() +
539 m_RequestedTemporalRegion.GetFrameDuration();
540 (bufEnd > reqEnd) ? (numFrames = bufEnd) : (numFrames = reqEnd);
541 }
542
543 // Go through the number of required frames, making sure none are empty and
544 // setting the region
545 for (SizeValueType i = startFrame; i < startFrame + numFrames; ++i)
546 {
547 this->SetFrameOrigin(i, origin);
548 }
549 }
550
551
552 template<typename TFrameType>
553 void
554 VideoStream<TFrameType>
SetAllFramesDirection(typename TFrameType::DirectionType direction)555 ::SetAllFramesDirection(typename TFrameType::DirectionType direction)
556 {
557 SizeValueType numFrames = m_LargestPossibleTemporalRegion.GetFrameDuration();
558 SizeValueType startFrame = m_LargestPossibleTemporalRegion.GetFrameStart();
559
560 // If the largest region is infinite, use the largest of the requested or
561 // buffered region
562 if (numFrames == ITK_INFINITE_FRAME_DURATION)
563 {
564 SizeValueType bufEnd = m_BufferedTemporalRegion.GetFrameStart() +
565 m_BufferedTemporalRegion.GetFrameDuration();
566 SizeValueType reqEnd = m_RequestedTemporalRegion.GetFrameStart() +
567 m_RequestedTemporalRegion.GetFrameDuration();
568 (bufEnd > reqEnd) ? (numFrames = bufEnd) : (numFrames = reqEnd);
569 }
570
571 // Go through the number of required frames, making sure none are empty and
572 // setting the region
573 for (SizeValueType i = startFrame; i < startFrame + numFrames; ++i)
574 {
575 this->SetFrameDirection(i, direction);
576 }
577 }
578
579
580 template<typename TFrameType>
581 void
582 VideoStream<TFrameType>
Allocate()583 ::Allocate()
584 {
585 SizeValueType numFrames = m_BufferedTemporalRegion.GetFrameDuration();
586 if (m_DataObjectBuffer->GetNumberOfBuffers() < numFrames)
587 {
588 itkExceptionMacro("itk::VideoStream::SetAllLargestPossibleSpatialRegions "
589 "not enough frame buffers available. Call InitializeEmptyFrames "
590 "to prepare the frame buffer correctly.");
591 }
592
593 // Go through the number of required frames, making sure none are empty and
594 // allocating them. We start at 1 and move forwards because frames will be
595 // added using AppendFrame which first moves the Head forward, then adds the
596 // frame
597 for (SizeValueType i = 1; i <= numFrames; ++i)
598 {
599 if (!m_DataObjectBuffer->BufferIsFull(i))
600 {
601 itkExceptionMacro("itk::VideoStream::SetAllLargestPossibleSpatialRegions "
602 "empty frame buffer found at offset " << i << ". Call "
603 "InitializeEmptyFrames to prepare the frame buffer correctly.");
604 }
605 FrameType* frame = dynamic_cast<FrameType*>(
606 m_DataObjectBuffer->GetBufferContents(i).GetPointer());
607 if (!frame)
608 {
609 itkExceptionMacro("itk::VideoStream::SetAllLargestPossibleSpatialRegions "
610 "could not cast frame " << i << " to the correct type.");
611 }
612 frame->Allocate();
613 }
614 }
615
616 } // end namespace itk
617
618 #endif
619