forked from bettar/miele-lxiv
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CPRProjectionOperation.m
116 lines (95 loc) · 3.27 KB
/
CPRProjectionOperation.m
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
/*=========================================================================
Program: OsiriX
Copyright (c) OsiriX Team
All rights reserved.
Distributed under GNU - LGPL
See http://www.osirix-viewer.com/copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
=========================================================================*/
#import "CPRProjectionOperation.h"
#include <Accelerate/Accelerate.h>
#import "CPRVolumeData.h"
@implementation CPRProjectionOperation
@synthesize volumeData = _volumeData;
@synthesize generatedVolume = _generatedVolume;
@synthesize projectionMode = _projectionMode;
- (id)init
{
if ( (self = [super init]) ) {
_projectionMode = CPRProjectionModeNone;
}
return self;
}
- (void)dealloc
{
[_volumeData release];
_volumeData = nil;
[_generatedVolume release];
_generatedVolume = nil;
[super dealloc];
}
- (void)main
{
float *floatBytes;
NSInteger i;
float floati;
NSInteger pixelsPerPlane;
N3AffineTransform volumeTransform;
CPRVolumeDataInlineBuffer inlineBuffer;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@try {
if ([self isCancelled]) {
return;
}
if (_projectionMode == CPRProjectionModeNone) {
_generatedVolume = [_volumeData retain];
return;
}
pixelsPerPlane = _volumeData.pixelsWide * _volumeData.pixelsHigh;
floatBytes = malloc(sizeof(float) * pixelsPerPlane);
if ([_volumeData aquireInlineBuffer:&inlineBuffer]) {
memcpy(floatBytes, CPRVolumeDataFloatBytes(&inlineBuffer), sizeof(float) * pixelsPerPlane);
switch (_projectionMode) {
case CPRProjectionModeMIP:
for (i = 1; i < _volumeData.pixelsDeep; i++) {
if ([self isCancelled]) {
break;
}
vDSP_vmax(floatBytes, 1, (float *)CPRVolumeDataFloatBytes(&inlineBuffer) + (i * pixelsPerPlane), 1, floatBytes, 1, pixelsPerPlane);
}
break;
case CPRProjectionModeMinIP:
for (i = 1; i < _volumeData.pixelsDeep; i++) {
if ([self isCancelled]) {
break;
}
vDSP_vmin(floatBytes, 1, (float *)CPRVolumeDataFloatBytes(&inlineBuffer) + (i * pixelsPerPlane), 1, floatBytes, 1, pixelsPerPlane);
}
break;
case CPRProjectionModeMean:
for (i = 1; i < _volumeData.pixelsDeep; i++) {
if ([self isCancelled]) {
break;
}
floati = i;
vDSP_vavlin((float *)CPRVolumeDataFloatBytes(&inlineBuffer) + (i * pixelsPerPlane), 1, &floati, floatBytes, 1, pixelsPerPlane);
}
break;
default:
break;
}
}
[_volumeData releaseInlineBuffer:&inlineBuffer];
volumeTransform = N3AffineTransformConcat(_volumeData.volumeTransform, N3AffineTransformMakeScale(1.0, 1.0, 1.0/(CGFloat)_volumeData.pixelsDeep));
_generatedVolume = [[CPRVolumeData alloc] initWithFloatBytesNoCopy:floatBytes pixelsWide:_volumeData.pixelsWide pixelsHigh:_volumeData.pixelsHigh pixelsDeep:1
volumeTransform:volumeTransform outOfBoundsValue:_volumeData.outOfBoundsValue freeWhenDone:YES];
}
@catch (...) {
}
@finally {
[pool release];
}
}
@end