1a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk/*
2a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * Copyright (C) 2013 The Android Open Source Project
3a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk *
4a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * Licensed under the Apache License, Version 2.0 (the "License");
5a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * you may not use this file except in compliance with the License.
6a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * You may obtain a copy of the License at
7a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk *
8a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk *      http://www.apache.org/licenses/LICENSE-2.0
9a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk *
10a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * Unless required by applicable law or agreed to in writing, software
11a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * distributed under the License is distributed on an "AS IS" BASIS,
12a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * See the License for the specific language governing permissions and
14a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk * limitations under the License.
15a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk */
16a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk
17a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunkpackage com.android.gallery3d.jpegstream;
18a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk
19a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunkimport java.nio.ByteOrder;
20a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk
21a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunkpublic class StreamUtils {
22a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk
23a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk    private StreamUtils() {
24a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk    }
25a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk
26a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk    /**
27a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk     * Copies the input byte array into the output int array with the given
28a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk     * endianness. If input is not a multiple of 4, ignores the last 1-3 bytes
29a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk     * and returns true.
30a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk     */
31a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk    public static boolean byteToIntArray(int[] output, byte[] input, ByteOrder endianness) {
32a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk        int length = input.length - (input.length % 4);
33a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk        if (output.length * 4 < length) {
34a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk            throw new ArrayIndexOutOfBoundsException("Output array is too short to hold input");
35a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk        }
36a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk        if (endianness == ByteOrder.BIG_ENDIAN) {
37a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk            for (int i = 0, j = 0; i < output.length; i++, j += 4) {
38a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk                output[i] = ((input[j] & 0xFF) << 24) | ((input[j + 1] & 0xFF) << 16)
39a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk                        | ((input[j + 2] & 0xFF) << 8) | ((input[j + 3] & 0xFF));
40a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk            }
41a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk        } else {
42a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk            for (int i = 0, j = 0; i < output.length; i++, j += 4) {
43a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk                output[i] = ((input[j + 3] & 0xFF) << 24) | ((input[j + 2] & 0xFF) << 16)
44a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk                        | ((input[j + 1] & 0xFF) << 8) | ((input[j] & 0xFF));
45a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk            }
46a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk        }
47a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk        return input.length % 4 != 0;
48a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk    }
49a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk
50a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk    public static int[] byteToIntArray(byte[] input, ByteOrder endianness) {
51a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk        int[] output = new int[input.length / 4];
52a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk        byteToIntArray(output, input, endianness);
53a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk        return output;
54a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk    }
55a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk
56a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk    /**
57a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk     * Uses native endianness.
58a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk     */
59a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk    public static int[] byteToIntArray(byte[] input) {
60a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk        return byteToIntArray(input, ByteOrder.nativeOrder());
61a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk    }
62a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk
63a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk    /**
64a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk     * Returns the number of bytes in a pixel for a given format defined in
65a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk     * JpegConfig.
66a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk     */
67a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk    public static int pixelSize(int format) {
68a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk        switch (format) {
69a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk            case JpegConfig.FORMAT_ABGR:
70a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk            case JpegConfig.FORMAT_RGBA:
71a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk                return 4;
72a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk            case JpegConfig.FORMAT_RGB:
73a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk                return 3;
74a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk            case JpegConfig.FORMAT_GRAYSCALE:
75a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk                return 1;
76a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk            default:
77a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk                return -1;
78a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk        }
79a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk    }
80a8221bbdb8ece9b02dbf7b72565f9fbc5b314f7cRuben Brunk}
81