1275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent/*
2275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent * Copyright 2013 The Android Open Source Project
3275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent *
4275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent * you may not use this file except in compliance with the License.
6275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent * You may obtain a copy of the License at
7275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent *
8275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
9275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent *
10275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent * Unless required by applicable law or agreed to in writing, software
11275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent * See the License for the specific language governing permissions and
14275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent * limitations under the License.
15275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent */
16275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurentpackage androidx.media.filterfw;
17275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
18275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurentimport java.nio.ByteBuffer;
19275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
20275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent/**
21275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent * A collection of utilities to deal with pixel operations on ByteBuffers.
22275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent */
23275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurentpublic class PixelUtils {
24275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
25275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    /**
26275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent     * Copy pixels from one buffer to another, applying a transformation.
27275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent     *
28275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent     * <p>The transformation is specified by specifying the initial offset in the output buffer, the
29275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent     * stride (in pixels) between each pixel, and the stride (in pixels) between each row. The row
30275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent     * stride is measured as the number of pixels between the start of each row.</p>
31e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi     *
32275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent     * <p>Note that this method is native for efficiency reasons. It does NOT do any bounds checking
33e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi     * other than making sure the buffers are of sufficient size. This means that you can corrupt
34e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi     * memory if specifying incorrect stride values!</p>
35275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent     *
36e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi     * @param input The input buffer containing pixel data.
37e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi     * @param output The output buffer to hold the transformed pixel data.
38275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent     * @param width The width of the input image.
39275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent     * @param height The height of the input image.
40275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent     * @param offset The start offset in the output (in pixels)
41275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent     * @param pixStride The stride between each pixel (in pixels)
42275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent     * @param rowStride The stride between the start of each row (in pixels)
43f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi     */
44f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi    public static void copyPixels(ByteBuffer input,
45f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi            ByteBuffer output,
46f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi            int width,
47f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi            int height,
48de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi            int offset,
49de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi            int pixStride,
50de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi            int rowStride) {
51de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi        if (input.remaining() != output.remaining()) {
52f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi            throw new IllegalArgumentException("Input and output buffers must have the same size!");
53f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi        } else if (input.remaining() % 4 != 0) {
547638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            throw new IllegalArgumentException("Input buffer size must be a multiple of 4!");
55de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi        } else if (output.remaining() % 4 != 0) {
56275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            throw new IllegalArgumentException("Output buffer size must be a multiple of 4!");
57275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        } else if ((width * height * 4) != input.remaining()) {
58275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            throw new IllegalArgumentException(
59e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi                    "Input buffer size does not match given dimensions!");
60275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        } else if ((width * height * 4) != output.remaining()) {
61e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi            throw new IllegalArgumentException(
62e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi                    "Output buffer size does not match given dimensions!");
63275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        }
64275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        nativeCopyPixels(input, output, width, height, offset, pixStride, rowStride);
65275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    }
66275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
67275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    private static native void nativeCopyPixels(ByteBuffer input,
68275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            ByteBuffer output,
69275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            int width,
70e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi            int height,
71e8decedb429ed76dfa84cdb3e80ab3b969e77298Jean-Michel Trivi            int offset,
72275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            int pixStride,
73275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent            int rowStride);
74275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent
75275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent    static {
76275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent        System.loadLibrary("smartcamera_jni");
77f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi    }
78f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi
79f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi}
80f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi