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