1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef BITMAP_H
17 #define BITMAP_H
18
19 #include "drawing/engine_adapter/impl_interface/bitmap_impl.h"
20 #include "utils/drawing_macros.h"
21
22 namespace OHOS {
23 namespace Rosen {
24 namespace Drawing {
25 struct BitmapFormat {
26 ColorType colorType;
27 AlphaType alphaType;
28 };
29
30 class DRAWING_API Bitmap {
31 public:
32 Bitmap();
33 virtual ~Bitmap();
34 bool Build(int32_t width, int32_t height, const BitmapFormat& format, int32_t stride = 0,
35 std::shared_ptr<Drawing::ColorSpace> colorSpace = nullptr);
36 bool Build(const ImageInfo& imageInfo, int32_t stride = 0);
37
38 /**
39 * @brief Gets the width of Bitmap.
40 */
41 int GetWidth() const;
42
43 /**
44 * @brief Gets the height of Bitmap.
45 */
46 int GetHeight() const;
47
48 /**
49 * @brief Returns row bytes, the interval from one pixel row to the next. Row bytes
50 * is at least as large as: GetWidth() * GetImageInfo().GetBytesPerPixel().
51 * @return byte length of pixel row
52 */
53 int GetRowBytes() const;
54 ColorType GetColorType() const;
55 AlphaType GetAlphaType() const;
56 bool ExtractSubset(Bitmap& dst, const Rect& subset) const;
57
58 /**
59 * @brief Copies a Rect of pixels from Bitmap to dstPixels. Copy starts at (srcX, srcY),
60 * and does not exceed Bitmap (GetWidth(), GetHeight()).
61 *
62 * dstInfo specifies width, height, ColorType, AlphaType, and ColorSpace of
63 * destination. dstRowBytes specifics the gap from one destination row to the next.
64 * Returns true if pixels are copied. Returns false if:
65 * - dstInfo has no address
66 * - dstRowBytes is less than dstInfo.GetMinRowBytes()
67 * - PixelRef is nullptr
68 * srcX and srcY may be negative to copy only top or left of source. Returns false
69 * if GetWidth() or GetHeight() is zero or negative.
70 * Returns false if abs(srcX) >= Bitmap GetWidth(), or if abs(srcY) >= Bitmap GetHeight().
71 *
72 * @param dstInfo destination width, height, ColorType, AlphaType, ColorSpace
73 * @param dstPixels destination pixel storage
74 * @param dstRowBytes destination row length
75 * @param srcX column index whose absolute value is less than GetWidth()
76 * @param srcY row index whose absolute value is less than GetHeight()
77 * @return true if pixels are copied to dstPixels
78 */
79 bool ReadPixels(const ImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
80 int32_t srcX, int32_t srcY) const;
81
82 size_t ComputeByteSize() const;
83
84 /**
85 * @brief Copies Bitmap pixel address, row bytes, and ImageInfo to pixmap, if address
86 * is available, and returns true. If pixel address is not available, return false and
87 * leave pixmap unchanged.
88 * pixmap contents become invalid on any future change to Bitmap.
89 *
90 * @param pixmap storage for pixel state if pixels are readable; otherwise, ignored
91 * @return true if Bitmap has direct access to pixels
92 */
93 bool PeekPixels(Pixmap& pixmap) const;
94
95 /**
96 * @brief Gets the pointer to Bitmap buffer.
97 */
98 void* GetPixels() const;
99
100 /**
101 * @brief Replaces PixelRef with pixels, preserving ImageInfo and GetRowBytes().
102 * Sets pixel pointer to (0,0). If pixels is nullptr, or if GetImageInfo().GetColorType()
103 * equals COLORTYPE_UNKNOWN; release reference to PixelRef, and set PixelRef to nullptr.
104 * Caller is responsible for handling ownership pixel memory for the lifetime of Bitmap and PixelRef.
105 *
106 * @param pixel address of pixel storage, managed by caller
107 */
108 void SetPixels(void* pixel);
109
110 /**
111 * @brief Copies a Rect of pixels from Bitmap to dst Bitmap Pixels.
112 * Copy starts at (srcLeft, srcTop), and does not exceed Bitmap (GetWidth(), GetHeight()).
113 *
114 * dstInfo specifies width, height, ColorType, AlphaType, and ColorSpace of
115 * destination. dstRowBytes specifics the gap from one destination row to the next.
116 * Returns true if pixels are copied. Returns false if:
117 * - dstInfo has no address
118 * - dstRowBytes is less than dstInfo.GetMinRowBytes()
119 * - PixelRef is nullptr
120 * srcX and srcY may be negative to copy only top or left of source. Returns false
121 * if GetWidth() or GetHeight() is zero or negative.
122 * Returns false if abs(srcLeft) >= Bitmap GetWidth(), or if abs(srcTop) >= Bitmap GetHeight().
123 *
124 * @param dst destination Bitmap
125 * @param srcLeft column index whose absolute value is less than GetWidth()
126 * @param srcTop row index whose absolute value is less than GetHeight()
127 */
128 void CopyPixels(Bitmap& dst, int srcLeft, int srcTop) const;
129
130 /**
131 * @brief Sets ImageInfo to info following the rules in setInfo(), and creates PixelRef
132 * containing pixels and rowBytes. releaseProc, if not nullptr, is called immediately on failure
133 * or when pixels are no longer referenced. context may be nullptr. If ImageInfo could not be
134 * set, or rowBytes is less than info.GetMinRowBytes():
135 * calls releaseProc if present, calls Free(), and returns false.
136 * Otherwise, if pixels equals nullptr: sets SkImageInfo, calls releaseProc if present, returns true.
137 * If ImageInfo is set, pixels is not nullptr, and releaseProc is not nullptr:
138 * when pixels are no longer referenced, calls releaseProc with pixels and context as parameters.
139 * @param info contains width, height, AlphaType, ColorType, ColorSpace
140 * @param pixels address or pixel storage; may be nullptr
141 * @param rowBytes size of pixel row or larger
142 * @param releaseProc function called when pixels can be deleted; may be nullptr
143 * @param context caller state passed to releaseProc; may be nullptr
144 * @return true if ImageInfo is set to info
145 */
146 bool InstallPixels(const ImageInfo& info, void* pixels, size_t rowBytes,
147 ReleaseProc releaseProc = nullptr, void* context = nullptr);
148 /**
149 * @brief Returns true if pixels can not change. Most
150 * immutable Bitmap checks trigger an assert only on debug builds.
151 * @return true if pixels are immutable
152 */
153 bool IsImmutable();
154
155 /**
156 * @brief Sets internal flag to mark Bitmap as immutable. Once set, pixels can not change.
157 * Any other bitmap sharing the same PixelRef are also marked as immutable. Once PixelRef
158 * is marked immutable, the setting cannot be cleared. Writing to immutable Bitmap pixels
159 * triggers an assert on debug builds.
160 */
161 void SetImmutable();
162
163 /**
164 * @brief Replaces pixel values with c, interpreted as being in the sRGB ColorSpace.
165 * @param color unpremultiplied color
166 */
167 void ClearWithColor(const ColorQuad& color) const;
168
169 /**
170 * @brief Returns true if GetWidth() or GetHeight() are zero, or if PixelRef is nullptr.
171 * If true, Bitmap has no effect when drawn or drawn into.
172 * @return true if drawing has no effect
173 */
174 bool IsValid() const;
175
176 /**
177 * @brief Returns true if either width() or height() are zero.
178 * Does not check if SkPixelRef is nullptr; call IsValid() to check GetWidth(), GetHeight(), and PixelRef.
179 * @return true if dimensions do not enclose area
180 */
181 bool IsEmpty() const;
182
183 /**
184 * @brief Returns pixel at (x, y) as unpremultiplied color. Returns black with
185 * alpha if ColorType is COLORTYPE_ALPHA_8. ColorSpace in ImageInfo is ignored.
186 * Some color precision may be lost in the conversion to unpremultiplied color;
187 * original pixel data may have additional precision.
188 *
189 * @param x column index, zero or greater, and less than GetWidth()
190 * @param y row index, zero or greater, and less than GetHeight()
191 * @return pixel converted to unpremultiplied color
192 */
193 ColorQuad GetColor(int x, int y) const;
194
195
196 /**
197 * @brief Resets to its initial state; all fields are set to zero, as if Bitmap
198 * had been initialized by Bitmap(). Sets width, height, row bytes to zero; pixel
199 * address to nullptr; ColorType to COLORTYPE_UNKNOWN; and AlphaType to ALPHATYPE_UNKNOWN.
200 * If PixelRef is allocated, its reference count is decreased by one, releasing its memory
201 * if Bitmap is the sole owner.
202 */
203 void Free();
204 BitmapFormat GetFormat() const;
205 void SetFormat(const BitmapFormat& format);
206
207 void SetInfo(const ImageInfo& info);
208
209 /**
210 * @brief Gets Image info which contains width, height, AlphaType, ColorType, and ColorSpace.
211 * @return Returns ImageInfo describing this Bitmap
212 */
213 ImageInfo GetImageInfo() const;
214
215 /**
216 * @brief Gets a constant reference to the Pixmap holding the Bitmap pixel
217 * address, row bytes, and ImageInfo.
218 * @return Returns Pixmap describing this Bitmap
219 */
220 Pixmap GetPixmap() const;
221
222 /**
223 * @brief Make new image from Bitmap but never copy Pixels
224 * @note the function never copy Pixels, make sure Pixels is available during using the image
225 */
226 std::shared_ptr<Image> MakeImage() const;
227
228 /**
229 * @brief Sets SkImageInfo to info following the rules in setInfo() and allocates pixel memory.
230 * Returns false and calls reset() if SkImageInfo could not be set, or memory could not be allocated.
231 * On most platforms, allocating pixel memory may succeed even though there is not sufficient memory
232 * to hold pixels; allocation does not take place until the pixels are written to. The actual behavior
233 * depends on the platform implementation of malloc().
234 * @param info contains width, height, AlphaType, ColorType, ColorSpace
235 * @return true if pixel storage is allocated
236 */
237 bool TryAllocPixels(const ImageInfo& info);
238
239 inline void Dump(std::string& out) const;
240
241 template<typename T>
GetImpl()242 T* GetImpl() const
243 {
244 return bmpImplPtr->DowncastingTo<T>();
245 }
246
247 std::shared_ptr<Data> Serialize() const;
248 bool Deserialize(std::shared_ptr<Data> data);
249
250 private:
251 std::shared_ptr<BitmapImpl> bmpImplPtr;
252 };
253
Dump(std::string & out)254 inline void Bitmap::Dump(std::string& out) const
255 {
256 out += '[';
257 if (bmpImplPtr != nullptr) {
258 out += "width:" + std::to_string(bmpImplPtr->GetWidth());
259 out += " height:" + std::to_string(bmpImplPtr->GetHeight());
260 out += " rowBytes:" + std::to_string(bmpImplPtr->GetRowBytes());
261 out += " colorType:" + std::to_string(static_cast<int>(bmpImplPtr->GetColorType()));
262 out += " alphaType:" + std::to_string(static_cast<int>(bmpImplPtr->GetAlphaType()));
263 }
264 out += ']';
265 }
266 } // namespace Drawing
267 } // namespace Rosen
268 } // namespace OHOS
269 #endif
270