1/*
2 * Copyright (C) 2008-2012 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 android.renderscript;
18
19import java.io.File;
20import java.io.IOException;
21import java.io.InputStream;
22
23import android.content.res.AssetManager;
24import android.content.res.Resources;
25import android.graphics.Bitmap;
26import android.graphics.BitmapFactory;
27import android.util.Log;
28import android.util.TypedValue;
29
30/**
31 * @deprecated in API 16
32 * FileA3D allows users to load Renderscript objects from files
33 * or resources stored on disk. It could be used to load items
34 * such as 3D geometry data converted to a Renderscript format from
35 * content creation tools. Currently only meshes are supported
36 * in FileA3D.
37 *
38 * When successfully loaded, FileA3D will contain a list of
39 * index entries for all the objects stored inside it.
40 *
41 **/
42public class FileA3D extends BaseObj {
43
44    /**
45    * @deprecated in API 16
46    * Specifies what renderscript object type is contained within
47    * the FileA3D IndexEntry
48    **/
49    public enum EntryType {
50
51        /**
52        * @deprecated in API 16
53        * Unknown or or invalid object, nothing will be loaded
54        **/
55        UNKNOWN (0),
56        /**
57        * @deprecated in API 16
58        * Renderscript Mesh object
59        **/
60        MESH (1);
61
62        int mID;
63        EntryType(int id) {
64            mID = id;
65        }
66
67        static EntryType toEntryType(int intID) {
68            return EntryType.values()[intID];
69        }
70    }
71
72    /**
73    * @deprecated in API 16
74    * IndexEntry contains information about one of the Renderscript
75    * objects inside the file's index. It could be used to query the
76    * object's type and also name and load the object itself if
77    * necessary.
78    */
79    public static class IndexEntry {
80        RenderScript mRS;
81        int mIndex;
82        int mID;
83        String mName;
84        EntryType mEntryType;
85        BaseObj mLoadedObj;
86
87        /**
88        * @deprecated in API 16
89        * Returns the name of a renderscript object the index entry
90        * describes
91        *
92        * @return name of a renderscript object the index entry
93        * describes
94        *
95        */
96        public String getName() {
97            return mName;
98        }
99
100        /**
101        * @deprecated in API 16
102        * Returns the type of a renderscript object the index entry
103        * describes
104        * @return type of a renderscript object the index entry
105        *         describes
106        */
107        public EntryType getEntryType() {
108            return mEntryType;
109        }
110
111        /**
112        * @deprecated in API 16
113        * Used to load the object described by the index entry
114        * @return base renderscript object described by the entry
115        */
116        public BaseObj getObject() {
117            mRS.validate();
118            BaseObj obj = internalCreate(mRS, this);
119            return obj;
120        }
121
122        /**
123        * @deprecated in API 16
124        * Used to load the mesh described by the index entry, object
125        * described by the index entry must be a renderscript mesh
126        *
127        * @return renderscript mesh object described by the entry
128        */
129        public Mesh getMesh() {
130            return (Mesh)getObject();
131        }
132
133        static synchronized BaseObj internalCreate(RenderScript rs, IndexEntry entry) {
134            if(entry.mLoadedObj != null) {
135                return entry.mLoadedObj;
136            }
137
138            // to be purged on cleanup
139            if(entry.mEntryType == EntryType.UNKNOWN) {
140                return null;
141            }
142
143            int objectID = rs.nFileA3DGetEntryByIndex(entry.mID, entry.mIndex);
144            if(objectID == 0) {
145                return null;
146            }
147
148            switch (entry.mEntryType) {
149            case MESH:
150                entry.mLoadedObj = new Mesh(objectID, rs);
151                break;
152            }
153
154            entry.mLoadedObj.updateFromNative();
155            return entry.mLoadedObj;
156        }
157
158        IndexEntry(RenderScript rs, int index, int id, String name, EntryType type) {
159            mRS = rs;
160            mIndex = index;
161            mID = id;
162            mName = name;
163            mEntryType = type;
164            mLoadedObj = null;
165        }
166    }
167
168    IndexEntry[] mFileEntries;
169    InputStream mInputStream;
170
171    FileA3D(int id, RenderScript rs, InputStream stream) {
172        super(id, rs);
173        mInputStream = stream;
174    }
175
176    private void initEntries() {
177        int numFileEntries = mRS.nFileA3DGetNumIndexEntries(getID(mRS));
178        if(numFileEntries <= 0) {
179            return;
180        }
181
182        mFileEntries = new IndexEntry[numFileEntries];
183        int[] ids = new int[numFileEntries];
184        String[] names = new String[numFileEntries];
185
186        mRS.nFileA3DGetIndexEntries(getID(mRS), numFileEntries, ids, names);
187
188        for(int i = 0; i < numFileEntries; i ++) {
189            mFileEntries[i] = new IndexEntry(mRS, i, getID(mRS), names[i], EntryType.toEntryType(ids[i]));
190        }
191    }
192
193    /**
194    * @deprecated in API 16
195    * Returns the number of objects stored inside the a3d file
196    *
197    * @return the number of objects stored inside the a3d file
198    */
199    public int getIndexEntryCount() {
200        if(mFileEntries == null) {
201            return 0;
202        }
203        return mFileEntries.length;
204    }
205
206    /**
207    * @deprecated in API 16
208    * Returns an index entry from the list of all objects inside
209    * FileA3D
210    *
211    * @param index number of the entry from the list to return
212    *
213    * @return entry in the a3d file described by the index
214    */
215    public IndexEntry getIndexEntry(int index) {
216        if(getIndexEntryCount() == 0 || index < 0 || index >= mFileEntries.length) {
217            return null;
218        }
219        return mFileEntries[index];
220    }
221
222    /**
223    * @deprecated in API 16
224    * Creates a FileA3D object from an asset stored on disk
225    *
226    * @param rs Context to which the object will belong.
227    * @param mgr asset manager used to load asset
228    * @param path location of the file to load
229    *
230    * @return a3d file containing renderscript objects
231    */
232    static public FileA3D createFromAsset(RenderScript rs, AssetManager mgr, String path) {
233        rs.validate();
234        int fileId = rs.nFileA3DCreateFromAsset(mgr, path);
235
236        if(fileId == 0) {
237            throw new RSRuntimeException("Unable to create a3d file from asset " + path);
238        }
239        FileA3D fa3d = new FileA3D(fileId, rs, null);
240        fa3d.initEntries();
241        return fa3d;
242    }
243
244    /**
245    * @deprecated in API 16
246    * Creates a FileA3D object from a file stored on disk
247    *
248    * @param rs Context to which the object will belong.
249    * @param path location of the file to load
250    *
251    * @return a3d file containing renderscript objects
252    */
253    static public FileA3D createFromFile(RenderScript rs, String path) {
254        int fileId = rs.nFileA3DCreateFromFile(path);
255
256        if(fileId == 0) {
257            throw new RSRuntimeException("Unable to create a3d file from " + path);
258        }
259        FileA3D fa3d = new FileA3D(fileId, rs, null);
260        fa3d.initEntries();
261        return fa3d;
262    }
263
264    /**
265    * @deprecated in API 16
266    * Creates a FileA3D object from a file stored on disk
267    *
268    * @param rs Context to which the object will belong.
269    * @param path location of the file to load
270    *
271    * @return a3d file containing renderscript objects
272    */
273    static public FileA3D createFromFile(RenderScript rs, File path) {
274        return createFromFile(rs, path.getAbsolutePath());
275    }
276
277    /**
278    * @deprecated in API 16
279    * Creates a FileA3D object from an application resource
280    *
281    * @param rs Context to which the object will belong.
282    * @param res resource manager used for loading
283    * @param id resource to create FileA3D from
284    *
285    * @return a3d file containing renderscript objects
286    */
287    static public FileA3D createFromResource(RenderScript rs, Resources res, int id) {
288
289        rs.validate();
290        InputStream is = null;
291        try {
292            is = res.openRawResource(id);
293        } catch (Exception e) {
294            throw new RSRuntimeException("Unable to open resource " + id);
295        }
296
297        int fileId = 0;
298        if (is instanceof AssetManager.AssetInputStream) {
299            int asset = ((AssetManager.AssetInputStream) is).getAssetInt();
300            fileId = rs.nFileA3DCreateFromAssetStream(asset);
301        } else {
302            throw new RSRuntimeException("Unsupported asset stream");
303        }
304
305        if(fileId == 0) {
306            throw new RSRuntimeException("Unable to create a3d file from resource " + id);
307        }
308        FileA3D fa3d = new FileA3D(fileId, rs, is);
309        fa3d.initEntries();
310        return fa3d;
311
312    }
313}
314