All Downloads are FREE. Search and download functionalities are using the official Maven repository.

boofcv.core.encoding.ConvertNV21 Maven / Gradle / Ivy

/*
 * Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved.
 *
 * This file is part of BoofCV (http://boofcv.org).
 *
 * 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 boofcv.core.encoding;

import boofcv.struct.image.*;

/**
 * Used to convert NV21 image format used in Android into BoofCV standard image types. NV21 is an encoding of a
 * YUV image [1] (more specifically YUV 4:2:0) where Y is encoded in the first block and UV are interlaced together.
 * The UV planes are at 1/2 resolution.
 *
 * @author Peter Abeles
 */
public class ConvertNV21 {

	/**
	 * Converts a NV21 encoded byte array into a BoofCV formatted image.
	 *
	 * @param data (input) NV21 byte array
	 * @param width (input) image width
	 * @param height (input) image height
	 * @param output (output) BoofCV image
	 */
	public static void nv21ToBoof(byte[] data, int width, int height, ImageBase output) {

		if( output instanceof Planar) {
			Planar ms = (Planar) output;

			if (ms.getBandType() == GrayU8.class) {
				ConvertNV21.nv21ToMsRgb_U8(data, width, height, ms);
			} else if (ms.getBandType() == GrayF32.class) {
				ConvertNV21.nv21ToMsRgb_F32(data, width, height , ms);
			} else {
				throw new IllegalArgumentException("Unsupported output band format");
			}
		} else if( output instanceof ImageGray) {
			if (output.getClass() == GrayU8.class) {
				nv21ToGray(data, width, height, (GrayU8) output);
			} else if (output.getClass() == GrayF32.class) {
				nv21ToGray(data, width, height, (GrayF32) output);
			} else {
				throw new IllegalArgumentException("Unsupported output type");
			}
		} else if( output instanceof ImageInterleaved ) {
			if( output.getClass() == InterleavedU8.class ) {
				ConvertNV21.nv21ToInterleaved(data, width, height, (InterleavedU8) output);
			} else if( output.getClass() == InterleavedF32.class ) {
				ConvertNV21.nv21ToInterleaved(data, width, height, (InterleavedF32) output);
			} else {
				throw new IllegalArgumentException("Unsupported output type");
			}
		} else {
			throw new IllegalArgumentException("Boofcv image type not yet supported");
		}
	}

	/**
	 * Converts an NV21 image into a gray scale image.  Image type is determined at runtime.
	 *
	 * @param data Input: NV21 image data
	 * @param width Input: NV21 image width
	 * @param height Input: NV21 image height
	 * @param output Output: Optional storage for output image.  Can be null.
	 * @param outputType  Output: Type of output image
	 * @param  Output image type
	 * @return Gray scale image
	 */
	public static 
	T nv21ToGray( byte[] data , int width , int height ,
				  T output , Class outputType ) {

		if( outputType == GrayU8.class ) {
			return (T)nv21ToGray(data,width,height,(GrayU8)output);
		} else if( outputType == GrayF32.class ) {
			return (T)nv21ToGray(data,width,height,(GrayF32)output);
		} else {
			throw new IllegalArgumentException("Unsupported BoofCV Image Type "+outputType.getSimpleName());
		}
	}

	/**
	 * Converts an NV21 image into a gray scale U8 image.
	 *
	 * @param data Input: NV21 image data
	 * @param width Input: NV21 image width
	 * @param height Input: NV21 image height
	 * @param output Output: Optional storage for output image.  Can be null.
	 * @return Gray scale image
	 */
	public static GrayU8 nv21ToGray(byte[] data , int width , int height , GrayU8 output ) {
		if( output != null ) {
			if( output.width != width || output.height != height )
				throw new IllegalArgumentException("output width and height must be "+width+" "+height);
		} else {
			output = new GrayU8(width,height);
		}

		ImplConvertNV21.nv21ToGray(data, output);

		return output;
	}

	/**
	 * Converts an NV21 image into a gray scale F32 image.
	 *
	 * @param data Input: NV21 image data
	 * @param width Input: NV21 image width
	 * @param height Input: NV21 image height
	 * @param output Output: Optional storage for output image.  Can be null.
	 * @return Gray scale image
	 */
	public static GrayF32 nv21ToGray(byte[] data , int width , int height , GrayF32 output ) {
		if( output != null ) {
			if( output.width != width || output.height != height )
				throw new IllegalArgumentException("output width and height must be "+width+" "+height);
		} else {
			output = new GrayF32(width,height);
		}

		ImplConvertNV21.nv21ToGray(data, output);

		return output;
	}

	/**
	 * Converts an NV21 image into a {@link Planar} YUV image.
	 *
	 * @param data Input: NV21 image data
	 * @param width Input: NV21 image width
	 * @param height Input: NV21 image height
	 * @param output Output: Optional storage for output image.  Can be null.
	 * @param outputType  Output: Type of output image
	 * @param  Output image type
	 */
	public static 
	Planar nv21ToMsYuv(byte[] data , int width , int height ,
						  Planar output , Class outputType ) {

		if( outputType == GrayU8.class ) {
			return (Planar)nv21ToMsYuv_U8(data,width,height,(Planar)output);
		} else if( outputType == GrayF32.class ) {
			return (Planar)nv21ToMsYuv_F32(data,width,height,(Planar)output);
		} else {
			throw new IllegalArgumentException("Unsupported BoofCV Image Type "+outputType.getSimpleName());
		}
	}

