SCM Repository
Annotation of /branches/vis12/src/compiler/fields/image-info.sml
Parent Directory
|
Revision Log
Revision 1790 - (view) (download)
1 : | jhr | 106 | (* image-info.sml |
2 : | * | ||
3 : | jhr | 435 | * COPYRIGHT (c) 2010 The Diderot Project (http://diderot-language.cs.uchicago.edu) |
4 : | jhr | 106 | * All rights reserved. |
5 : | * | ||
6 : | jhr | 1116 | * Information about a NRRD file. |
7 : | * | ||
8 : | * TODO: | ||
9 : | * handle images where the symmetries are exploited. | ||
10 : | jhr | 106 | *) |
11 : | |||
12 : | structure ImageInfo : sig | ||
13 : | |||
14 : | jhr | 1116 | (* Image voxels are tensors of some raw representation type *) |
15 : | type voxel_ty = (int list * RawTypes.ty) | ||
16 : | jhr | 284 | |
17 : | jhr | 1784 | (* a subset of the Nrrd file axis kinds (see http://teem.sourceforge.net/nrrd/format.html#kinds) *) |
18 : | datatype axis_kind | ||
19 : | = SPACE | ||
20 : | | SCALAR | ||
21 : | | VEC of int (* 2, 3, or 4-vector *) | ||
22 : | | MAT of int (* 2x2 or 3x3 matrix *) | ||
23 : | |||
24 : | jhr | 165 | datatype info = ImgInfo of { |
25 : | jhr | 465 | id : OS.FileSys.file_id, (* ID of image file *) |
26 : | dim : int, (* dimension of space *) | ||
27 : | jhr | 1116 | ty : voxel_ty, (* types of image samples *) |
28 : | jhr | 465 | origin : FloatLit.float list, (* center of first sample *) |
29 : | jhr | 1789 | kinds : NrrdEnums.axis_kind list, (* the kinds of each axis; |
30 : | jhr | 465 | * we follow the Nrrd convention of |
31 : | * listing the axes in fast to slow | ||
32 : | * order. | ||
33 : | *) | ||
34 : | jhr | 1784 | sizes : int list (* number of samples along each axis *) |
35 : | jhr | 465 | } |
36 : | jhr | 165 | |
37 : | (* are the underlying files the same? *) | ||
38 : | val same : info * info -> bool | ||
39 : | |||
40 : | (* hash value (based on image file ID) *) | ||
41 : | val hash : info -> word | ||
42 : | |||
43 : | (* get image info from a Nrrd file *) | ||
44 : | jhr | 130 | val getInfo : string -> info |
45 : | jhr | 106 | |
46 : | jhr | 192 | val toString : info -> string |
47 : | jhr | 1116 | val dim : info -> int (* dimension of space *) |
48 : | val sizes : info -> int list (* size of each dimension *) | ||
49 : | val voxelShape : info -> int list (* shape of voxels; empty list for scalars *) | ||
50 : | val voxelSzB : info -> int (* size in bytes of a voxel *) | ||
51 : | val stride : info -> int (* for non-scalar images, this returns the *) | ||
52 : | (* number of samples between voxels *) | ||
53 : | val sampleTy : info -> RawTypes.ty (* representation type of samples *) | ||
54 : | jhr | 192 | |
55 : | jhr | 106 | end = struct |
56 : | |||
57 : | jhr | 284 | (* Image samples are tensors of some raw representation type *) |
58 : | jhr | 1116 | type voxel_ty = (int list * RawTypes.ty) |
59 : | jhr | 284 | |
60 : | jhr | 1784 | (* a subset of the Nrrd file axis kinds (see http://teem.sourceforge.net/nrrd/format.html#kinds) *) |
61 : | datatype axis_kind | ||
62 : | = SPACE | ||
63 : | | SCALAR | ||
64 : | | VEC of int (* 2, 3, or 4-vector *) | ||
65 : | | MAT of int (* 2x2 or 3x3 matrix *) | ||
66 : | |||
67 : | jhr | 165 | datatype info = ImgInfo of { |
68 : | jhr | 465 | id : OS.FileSys.file_id, (* ID of image file *) |
69 : | dim : int, (* dimension of space *) | ||
70 : | jhr | 1116 | ty : voxel_ty, (* types of image samples *) |
71 : | jhr | 465 | origin : FloatLit.float list, (* center of first sample *) |
72 : | jhr | 1789 | kinds : NrrdEnums.axis_kind list, (* the kinds of each axis; |
73 : | jhr | 465 | * we follow the Nrrd convention of |
74 : | * listing the axes in fast to slow | ||
75 : | * order. | ||
76 : | *) | ||
77 : | jhr | 1784 | sizes : int list (* number of samples along each axis *) |
78 : | jhr | 465 | } |
79 : | jhr | 135 | |
80 : | jhr | 165 | fun same (ImgInfo{id=a, ...}, ImgInfo{id=b, ...}) = (a = b) |
81 : | |||
82 : | fun hash (ImgInfo{id, ...}) = OS.FileSys.hash id | ||
83 : | |||
84 : | jhr | 1116 | fun doHeader (fileName, header) = let |
85 : | jhr | 511 | fun fields s = String.tokens Char.isSpace s |
86 : | jhr | 239 | fun set (r, v) = (r := SOME v) |
87 : | fun get (tag, r) = (case !r of NONE => raise Fail("missing "^tag) | SOME v => v) | ||
88 : | val ty = ref NONE | ||
89 : | jhr | 284 | val totalDim = ref NONE |
90 : | jhr | 239 | val dim = ref NONE |
91 : | jhr | 1784 | val kinds = ref NONE |
92 : | jhr | 511 | val sizes = ref NONE |
93 : | jhr | 1790 | fun doValue ("type", v) = (case NrrdEnums.tyFromString v |
94 : | of SOME ty' => set(ty, ty') | ||
95 : | | NONE => raise Fail(concat[ | ||
96 : | "bogus dnorm output: \"", "type: ", String.toString v, "\n" | ||
97 : | ]) | ||
98 : | (* end case *)) | ||
99 : | jhr | 284 | | doValue ("dimension", v) = set (totalDim, valOf(Int.fromString v)) |
100 : | jhr | 239 | | doValue ("space dimension", v) = set (dim, valOf(Int.fromString v)) |
101 : | jhr | 511 | | doValue ("sizes", v) = let |
102 : | fun atoi s = (case Int.fromString s | ||
103 : | of SOME i => i | ||
104 : | | NONE => raise Fail(concat[ | ||
105 : | "bogus dnorm output: \"", "sizes: ", String.toString v, "\n" | ||
106 : | ]) | ||
107 : | (* end case *)) | ||
108 : | in | ||
109 : | set (sizes, List.map atoi (fields v)) | ||
110 : | end | ||
111 : | jhr | 239 | | doValue ("space directions", v) = () |
112 : | jhr | 1784 | | doValue ("kinds", v) = let |
113 : | jhr | 1789 | fun s2kind s = (case NrrdEnums.kindFromString s |
114 : | of SOME k => k | ||
115 : | | NONE => raise Fail(concat["axis kind \"", s, "\" not supported"]) | ||
116 : | (* end case *)) | ||
117 : | jhr | 1784 | in |
118 : | set (kinds, List.map s2kind (fields v)) | ||
119 : | end | ||
120 : | jhr | 239 | | doValue ("endian", v) = () |
121 : | | doValue ("encoding", v) = () | ||
122 : | | doValue ("space origin", v) = () | ||
123 : | | doValue _ = () | ||
124 : | jhr | 135 | in |
125 : | jhr | 238 | Log.msg (concat[fileName, " file header:\n"]); |
126 : | List.app (fn (tag, value) => Log.msg(concat[" ", tag, ": ", value, "\n"])) header; | ||
127 : | jhr | 239 | List.app doValue header; |
128 : | jhr | 1116 | let |
129 : | val dim = get ("space dimension", dim) | ||
130 : | val rngDim = get ("dimension", totalDim) - dim | ||
131 : | (* split the sizes into those that control the shape of the voxels, which come first | ||
132 : | * in the list, and those that span the image's dimensions. | ||
133 : | *) | ||
134 : | val (rngShape, sizes) = let | ||
135 : | fun split (0, l, prefix) = (List.rev prefix, l) | ||
136 : | | split (i, d::l, prefix) = split(i-1, l, d::prefix) | ||
137 : | | split _ = raise Fail "bogus dnorm output: too few sizes" | ||
138 : | in | ||
139 : | split (rngDim, get ("sizes", sizes), []) | ||
140 : | end | ||
141 : | in | ||
142 : | ImgInfo{ | ||
143 : | id = OS.FileSys.fileId fileName, | ||
144 : | dim = dim, | ||
145 : | jhr | 1790 | ty = (rngShape, NrrdEnums.tyToRaw (get ("type", ty))), |
146 : | jhr | 1116 | origin = [], (* FIXME *) |
147 : | jhr | 1784 | kinds = get ("kinds", kinds), |
148 : | jhr | 1116 | sizes = sizes |
149 : | } | ||
150 : | end | ||
151 : | jhr | 135 | end |
152 : | |||
153 : | jhr | 1116 | fun getInfo fileName = if OS.FileSys.access(fileName, [OS.FileSys.A_READ]) |
154 : | then let | ||
155 : | val {version, header} = RunDNorm.run fileName | ||
156 : | in | ||
157 : | doHeader (fileName, header) | ||
158 : | end | ||
159 : | else raise Fail(concat["Nrrd file \"", fileName, "\" does not exist"]) | ||
160 : | jhr | 192 | |
161 : | jhr | 1116 | fun toString (ImgInfo{dim, ty=(dd, rTy), ...}) = let |
162 : | val shape = (case dd | ||
163 : | of [] => "" | ||
164 : | | [d] => concat["{", Int.toString d, "}"] | ||
165 : | | dd => concat["{", String.concatWith "," (List.map Int.toString dd), "}"] | ||
166 : | (* end case *)) | ||
167 : | in | ||
168 : | concat[ | ||
169 : | "IMAGE", Int.toString dim, "D<", RawTypes.toString rTy, shape, ">" | ||
170 : | ] | ||
171 : | end | ||
172 : | |||
173 : | jhr | 394 | fun dim (ImgInfo{dim, ...}) = dim |
174 : | |||
175 : | jhr | 1116 | fun sizes (ImgInfo{sizes, ...}) = sizes |
176 : | |||
177 : | fun voxelShape (ImgInfo{ty=(dd, _), ...}) = dd | ||
178 : | |||
179 : | fun voxelSzB (ImgInfo{ty=(dd, rTy), ...}) = let | ||
180 : | val nSamples = List.foldl (op * ) 1 dd | ||
181 : | in | ||
182 : | nSamples * RawTypes.sizeb rTy | ||
183 : | end | ||
184 : | |||
185 : | fun stride (ImgInfo{ty=(dd, rTy), ...}) = List.foldl (op * ) 1 dd | ||
186 : | |||
187 : | fun sampleTy (ImgInfo{ty=(_, rTy), ...}) = rTy | ||
188 : | |||
189 : | jhr | 106 | end |
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |