YUVImage.h revision db205a1d75c1e9a7d0dbd8fa011335249ad6f4ac
1db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra/* 2db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * Copyright (C) 2010 The Android Open Source Project 3db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * 4db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * Licensed under the Apache License, Version 2.0 (the "License"); 5db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * you may not use this file except in compliance with the License. 6db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * You may obtain a copy of the License at 7db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * 8db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * http://www.apache.org/licenses/LICENSE-2.0 9db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * 10db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * Unless required by applicable law or agreed to in writing, software 11db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * distributed under the License is distributed on an "AS IS" BASIS, 12db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * See the License for the specific language governing permissions and 14db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * limitations under the License. 15db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra */ 16db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 17db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// A container class to hold YUV data and provide various utilities, 18db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// e.g. to set/get pixel values. 19db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// Supported formats: 20db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// - YUV420 Planar 21db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// - YUV420 Semi Planar 22db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// 23db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// Currently does not support variable strides. 24db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// 25db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// Implementation: Two simple abstractions are done to simplify access 26db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// to YUV channels for different formats: 27db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// - initializeYUVPointers() sets up pointers (mYdata, mUdata, mVdata) to 28db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// point to the right start locations of the different channel data depending 29db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// on the format. 30db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// - getOffsets() returns the correct offset for the different channels 31db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// depending on the format. 32db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// Location of any pixel's YUV channels can then be easily computed using these. 33db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra// 34db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 35db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra#ifndef YUV_IMAGE_H_ 36db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 37db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra#define YUV_IMAGE_H_ 38db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 39db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra#include <stdint.h> 40db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra#include <cstring> 41db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 42db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatranamespace android { 43db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 44db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatraclass Rect; 45db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 46db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatraclass YUVImage { 47db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatrapublic: 48db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Supported YUV formats 49db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra enum YUVFormat { 50db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra YUV420Planar, 51db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra YUV420SemiPlanar 52db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra }; 53db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 54db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Constructs an image with the given size, format. Also allocates and owns 55db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // the required memory. 56db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra YUVImage(YUVFormat yuvFormat, int32_t width, int32_t height); 57db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 58db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Constructs an image with the given size, format. The memory is provided 59db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // by the caller and we don't own it. 60db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra YUVImage(YUVFormat yuvFormat, int32_t width, int32_t height, uint8_t *buffer); 61db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 62db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Destructor to delete the memory if it owns it. 63db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra ~YUVImage(); 64db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 65db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Returns the size of the buffer required to store the YUV data for the given 66db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // format and geometry. Useful when the caller wants to allocate the requisite 67db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // memory. 68db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra static size_t bufferSize(YUVFormat yuvFormat, int32_t width, int32_t height); 69db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 70db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t width() {return mWidth;} 71db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t height() {return mHeight;} 72db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 73db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Get the pixel YUV value at pixel (x,y). 74db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. 75db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Returns true if get was succesful and false otherwise. 76db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool getPixelValue(int32_t x, int32_t y, 77db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t *yPtr, uint8_t *uPtr, uint8_t *vPtr) const; 78db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 79db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Set the pixel YUV value at pixel (x,y). 80db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. 81db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Returns true if set was succesful and false otherwise. 82db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool setPixelValue(int32_t x, int32_t y, 83db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t yValue, uint8_t uValue, uint8_t vValue); 84db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 85db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Uses memcpy to copy an entire row of data 86db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra static void fastCopyRectangle420Planar( 87db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra const Rect& srcRect, 88db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t destStartX, int32_t destStartY, 89db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra const YUVImage &srcImage, YUVImage &destImage); 90db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 91db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Uses memcpy to copy an entire row of data 92db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra static void fastCopyRectangle420SemiPlanar( 93db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra const Rect& srcRect, 94db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t destStartX, int32_t destStartY, 95db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra const YUVImage &srcImage, YUVImage &destImage); 96db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 97db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Tries to use memcopy to copy entire rows of data. 98db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Returns false if fast copy is not possible for the passed image formats. 99db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra static bool fastCopyRectangle( 100db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra const Rect& srcRect, 101db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t destStartX, int32_t destStartY, 102db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra const YUVImage &srcImage, YUVImage &destImage); 103db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 104db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Convert the given YUV value to RGB. 105db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra void yuv2rgb(uint8_t yValue, uint8_t uValue, uint8_t vValue, 106db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t *r, uint8_t *g, uint8_t *b) const; 107db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 108db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Write the image to a human readable PPM file. 109db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Returns true if write was succesful and false otherwise. 110db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool writeToPPM(const char *filename) const; 111db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 112db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatraprivate: 113db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // YUV Format of the image. 114db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra YUVFormat mYUVFormat; 115db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 116db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t mWidth; 117db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t mHeight; 118db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 119db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Pointer to the memory buffer. 120db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t *mBuffer; 121db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 122db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Boolean telling whether we own the memory buffer. 123db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool mOwnBuffer; 124db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 125db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Pointer to start of the Y data plane. 126db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t *mYdata; 127db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 128db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Pointer to start of the U data plane. Note that in case of interleaved formats like 129db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // YUV420 semiplanar, mUdata points to the start of the U data in the UV plane. 130db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t *mUdata; 131db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 132db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Pointer to start of the V data plane. Note that in case of interleaved formats like 133db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // YUV420 semiplanar, mVdata points to the start of the V data in the UV plane. 134db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t *mVdata; 135db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 136db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Initialize the pointers mYdata, mUdata, mVdata to point to the right locations for 137db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // the given format and geometry. 138db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Returns true if initialize was succesful and false otherwise. 139db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool initializeYUVPointers(); 140db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 141db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // For the given pixel location, this returns the offset of the location of y, u and v 142db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // data from the corresponding base pointers -- mYdata, mUdata, mVdata. 143db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. 144db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Returns true if getting offsets was succesful and false otherwise. 145db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool getOffsets(int32_t x, int32_t y, 146db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t *yOffset, int32_t *uOffset, int32_t *vOffset) const; 147db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 148db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Returns the offset increments incurred in going from one data row to the next data row 149db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // for the YUV channels. Note that this corresponds to data rows and not pixel rows. 150db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // E.g. depending on formats, U/V channels may have only one data row corresponding 151db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // to two pixel rows. 152db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool getOffsetIncrementsPerDataRow( 153db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t *yDataOffsetIncrement, 154db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t *uDataOffsetIncrement, 155db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t *vDataOffsetIncrement) const; 156db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 157db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Given the offset return the address of the corresponding channel's data. 158db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t* getYAddress(int32_t offset) const; 159db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t* getUAddress(int32_t offset) const; 160db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t* getVAddress(int32_t offset) const; 161db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 162db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Given the pixel location, returns the address of the corresponding channel's data. 163db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. 164db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool getYUVAddresses(int32_t x, int32_t y, 165db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t **yAddr, uint8_t **uAddr, uint8_t **vAddr) const; 166db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 167db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Disallow implicit casting and copying. 168db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra YUVImage(const YUVImage &); 169db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra YUVImage &operator=(const YUVImage &); 170db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra}; 171db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 172db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra} // namespace android 173db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 174db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra#endif // YUV_IMAGE_H_ 175