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