	/**
	 * Converts an NV21 image into a {@link Planar} YUV image with U8 bands.
	 *
	 * @param data Input: NV21 image data
	 * @param width Input: NV21 image width
	 * @param height Input: NV21 image height
	 * @param output Output: Optional storage for output image.  Can be null.
	 */
	public static Planar nv21ToMsYuv_U8(byte[] data , int width , int height ,
												Planar output ) {
		if( output == null ) {
			output = new Planar(GrayU8.class,width,height,3);
		} else if( output.width != width || output.height != height )
			throw new IllegalArgumentException("output width and height must be "+width+" "+height);
		else if( output.getNumBands() != 3 )
			throw new IllegalArgumentException("three bands expected");

		ImplConvertNV21.nv21ToMultiYuv_U8(data,output);

		return output;
	}

	/**
	 * Converts an NV21 image into a {@link Planar} RGB image with U8 bands.
	 *
	 * @param data Input: NV21 image data
	 * @param width Input: NV21 image width
	 * @param height Input: NV21 image height
	 * @param output Output: Optional storage for output image.  Can be null.
	 */
	public static Planar nv21ToMsRgb_U8(byte[] data , int width , int height ,
												Planar output ) {
		if( output == null ) {
			output = new Planar(GrayU8.class,width,height,3);
		} else if( output.width != width || output.height != height )
			throw new IllegalArgumentException("output width and height must be "+width+" "+height);
		else if( output.getNumBands() != 3 )
			throw new IllegalArgumentException("three bands expected");

		ImplConvertNV21.nv21ToMultiRgb_U8(data, output);

		return output;
	}

	/**
	 * Converts an NV21 image into a {@link InterleavedU8} RGB image.
	 *
	 * @param data Input: NV21 image data
	 * @param width Input: NV21 image width
	 * @param height Input: NV21 image height
	 * @param output Output: Optional storage for output image.  Can be null.
	 */
	public static InterleavedU8 nv21ToInterleaved( byte[] data , int width , int height ,
												   InterleavedU8 output ) {
		if( output == null ) {
			output = new InterleavedU8(width,height,3);
		} else if( output.width != width || output.height != height )
			throw new IllegalArgumentException("output width and height must be "+width+" "+height);
		else if( output.getNumBands() != 3 )
			throw new IllegalArgumentException("three bands expected");

		ImplConvertNV21.nv21ToInterleaved_U8(data, output);

		return output;
	}

	/**
	 * Converts an NV21 image into a {@link Planar} YUV image with F32 bands.
	 *
	 * @param data Input: NV21 image data
	 * @param width Input: NV21 image width
	 * @param height Input: NV21 image height
	 * @param output Output: Optional storage for output image.  Can be null.
	 */
	public static Planar nv21ToMsYuv_F32(byte[] data , int width , int height ,
												  Planar output ) {
		if( output == null ) {
			output = new Planar(GrayF32.class,width,height,3);
		} else if( output.width != width || output.height != height )
			throw new IllegalArgumentException("output width and height must be "+width+" "+height);
		else if( output.getNumBands() != 3 )
			throw new IllegalArgumentException("three bands expected");

		ImplConvertNV21.nv21ToMultiYuv_F32(data, output);

		return output;
	}

	/**
	 * Converts an NV21 image into a {@link Planar} RGB image with F32 bands.
	 *
	 * @param data Input: NV21 image data
	 * @param width Input: NV21 image width
	 * @param height Input: NV21 image height
	 * @param output Output: Optional storage for output image.  Can be null.
	 */
	public static Planar nv21ToMsRgb_F32(byte[] data , int width , int height ,
												  Planar output ) {
		if( output == null ) {
			output = new Planar(GrayF32.class,width,height,3);
		} else if( output.width != width || output.height != height )
			throw new IllegalArgumentException("output width and height must be "+width+" "+height);
		else if( output.getNumBands() != 3 )
			throw new IllegalArgumentException("three bands expected");

		ImplConvertNV21.nv21ToMultiRgb_F32(data, output);

		return output;
	}

	/**
	 * Converts an NV21 image into a {@link InterleavedF32} RGB image.
	 *
	 * @param data Input: NV21 image data
	 * @param width Input: NV21 image width
	 * @param height Input: NV21 image height
	 * @param output Output: Optional storage for output image.  Can be null.
	 */
	public static InterleavedF32 nv21ToInterleaved( byte[] data , int width , int height ,
															   InterleavedF32 output ) {
		if( output == null ) {
			output = new InterleavedF32(width,height,3);
		} else if( output.width != width || output.height != height )
			throw new IllegalArgumentException("output width and height must be "+width+" "+height);
		else if( output.getNumBands() != 3 )
			throw new IllegalArgumentException("three bands expected");

		ImplConvertNV21.nv21ToInterleaved_F32(data, output);

		return output;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy