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