Home | History | Annotate | Download | only in filterfw
      1 /*
      2  * Copyright 2013 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 package androidx.media.filterfw;
     17 
     18 import java.nio.ByteBuffer;
     19 
     20 /**
     21  * Utility functions to convert between color-spaces.
     22  *
     23  * Currently these methods are all CPU based native methods. These could be updated in the future
     24  * to provide other implementations.
     25  */
     26 public class ColorSpace {
     27 
     28     /**
     29      * Convert YUV420-Planer data to RGBA8888.
     30      *
     31      * The input data is expected to be laid out in 3 planes. The width x height Y plane, followed
     32      * by the U and V planes, where each chroma value corresponds to a 2x2 luminance value block.
     33      * YUV to RGB conversion is done using the ITU-R BT.601 transformation. The output buffer must
     34      * be large enough to hold the data, and the dimensions must be multiples of 2.
     35      *
     36      * @param input data encoded in YUV420-Planar.
     37      * @param output buffer to hold RGBA8888 data.
     38      * @param width the width of the image (must be a multiple of 2)
     39      * @param height the height of the image (must be a multiple of 2)
     40      */
     41     public static void convertYuv420pToRgba8888(
     42             ByteBuffer input, ByteBuffer output, int width, int height) {
     43         expectInputSize(input, (3 * width * height) / 2);
     44         expectOutputSize(output, width * height * 4);
     45         nativeYuv420pToRgba8888(input, output, width, height);
     46     }
     47 
     48     /**
     49      * Convert ARGB8888 to RGBA8888.
     50      *
     51      * The input data is expected to be encoded in 8-bit interleaved ARGB channels. The output
     52      * buffer must be large enough to hold the data. The output buffer may be the same as the
     53      * input buffer.
     54      *
     55      * @param input data encoded in ARGB8888.
     56      * @param output buffer to hold RGBA8888 data.
     57      * @param width the width of the image
     58      * @param height the height of the image
     59      */
     60     public static void convertArgb8888ToRgba8888(
     61             ByteBuffer input, ByteBuffer output, int width, int height) {
     62         expectInputSize(input, width * height * 4);
     63         expectOutputSize(output, width * height * 4);
     64         nativeArgb8888ToRgba8888(input, output, width, height);
     65     }
     66 
     67     /**
     68      * Convert RGBA8888 to HSVA8888.
     69      *
     70      * The input data is expected to be encoded in 8-bit interleaved RGBA channels. The output
     71      * buffer must be large enough to hold the data. The output buffer may be the same as the
     72      * input buffer.
     73      *
     74      * @param input data encoded in RGBA8888.
     75      * @param output buffer to hold HSVA8888 data.
     76      * @param width the width of the image
     77      * @param height the height of the image
     78      */
     79     public static void convertRgba8888ToHsva8888(
     80             ByteBuffer input, ByteBuffer output, int width, int height) {
     81         expectInputSize(input, width * height * 4);
     82         expectOutputSize(output, width * height * 4);
     83         nativeRgba8888ToHsva8888(input, output, width, height);
     84     }
     85 
     86     /**
     87      * Convert RGBA8888 to YCbCrA8888.
     88      *
     89      * The input data is expected to be encoded in 8-bit interleaved RGBA channels. The output
     90      * buffer must be large enough to hold the data. The output buffer may be the same as the
     91      * input buffer.
     92      *
     93      * @param input data encoded in RGBA8888.
     94      * @param output buffer to hold YCbCrA8888 data.
     95      * @param width the width of the image
     96      * @param height the height of the image
     97      */
     98     public static void convertRgba8888ToYcbcra8888(
     99             ByteBuffer input, ByteBuffer output, int width, int height) {
    100         expectInputSize(input, width * height * 4);
    101         expectOutputSize(output, width * height * 4);
    102         nativeRgba8888ToYcbcra8888(input, output, width, height);
    103     }
    104 
    105     private static void expectInputSize(ByteBuffer input, int expectedSize) {
    106         if (input.remaining() < expectedSize) {
    107             throw new IllegalArgumentException("Input buffer's size does not fit given width "
    108                     + "and height! Expected: " + expectedSize + ", Got: " + input.remaining()
    109                     + ".");
    110         }
    111     }
    112 
    113     private static void expectOutputSize(ByteBuffer output, int expectedSize) {
    114         if (output.remaining() < expectedSize) {
    115             throw new IllegalArgumentException("Output buffer's size does not fit given width "
    116                     + "and height! Expected: " + expectedSize + ", Got: " + output.remaining()
    117                     + ".");
    118         }
    119     }
    120 
    121     private static native void nativeYuv420pToRgba8888(
    122             ByteBuffer input, ByteBuffer output, int width, int height);
    123 
    124     private static native void nativeArgb8888ToRgba8888(
    125             ByteBuffer input, ByteBuffer output, int width, int height);
    126 
    127     private static native void nativeRgba8888ToHsva8888(
    128             ByteBuffer input, ByteBuffer output, int width, int height);
    129 
    130     private static native void nativeRgba8888ToYcbcra8888(
    131             ByteBuffer input, ByteBuffer output, int width, int height);
    132 
    133     static {
    134         System.loadLibrary("smartcamera_jni");
    135     }
    136 
    137 }
    138