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 704a6b74563ac0fe752fbdfd15f91772473f8a4711Nipun Kwatra int32_t width() const {return mWidth;} 714a6b74563ac0fe752fbdfd15f91772473f8a4711Nipun Kwatra int32_t height() const {return mHeight;} 724a6b74563ac0fe752fbdfd15f91772473f8a4711Nipun Kwatra 734a6b74563ac0fe752fbdfd15f91772473f8a4711Nipun Kwatra // Returns true if pixel is the range [0, width-1] x [0, height-1] 744a6b74563ac0fe752fbdfd15f91772473f8a4711Nipun Kwatra // and false otherwise. 754a6b74563ac0fe752fbdfd15f91772473f8a4711Nipun Kwatra bool validPixel(int32_t x, int32_t y) const; 76db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 77db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Get the pixel YUV value at pixel (x,y). 78db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. 794a6b74563ac0fe752fbdfd15f91772473f8a4711Nipun Kwatra // Returns true if get was successful and false otherwise. 80db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool getPixelValue(int32_t x, int32_t y, 81db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t *yPtr, uint8_t *uPtr, uint8_t *vPtr) const; 82db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 83db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Set the pixel YUV value at pixel (x,y). 84db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. 854a6b74563ac0fe752fbdfd15f91772473f8a4711Nipun Kwatra // Returns true if set was successful and false otherwise. 86db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool setPixelValue(int32_t x, int32_t y, 87db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t yValue, uint8_t uValue, uint8_t vValue); 88db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 89db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Uses memcpy to copy an entire row of data 90db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra static void fastCopyRectangle420Planar( 91db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra const Rect& srcRect, 92db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t destStartX, int32_t destStartY, 93db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra const YUVImage &srcImage, YUVImage &destImage); 94db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 95db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Uses memcpy to copy an entire row of data 96db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra static void fastCopyRectangle420SemiPlanar( 97db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra const Rect& srcRect, 98db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t destStartX, int32_t destStartY, 99db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra const YUVImage &srcImage, YUVImage &destImage); 100db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 101db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Tries to use memcopy to copy entire rows of data. 102db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Returns false if fast copy is not possible for the passed image formats. 103db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra static bool fastCopyRectangle( 104db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra const Rect& srcRect, 105db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t destStartX, int32_t destStartY, 106db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra const YUVImage &srcImage, YUVImage &destImage); 107db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 108db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Convert the given YUV value to RGB. 109db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra void yuv2rgb(uint8_t yValue, uint8_t uValue, uint8_t vValue, 110db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t *r, uint8_t *g, uint8_t *b) const; 111db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 112db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Write the image to a human readable PPM file. 113db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Returns true if write was succesful and false otherwise. 114db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool writeToPPM(const char *filename) const; 115db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 116db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatraprivate: 117db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // YUV Format of the image. 118db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra YUVFormat mYUVFormat; 119db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 120db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t mWidth; 121db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t mHeight; 122db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 123db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Pointer to the memory buffer. 124db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t *mBuffer; 125db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 126db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Boolean telling whether we own the memory buffer. 127db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool mOwnBuffer; 128db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 129db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Pointer to start of the Y data plane. 130db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t *mYdata; 131db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 132db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Pointer to start of the U data plane. Note that in case of interleaved formats like 133db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // YUV420 semiplanar, mUdata points to the start of the U data in the UV plane. 134db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t *mUdata; 135db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 136db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Pointer to start of the V data plane. Note that in case of interleaved formats like 137db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // YUV420 semiplanar, mVdata points to the start of the V data in the UV plane. 138db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t *mVdata; 139db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 140db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Initialize the pointers mYdata, mUdata, mVdata to point to the right locations for 141db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // the given format and geometry. 142db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Returns true if initialize was succesful and false otherwise. 143db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool initializeYUVPointers(); 144db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 145db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // For the given pixel location, this returns the offset of the location of y, u and v 146db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // data from the corresponding base pointers -- mYdata, mUdata, mVdata. 147db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. 148db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Returns true if getting offsets was succesful and false otherwise. 149db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool getOffsets(int32_t x, int32_t y, 150db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t *yOffset, int32_t *uOffset, int32_t *vOffset) const; 151db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 152db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Returns the offset increments incurred in going from one data row to the next data row 153db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // for the YUV channels. Note that this corresponds to data rows and not pixel rows. 154db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // E.g. depending on formats, U/V channels may have only one data row corresponding 155db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // to two pixel rows. 156db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool getOffsetIncrementsPerDataRow( 157db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t *yDataOffsetIncrement, 158db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t *uDataOffsetIncrement, 159db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t *vDataOffsetIncrement) const; 160db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 161db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Given the offset return the address of the corresponding channel's data. 162db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t* getYAddress(int32_t offset) const; 163db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t* getUAddress(int32_t offset) const; 164db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t* getVAddress(int32_t offset) const; 165db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 166db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Given the pixel location, returns the address of the corresponding channel's data. 167db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. 168db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra bool getYUVAddresses(int32_t x, int32_t y, 169db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t **yAddr, uint8_t **uAddr, uint8_t **vAddr) const; 170db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 171db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Disallow implicit casting and copying. 172db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra YUVImage(const YUVImage &); 173db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra YUVImage &operator=(const YUVImage &); 174db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra}; 175db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 176db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra} // namespace android 177db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 178db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra#endif // YUV_IMAGE_H_ 179