| /* |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * 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. |
| */ |
| |
| // A container class to hold YUV data and provide various utilities, |
| // e.g. to set/get pixel values. |
| // Supported formats: |
| // - YUV420 Planar |
| // - YUV420 Semi Planar |
| // |
| // Currently does not support variable strides. |
| // |
| // Implementation: Two simple abstractions are done to simplify access |
| // to YUV channels for different formats: |
| // - initializeYUVPointers() sets up pointers (mYdata, mUdata, mVdata) to |
| // point to the right start locations of the different channel data depending |
| // on the format. |
| // - getOffsets() returns the correct offset for the different channels |
| // depending on the format. |
| // Location of any pixel's YUV channels can then be easily computed using these. |
| // |
| |
| #ifndef YUV_IMAGE_H_ |
| |
| #define YUV_IMAGE_H_ |
| |
| #include <stdint.h> |
| #include <cstring> |
| |
| namespace android { |
| |
| class Rect; |
| |
| class YUVImage { |
| public: |
| // Supported YUV formats |
| enum YUVFormat { |
| YUV420Planar, |
| YUV420SemiPlanar |
| }; |
| |
| // Constructs an image with the given size, format. Also allocates and owns |
| // the required memory. |
| YUVImage(YUVFormat yuvFormat, int32_t width, int32_t height); |
| |
| // Constructs an image with the given size, format. The memory is provided |
| // by the caller and we don't own it. |
| YUVImage(YUVFormat yuvFormat, int32_t width, int32_t height, uint8_t *buffer); |
| |
| // Destructor to delete the memory if it owns it. |
| ~YUVImage(); |
| |
| // Returns the size of the buffer required to store the YUV data for the given |
| // format and geometry. Useful when the caller wants to allocate the requisite |
| // memory. |
| static size_t bufferSize(YUVFormat yuvFormat, int32_t width, int32_t height); |
| |
| int32_t width() const {return mWidth;} |
| int32_t height() const {return mHeight;} |
| |
| // Returns true if pixel is the range [0, width-1] x [0, height-1] |
| // and false otherwise. |
| bool validPixel(int32_t x, int32_t y) const; |
| |
| // Get the pixel YUV value at pixel (x,y). |
| // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. |
| // Returns true if get was successful and false otherwise. |
| bool getPixelValue(int32_t x, int32_t y, |
| uint8_t *yPtr, uint8_t *uPtr, uint8_t *vPtr) const; |
| |
| // Set the pixel YUV value at pixel (x,y). |
| // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. |
| // Returns true if set was successful and false otherwise. |
| bool setPixelValue(int32_t x, int32_t y, |
| uint8_t yValue, uint8_t uValue, uint8_t vValue); |
| |
| // Uses memcpy to copy an entire row of data |
| static void fastCopyRectangle420Planar( |
| const Rect& srcRect, |
| int32_t destStartX, int32_t destStartY, |
| const YUVImage &srcImage, YUVImage &destImage); |
| |
| // Uses memcpy to copy an entire row of data |
| static void fastCopyRectangle420SemiPlanar( |
| const Rect& srcRect, |
| int32_t destStartX, int32_t destStartY, |
| const YUVImage &srcImage, YUVImage &destImage); |
| |
| // Tries to use memcopy to copy entire rows of data. |
| // Returns false if fast copy is not possible for the passed image formats. |
| static bool fastCopyRectangle( |
| const Rect& srcRect, |
| int32_t destStartX, int32_t destStartY, |
| const YUVImage &srcImage, YUVImage &destImage); |
| |
| // Convert the given YUV value to RGB. |
| void yuv2rgb(uint8_t yValue, uint8_t uValue, uint8_t vValue, |
| uint8_t *r, uint8_t *g, uint8_t *b) const; |
| |
| // Write the image to a human readable PPM file. |
| // Returns true if write was succesful and false otherwise. |
| bool writeToPPM(const char *filename) const; |
| |
| private: |
| // YUV Format of the image. |
| YUVFormat mYUVFormat; |
| |
| int32_t mWidth; |
| int32_t mHeight; |
| |
| // Pointer to the memory buffer. |
| uint8_t *mBuffer; |
| |
| // Boolean telling whether we own the memory buffer. |
| bool mOwnBuffer; |
| |
| // Pointer to start of the Y data plane. |
| uint8_t *mYdata; |
| |
| // Pointer to start of the U data plane. Note that in case of interleaved formats like |
| // YUV420 semiplanar, mUdata points to the start of the U data in the UV plane. |
| uint8_t *mUdata; |
| |
| // Pointer to start of the V data plane. Note that in case of interleaved formats like |
| // YUV420 semiplanar, mVdata points to the start of the V data in the UV plane. |
| uint8_t *mVdata; |
| |
| // Initialize the pointers mYdata, mUdata, mVdata to point to the right locations for |
| // the given format and geometry. |
| // Returns true if initialize was succesful and false otherwise. |
| bool initializeYUVPointers(); |
| |
| // For the given pixel location, this returns the offset of the location of y, u and v |
| // data from the corresponding base pointers -- mYdata, mUdata, mVdata. |
| // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. |
| // Returns true if getting offsets was succesful and false otherwise. |
| bool getOffsets(int32_t x, int32_t y, |
| int32_t *yOffset, int32_t *uOffset, int32_t *vOffset) const; |
| |
| // Returns the offset increments incurred in going from one data row to the next data row |
| // for the YUV channels. Note that this corresponds to data rows and not pixel rows. |
| // E.g. depending on formats, U/V channels may have only one data row corresponding |
| // to two pixel rows. |
| bool getOffsetIncrementsPerDataRow( |
| int32_t *yDataOffsetIncrement, |
| int32_t *uDataOffsetIncrement, |
| int32_t *vDataOffsetIncrement) const; |
| |
| // Given the offset return the address of the corresponding channel's data. |
| uint8_t* getYAddress(int32_t offset) const; |
| uint8_t* getUAddress(int32_t offset) const; |
| uint8_t* getVAddress(int32_t offset) const; |
| |
| // Given the pixel location, returns the address of the corresponding channel's data. |
| // Note that the range of x is [0, width-1] and the range of y is [0, height-1]. |
| bool getYUVAddresses(int32_t x, int32_t y, |
| uint8_t **yAddr, uint8_t **uAddr, uint8_t **vAddr) const; |
| |
| // Disallow implicit casting and copying. |
| YUVImage(const YUVImage &); |
| YUVImage &operator=(const YUVImage &); |
| }; |
| |
| } // namespace android |
| |
| #endif // YUV_IMAGE_H_ |