190a7e46b8c9a193f8de5634d1050c9ed431c711
[platform/core/uifw/lottie-player.git] / src / vector / vbitmap.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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 #include "vbitmap.h"
18 #include <string.h>
19 #include "vglobal.h"
20
21 V_BEGIN_NAMESPACE
22
23 struct VBitmapData {
24     ~VBitmapData();
25     VBitmapData();
26     static VBitmapData *create(int width, int height, VBitmap::Format format);
27     RefCount            ref;
28     int                 width;
29     int                 height;
30     int                 depth;
31     int                 stride;
32     int                 nBytes;
33     VBitmap::Format     format;
34     uchar *             data;
35     VBitmapCleanupFunction cleanupFunction;
36     void *                 cleanupInfo;
37     uint                   ownData : 1;
38     uint                   roData : 1;
39 };
40
41 VBitmapData::~VBitmapData()
42 {
43     if (cleanupFunction) cleanupFunction(cleanupInfo);
44     if (data && ownData) free(data);
45     data = 0;
46 }
47
48 VBitmapData::VBitmapData()
49     : ref(0),
50       width(0),
51       height(0),
52       depth(0),
53       stride(0),
54       nBytes(0),
55       format(VBitmap::Format::ARGB32),
56       data(nullptr),
57       cleanupFunction(0),
58       cleanupInfo(0),
59       ownData(true),
60       roData(false)
61 {
62 }
63
64 VBitmapData *VBitmapData::create(int width, int height, VBitmap::Format format)
65 {
66     if ((width <= 0) || (height <= 0) || format == VBitmap::Format::Invalid)
67         return nullptr;
68
69     int depth = 1;
70     switch (format) {
71     case VBitmap::Format::Alpha8:
72         depth = 8;
73         VECTOR_FALLTHROUGH
74     case VBitmap::Format::ARGB32:
75     case VBitmap::Format::ARGB32_Premultiplied:
76         depth = 32;
77         break;
78     default:
79         break;
80     }
81
82     const int stride = ((width * depth + 31) >> 5)
83                        << 2;  // bytes per scanline (must be multiple of 4)
84
85     VBitmapData *d = new VBitmapData;
86
87     d->width = width;
88     d->height = height;
89     d->depth = depth;
90     d->format = format;
91     d->stride = stride;
92     d->nBytes = d->stride * height;
93     d->data = (uchar *)malloc(d->nBytes);
94
95     if (!d->data) {
96         delete d;
97         return 0;
98     }
99
100     return d;
101 }
102
103 inline void VBitmap::cleanUp(VBitmapData *d)
104 {
105     delete d;
106 }
107
108 void VBitmap::detach()
109 {
110     if (d) {
111         if (d->ref.isShared() || d->roData) *this = copy();
112     }
113 }
114
115 VBitmap::~VBitmap()
116 {
117     if (!d) return;
118
119     if (!d->ref.deref()) cleanUp(d);
120 }
121
122 VBitmap::VBitmap() : d(nullptr) {}
123
124 VBitmap::VBitmap(const VBitmap &other)
125 {
126     d = other.d;
127     if (d) d->ref.ref();
128 }
129
130 VBitmap::VBitmap(VBitmap &&other) : d(other.d)
131 {
132     other.d = nullptr;
133 }
134
135 VBitmap &VBitmap::operator=(const VBitmap &other)
136 {
137     if (!d) {
138         d = other.d;
139         if (d) d->ref.ref();
140     } else {
141         if (!d->ref.deref()) cleanUp(d);
142         other.d->ref.ref();
143         d = other.d;
144     }
145
146     return *this;
147 }
148
149 inline VBitmap &VBitmap::operator=(VBitmap &&other)
150 {
151     if (d && !d->ref.deref()) cleanUp(d);
152     d = other.d;
153     return *this;
154 }
155
156 VBitmap::VBitmap(int w, int h, VBitmap::Format format) {}
157 VBitmap::VBitmap(uchar *data, int w, int h, int bytesPerLine,
158                  VBitmap::Format format, VBitmapCleanupFunction f,
159                  void *cleanupInfo)
160 {
161     d = new VBitmapData;
162     d->data = data;
163     d->format = format;
164     d->width = w;
165     d->height = h;
166     d->stride = bytesPerLine;
167     d->cleanupFunction = nullptr;
168     d->cleanupInfo = nullptr;
169     d->ownData = false;
170     d->roData = false;
171     d->ref.setOwned();
172 }
173
174 VBitmap VBitmap::copy(const VRect &r) const
175 {
176     // TODO implement properly.
177     return *this;
178 }
179
180 int VBitmap::stride() const
181 {
182     return d ? d->stride : 0;
183 }
184
185 int VBitmap::width() const
186 {
187     return d ? d->width : 0;
188 }
189
190 int VBitmap::height() const
191 {
192     return d ? d->height : 0;
193 }
194
195 uchar *VBitmap::bits()
196 {
197     if (!d) return 0;
198     detach();
199
200     // In case detach ran out of memory...
201     if (!d) return 0;
202
203     return d->data;
204 }
205
206 const uchar *VBitmap::bits() const
207 {
208     return d ? d->data : 0;
209 }
210
211 bool VBitmap::isNull() const
212 {
213     return !d;
214 }
215
216 uchar *VBitmap::scanLine(int i)
217 {
218     if (!d) return 0;
219
220     detach();
221
222     // In case detach() ran out of memory
223     if (!d) return 0;
224
225     return d->data + i * d->stride;
226 }
227
228 const uchar *VBitmap::scanLine(int i) const
229 {
230     if (!d) return 0;
231
232     // assert(i >= 0 && i < height());
233     return d->data + i * d->stride;
234 }
235
236 VBitmap::Format VBitmap::format() const
237 {
238     if (!d) return VBitmap::Format::Invalid;
239     return d->format;
240 }
241
242 void VBitmap::fill(uint pixel)
243 {
244     if (!d) return;
245 }
246
247 V_END_NAMESPACE