blob: 4e98618948a68b3e02e4397c9bff03f49bfb8263 [file] [log] [blame]
Nipun Kwatraa435c132010-07-27 22:13:04 -07001/*
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
42namespace android {
43
44class Rect;
45
46class YUVImage {
47public:
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
Nipun Kwatrad1fbdf12010-08-19 17:34:52 -070070 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;
Nipun Kwatraa435c132010-07-27 22:13:04 -070076
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].
Nipun Kwatrad1fbdf12010-08-19 17:34:52 -070079 // Returns true if get was successful and false otherwise.
Nipun Kwatraa435c132010-07-27 22:13:04 -070080 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].
Nipun Kwatrad1fbdf12010-08-19 17:34:52 -070085 // Returns true if set was successful and false otherwise.
Nipun Kwatraa435c132010-07-27 22:13:04 -070086 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
116private:
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_