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