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     template<typename T>
GetImpl()239     T* GetImpl() const
240     {
241         return bmpImplPtr->DowncastingTo<T>();
242     }
243 
244     std::shared_ptr<Data> Serialize() const;
245     bool Deserialize(std::shared_ptr<Data> data);
246 
247 private:
248     std::shared_ptr<BitmapImpl> bmpImplPtr;
249 };
250 } // namespace Drawing
251 } // namespace Rosen
252 } // namespace OHOS
253 #endif
254