blob: f2bfe08e716601717ac049dd0a24d53eb584aa16 [file] [log] [blame]
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.media.filterfw;
import java.nio.ByteBuffer;
/**
* Utility functions to convert between color-spaces.
*
* Currently these methods are all CPU based native methods. These could be updated in the future
* to provide other implementations.
*/
public class ColorSpace {
/**
* Convert YUV420-Planer data to RGBA8888.
*
* The input data is expected to be laid out in 3 planes. The width x height Y plane, followed
* by the U and V planes, where each chroma value corresponds to a 2x2 luminance value block.
* YUV to RGB conversion is done using the ITU-R BT.601 transformation. The output buffer must
* be large enough to hold the data, and the dimensions must be multiples of 2.
*
* @param input data encoded in YUV420-Planar.
* @param output buffer to hold RGBA8888 data.
* @param width the width of the image (must be a multiple of 2)
* @param height the height of the image (must be a multiple of 2)
*/
public static void convertYuv420pToRgba8888(
ByteBuffer input, ByteBuffer output, int width, int height) {
expectInputSize(input, (3 * width * height) / 2);
expectOutputSize(output, width * height * 4);
nativeYuv420pToRgba8888(input, output, width, height);
}
/**
* Convert ARGB8888 to RGBA8888.
*
* The input data is expected to be encoded in 8-bit interleaved ARGB channels. The output
* buffer must be large enough to hold the data. The output buffer may be the same as the
* input buffer.
*
* @param input data encoded in ARGB8888.
* @param output buffer to hold RGBA8888 data.
* @param width the width of the image
* @param height the height of the image
*/
public static void convertArgb8888ToRgba8888(
ByteBuffer input, ByteBuffer output, int width, int height) {
expectInputSize(input, width * height * 4);
expectOutputSize(output, width * height * 4);
nativeArgb8888ToRgba8888(input, output, width, height);
}
/**
* Convert RGBA8888 to HSVA8888.
*
* The input data is expected to be encoded in 8-bit interleaved RGBA channels. The output
* buffer must be large enough to hold the data. The output buffer may be the same as the
* input buffer.
*
* @param input data encoded in RGBA8888.
* @param output buffer to hold HSVA8888 data.
* @param width the width of the image
* @param height the height of the image
*/
public static void convertRgba8888ToHsva8888(
ByteBuffer input, ByteBuffer output, int width, int height) {
expectInputSize(input, width * height * 4);
expectOutputSize(output, width * height * 4);
nativeRgba8888ToHsva8888(input, output, width, height);
}
/**
* Convert RGBA8888 to YCbCrA8888.
*
* The input data is expected to be encoded in 8-bit interleaved RGBA channels. The output
* buffer must be large enough to hold the data. The output buffer may be the same as the
* input buffer.
*
* @param input data encoded in RGBA8888.
* @param output buffer to hold YCbCrA8888 data.
* @param width the width of the image
* @param height the height of the image
*/
public static void convertRgba8888ToYcbcra8888(
ByteBuffer input, ByteBuffer output, int width, int height) {
expectInputSize(input, width * height * 4);
expectOutputSize(output, width * height * 4);
nativeRgba8888ToYcbcra8888(input, output, width, height);
}
private static void expectInputSize(ByteBuffer input, int expectedSize) {
if (input.remaining() < expectedSize) {
throw new IllegalArgumentException("Input buffer's size does not fit given width "
+ "and height! Expected: " + expectedSize + ", Got: " + input.remaining()
+ ".");
}
}
private static void expectOutputSize(ByteBuffer output, int expectedSize) {
if (output.remaining() < expectedSize) {
throw new IllegalArgumentException("Output buffer's size does not fit given width "
+ "and height! Expected: " + expectedSize + ", Got: " + output.remaining()
+ ".");
}
}
private static native void nativeYuv420pToRgba8888(
ByteBuffer input, ByteBuffer output, int width, int height);
private static native void nativeArgb8888ToRgba8888(
ByteBuffer input, ByteBuffer output, int width, int height);
private static native void nativeRgba8888ToHsva8888(
ByteBuffer input, ByteBuffer output, int width, int height);
private static native void nativeRgba8888ToYcbcra8888(
ByteBuffer input, ByteBuffer output, int width, int height);
static {
System.loadLibrary("smartcamera_jni");
}
}