Revert "[Tizen] Add codes for Dali Windows Backend"
[platform/core/uifw/dali-adaptor.git] / dali / internal / imaging / common / loader-wbmp.cpp
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
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
18 // HEADER
19 #include <dali/internal/imaging/common/loader-wbmp.h>
20
21 // EXTERNAL INCLUDES
22 #include <cstdio>
23 #include <cstdlib>
24 #include <cstring>
25
26 // INTERNAL INCLUDES
27 #include <dali/integration-api/debug.h>
28 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
29
30 namespace Dali
31 {
32
33 namespace TizenPlatform
34 {
35
36 namespace
37 {
38
39 #if defined(DEBUG_ENABLED)
40 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_LOADER_WBMP");
41 #endif
42
43 #define IMG_MAX_SIZE 65536
44
45 #define IMG_TOO_BIG(w, h) \
46         ((((unsigned long long)w) * ((unsigned long long)h)) >= \
47            ((1ULL << (29)) - 2048))
48
49
50 //extract multiple bytes integer , and saved in *data
51 int extractMultiByteInteger(unsigned int *data, void *map, size_t length, size_t *position)
52 {
53   // the header field contains an image type indentifier of multi-byte length(TypeField), an octet of general header info(FixHeaderField)
54   //,  a multi-byte width field(Width) and a multi-byte height field(Height) and so on.
55   // The actual organisation of the image data depends on the image type
56   // for Ext Headers flag (7th bit), 1 = More will follow, 0 = Last octet
57   // so in the for loop, if(buf & 0x80 == 0), loop will be exited
58   int targetMultiByteInteger = 0, readBufCount;
59   unsigned char buf;
60
61   for (readBufCount = 0;;)
62   {
63     // readBufCount means the count that fetched data from map
64     // extractMultiByteInteger() is to fetch wbmp type , width, and height
65     // for wbmp type, when readBufCount == 1, buf = 0x00, it will exit the loop
66     // for width, it have 4 bytes, so when readBufCount == 4, it must exit the loop
67     // for general width and height, if(buf & 0x80) == 0, then the next byte does not need to fetch again
68     // first step, readBufCount = 1 , read int(4 bytes) to buf, if buf & 0x80 !=0, the buf need to continue to fetch
69     // second step, readBufCount = 2, read next( 4 bytes) to buf, if buf & 0x80 == 0, then assigned the buf to target
70     if ((readBufCount ++) == 4)
71     {
72       return -1;
73     }
74     if (*position > length)
75     {
76       return -1;
77     }
78     buf = reinterpret_cast< unsigned char * >( map )[(*position)++];
79     targetMultiByteInteger = (targetMultiByteInteger << 7) | (buf & 0x7f);
80
81     if ((buf & 0x80) == 0)
82     {
83       DALI_LOG_INFO(gLogFilter, Debug::Verbose, "position: %d, readBufCount: %d\n", *position, readBufCount);
84       break;
85     }
86   }
87   *data = targetMultiByteInteger;
88   return 0;
89 }
90
91 }// end unnamed namespace
92
93 bool LoadBitmapFromWbmp( const Dali::ImageLoader::Input& input, Dali::Devel::PixelBuffer& bitmap )
94 {
95   FILE* const fp = input.file;
96   if(fp == NULL)
97   {
98     DALI_LOG_ERROR("Error loading bitmap\n");
99     return false;
100   }
101   Dali::Vector<unsigned char> map;
102   Dali::Vector<unsigned char> surface;//unsigned int
103   size_t position = 0;
104
105   unsigned int w, h;
106   unsigned int type;
107   unsigned int line_length;
108   unsigned char *line = NULL;
109   unsigned int cur = 0, x, y;
110
111   if( fseek(fp,0,SEEK_END) )
112   {
113     DALI_LOG_ERROR("Error seeking WBMP data\n");
114     return false;
115   }
116   long positionIndicator = ftell(fp);
117
118   unsigned int fsize( 0u );
119   if( positionIndicator > -1L )
120   {
121     fsize = static_cast<unsigned int>(positionIndicator);
122   }
123
124   if( 0u == fsize )
125   {
126     DALI_LOG_ERROR("Error: filesize is 0!\n");
127     return false;
128   }
129
130   if( fseek(fp, 0, SEEK_SET) )
131   {
132     DALI_LOG_ERROR("Error seeking WBMP data\n");
133     return false;
134   }
135   if(fsize <= 4)
136   {
137     DALI_LOG_ERROR("Error: WBMP Raw Data Not Found!\n");
138     return false;
139   }
140   if(fsize > 4096 * 4096 * 4)
141   {
142     DALI_LOG_ERROR("Error: WBMP size is too large!\n");
143     return false;
144   }
145   map.Resize(fsize);
146
147   if(fread(&map[0], 1, fsize, fp) != fsize)
148   {
149     DALI_LOG_WARNING("image file read opeation error!\n");
150     return false;
151   }
152
153   if (extractMultiByteInteger(&type, &map[0], fsize, &position) < 0)
154   {
155     return false;
156   }
157
158   position++; /* skipping one byte */
159
160   if (extractMultiByteInteger(&w, &map[0], fsize, &position) < 0)
161   {
162     return false;
163   }
164   if (extractMultiByteInteger(&h, &map[0], fsize, &position) < 0)
165   {
166     return false;
167   }
168   if(type != 0)
169   {
170     DALI_LOG_ERROR("Unknown Format!\n");
171     return false;
172   }
173
174   if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE))
175   {
176     return false;
177   }
178
179   surface.Resize(w* h );//(w * h * 4);
180   memset(&surface[0], 0, w * h ); // w * h * 4
181
182   line_length = (w + 7) >> 3;
183   for (y = 0; y < h; y ++)
184   {
185     if (position + line_length > fsize)
186     {
187       return false;
188     }
189     line = &map[0] + position;
190     position += line_length;
191     for (x = 0; x < w; x++)
192     {
193       int idx = x >> 3;
194       int offset = 1 << (0x07 - (x & 0x07));
195       if (line[idx] & offset)
196       {
197         surface[cur] = 0xff;//0xffffffff;
198       }
199       else
200       {
201         surface[cur] = 0x00;//0xff000000;
202       }
203       cur++;
204     }
205   }
206   auto pixels = (bitmap = Dali::Devel::PixelBuffer::New(w, h, Pixel::L8)).GetBuffer();
207
208   memcpy( pixels, &surface[0], w * h ); //w * h * 4
209
210   return true;
211 }
212
213
214 bool LoadWbmpHeader( const Dali::ImageLoader::Input& input, unsigned int& width, unsigned int& height )
215 {
216   FILE* const fp = input.file;
217   if(fp == NULL)
218   {
219     DALI_LOG_ERROR("Error loading bitmap\n");
220     return false;
221   }
222   Dali::Vector<unsigned char> map;
223   size_t position = 0;
224
225   unsigned int  w, h;
226   unsigned int type;
227   if( fseek(fp,0,SEEK_END) )
228   {
229     DALI_LOG_ERROR("Error seeking WBMP data\n");
230     return false;
231   }
232   long positionIndicator = ftell(fp);
233
234   unsigned int fsize( 0u );
235   if( positionIndicator > -1L )
236   {
237     fsize = static_cast<unsigned int>(positionIndicator);
238   }
239
240   if( 0u == fsize )
241   {
242     return false;
243   }
244
245   if( fseek(fp, 0, SEEK_SET) )
246   {
247     DALI_LOG_ERROR("Error seeking WBMP data\n");
248     return false;
249   }
250   if(fsize <= 4)
251   {
252     DALI_LOG_ERROR("Error: WBMP Raw Data Not Found!\n");
253     return false;
254   }
255
256   // type(1 byte) + fixedheader(1 byte) + width(uint) + height(uint)
257   unsigned int headerSize = 1 + 1 + 4 + 4;// 8 + 8 + 32 + 32;
258   headerSize = std::min(headerSize, fsize);
259
260   map.Resize(headerSize);
261   if(fread(&map[0], 1, headerSize, fp) != headerSize)
262   {
263     DALI_LOG_WARNING("image file read opeation error!\n");
264     return false;
265   }
266
267   if (extractMultiByteInteger(&type, &map[0], headerSize, &position) < 0)
268   {
269     DALI_LOG_ERROR("Error: unable to read type!\n");
270     return false;
271   }
272   position++; /* skipping one byte */
273   if(type != 0)
274   {
275     DALI_LOG_ERROR("Error: unknown format!\n");
276     return false;
277   }
278   if (extractMultiByteInteger(&w, &map[0], headerSize, &position) < 0)
279   {
280     DALI_LOG_ERROR("Error: can not read width!\n");
281     return false;
282   }
283   if (extractMultiByteInteger(&h, &map[0], headerSize, &position) < 0)
284   {
285     DALI_LOG_ERROR("Error: can not read height!\n");
286     return false;
287   }
288
289   if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) )
290   {
291     DALI_LOG_ERROR("Error: file size is not supported!\n");
292     return false;
293   }
294
295   width = w;
296   height = h;
297   return true;
298 }
299
300 }
301 }