1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.example.android.rs.vr.loaders;
18 
19 import android.renderscript.Allocation;
20 import android.renderscript.RenderScript;
21 import android.renderscript.Type;
22 import android.util.Log;
23 
24 import com.example.android.rs.vr.engine.ScriptC_bricked;
25 import com.example.android.rs.vr.engine.Volume;
26 
27 import java.io.File;
28 import java.io.FileInputStream;
29 import java.nio.MappedByteBuffer;
30 import java.nio.channels.FileChannel;
31 import java.util.Arrays;
32 import java.util.Comparator;
33 import java.util.HashMap;
34 import java.util.Properties;
35 import java.util.Vector;
36 
37 /**
38  * Created by hoford on 2/2/15.
39  */
40 public class LoaderRaw {
41     private static final String LOGTAG = "RawLoader";
42 
43     /**
44      * This builds the volume based on a collection of raw image files
45      * @param rs The Renderscript context
46      * @param dir The directory containing the raw images
47      * @param prop property object containing information about the files
48      * @param listener To provide feedback
49      * @return The created volume
50      */
buildRSVolume(final RenderScript rs, File dir, Properties prop, final VolumeLoader.ProgressListener listener)51     public static Volume buildRSVolume(final RenderScript rs, File dir, Properties prop,
52                                        final VolumeLoader.ProgressListener listener) {
53         String[] dim = prop.getProperty("dim").split("x");
54         Volume v = new Volume();
55         v.mDimx = Integer.parseInt(dim[0]);
56         v.mDimy = Integer.parseInt(dim[1]);
57         v.mDimz = Integer.parseInt(dim[2]);
58         String[] voxeldim = prop.getProperty("voxeldim").split(",");
59         v.mVoxelDim[0] = Float.parseFloat(voxeldim[0]);
60         v.mVoxelDim[1] = Float.parseFloat(voxeldim[1]);
61         v.mVoxelDim[2] = Float.parseFloat(voxeldim[2]);
62         Float min = Math.min(v.mVoxelDim[0], Math.min(v.mVoxelDim[1], v.mVoxelDim[2]));
63         v.mVoxelDim[0] /= min;
64         v.mVoxelDim[1] /= min;
65         v.mVoxelDim[2] /= min;
66         listener.progress(0, v.mDimz);
67         if (v.mDimz < 20) {
68             return null;
69         }
70         Log.v(LOGTAG, "Loading " + dir.getPath());
71         File[] f = dir.listFiles();
72         Log.v(LOGTAG, "dir contains " + f.length + " files");
73         Arrays.sort(f, new Comparator<File>() {
74 
75             @Override
76             public int compare(File o1, File o2) {
77 
78                 return Integer.decode(o1.getName()).compareTo(Integer.decode(o2.getName()));
79             }
80         });
81 
82         int count = 0;
83 
84 
85         final Vector<File> toRun = new Vector<File>();
86         final HashMap<File, Integer> fileMap = new HashMap<File, Integer>();
87         for (int i = 0; i < f.length; i++) {
88             if (f[i].isDirectory()) {
89                 continue;
90             }
91 
92             toRun.add(f[i]);
93             fileMap.put(f[i], count);
94             count++;
95         }
96 
97         v.mDimz = count;
98         if (listener != null) {
99             listener.progress(0, v.mDimz);
100         }
101 
102         v.mVolumeAllocation = null;
103         Allocation alloc_slice = null;
104         ScriptC_bricked scriptC_bricked = new ScriptC_bricked(rs);
105         FileInputStream inputStream;
106         String pixel_spacing = null;
107         String slice1_pos = null;
108         String slice2_pos = null;
109         boolean slice_spacing_set = false;
110         int z = 0;
111         for (File file : toRun) {
112             try {
113                 inputStream = new FileInputStream(file);
114                 MappedByteBuffer mbb = inputStream.getChannel().map(FileChannel.MapMode.READ_ONLY,
115                         0, v.mDimy * v.mDimx * 2);
116                 short[] slice = new short[v.mDimy * v.mDimx];
117                 mbb.asShortBuffer().get(slice);
118                 inputStream.close();
119                 mbb = null;
120                 if (v.mVolumeAllocation == null) {
121                     Log.v(LOGTAG, "make Volume " + z);
122                     Type.Builder b = new Type.Builder(rs, android.renderscript.Element.I16(rs));
123                     b.setX(v.mDimx).setY(v.mDimy);
124                     alloc_slice = Allocation.createTyped(rs, b.create(), Allocation.USAGE_SCRIPT);
125                     b.setZ(v.mDimz);
126                     v.mVolumeAllocation = Allocation.createTyped(rs,
127                             b.create(), Allocation.USAGE_SCRIPT);
128                     scriptC_bricked.set_volume(v.mVolumeAllocation);
129 
130                 }
131                 Log.v(LOGTAG, "LOAD SLICE " + z);
132                 int size = v.mDimy * v.mDimx;
133                 alloc_slice.copyFromUnchecked(slice);
134                 scriptC_bricked.set_z(z);
135                 scriptC_bricked.forEach_copy(alloc_slice);
136                 z++;
137                 if (listener != null) {
138                     listener.progress(z, v.mDimz);
139                 }
140 
141             } catch (Exception e) {
142                 e.printStackTrace();
143             }
144         }
145         rs.finish();
146         alloc_slice.destroy();
147         Log.v(LOGTAG,"LOADING DONE ....");
148 
149         scriptC_bricked.destroy();
150         return v;
151     }
152 }
153