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
17package com.example.android.rs.vr.loaders;
18
19import android.renderscript.Allocation;
20import android.renderscript.RenderScript;
21import android.renderscript.Type;
22import android.util.Log;
23
24import com.example.android.rs.vr.engine.ScriptC_bricked;
25import com.example.android.rs.vr.engine.Volume;
26
27import java.io.File;
28import java.io.FileInputStream;
29import java.nio.MappedByteBuffer;
30import java.nio.channels.FileChannel;
31import java.util.Arrays;
32import java.util.Comparator;
33import java.util.HashMap;
34import java.util.Properties;
35import java.util.Vector;
36
37/**
38 * Created by hoford on 2/2/15.
39 */
40public 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     */
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