15b539461dcc159bd89297443780d635ccc5e3564John Hoford/*
25b539461dcc159bd89297443780d635ccc5e3564John Hoford * Copyright (C) 2015 The Android Open Source Project
35b539461dcc159bd89297443780d635ccc5e3564John Hoford *
45b539461dcc159bd89297443780d635ccc5e3564John Hoford * Licensed under the Apache License, Version 2.0 (the "License");
55b539461dcc159bd89297443780d635ccc5e3564John Hoford * you may not use this file except in compliance with the License.
65b539461dcc159bd89297443780d635ccc5e3564John Hoford * You may obtain a copy of the License at
75b539461dcc159bd89297443780d635ccc5e3564John Hoford *
85b539461dcc159bd89297443780d635ccc5e3564John Hoford *      http://www.apache.org/licenses/LICENSE-2.0
95b539461dcc159bd89297443780d635ccc5e3564John Hoford *
105b539461dcc159bd89297443780d635ccc5e3564John Hoford * Unless required by applicable law or agreed to in writing, software
115b539461dcc159bd89297443780d635ccc5e3564John Hoford * distributed under the License is distributed on an "AS IS" BASIS,
125b539461dcc159bd89297443780d635ccc5e3564John Hoford * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135b539461dcc159bd89297443780d635ccc5e3564John Hoford * See the License for the specific language governing permissions and
145b539461dcc159bd89297443780d635ccc5e3564John Hoford * limitations under the License.
155b539461dcc159bd89297443780d635ccc5e3564John Hoford */
165b539461dcc159bd89297443780d635ccc5e3564John Hoford
175b539461dcc159bd89297443780d635ccc5e3564John Hofordpackage com.example.android.rs.vr.loaders;
185b539461dcc159bd89297443780d635ccc5e3564John Hoford
195b539461dcc159bd89297443780d635ccc5e3564John Hofordimport android.renderscript.Allocation;
205b539461dcc159bd89297443780d635ccc5e3564John Hofordimport android.renderscript.RenderScript;
215b539461dcc159bd89297443780d635ccc5e3564John Hofordimport android.renderscript.Type;
225b539461dcc159bd89297443780d635ccc5e3564John Hofordimport android.util.Log;
235b539461dcc159bd89297443780d635ccc5e3564John Hoford
245b539461dcc159bd89297443780d635ccc5e3564John Hofordimport com.example.android.rs.vr.engine.ScriptC_bricked;
255b539461dcc159bd89297443780d635ccc5e3564John Hofordimport com.example.android.rs.vr.engine.Volume;
265b539461dcc159bd89297443780d635ccc5e3564John Hoford
275b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.io.File;
285b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.io.RandomAccessFile;
295b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.nio.ByteOrder;
305b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.nio.MappedByteBuffer;
315b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.nio.channels.FileChannel.MapMode;
325b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.util.Arrays;
335b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.util.Comparator;
345b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.util.HashMap;
355b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.util.HashSet;
365b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.util.Vector;
375b539461dcc159bd89297443780d635ccc5e3564John Hoford
385b539461dcc159bd89297443780d635ccc5e3564John Hoford/**
395b539461dcc159bd89297443780d635ccc5e3564John Hoford * The simplest possible DICOM Reader.
405b539461dcc159bd89297443780d635ccc5e3564John Hoford * Will only read raw 16 bit dicom slices (the most common type)
415b539461dcc159bd89297443780d635ccc5e3564John Hoford * If the volume is compressed (usually JPEG2000) you need a decompression tool
425b539461dcc159bd89297443780d635ccc5e3564John Hoford *
435b539461dcc159bd89297443780d635ccc5e3564John Hoford * Note: All constants 0xNNNN, 0xNNNN are DICOM TAGS
445b539461dcc159bd89297443780d635ccc5e3564John Hoford * (see online documentation of DICOM standard)
455b539461dcc159bd89297443780d635ccc5e3564John Hoford */
465b539461dcc159bd89297443780d635ccc5e3564John Hofordpublic class LoaderDicom {
475b539461dcc159bd89297443780d635ccc5e3564John Hoford    private static final String LOGTAG = "ReadDicom";
485b539461dcc159bd89297443780d635ccc5e3564John Hoford    String mName;
495b539461dcc159bd89297443780d635ccc5e3564John Hoford    final boolean dbg = false;
505b539461dcc159bd89297443780d635ccc5e3564John Hoford    private ByteOrder mByteOrder;
515b539461dcc159bd89297443780d635ccc5e3564John Hoford    boolean explicit = true;
525b539461dcc159bd89297443780d635ccc5e3564John Hoford    MappedByteBuffer mMappedByteBuffer;
535b539461dcc159bd89297443780d635ccc5e3564John Hoford    long mFileLen;
545b539461dcc159bd89297443780d635ccc5e3564John Hoford    private static final int MIN_VOLUME_SIZE = 20;
555b539461dcc159bd89297443780d635ccc5e3564John Hoford    class Element {
565b539461dcc159bd89297443780d635ccc5e3564John Hoford        int mGroup;
575b539461dcc159bd89297443780d635ccc5e3564John Hoford        int mElement;
585b539461dcc159bd89297443780d635ccc5e3564John Hoford        short mVR;
595b539461dcc159bd89297443780d635ccc5e3564John Hoford        long mLength;
605b539461dcc159bd89297443780d635ccc5e3564John Hoford        Object mValue;
615b539461dcc159bd89297443780d635ccc5e3564John Hoford
625b539461dcc159bd89297443780d635ccc5e3564John Hoford        @Override
635b539461dcc159bd89297443780d635ccc5e3564John Hoford        public String toString() {
645b539461dcc159bd89297443780d635ccc5e3564John Hoford            byte[] vrs = new byte[]{(byte) (mVR & 0xFF), (byte) ((mVR >> 8) & 0xFF)};
655b539461dcc159bd89297443780d635ccc5e3564John Hoford            return Integer.toHexString(mGroup) + "," +
665b539461dcc159bd89297443780d635ccc5e3564John Hoford                    Integer.toHexString(mElement) + "(" +
675b539461dcc159bd89297443780d635ccc5e3564John Hoford                    new String(vrs) + ") [" + mLength + "] ";
685b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
695b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
705b539461dcc159bd89297443780d635ccc5e3564John Hoford
715b539461dcc159bd89297443780d635ccc5e3564John Hoford    static short vr(String v) {
725b539461dcc159bd89297443780d635ccc5e3564John Hoford        byte[] b = v.getBytes();
735b539461dcc159bd89297443780d635ccc5e3564John Hoford        return (short) (((b[1] & 0xFF) << 8) | (b[0] & 0xFF));
745b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
755b539461dcc159bd89297443780d635ccc5e3564John Hoford
765b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short OB = vr("OB");
775b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short OW = vr("OW");
785b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short OF = vr("OF");
795b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short SQ = vr("SQ");
805b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short UT = vr("UT");
815b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short UN = vr("UN");
825b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short DS = vr("DS");
835b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short US = vr("US");
845b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short AS = vr("AS");
855b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short AT = vr("AT");
865b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short CS = vr("CS");
875b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short DA = vr("DA");
885b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short DT = vr("DT");
895b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short FL = vr("FL");
905b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short FD = vr("FD");
915b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short IS = vr("IS");
925b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short LO = vr("LO");
935b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short LT = vr("LT");
945b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short PN = vr("PN");
955b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short SH = vr("SH");
965b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short SL = vr("SL");
975b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short SS = vr("SS");
985b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short ST = vr("ST");
995b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short TM = vr("TM");
1005b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short UI = vr("UI");
1015b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short UL = vr("UL");
1025b539461dcc159bd89297443780d635ccc5e3564John Hoford    static final short AE = vr("AE");
1035b539461dcc159bd89297443780d635ccc5e3564John Hoford
1045b539461dcc159bd89297443780d635ccc5e3564John Hoford    static HashSet<Short> strVRs = new HashSet<Short>();
1055b539461dcc159bd89297443780d635ccc5e3564John Hoford
1065b539461dcc159bd89297443780d635ccc5e3564John Hoford    static {
1075b539461dcc159bd89297443780d635ccc5e3564John Hoford        short[] all = new short[]{
1085b539461dcc159bd89297443780d635ccc5e3564John Hoford                AE, AS, CS, DA, DS, DT, IS, LO, LT, PN, SH, ST, TM, UT
1095b539461dcc159bd89297443780d635ccc5e3564John Hoford        };
1105b539461dcc159bd89297443780d635ccc5e3564John Hoford        for (short anAll : all) {
1115b539461dcc159bd89297443780d635ccc5e3564John Hoford            strVRs.add(anAll);
1125b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
1135b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1145b539461dcc159bd89297443780d635ccc5e3564John Hoford
1155b539461dcc159bd89297443780d635ccc5e3564John Hoford    boolean str(short vr) {
1165b539461dcc159bd89297443780d635ccc5e3564John Hoford        return strVRs.contains(vr);
1175b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1185b539461dcc159bd89297443780d635ccc5e3564John Hoford
1195b539461dcc159bd89297443780d635ccc5e3564John Hoford    boolean big(short vr) {
1205b539461dcc159bd89297443780d635ccc5e3564John Hoford        return OB == vr || OW == vr || OF == vr || SQ == vr || UT == vr || UN == vr;
1215b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1225b539461dcc159bd89297443780d635ccc5e3564John Hoford
1235b539461dcc159bd89297443780d635ccc5e3564John Hoford    class TagSet extends HashMap<Integer, Element> {
1245b539461dcc159bd89297443780d635ccc5e3564John Hoford        Element get(int group, int element) {
1255b539461dcc159bd89297443780d635ccc5e3564John Hoford            return get(tagInt(group, element));
1265b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
1275b539461dcc159bd89297443780d635ccc5e3564John Hoford
1285b539461dcc159bd89297443780d635ccc5e3564John Hoford        void put(Element e) {
1295b539461dcc159bd89297443780d635ccc5e3564John Hoford            put(tagInt(e.mGroup, e.mElement), e);
1305b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
1315b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1325b539461dcc159bd89297443780d635ccc5e3564John Hoford
1335b539461dcc159bd89297443780d635ccc5e3564John Hoford    static int tagInt(int g, int e) {
1345b539461dcc159bd89297443780d635ccc5e3564John Hoford        return (g << 16) | (e & 0xFFFF);
1355b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1365b539461dcc159bd89297443780d635ccc5e3564John Hoford
1375b539461dcc159bd89297443780d635ccc5e3564John Hoford    public static ByteOrder reverse(ByteOrder o) {
1385b539461dcc159bd89297443780d635ccc5e3564John Hoford        return (o == ByteOrder.LITTLE_ENDIAN) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
1395b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1405b539461dcc159bd89297443780d635ccc5e3564John Hoford
1415b539461dcc159bd89297443780d635ccc5e3564John Hoford    public TagSet read(File file, int[] tags) throws Exception {
1425b539461dcc159bd89297443780d635ccc5e3564John Hoford        mName = file.getName();
1435b539461dcc159bd89297443780d635ccc5e3564John Hoford        TagSet set = new TagSet();
1445b539461dcc159bd89297443780d635ccc5e3564John Hoford        HashSet<Integer> toAdd = new HashSet<Integer>();
1455b539461dcc159bd89297443780d635ccc5e3564John Hoford        for (int n : tags) {
1465b539461dcc159bd89297443780d635ccc5e3564John Hoford            toAdd.add(n);
1475b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
1485b539461dcc159bd89297443780d635ccc5e3564John Hoford        RandomAccessFile f = new RandomAccessFile(file, "r");
1495b539461dcc159bd89297443780d635ccc5e3564John Hoford
1505b539461dcc159bd89297443780d635ccc5e3564John Hoford        mMappedByteBuffer = f.getChannel().map(MapMode.READ_ONLY, 0, mFileLen = f.length());
1515b539461dcc159bd89297443780d635ccc5e3564John Hoford        mMappedByteBuffer.position(132);
1525b539461dcc159bd89297443780d635ccc5e3564John Hoford        setOrder(ByteOrder.LITTLE_ENDIAN);
1535b539461dcc159bd89297443780d635ccc5e3564John Hoford        Element e = new Element();
1545b539461dcc159bd89297443780d635ccc5e3564John Hoford        boolean early = true;
1555b539461dcc159bd89297443780d635ccc5e3564John Hoford
1565b539461dcc159bd89297443780d635ccc5e3564John Hoford        while (mMappedByteBuffer.position() < mFileLen) {
1575b539461dcc159bd89297443780d635ccc5e3564John Hoford            int pos = mMappedByteBuffer.position();
1585b539461dcc159bd89297443780d635ccc5e3564John Hoford            int jump = (int) readTag(e);
1595b539461dcc159bd89297443780d635ccc5e3564John Hoford
1605b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (early) {
1615b539461dcc159bd89297443780d635ccc5e3564John Hoford                if (e.mGroup > 255) {
1625b539461dcc159bd89297443780d635ccc5e3564John Hoford                    setOrder((mByteOrder == ByteOrder.LITTLE_ENDIAN) ?
1635b539461dcc159bd89297443780d635ccc5e3564John Hoford                            ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
1645b539461dcc159bd89297443780d635ccc5e3564John Hoford                    mMappedByteBuffer.position(mMappedByteBuffer.position() - jump);
1655b539461dcc159bd89297443780d635ccc5e3564John Hoford                    readTag(e);
1665b539461dcc159bd89297443780d635ccc5e3564John Hoford                }
1675b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
1685b539461dcc159bd89297443780d635ccc5e3564John Hoford
1695b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (early && e.mGroup >= 8) {
1705b539461dcc159bd89297443780d635ccc5e3564John Hoford
1715b539461dcc159bd89297443780d635ccc5e3564John Hoford                early = false;
1725b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
1735b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (toAdd.contains(tagInt(e.mGroup, e.mElement))) {
1745b539461dcc159bd89297443780d635ccc5e3564John Hoford                readValue(e);
1755b539461dcc159bd89297443780d635ccc5e3564John Hoford                set.put(e);
1765b539461dcc159bd89297443780d635ccc5e3564John Hoford                if (e.mGroup == 0x7fe0 && e.mElement == 0x10) {
1775b539461dcc159bd89297443780d635ccc5e3564John Hoford                    return set;
1785b539461dcc159bd89297443780d635ccc5e3564John Hoford                }
1795b539461dcc159bd89297443780d635ccc5e3564John Hoford                e = new Element();
1805b539461dcc159bd89297443780d635ccc5e3564John Hoford
1815b539461dcc159bd89297443780d635ccc5e3564John Hoford            } else {
1825b539461dcc159bd89297443780d635ccc5e3564John Hoford                if (e.mGroup == 0x7fe0 && e.mElement == 0x10) {
1835b539461dcc159bd89297443780d635ccc5e3564John Hoford                    return set;
1845b539461dcc159bd89297443780d635ccc5e3564John Hoford                }
1855b539461dcc159bd89297443780d635ccc5e3564John Hoford
1865b539461dcc159bd89297443780d635ccc5e3564John Hoford                skipValue(e);
1875b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
1885b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
1895b539461dcc159bd89297443780d635ccc5e3564John Hoford        return set;
1905b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
1915b539461dcc159bd89297443780d635ccc5e3564John Hoford
1925b539461dcc159bd89297443780d635ccc5e3564John Hoford    private long readTag(Element e) {
1935b539461dcc159bd89297443780d635ccc5e3564John Hoford        e.mGroup = mMappedByteBuffer.getShort() & 0xFFFF;
1945b539461dcc159bd89297443780d635ccc5e3564John Hoford        e.mElement = mMappedByteBuffer.getShort() & 0xFFFF;
1955b539461dcc159bd89297443780d635ccc5e3564John Hoford
1965b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (e.mGroup == 0xFFFE && e.mElement == 0xE000) {
1975b539461dcc159bd89297443780d635ccc5e3564John Hoford            e.mLength = mMappedByteBuffer.getInt();
1985b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (e.mLength == -1) {
1995b539461dcc159bd89297443780d635ccc5e3564John Hoford                e.mLength = 0;
2005b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
2015b539461dcc159bd89297443780d635ccc5e3564John Hoford            e.mVR = vr("s<");
2025b539461dcc159bd89297443780d635ccc5e3564John Hoford            return 8;
2035b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
2045b539461dcc159bd89297443780d635ccc5e3564John Hoford
2055b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (explicit) {
2065b539461dcc159bd89297443780d635ccc5e3564John Hoford            e.mVR = mMappedByteBuffer.getShort();
2075b539461dcc159bd89297443780d635ccc5e3564John Hoford
2085b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (big(e.mVR)) {
2095b539461dcc159bd89297443780d635ccc5e3564John Hoford                mMappedByteBuffer.getShort();
2105b539461dcc159bd89297443780d635ccc5e3564John Hoford                e.mLength = mMappedByteBuffer.getInt() & 0xFFFFFFFF;
2115b539461dcc159bd89297443780d635ccc5e3564John Hoford            } else {
2125b539461dcc159bd89297443780d635ccc5e3564John Hoford                e.mLength = mMappedByteBuffer.getShort() & 0xFFFF;
2135b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
2145b539461dcc159bd89297443780d635ccc5e3564John Hoford        } else {
2155b539461dcc159bd89297443780d635ccc5e3564John Hoford            e.mVR = 0;
2165b539461dcc159bd89297443780d635ccc5e3564John Hoford            int len = mMappedByteBuffer.getInt();
2175b539461dcc159bd89297443780d635ccc5e3564John Hoford            e.mLength = (len) & 0xFFFFFFFFL;
2185b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (0xFFFFFFFF == e.mLength) {
2195b539461dcc159bd89297443780d635ccc5e3564John Hoford                Log.v(LOGTAG, "undefined");
2205b539461dcc159bd89297443780d635ccc5e3564John Hoford                e.mLength = 0;
2215b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
2225b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
2235b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (e.mLength == -1 || e.mLength == 65535) {
2245b539461dcc159bd89297443780d635ccc5e3564John Hoford            e.mLength = 0;
2255b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
2265b539461dcc159bd89297443780d635ccc5e3564John Hoford        return 8;
2275b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
2285b539461dcc159bd89297443780d635ccc5e3564John Hoford
2295b539461dcc159bd89297443780d635ccc5e3564John Hoford    private void skipValue(Element e) {
2305b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (e.mLength == 0) {
2315b539461dcc159bd89297443780d635ccc5e3564John Hoford            return;
2325b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
2335b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (dbg && str(e.mVR)) {
2345b539461dcc159bd89297443780d635ccc5e3564John Hoford            mMappedByteBuffer.get(readBuff, 0, (int) (e.mLength));
2355b539461dcc159bd89297443780d635ccc5e3564John Hoford            e.mValue = new String(readBuff, 0, (int) (e.mLength));
2365b539461dcc159bd89297443780d635ccc5e3564John Hoford            //    Log.v(LOGTAG, e + "  " + e.mValue);
2375b539461dcc159bd89297443780d635ccc5e3564John Hoford        } else {
2385b539461dcc159bd89297443780d635ccc5e3564John Hoford            mMappedByteBuffer.position((int) (mMappedByteBuffer.position() + e.mLength));
2395b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
2405b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
2415b539461dcc159bd89297443780d635ccc5e3564John Hoford
2425b539461dcc159bd89297443780d635ccc5e3564John Hoford    byte[] readBuff = new byte[200];
2435b539461dcc159bd89297443780d635ccc5e3564John Hoford
2445b539461dcc159bd89297443780d635ccc5e3564John Hoford    private void readValue(Element e) {
2455b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (str(e.mVR)) {
2465b539461dcc159bd89297443780d635ccc5e3564John Hoford            mMappedByteBuffer.get(readBuff, 0, (int) (e.mLength));
2475b539461dcc159bd89297443780d635ccc5e3564John Hoford            e.mValue = new String(readBuff, 0, (int) (e.mLength));
2485b539461dcc159bd89297443780d635ccc5e3564John Hoford        } else if (e.mVR == US) {
2495b539461dcc159bd89297443780d635ccc5e3564John Hoford            e.mValue = new Short(mMappedByteBuffer.getShort());
2505b539461dcc159bd89297443780d635ccc5e3564John Hoford        } else if (e.mVR == OW) {
2515b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (e.mLength == -1) {
2525b539461dcc159bd89297443780d635ccc5e3564John Hoford                e.mLength = mFileLen - mMappedByteBuffer.position();
2535b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
2545b539461dcc159bd89297443780d635ccc5e3564John Hoford            short[] s = new short[(int) (e.mLength / 2)];
2555b539461dcc159bd89297443780d635ccc5e3564John Hoford            mMappedByteBuffer.asShortBuffer().get(s);
2565b539461dcc159bd89297443780d635ccc5e3564John Hoford            e.mValue = s;
2575b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
2585b539461dcc159bd89297443780d635ccc5e3564John Hoford
2595b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
2605b539461dcc159bd89297443780d635ccc5e3564John Hoford
2615b539461dcc159bd89297443780d635ccc5e3564John Hoford    private void setOrder(ByteOrder order) {
2625b539461dcc159bd89297443780d635ccc5e3564John Hoford        mByteOrder = order;
2635b539461dcc159bd89297443780d635ccc5e3564John Hoford        mMappedByteBuffer.order(mByteOrder);
2645b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
2655b539461dcc159bd89297443780d635ccc5e3564John Hoford
2665b539461dcc159bd89297443780d635ccc5e3564John Hoford    public static Volume buildVolume(String dirName) {
2675b539461dcc159bd89297443780d635ccc5e3564John Hoford        return buildVolume(new File(dirName));
2685b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
2695b539461dcc159bd89297443780d635ccc5e3564John Hoford
2705b539461dcc159bd89297443780d635ccc5e3564John Hoford    public static Volume buildVolume(File dir) {
2715b539461dcc159bd89297443780d635ccc5e3564John Hoford        LoaderDicom d = new LoaderDicom();
2725b539461dcc159bd89297443780d635ccc5e3564John Hoford        int[] tags = new int[]{
2735b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x20, 0x32),
2745b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x20, 0x37),
2755b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x28, 0x10),
2765b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x28, 0x11),
2775b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x7fe0, 0x10)
2785b539461dcc159bd89297443780d635ccc5e3564John Hoford        };
2795b539461dcc159bd89297443780d635ccc5e3564John Hoford
2805b539461dcc159bd89297443780d635ccc5e3564John Hoford        File[] files = dir.listFiles();
2815b539461dcc159bd89297443780d635ccc5e3564John Hoford        Arrays.sort(files, new Comparator<File>() {
2825b539461dcc159bd89297443780d635ccc5e3564John Hoford
2835b539461dcc159bd89297443780d635ccc5e3564John Hoford            @Override
2845b539461dcc159bd89297443780d635ccc5e3564John Hoford            public int compare(File o1, File o2) {
2855b539461dcc159bd89297443780d635ccc5e3564John Hoford
2865b539461dcc159bd89297443780d635ccc5e3564John Hoford                return o1.getName().compareTo(o2.getName());
2875b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
2885b539461dcc159bd89297443780d635ccc5e3564John Hoford        });
2895b539461dcc159bd89297443780d635ccc5e3564John Hoford        Volume v = new Volume();
2905b539461dcc159bd89297443780d635ccc5e3564John Hoford        int count = 0;
2915b539461dcc159bd89297443780d635ccc5e3564John Hoford        for (File file : files) {
2925b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (file.isDirectory()) {
2935b539461dcc159bd89297443780d635ccc5e3564John Hoford                continue;
2945b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
2955b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (file.getName().equals(".DS_Store")) {
2965b539461dcc159bd89297443780d635ccc5e3564John Hoford                continue;
2975b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
2985b539461dcc159bd89297443780d635ccc5e3564John Hoford            count++;
2995b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
3005b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (count < MIN_VOLUME_SIZE) {
3015b539461dcc159bd89297443780d635ccc5e3564John Hoford            return null;
3025b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
3035b539461dcc159bd89297443780d635ccc5e3564John Hoford        v.mData = new short[count][];
3045b539461dcc159bd89297443780d635ccc5e3564John Hoford        v.mDimz = count;
3055b539461dcc159bd89297443780d635ccc5e3564John Hoford        count = 0;
3065b539461dcc159bd89297443780d635ccc5e3564John Hoford        for (File file : files) {
3075b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (file.isDirectory()) {
3085b539461dcc159bd89297443780d635ccc5e3564John Hoford                continue;
3095b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
3105b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (file.getName().equals(".DS_Store")) {
3115b539461dcc159bd89297443780d635ccc5e3564John Hoford                continue;
3125b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
3135b539461dcc159bd89297443780d635ccc5e3564John Hoford            try {
3145b539461dcc159bd89297443780d635ccc5e3564John Hoford                TagSet data = d.read(file, tags);
3155b539461dcc159bd89297443780d635ccc5e3564John Hoford                v.mData[count] = (short[]) data.get(0x7fe0, 0x10).mValue;
3165b539461dcc159bd89297443780d635ccc5e3564John Hoford                count++;
3175b539461dcc159bd89297443780d635ccc5e3564John Hoford                v.mDimx = (Short) data.get(0x28, 0x10).mValue;
3185b539461dcc159bd89297443780d635ccc5e3564John Hoford                v.mDimy = (Short) data.get(0x28, 0x11).mValue;
3195b539461dcc159bd89297443780d635ccc5e3564John Hoford            } catch (Exception e) {
3205b539461dcc159bd89297443780d635ccc5e3564John Hoford                Log.e(LOGTAG, "Failed to parse " + file.getPath());
3215b539461dcc159bd89297443780d635ccc5e3564John Hoford                e.printStackTrace();
3225b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
3235b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
3245b539461dcc159bd89297443780d635ccc5e3564John Hoford        return v;
3255b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
3265b539461dcc159bd89297443780d635ccc5e3564John Hoford
3275b539461dcc159bd89297443780d635ccc5e3564John Hoford    /**
3285b539461dcc159bd89297443780d635ccc5e3564John Hoford     * This is a multi threaded volume loaded
3295b539461dcc159bd89297443780d635ccc5e3564John Hoford     * It creates 2xthe number of cores
3305b539461dcc159bd89297443780d635ccc5e3564John Hoford     * @param rs The renderscript context
3315b539461dcc159bd89297443780d635ccc5e3564John Hoford     * @param dir The directory containing the DICOM files
3325b539461dcc159bd89297443780d635ccc5e3564John Hoford     * @param listener The Listener to provide feedback to the UI on loading
3335b539461dcc159bd89297443780d635ccc5e3564John Hoford     * @return The Volume object loaded with the volume
3345b539461dcc159bd89297443780d635ccc5e3564John Hoford     */
3355b539461dcc159bd89297443780d635ccc5e3564John Hoford    public static Volume buildRSVolume(final RenderScript rs, File dir,
3365b539461dcc159bd89297443780d635ccc5e3564John Hoford                                       final VolumeLoader.ProgressListener listener) {
3375b539461dcc159bd89297443780d635ccc5e3564John Hoford        final int[] tags = new int[]{
3385b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x20, 0x32),
3395b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x20, 0x37),
3405b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x28, 0x10),
3415b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x28, 0x11),
3425b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x28, 0x30),
3435b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x7fe0, 0x10)
3445b539461dcc159bd89297443780d635ccc5e3564John Hoford        };
3455b539461dcc159bd89297443780d635ccc5e3564John Hoford
3465b539461dcc159bd89297443780d635ccc5e3564John Hoford        File[] files = dir.listFiles();
3475b539461dcc159bd89297443780d635ccc5e3564John Hoford        Arrays.sort(files, new Comparator<File>() {
3485b539461dcc159bd89297443780d635ccc5e3564John Hoford
3495b539461dcc159bd89297443780d635ccc5e3564John Hoford            @Override
3505b539461dcc159bd89297443780d635ccc5e3564John Hoford            public int compare(File o1, File o2) {
3515b539461dcc159bd89297443780d635ccc5e3564John Hoford
3525b539461dcc159bd89297443780d635ccc5e3564John Hoford                return o1.getName().compareTo(o2.getName());
3535b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
3545b539461dcc159bd89297443780d635ccc5e3564John Hoford        });
3555b539461dcc159bd89297443780d635ccc5e3564John Hoford        final Volume v = new Volume();
3565b539461dcc159bd89297443780d635ccc5e3564John Hoford        int count = 0;
3575b539461dcc159bd89297443780d635ccc5e3564John Hoford
3585b539461dcc159bd89297443780d635ccc5e3564John Hoford
3595b539461dcc159bd89297443780d635ccc5e3564John Hoford        final Vector<File> toRun = new Vector<File>();
3605b539461dcc159bd89297443780d635ccc5e3564John Hoford        final HashMap<File, Integer> fileMap = new HashMap<File, Integer>();
3615b539461dcc159bd89297443780d635ccc5e3564John Hoford        for (File file : files) {
3625b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (file.isDirectory()) {
3635b539461dcc159bd89297443780d635ccc5e3564John Hoford                continue;
3645b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
3655b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (file.getName().equals(".DS_Store")) {
3665b539461dcc159bd89297443780d635ccc5e3564John Hoford                continue;
3675b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
3685b539461dcc159bd89297443780d635ccc5e3564John Hoford            toRun.add(file);
3695b539461dcc159bd89297443780d635ccc5e3564John Hoford            fileMap.put(file, count);
3705b539461dcc159bd89297443780d635ccc5e3564John Hoford            count++;
3715b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
3725b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (count < MIN_VOLUME_SIZE) {
3735b539461dcc159bd89297443780d635ccc5e3564John Hoford            return null;
3745b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
3755b539461dcc159bd89297443780d635ccc5e3564John Hoford        v.mDimz = count;
3765b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (listener != null) {
3775b539461dcc159bd89297443780d635ccc5e3564John Hoford            listener.progress(0, v.mDimx);
3785b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
3795b539461dcc159bd89297443780d635ccc5e3564John Hoford        v.mVolumeAllocation = null;
3805b539461dcc159bd89297443780d635ccc5e3564John Hoford        final String []pixel_spacing = new String[count];
3815b539461dcc159bd89297443780d635ccc5e3564John Hoford        final String []slice_pos = new String[count];
3825b539461dcc159bd89297443780d635ccc5e3564John Hoford
3835b539461dcc159bd89297443780d635ccc5e3564John Hoford        final ScriptC_bricked scriptC_bricked = new ScriptC_bricked(rs);
3845b539461dcc159bd89297443780d635ccc5e3564John Hoford        int number_of_threads = 2 * Runtime.getRuntime().availableProcessors();
3855b539461dcc159bd89297443780d635ccc5e3564John Hoford        Thread[] t = new Thread[number_of_threads];
3865b539461dcc159bd89297443780d635ccc5e3564John Hoford        for (int i = 0; i < number_of_threads; i++) {
3875b539461dcc159bd89297443780d635ccc5e3564John Hoford
3885b539461dcc159bd89297443780d635ccc5e3564John Hoford            t[i] = new Thread() {
3895b539461dcc159bd89297443780d635ccc5e3564John Hoford                LoaderDicom d = new LoaderDicom();
3905b539461dcc159bd89297443780d635ccc5e3564John Hoford
3915b539461dcc159bd89297443780d635ccc5e3564John Hoford
3925b539461dcc159bd89297443780d635ccc5e3564John Hoford                private File getOne() {
3935b539461dcc159bd89297443780d635ccc5e3564John Hoford                    synchronized (toRun) {
3945b539461dcc159bd89297443780d635ccc5e3564John Hoford                        if (toRun.isEmpty()) {
3955b539461dcc159bd89297443780d635ccc5e3564John Hoford                            return null;
3965b539461dcc159bd89297443780d635ccc5e3564John Hoford                        }
3975b539461dcc159bd89297443780d635ccc5e3564John Hoford                        return toRun.remove(0);
3985b539461dcc159bd89297443780d635ccc5e3564John Hoford                    }
3995b539461dcc159bd89297443780d635ccc5e3564John Hoford                }
4005b539461dcc159bd89297443780d635ccc5e3564John Hoford
4015b539461dcc159bd89297443780d635ccc5e3564John Hoford                public void run() {
4025b539461dcc159bd89297443780d635ccc5e3564John Hoford                    File file;
4035b539461dcc159bd89297443780d635ccc5e3564John Hoford
4045b539461dcc159bd89297443780d635ccc5e3564John Hoford                    Allocation alloc_slice = null;
4055b539461dcc159bd89297443780d635ccc5e3564John Hoford
4065b539461dcc159bd89297443780d635ccc5e3564John Hoford                    while ((file = getOne()) != null) {
4075b539461dcc159bd89297443780d635ccc5e3564John Hoford                        int z = fileMap.get(file);
4085b539461dcc159bd89297443780d635ccc5e3564John Hoford                        try {
4095b539461dcc159bd89297443780d635ccc5e3564John Hoford                            TagSet data = d.read(file, tags);
4105b539461dcc159bd89297443780d635ccc5e3564John Hoford                            short[] slice = (short[]) data.get(0x7fe0, 0x10).mValue;
4115b539461dcc159bd89297443780d635ccc5e3564John Hoford                            short dimX = (Short) data.get(0x28, 0x10).mValue;
4125b539461dcc159bd89297443780d635ccc5e3564John Hoford                            short dimY = (Short) data.get(0x28, 0x11).mValue;
4135b539461dcc159bd89297443780d635ccc5e3564John Hoford                            String val;
4145b539461dcc159bd89297443780d635ccc5e3564John Hoford                            val = (String) data.get(0x28,0x30).mValue;
4155b539461dcc159bd89297443780d635ccc5e3564John Hoford                            pixel_spacing[z] = val;
4165b539461dcc159bd89297443780d635ccc5e3564John Hoford
4175b539461dcc159bd89297443780d635ccc5e3564John Hoford                            val = (String) data.get(0x20,0x32).mValue;
4185b539461dcc159bd89297443780d635ccc5e3564John Hoford                            slice_pos[z] = val;
4195b539461dcc159bd89297443780d635ccc5e3564John Hoford
4205b539461dcc159bd89297443780d635ccc5e3564John Hoford                            if (v.mDimx == -1) {
4215b539461dcc159bd89297443780d635ccc5e3564John Hoford                                v.mDimy = dimY;
4225b539461dcc159bd89297443780d635ccc5e3564John Hoford                                v.mDimx = dimX;
4235b539461dcc159bd89297443780d635ccc5e3564John Hoford                            }
4245b539461dcc159bd89297443780d635ccc5e3564John Hoford                            synchronized (v) {
4255b539461dcc159bd89297443780d635ccc5e3564John Hoford                                if (v.mVolumeAllocation == null) {
4265b539461dcc159bd89297443780d635ccc5e3564John Hoford                                    Type.Builder b = new Type.Builder(rs,
4275b539461dcc159bd89297443780d635ccc5e3564John Hoford                                            android.renderscript.Element.I16(rs));
4285b539461dcc159bd89297443780d635ccc5e3564John Hoford                                    b.setX(v.mDimx).setY(v.mDimy);
4295b539461dcc159bd89297443780d635ccc5e3564John Hoford                                    b.setZ(v.mDimz);
4305b539461dcc159bd89297443780d635ccc5e3564John Hoford                                    v.mVolumeAllocation = Allocation.createTyped(rs, b.create(),
4315b539461dcc159bd89297443780d635ccc5e3564John Hoford                                            Allocation.USAGE_SCRIPT);
4325b539461dcc159bd89297443780d635ccc5e3564John Hoford                                    scriptC_bricked.set_volume(v.mVolumeAllocation);
4335b539461dcc159bd89297443780d635ccc5e3564John Hoford                                }
4345b539461dcc159bd89297443780d635ccc5e3564John Hoford                            }
4355b539461dcc159bd89297443780d635ccc5e3564John Hoford
4365b539461dcc159bd89297443780d635ccc5e3564John Hoford                            if (alloc_slice == null) {
4375b539461dcc159bd89297443780d635ccc5e3564John Hoford                                Type.Builder b = new Type.Builder(rs,
4385b539461dcc159bd89297443780d635ccc5e3564John Hoford                                        android.renderscript.Element.I16(rs));
4395b539461dcc159bd89297443780d635ccc5e3564John Hoford                                b.setX(v.mDimx).setY(v.mDimy);
4405b539461dcc159bd89297443780d635ccc5e3564John Hoford                                alloc_slice = Allocation.createTyped(rs, b.create(),
4415b539461dcc159bd89297443780d635ccc5e3564John Hoford                                        Allocation.USAGE_SCRIPT);
4425b539461dcc159bd89297443780d635ccc5e3564John Hoford                            }
4435b539461dcc159bd89297443780d635ccc5e3564John Hoford                            if (listener != null) {
4445b539461dcc159bd89297443780d635ccc5e3564John Hoford                                listener.progress(z, v.mDimx);
4455b539461dcc159bd89297443780d635ccc5e3564John Hoford                            }
4465b539461dcc159bd89297443780d635ccc5e3564John Hoford                            int size = v.mDimy * v.mDimx;
4475b539461dcc159bd89297443780d635ccc5e3564John Hoford                            alloc_slice.copyFromUnchecked(slice);
4485b539461dcc159bd89297443780d635ccc5e3564John Hoford                            synchronized (v) {
4495b539461dcc159bd89297443780d635ccc5e3564John Hoford                                scriptC_bricked.set_z(z);
4505b539461dcc159bd89297443780d635ccc5e3564John Hoford                                scriptC_bricked.forEach_copy(alloc_slice);
4515b539461dcc159bd89297443780d635ccc5e3564John Hoford                            }
4525b539461dcc159bd89297443780d635ccc5e3564John Hoford
4535b539461dcc159bd89297443780d635ccc5e3564John Hoford                        } catch (Exception e) {
4545b539461dcc159bd89297443780d635ccc5e3564John Hoford                            e.printStackTrace();
4555b539461dcc159bd89297443780d635ccc5e3564John Hoford                        }
4565b539461dcc159bd89297443780d635ccc5e3564John Hoford                    }
4575b539461dcc159bd89297443780d635ccc5e3564John Hoford                    alloc_slice.destroy();
4585b539461dcc159bd89297443780d635ccc5e3564John Hoford                }
4595b539461dcc159bd89297443780d635ccc5e3564John Hoford            };
4605b539461dcc159bd89297443780d635ccc5e3564John Hoford            t[i].start();
4615b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
4625b539461dcc159bd89297443780d635ccc5e3564John Hoford
4635b539461dcc159bd89297443780d635ccc5e3564John Hoford        for (int i = 0; i < number_of_threads; i++) {
4645b539461dcc159bd89297443780d635ccc5e3564John Hoford            try {
4655b539461dcc159bd89297443780d635ccc5e3564John Hoford                t[i].join();
4665b539461dcc159bd89297443780d635ccc5e3564John Hoford            } catch (InterruptedException e) {
4675b539461dcc159bd89297443780d635ccc5e3564John Hoford                e.printStackTrace();
4685b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
4695b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
4705b539461dcc159bd89297443780d635ccc5e3564John Hoford        String[]pss = pixel_spacing[0].split("\\\\");
4715b539461dcc159bd89297443780d635ccc5e3564John Hoford        String[]s1ps = slice_pos[0].split("\\\\");
4725b539461dcc159bd89297443780d635ccc5e3564John Hoford        String[]s2ps = slice_pos[1].split("\\\\");
4735b539461dcc159bd89297443780d635ccc5e3564John Hoford        float sx = Float.parseFloat(pss[0]);
4745b539461dcc159bd89297443780d635ccc5e3564John Hoford        float sy = Float.parseFloat(pss[1]);
4755b539461dcc159bd89297443780d635ccc5e3564John Hoford        double dzx = Double.parseDouble(s1ps[0]) - Double.parseDouble(s2ps[0]);
4765b539461dcc159bd89297443780d635ccc5e3564John Hoford        double dzy = Double.parseDouble(s1ps[1]) - Double.parseDouble(s2ps[1]);
4775b539461dcc159bd89297443780d635ccc5e3564John Hoford        double dzz = Double.parseDouble(s1ps[2]) - Double.parseDouble(s2ps[2]);
4785b539461dcc159bd89297443780d635ccc5e3564John Hoford        float sz = (float) Math.hypot(dzx,Math.hypot(dzy,dzz));
4795b539461dcc159bd89297443780d635ccc5e3564John Hoford        float min = Math.min(sx,Math.min(sy,sz));
4805b539461dcc159bd89297443780d635ccc5e3564John Hoford        v.mVoxelDim[0] = sx/min;
4815b539461dcc159bd89297443780d635ccc5e3564John Hoford        v.mVoxelDim[1] = sy/min;
4825b539461dcc159bd89297443780d635ccc5e3564John Hoford        v.mVoxelDim[2] = sz/min;
4835b539461dcc159bd89297443780d635ccc5e3564John Hoford        Log.v(LOGTAG,"LOADING DONE ....");
4845b539461dcc159bd89297443780d635ccc5e3564John Hoford        scriptC_bricked.destroy();
4855b539461dcc159bd89297443780d635ccc5e3564John Hoford        return v;
4865b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
4875b539461dcc159bd89297443780d635ccc5e3564John Hoford
4885b539461dcc159bd89297443780d635ccc5e3564John Hoford    /**
4895b539461dcc159bd89297443780d635ccc5e3564John Hoford     * Single threaded version of the volume createor
4905b539461dcc159bd89297443780d635ccc5e3564John Hoford     * @param rs the renderscript context
4915b539461dcc159bd89297443780d635ccc5e3564John Hoford     * @param dir the directory containing the dicom files
4925b539461dcc159bd89297443780d635ccc5e3564John Hoford     * @param listener used to feed back status to progress listeners
4935b539461dcc159bd89297443780d635ccc5e3564John Hoford     * @return Built volume
4945b539461dcc159bd89297443780d635ccc5e3564John Hoford     */
4955b539461dcc159bd89297443780d635ccc5e3564John Hoford    public static Volume buildRSVolume2(final RenderScript rs, File dir,
4965b539461dcc159bd89297443780d635ccc5e3564John Hoford                                        VolumeLoader.ProgressListener listener) {
4975b539461dcc159bd89297443780d635ccc5e3564John Hoford        final int[] tags = new int[]{
4985b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x20, 0x32),
4995b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x20, 0x37),
5005b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x28, 0x10),
5015b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x28, 0x11),
5025b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x28, 0x30),
5035b539461dcc159bd89297443780d635ccc5e3564John Hoford                tagInt(0x7fe0, 0x10)
5045b539461dcc159bd89297443780d635ccc5e3564John Hoford        };
5055b539461dcc159bd89297443780d635ccc5e3564John Hoford        File[] files = dir.listFiles();
5065b539461dcc159bd89297443780d635ccc5e3564John Hoford        Arrays.sort(files, new Comparator<File>() {
5075b539461dcc159bd89297443780d635ccc5e3564John Hoford
5085b539461dcc159bd89297443780d635ccc5e3564John Hoford            @Override
5095b539461dcc159bd89297443780d635ccc5e3564John Hoford            public int compare(File o1, File o2) {
5105b539461dcc159bd89297443780d635ccc5e3564John Hoford
5115b539461dcc159bd89297443780d635ccc5e3564John Hoford                return o1.getName().compareTo(o2.getName());
5125b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
5135b539461dcc159bd89297443780d635ccc5e3564John Hoford        });
5145b539461dcc159bd89297443780d635ccc5e3564John Hoford        Volume v = new Volume();
5155b539461dcc159bd89297443780d635ccc5e3564John Hoford        int count = 0;
5165b539461dcc159bd89297443780d635ccc5e3564John Hoford
5175b539461dcc159bd89297443780d635ccc5e3564John Hoford
5185b539461dcc159bd89297443780d635ccc5e3564John Hoford        final Vector<File> toRun = new Vector<File>();
5195b539461dcc159bd89297443780d635ccc5e3564John Hoford        final HashMap<File, Integer> fileMap = new HashMap<File, Integer>();
5205b539461dcc159bd89297443780d635ccc5e3564John Hoford        for (File file1 : files) {
5215b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (file1.isDirectory()) {
5225b539461dcc159bd89297443780d635ccc5e3564John Hoford                continue;
5235b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
5245b539461dcc159bd89297443780d635ccc5e3564John Hoford            if (file1.getName().equals(".DS_Store")) {
5255b539461dcc159bd89297443780d635ccc5e3564John Hoford                continue;
5265b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
5275b539461dcc159bd89297443780d635ccc5e3564John Hoford            toRun.add(file1);
5285b539461dcc159bd89297443780d635ccc5e3564John Hoford            fileMap.put(file1, count);
5295b539461dcc159bd89297443780d635ccc5e3564John Hoford            count++;
5305b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
5315b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (count < 20) {
5325b539461dcc159bd89297443780d635ccc5e3564John Hoford            return null;
5335b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
5345b539461dcc159bd89297443780d635ccc5e3564John Hoford        v.mDimz = count;
5355b539461dcc159bd89297443780d635ccc5e3564John Hoford        if (listener != null) {
5365b539461dcc159bd89297443780d635ccc5e3564John Hoford            listener.progress(0, v.mDimz);
5375b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
5385b539461dcc159bd89297443780d635ccc5e3564John Hoford        v.mVolumeAllocation = null;
5395b539461dcc159bd89297443780d635ccc5e3564John Hoford        Allocation alloc_slice = null;
5405b539461dcc159bd89297443780d635ccc5e3564John Hoford        ScriptC_bricked scriptC_bricked = new ScriptC_bricked(rs);
5415b539461dcc159bd89297443780d635ccc5e3564John Hoford        LoaderDicom d = new LoaderDicom();
5425b539461dcc159bd89297443780d635ccc5e3564John Hoford        String pixel_spacing = null;
5435b539461dcc159bd89297443780d635ccc5e3564John Hoford        String slice1_pos = null;
5445b539461dcc159bd89297443780d635ccc5e3564John Hoford        String slice2_pos = null;
5455b539461dcc159bd89297443780d635ccc5e3564John Hoford        boolean slice_spacing_set = false;
5465b539461dcc159bd89297443780d635ccc5e3564John Hoford        int z = 0;
5475b539461dcc159bd89297443780d635ccc5e3564John Hoford        for (File file : toRun) {
5485b539461dcc159bd89297443780d635ccc5e3564John Hoford            try {
5495b539461dcc159bd89297443780d635ccc5e3564John Hoford                TagSet data = d.read(file, tags);
5505b539461dcc159bd89297443780d635ccc5e3564John Hoford                short[] slice = (short[]) data.get(0x7fe0, 0x10).mValue;
5515b539461dcc159bd89297443780d635ccc5e3564John Hoford                short mDimx = (Short) data.get(0x28, 0x10).mValue;
5525b539461dcc159bd89297443780d635ccc5e3564John Hoford                short mDimy = (Short) data.get(0x28, 0x11).mValue;
5535b539461dcc159bd89297443780d635ccc5e3564John Hoford                String val;
5545b539461dcc159bd89297443780d635ccc5e3564John Hoford                val = (String) data.get(0x28,0x30).mValue;
5555b539461dcc159bd89297443780d635ccc5e3564John Hoford                if (val != null && pixel_spacing==null) {
5565b539461dcc159bd89297443780d635ccc5e3564John Hoford                    pixel_spacing = val;
5575b539461dcc159bd89297443780d635ccc5e3564John Hoford                }
5585b539461dcc159bd89297443780d635ccc5e3564John Hoford                val = (String) data.get(0x20,0x32).mValue;
5595b539461dcc159bd89297443780d635ccc5e3564John Hoford                if (val != null) {
5605b539461dcc159bd89297443780d635ccc5e3564John Hoford                    if (slice1_pos == null) {
5615b539461dcc159bd89297443780d635ccc5e3564John Hoford                        slice1_pos = val;
5625b539461dcc159bd89297443780d635ccc5e3564John Hoford                    } else if (slice2_pos == null) {
5635b539461dcc159bd89297443780d635ccc5e3564John Hoford                        slice2_pos = val;
5645b539461dcc159bd89297443780d635ccc5e3564John Hoford                    }
5655b539461dcc159bd89297443780d635ccc5e3564John Hoford                }
5665b539461dcc159bd89297443780d635ccc5e3564John Hoford                if (v.mDimx == -1) {
5675b539461dcc159bd89297443780d635ccc5e3564John Hoford                    v.mDimy = mDimy;
5685b539461dcc159bd89297443780d635ccc5e3564John Hoford                    v.mDimx = mDimx;
5695b539461dcc159bd89297443780d635ccc5e3564John Hoford                }
5705b539461dcc159bd89297443780d635ccc5e3564John Hoford
5715b539461dcc159bd89297443780d635ccc5e3564John Hoford                if (v.mVolumeAllocation == null) {
5725b539461dcc159bd89297443780d635ccc5e3564John Hoford                    Type.Builder b = new Type.Builder(rs, android.renderscript.Element.I16(rs));
5735b539461dcc159bd89297443780d635ccc5e3564John Hoford                    b.setX(v.mDimx).setY(v.mDimy);
5745b539461dcc159bd89297443780d635ccc5e3564John Hoford                    alloc_slice = Allocation.createTyped(rs, b.create(), Allocation.USAGE_SCRIPT);
5755b539461dcc159bd89297443780d635ccc5e3564John Hoford                    b.setZ(v.mDimz);
5765b539461dcc159bd89297443780d635ccc5e3564John Hoford                    v.mVolumeAllocation = Allocation.createTyped(rs, b.create(),
5775b539461dcc159bd89297443780d635ccc5e3564John Hoford                            Allocation.USAGE_SCRIPT);
5785b539461dcc159bd89297443780d635ccc5e3564John Hoford                    scriptC_bricked.set_volume(v.mVolumeAllocation);
5795b539461dcc159bd89297443780d635ccc5e3564John Hoford
5805b539461dcc159bd89297443780d635ccc5e3564John Hoford                }
5815b539461dcc159bd89297443780d635ccc5e3564John Hoford                if (listener != null) {
5825b539461dcc159bd89297443780d635ccc5e3564John Hoford                    listener.progress(z, v.mDimz);
5835b539461dcc159bd89297443780d635ccc5e3564John Hoford                }
5845b539461dcc159bd89297443780d635ccc5e3564John Hoford
5855b539461dcc159bd89297443780d635ccc5e3564John Hoford                int size = v.mDimy * v.mDimx;
5865b539461dcc159bd89297443780d635ccc5e3564John Hoford                alloc_slice.copyFromUnchecked(slice);
5875b539461dcc159bd89297443780d635ccc5e3564John Hoford                scriptC_bricked.set_z(z);
5885b539461dcc159bd89297443780d635ccc5e3564John Hoford                scriptC_bricked.forEach_copy(alloc_slice);
5895b539461dcc159bd89297443780d635ccc5e3564John Hoford                z++;
5905b539461dcc159bd89297443780d635ccc5e3564John Hoford                if (!slice_spacing_set
5915b539461dcc159bd89297443780d635ccc5e3564John Hoford                        && pixel_spacing!=null
5925b539461dcc159bd89297443780d635ccc5e3564John Hoford                        && slice1_pos!=null
5935b539461dcc159bd89297443780d635ccc5e3564John Hoford                        && slice2_pos != null) {
5945b539461dcc159bd89297443780d635ccc5e3564John Hoford                    String[]pss = pixel_spacing.split("\\\\");
5955b539461dcc159bd89297443780d635ccc5e3564John Hoford                    String[]s1ps = slice1_pos.split("\\\\");
5965b539461dcc159bd89297443780d635ccc5e3564John Hoford                    String[]s2ps = slice2_pos.split("\\\\");
5975b539461dcc159bd89297443780d635ccc5e3564John Hoford                    float sx = Float.parseFloat(pss[0]);
5985b539461dcc159bd89297443780d635ccc5e3564John Hoford                    float sy = Float.parseFloat(pss[1]);
5995b539461dcc159bd89297443780d635ccc5e3564John Hoford                    double dzx = Double.parseDouble(s1ps[0]) - Double.parseDouble(s2ps[0]);
6005b539461dcc159bd89297443780d635ccc5e3564John Hoford                    double dzy = Double.parseDouble(s1ps[1]) - Double.parseDouble(s2ps[1]);
6015b539461dcc159bd89297443780d635ccc5e3564John Hoford                    double dzz = Double.parseDouble(s1ps[2]) - Double.parseDouble(s2ps[2]);
6025b539461dcc159bd89297443780d635ccc5e3564John Hoford                    float sz = (float) Math.hypot(dzx,Math.hypot(dzy,dzz));
6035b539461dcc159bd89297443780d635ccc5e3564John Hoford                    float min = Math.min(sx,Math.min(sy,sz));
6045b539461dcc159bd89297443780d635ccc5e3564John Hoford                    v.mVoxelDim[0] = sx/min;
6055b539461dcc159bd89297443780d635ccc5e3564John Hoford                    v.mVoxelDim[1] = sy/min;
6065b539461dcc159bd89297443780d635ccc5e3564John Hoford                    v.mVoxelDim[2] = sz/min;
6075b539461dcc159bd89297443780d635ccc5e3564John Hoford                    slice_spacing_set = true;
6085b539461dcc159bd89297443780d635ccc5e3564John Hoford                }
6095b539461dcc159bd89297443780d635ccc5e3564John Hoford            } catch (Exception e) {
6105b539461dcc159bd89297443780d635ccc5e3564John Hoford                e.printStackTrace();
6115b539461dcc159bd89297443780d635ccc5e3564John Hoford            }
6125b539461dcc159bd89297443780d635ccc5e3564John Hoford        }
6135b539461dcc159bd89297443780d635ccc5e3564John Hoford        Log.v(LOGTAG,"LOADING DONE ....");
6145b539461dcc159bd89297443780d635ccc5e3564John Hoford
6155b539461dcc159bd89297443780d635ccc5e3564John Hoford        alloc_slice.destroy();
6165b539461dcc159bd89297443780d635ccc5e3564John Hoford
6175b539461dcc159bd89297443780d635ccc5e3564John Hoford        scriptC_bricked.destroy();
6185b539461dcc159bd89297443780d635ccc5e3564John Hoford        return v;
6195b539461dcc159bd89297443780d635ccc5e3564John Hoford    }
6205b539461dcc159bd89297443780d635ccc5e3564John Hoford}
621