1 /*
2  * Copyright (C) 2018 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.android.nn.benchmark.util;
18 
19 import android.content.res.AssetManager;
20 
21 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.nio.ByteBuffer;
25 import java.nio.ByteOrder;
26 
27 /**
28  * Input/Output utilities.
29  */
30 public final class IOUtils {
IOUtils()31     private IOUtils() {}
32 
33     /** Reads float values from a byte array. */
readFloats(byte[] bytes, int dataSize)34     public static float[] readFloats(byte[] bytes, int dataSize) {
35         ByteBuffer buffer = ByteBuffer.wrap(bytes);
36         buffer.order(ByteOrder.LITTLE_ENDIAN);
37         int size = bytes.length / dataSize;
38         float[] result = new float[size];
39         for (int i = 0; i < size; ++i) {
40             if (dataSize == 4) {
41                 result[i] = buffer.getFloat();
42             } else if (dataSize == 1) {
43                 result[i] = (float)(buffer.get() & 0xff);
44             }
45         }
46         return result;
47     }
48 
49     /** Reads data in native byte order */
readAsset(AssetManager assetManager, String assetFilename, int dataBytesSize)50     public static byte[] readAsset(AssetManager assetManager, String assetFilename,
51                                    int dataBytesSize)
52             throws IOException {
53         try (InputStream in = assetManager.open(assetFilename)) {
54             byte[] buffer = new byte[8192];
55             int bytesRead;
56             ByteArrayOutputStream output = new ByteArrayOutputStream();
57             while ((bytesRead = in.read(buffer)) != -1) {
58                 output.write(buffer, 0, bytesRead);
59             }
60 
61             byte[] result = output.toByteArray();
62             // Do we need to swap data endianess?
63             if (dataBytesSize > 1 && ByteOrder.nativeOrder() != ByteOrder.LITTLE_ENDIAN) {
64                 if (dataBytesSize == 4) {
65                     invertOrder4(result);
66                 } if (dataBytesSize == 2) {
67                     invertOrder2(result);
68                 } else {
69                     throw new IllegalArgumentException(
70                             "Byte order swapping for " + dataBytesSize
71                                     + " bytes is not implmemented (yet)");
72                 }
73             }
74             return result;
75         }
76     }
77 
78     /** Reverses endianness on array of 4 byte elements */
invertOrder4(byte[] data)79     private static void invertOrder4(byte[] data) {
80         if (data.length % 4 != 0) {
81             throw new IllegalArgumentException("Data is not 4 byte aligned");
82         }
83         for (int i = 0; i < data.length; i += 4) {
84             byte a = data[i];
85             byte b = data[i + 1];
86             data[i] = data[i + 3];
87             data[i + 1] = data[i + 2];
88             data[i + 2] = b;
89             data[i + 3] = a;
90         }
91     }
92 
93     /** Reverses endianness on array of 2 byte elements */
invertOrder2(byte[] data)94     private static void invertOrder2(byte[] data) {
95         if (data.length % 2 != 0) {
96             throw new IllegalArgumentException("Data is not 2 byte aligned");
97         }
98         for (int i = 0; i < data.length; i += 2) {
99             byte a = data[i];
100             data[i] = data[i + 1];
101             data[i + 1] = a;
102         }
103     }
104 }
105