149a05d7b82956009f03acbb92a064eed054eb031Jason Sams/*
249a05d7b82956009f03acbb92a064eed054eb031Jason Sams * Copyright (C) 2008 The Android Open Source Project
349a05d7b82956009f03acbb92a064eed054eb031Jason Sams *
449a05d7b82956009f03acbb92a064eed054eb031Jason Sams * Licensed under the Apache License, Version 2.0 (the "License");
549a05d7b82956009f03acbb92a064eed054eb031Jason Sams * you may not use this file except in compliance with the License.
649a05d7b82956009f03acbb92a064eed054eb031Jason Sams * You may obtain a copy of the License at
749a05d7b82956009f03acbb92a064eed054eb031Jason Sams *
849a05d7b82956009f03acbb92a064eed054eb031Jason Sams *      http://www.apache.org/licenses/LICENSE-2.0
949a05d7b82956009f03acbb92a064eed054eb031Jason Sams *
1049a05d7b82956009f03acbb92a064eed054eb031Jason Sams * Unless required by applicable law or agreed to in writing, software
1149a05d7b82956009f03acbb92a064eed054eb031Jason Sams * distributed under the License is distributed on an "AS IS" BASIS,
1249a05d7b82956009f03acbb92a064eed054eb031Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1349a05d7b82956009f03acbb92a064eed054eb031Jason Sams * See the License for the specific language governing permissions and
1449a05d7b82956009f03acbb92a064eed054eb031Jason Sams * limitations under the License.
1549a05d7b82956009f03acbb92a064eed054eb031Jason Sams */
1649a05d7b82956009f03acbb92a064eed054eb031Jason Sams
1749a05d7b82956009f03acbb92a064eed054eb031Jason Samspackage android.renderscript;
1849a05d7b82956009f03acbb92a064eed054eb031Jason Sams
1949a05d7b82956009f03acbb92a064eed054eb031Jason Samsimport android.content.res.Resources;
2049a05d7b82956009f03acbb92a064eed054eb031Jason Samsimport android.graphics.Bitmap;
2149a05d7b82956009f03acbb92a064eed054eb031Jason Samsimport android.graphics.BitmapFactory;
2249a05d7b82956009f03acbb92a064eed054eb031Jason Samsimport android.util.TypedValue;
2349a05d7b82956009f03acbb92a064eed054eb031Jason Sams
249c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines/**
25c11e25c4e653124def1fb18e203b894f42106cbeTim Murray * Only intended for use by generated reflected code.
2649a05d7b82956009f03acbb92a064eed054eb031Jason Sams *
2749a05d7b82956009f03acbb92a064eed054eb031Jason Sams **/
2849a05d7b82956009f03acbb92a064eed054eb031Jason Samspublic class AllocationAdapter extends Allocation {
2949a05d7b82956009f03acbb92a064eed054eb031Jason Sams    AllocationAdapter(int id, RenderScript rs, Allocation alloc) {
30ba862d1544a06528151550be1784a926ee986580Jason Sams        super(id, rs, alloc.mType, alloc.mUsage);
31ba862d1544a06528151550be1784a926ee986580Jason Sams        mAdaptedAllocation = alloc;
3249a05d7b82956009f03acbb92a064eed054eb031Jason Sams    }
3349a05d7b82956009f03acbb92a064eed054eb031Jason Sams
34e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams    int getID(RenderScript rs) {
3548fe534838d8b9d10f98ea2662eec258320ab4e7Jason Sams        throw new RSInvalidStateException(
3648fe534838d8b9d10f98ea2662eec258320ab4e7Jason Sams            "This operation is not supported with adapters at this time.");
37ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams    }
38ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams
39ba862d1544a06528151550be1784a926ee986580Jason Sams    /**
40ba862d1544a06528151550be1784a926ee986580Jason Sams     * @hide
41ba862d1544a06528151550be1784a926ee986580Jason Sams     */
4249a05d7b82956009f03acbb92a064eed054eb031Jason Sams    public void subData(int xoff, FieldPacker fp) {
43ba862d1544a06528151550be1784a926ee986580Jason Sams        super.setFromFieldPacker(xoff, fp);
4449a05d7b82956009f03acbb92a064eed054eb031Jason Sams    }
45ba862d1544a06528151550be1784a926ee986580Jason Sams    /**
46ba862d1544a06528151550be1784a926ee986580Jason Sams     * @hide
47ba862d1544a06528151550be1784a926ee986580Jason Sams     */
4849a05d7b82956009f03acbb92a064eed054eb031Jason Sams    public void subElementData(int xoff, int component_number, FieldPacker fp) {
49ba862d1544a06528151550be1784a926ee986580Jason Sams        super.setFromFieldPacker(xoff, component_number, fp);
5049a05d7b82956009f03acbb92a064eed054eb031Jason Sams    }
51ba862d1544a06528151550be1784a926ee986580Jason Sams    /**
52ba862d1544a06528151550be1784a926ee986580Jason Sams     * @hide
53ba862d1544a06528151550be1784a926ee986580Jason Sams     */
5449a05d7b82956009f03acbb92a064eed054eb031Jason Sams    public void subData1D(int off, int count, int[] d) {
55ba862d1544a06528151550be1784a926ee986580Jason Sams        super.copy1DRangeFrom(off, count, d);
5649a05d7b82956009f03acbb92a064eed054eb031Jason Sams    }
57ba862d1544a06528151550be1784a926ee986580Jason Sams    /**
58ba862d1544a06528151550be1784a926ee986580Jason Sams     * @hide
59ba862d1544a06528151550be1784a926ee986580Jason Sams     */
6049a05d7b82956009f03acbb92a064eed054eb031Jason Sams    public void subData1D(int off, int count, short[] d) {
61ba862d1544a06528151550be1784a926ee986580Jason Sams        super.copy1DRangeFrom(off, count, d);
6249a05d7b82956009f03acbb92a064eed054eb031Jason Sams    }
63ba862d1544a06528151550be1784a926ee986580Jason Sams    /**
64ba862d1544a06528151550be1784a926ee986580Jason Sams     * @hide
65ba862d1544a06528151550be1784a926ee986580Jason Sams     */
6649a05d7b82956009f03acbb92a064eed054eb031Jason Sams    public void subData1D(int off, int count, byte[] d) {
67ba862d1544a06528151550be1784a926ee986580Jason Sams        super.copy1DRangeFrom(off, count, d);
6849a05d7b82956009f03acbb92a064eed054eb031Jason Sams    }
69ba862d1544a06528151550be1784a926ee986580Jason Sams    /**
70ba862d1544a06528151550be1784a926ee986580Jason Sams     * @hide
71ba862d1544a06528151550be1784a926ee986580Jason Sams     */
7249a05d7b82956009f03acbb92a064eed054eb031Jason Sams    public void subData1D(int off, int count, float[] d) {
73ba862d1544a06528151550be1784a926ee986580Jason Sams        super.copy1DRangeFrom(off, count, d);
7449a05d7b82956009f03acbb92a064eed054eb031Jason Sams    }
75304b1f5497155bcf91e7b855cfab7a675e80bf26Alex Sakhartchouk    /**
76ba862d1544a06528151550be1784a926ee986580Jason Sams     * @hide
77304b1f5497155bcf91e7b855cfab7a675e80bf26Alex Sakhartchouk     */
7849a05d7b82956009f03acbb92a064eed054eb031Jason Sams    public void subData2D(int xoff, int yoff, int w, int h, int[] d) {
79ba862d1544a06528151550be1784a926ee986580Jason Sams        super.copy2DRangeFrom(xoff, yoff, w, h, d);
8049a05d7b82956009f03acbb92a064eed054eb031Jason Sams    }
81ba862d1544a06528151550be1784a926ee986580Jason Sams    /**
82ba862d1544a06528151550be1784a926ee986580Jason Sams     * @hide
83ba862d1544a06528151550be1784a926ee986580Jason Sams     */
8449a05d7b82956009f03acbb92a064eed054eb031Jason Sams    public void subData2D(int xoff, int yoff, int w, int h, float[] d) {
85ba862d1544a06528151550be1784a926ee986580Jason Sams        super.copy2DRangeFrom(xoff, yoff, w, h, d);
86304b1f5497155bcf91e7b855cfab7a675e80bf26Alex Sakhartchouk    }
87304b1f5497155bcf91e7b855cfab7a675e80bf26Alex Sakhartchouk    /**
88ba862d1544a06528151550be1784a926ee986580Jason Sams     * @hide
89304b1f5497155bcf91e7b855cfab7a675e80bf26Alex Sakhartchouk     */
9049a05d7b82956009f03acbb92a064eed054eb031Jason Sams    public void readData(int[] d) {
91ba862d1544a06528151550be1784a926ee986580Jason Sams        super.copyTo(d);
9249a05d7b82956009f03acbb92a064eed054eb031Jason Sams    }
93ba862d1544a06528151550be1784a926ee986580Jason Sams    /**
94ba862d1544a06528151550be1784a926ee986580Jason Sams     * @hide
95ba862d1544a06528151550be1784a926ee986580Jason Sams     */
9649a05d7b82956009f03acbb92a064eed054eb031Jason Sams    public void readData(float[] d) {
97ba862d1544a06528151550be1784a926ee986580Jason Sams        super.copyTo(d);
9849a05d7b82956009f03acbb92a064eed054eb031Jason Sams    }
9949a05d7b82956009f03acbb92a064eed054eb031Jason Sams
100ba862d1544a06528151550be1784a926ee986580Jason Sams    void initLOD(int lod) {
101ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams        if (lod < 0) {
102ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams            throw new RSIllegalArgumentException("Attempting to set negative lod (" + lod + ").");
103ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams        }
104ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams
105ba862d1544a06528151550be1784a926ee986580Jason Sams        int tx = mAdaptedAllocation.mType.getX();
106ba862d1544a06528151550be1784a926ee986580Jason Sams        int ty = mAdaptedAllocation.mType.getY();
107ba862d1544a06528151550be1784a926ee986580Jason Sams        int tz = mAdaptedAllocation.mType.getZ();
108ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams
109ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams        for (int ct=0; ct < lod; ct++) {
110ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams            if ((tx==1) && (ty == 1) && (tz == 1)) {
111ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams                throw new RSIllegalArgumentException("Attempting to set lod (" + lod + ") out of range.");
112ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams            }
113ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams
114ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams            if (tx > 1) tx >>= 1;
115ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams            if (ty > 1) ty >>= 1;
116ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams            if (tz > 1) tz >>= 1;
117ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams        }
118ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams
119ba862d1544a06528151550be1784a926ee986580Jason Sams        mCurrentDimX = tx;
120ba862d1544a06528151550be1784a926ee986580Jason Sams        mCurrentDimY = ty;
121ba862d1544a06528151550be1784a926ee986580Jason Sams        mCurrentDimZ = tz;
122ba862d1544a06528151550be1784a926ee986580Jason Sams        mCurrentCount = mCurrentDimX;
123ba862d1544a06528151550be1784a926ee986580Jason Sams        if (mCurrentDimY > 1) {
124ba862d1544a06528151550be1784a926ee986580Jason Sams            mCurrentCount *= mCurrentDimY;
125ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams        }
126ba862d1544a06528151550be1784a926ee986580Jason Sams        if (mCurrentDimZ > 1) {
127ba862d1544a06528151550be1784a926ee986580Jason Sams            mCurrentCount *= mCurrentDimZ;
128ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams        }
129ba862d1544a06528151550be1784a926ee986580Jason Sams        mSelectedY = 0;
130ba862d1544a06528151550be1784a926ee986580Jason Sams        mSelectedZ = 0;
131ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams    }
132ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams
1339c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines    /**
134ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams     * Set the active LOD.  The LOD must be within the range for the
135ba862d1544a06528151550be1784a926ee986580Jason Sams     * type being adapted.  The base allocation must have mipmaps.
136ba862d1544a06528151550be1784a926ee986580Jason Sams     *
137ba862d1544a06528151550be1784a926ee986580Jason Sams     * Because this changes the dimensions of the adapter the
138ba862d1544a06528151550be1784a926ee986580Jason Sams     * current Y and Z will be reset.
139ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams     *
140ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams     * @param lod The LOD to make active.
141ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams     */
14249a05d7b82956009f03acbb92a064eed054eb031Jason Sams    public void setLOD(int lod) {
143ba862d1544a06528151550be1784a926ee986580Jason Sams        if (!mAdaptedAllocation.getType().hasMipmaps()) {
144ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams            throw new RSInvalidStateException("Cannot set LOD when the allocation type does not include mipmaps.");
145ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams        }
146ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams        if (!mConstrainedLOD) {
147ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams            throw new RSInvalidStateException("Cannot set LOD when the adapter includes mipmaps.");
148ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams        }
149ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams
150ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams        initLOD(lod);
15149a05d7b82956009f03acbb92a064eed054eb031Jason Sams    }
15249a05d7b82956009f03acbb92a064eed054eb031Jason Sams
1539c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines    /**
154ba862d1544a06528151550be1784a926ee986580Jason Sams     * Set the active Face.  The base allocation must be of a type
155ba862d1544a06528151550be1784a926ee986580Jason Sams     * that includes faces.
156ba862d1544a06528151550be1784a926ee986580Jason Sams     *
157ba862d1544a06528151550be1784a926ee986580Jason Sams     * @param cf The face to make active.
158ba862d1544a06528151550be1784a926ee986580Jason Sams     */
15949a05d7b82956009f03acbb92a064eed054eb031Jason Sams    public void setFace(Type.CubemapFace cf) {
160ba862d1544a06528151550be1784a926ee986580Jason Sams        if (!mAdaptedAllocation.getType().hasFaces()) {
161ba862d1544a06528151550be1784a926ee986580Jason Sams            throw new RSInvalidStateException("Cannot set Face when the allocation type does not include faces.");
162ba862d1544a06528151550be1784a926ee986580Jason Sams        }
163ba862d1544a06528151550be1784a926ee986580Jason Sams        if (!mConstrainedFace) {
164ba862d1544a06528151550be1784a926ee986580Jason Sams            throw new RSInvalidStateException("Cannot set LOD when the adapter includes mipmaps.");
165ba862d1544a06528151550be1784a926ee986580Jason Sams        }
166ba862d1544a06528151550be1784a926ee986580Jason Sams        if (cf == null) {
167ba862d1544a06528151550be1784a926ee986580Jason Sams            throw new RSIllegalArgumentException("Cannot set null face.");
168ba862d1544a06528151550be1784a926ee986580Jason Sams        }
169ba862d1544a06528151550be1784a926ee986580Jason Sams
170304b1f5497155bcf91e7b855cfab7a675e80bf26Alex Sakhartchouk        mSelectedFace = cf;
17149a05d7b82956009f03acbb92a064eed054eb031Jason Sams    }
17249a05d7b82956009f03acbb92a064eed054eb031Jason Sams
1739c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines    /**
174ba862d1544a06528151550be1784a926ee986580Jason Sams     * Set the active Y.  The y value must be within the range for
175ba862d1544a06528151550be1784a926ee986580Jason Sams     * the allocation being adapted.  The base allocation must
176ba862d1544a06528151550be1784a926ee986580Jason Sams     * contain the Y dimension.
177ba862d1544a06528151550be1784a926ee986580Jason Sams     *
178ba862d1544a06528151550be1784a926ee986580Jason Sams     * @param y The y to make active.
179ba862d1544a06528151550be1784a926ee986580Jason Sams     */
18049a05d7b82956009f03acbb92a064eed054eb031Jason Sams    public void setY(int y) {
181ba862d1544a06528151550be1784a926ee986580Jason Sams        if (mAdaptedAllocation.getType().getY() == 0) {
182ba862d1544a06528151550be1784a926ee986580Jason Sams            throw new RSInvalidStateException("Cannot set Y when the allocation type does not include Y dim.");
183ba862d1544a06528151550be1784a926ee986580Jason Sams        }
184ba862d1544a06528151550be1784a926ee986580Jason Sams        if (mAdaptedAllocation.getType().getY() <= y) {
185ba862d1544a06528151550be1784a926ee986580Jason Sams            throw new RSInvalidStateException("Cannot set Y greater than dimension of allocation.");
186ba862d1544a06528151550be1784a926ee986580Jason Sams        }
187ba862d1544a06528151550be1784a926ee986580Jason Sams        if (!mConstrainedY) {
188ba862d1544a06528151550be1784a926ee986580Jason Sams            throw new RSInvalidStateException("Cannot set Y when the adapter includes Y.");
189ba862d1544a06528151550be1784a926ee986580Jason Sams        }
190ba862d1544a06528151550be1784a926ee986580Jason Sams
191ba862d1544a06528151550be1784a926ee986580Jason Sams        mSelectedY = y;
19249a05d7b82956009f03acbb92a064eed054eb031Jason Sams    }
19349a05d7b82956009f03acbb92a064eed054eb031Jason Sams
1949c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines    /**
195ba862d1544a06528151550be1784a926ee986580Jason Sams     * Set the active Z.  The z value must be within the range for
196ba862d1544a06528151550be1784a926ee986580Jason Sams     * the allocation being adapted.  The base allocation must
197ba862d1544a06528151550be1784a926ee986580Jason Sams     * contain the Z dimension.
198ba862d1544a06528151550be1784a926ee986580Jason Sams     *
199ba862d1544a06528151550be1784a926ee986580Jason Sams     * @param z The z to make active.
200ba862d1544a06528151550be1784a926ee986580Jason Sams     */
20149a05d7b82956009f03acbb92a064eed054eb031Jason Sams    public void setZ(int z) {
202ba862d1544a06528151550be1784a926ee986580Jason Sams        if (mAdaptedAllocation.getType().getZ() == 0) {
203ba862d1544a06528151550be1784a926ee986580Jason Sams            throw new RSInvalidStateException("Cannot set Z when the allocation type does not include Z dim.");
204ba862d1544a06528151550be1784a926ee986580Jason Sams        }
205ba862d1544a06528151550be1784a926ee986580Jason Sams        if (mAdaptedAllocation.getType().getZ() <= z) {
206ba862d1544a06528151550be1784a926ee986580Jason Sams            throw new RSInvalidStateException("Cannot set Z greater than dimension of allocation.");
207ba862d1544a06528151550be1784a926ee986580Jason Sams        }
208ba862d1544a06528151550be1784a926ee986580Jason Sams        if (!mConstrainedZ) {
209ba862d1544a06528151550be1784a926ee986580Jason Sams            throw new RSInvalidStateException("Cannot set Z when the adapter includes Z.");
210ba862d1544a06528151550be1784a926ee986580Jason Sams        }
211ba862d1544a06528151550be1784a926ee986580Jason Sams
212ba862d1544a06528151550be1784a926ee986580Jason Sams        mSelectedZ = z;
21349a05d7b82956009f03acbb92a064eed054eb031Jason Sams    }
21449a05d7b82956009f03acbb92a064eed054eb031Jason Sams
215ba862d1544a06528151550be1784a926ee986580Jason Sams    static public AllocationAdapter create1D(RenderScript rs, Allocation a) {
216ba862d1544a06528151550be1784a926ee986580Jason Sams        rs.validate();
217ba862d1544a06528151550be1784a926ee986580Jason Sams        AllocationAdapter aa = new AllocationAdapter(0, rs, a);
218ba862d1544a06528151550be1784a926ee986580Jason Sams        aa.mConstrainedLOD = true;
219ba862d1544a06528151550be1784a926ee986580Jason Sams        aa.mConstrainedFace = true;
220ba862d1544a06528151550be1784a926ee986580Jason Sams        aa.mConstrainedY = true;
221ba862d1544a06528151550be1784a926ee986580Jason Sams        aa.mConstrainedZ = true;
222ba862d1544a06528151550be1784a926ee986580Jason Sams        aa.initLOD(0);
223ba862d1544a06528151550be1784a926ee986580Jason Sams        return aa;
224ba862d1544a06528151550be1784a926ee986580Jason Sams    }
22549a05d7b82956009f03acbb92a064eed054eb031Jason Sams
22649a05d7b82956009f03acbb92a064eed054eb031Jason Sams    static public AllocationAdapter create2D(RenderScript rs, Allocation a) {
227ba862d1544a06528151550be1784a926ee986580Jason Sams        android.util.Log.e("rs", "create2d " + a);
22849a05d7b82956009f03acbb92a064eed054eb031Jason Sams        rs.validate();
22949a05d7b82956009f03acbb92a064eed054eb031Jason Sams        AllocationAdapter aa = new AllocationAdapter(0, rs, a);
230ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams        aa.mConstrainedLOD = true;
231ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams        aa.mConstrainedFace = true;
232ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams        aa.mConstrainedY = false;
233ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams        aa.mConstrainedZ = true;
234ee2d809ab099e67698a37f13a42d22eaa2251f77Jason Sams        aa.initLOD(0);
23549a05d7b82956009f03acbb92a064eed054eb031Jason Sams        return aa;
23649a05d7b82956009f03acbb92a064eed054eb031Jason Sams    }
23749a05d7b82956009f03acbb92a064eed054eb031Jason Sams
23849a05d7b82956009f03acbb92a064eed054eb031Jason Sams
2399c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines    /**
240ba862d1544a06528151550be1784a926ee986580Jason Sams     * Override the Allocation resize.  Resizing adapters is not
241ba862d1544a06528151550be1784a926ee986580Jason Sams     * allowed and will throw a RSInvalidStateException.
242ba862d1544a06528151550be1784a926ee986580Jason Sams     *
243ba862d1544a06528151550be1784a926ee986580Jason Sams     * @param dimX ignored.
244ba862d1544a06528151550be1784a926ee986580Jason Sams     */
245ba862d1544a06528151550be1784a926ee986580Jason Sams    public synchronized void resize(int dimX) {
246ba862d1544a06528151550be1784a926ee986580Jason Sams        throw new RSInvalidStateException("Resize not allowed for Adapters.");
247ba862d1544a06528151550be1784a926ee986580Jason Sams    }
248ba862d1544a06528151550be1784a926ee986580Jason Sams
24949a05d7b82956009f03acbb92a064eed054eb031Jason Sams}
25049a05d7b82956009f03acbb92a064eed054eb031Jason Sams
25149a05d7b82956009f03acbb92a064eed054eb031Jason Sams
252