2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/imaging/common/loader-wbmp.h>
27 #include <dali/integration-api/debug.h>
28 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
30 #include <dali/internal/system/common/file-closer.h>
32 using namespace Dali::Internal::Platform;
37 namespace TizenPlatform
43 #if defined(DEBUG_ENABLED)
44 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_LOADER_WBMP");
47 #define IMG_MAX_SIZE 65536
49 #define IMG_TOO_BIG(w, h) \
50 ((((unsigned long long)w) * ((unsigned long long)h)) >= \
51 ((1ULL << (29)) - 2048))
54 //extract multiple bytes integer , and saved in *data
55 int extractMultiByteInteger(unsigned int *data, void *map, size_t length, size_t *position)
57 // the header field contains an image type indentifier of multi-byte length(TypeField), an octet of general header info(FixHeaderField)
58 //, a multi-byte width field(Width) and a multi-byte height field(Height) and so on.
59 // The actual organisation of the image data depends on the image type
60 // for Ext Headers flag (7th bit), 1 = More will follow, 0 = Last octet
61 // so in the for loop, if(buf & 0x80 == 0), loop will be exited
62 int targetMultiByteInteger = 0, readBufCount;
65 for (readBufCount = 0;;)
67 // readBufCount means the count that fetched data from map
68 // extractMultiByteInteger() is to fetch wbmp type , width, and height
69 // for wbmp type, when readBufCount == 1, buf = 0x00, it will exit the loop
70 // for width, it have 4 bytes, so when readBufCount == 4, it must exit the loop
71 // for general width and height, if(buf & 0x80) == 0, then the next byte does not need to fetch again
72 // first step, readBufCount = 1 , read int(4 bytes) to buf, if buf & 0x80 !=0, the buf need to continue to fetch
73 // second step, readBufCount = 2, read next( 4 bytes) to buf, if buf & 0x80 == 0, then assigned the buf to target
74 if ((readBufCount ++) == 4)
78 if (*position > length)
82 buf = reinterpret_cast< unsigned char * >( map )[(*position)++];
83 targetMultiByteInteger = (targetMultiByteInteger << 7) | (buf & 0x7f);
85 if ((buf & 0x80) == 0)
87 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "position: %d, readBufCount: %d\n", *position, readBufCount);
91 *data = targetMultiByteInteger;
95 }// end unnamed namespace
97 bool LoadBitmapFromWbmp( const Dali::ImageLoader::Input& input, Dali::Devel::PixelBuffer& bitmap )
99 FILE* const fp = input.file;
102 DALI_LOG_ERROR("Error loading bitmap\n");
105 Dali::Vector<unsigned char> map;
106 Dali::Vector<unsigned char> surface;//unsigned int
111 unsigned int line_length;
112 unsigned char *line = NULL;
113 unsigned int cur = 0, x, y;
115 if( InternalFile::fseek(fp,0,SEEK_END) )
117 DALI_LOG_ERROR("Error seeking WBMP data\n");
120 long positionIndicator = InternalFile::ftell(fp);
122 unsigned int fsize( 0u );
123 if( positionIndicator > -1L )
125 fsize = static_cast<unsigned int>(positionIndicator);
130 DALI_LOG_ERROR("Error: filesize is 0!\n");
134 if( InternalFile::fseek(fp, 0, SEEK_SET) )
136 DALI_LOG_ERROR("Error seeking WBMP data\n");
141 DALI_LOG_ERROR("Error: WBMP Raw Data Not Found!\n");
144 if(fsize > 4096 * 4096 * 4)
146 DALI_LOG_ERROR("Error: WBMP size is too large!\n");
151 if( InternalFile::fread(&map[0], 1, fsize, fp) != fsize)
153 DALI_LOG_WARNING("image file read opeation error!\n");
157 if (extractMultiByteInteger(&type, &map[0], fsize, &position) < 0)
162 position++; /* skipping one byte */
164 if (extractMultiByteInteger(&w, &map[0], fsize, &position) < 0)
168 if (extractMultiByteInteger(&h, &map[0], fsize, &position) < 0)
174 DALI_LOG_ERROR("Unknown Format!\n");
178 if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE))
183 surface.Resize(w* h );//(w * h * 4);
184 memset(&surface[0], 0, w * h ); // w * h * 4
186 line_length = (w + 7) >> 3;
187 for (y = 0; y < h; y ++)
189 if (position + line_length > fsize)
193 line = &map[0] + position;
194 position += line_length;
195 for (x = 0; x < w; x++)
198 int offset = 1 << (0x07 - (x & 0x07));
199 if (line[idx] & offset)
201 surface[cur] = 0xff;//0xffffffff;
205 surface[cur] = 0x00;//0xff000000;
210 auto pixels = (bitmap = Dali::Devel::PixelBuffer::New(w, h, Pixel::L8)).GetBuffer();
212 memcpy( pixels, &surface[0], w * h ); //w * h * 4
218 bool LoadWbmpHeader( const Dali::ImageLoader::Input& input, unsigned int& width, unsigned int& height )
220 FILE* const fp = input.file;
223 DALI_LOG_ERROR("Error loading bitmap\n");
226 Dali::Vector<unsigned char> map;
231 if( InternalFile::fseek(fp,0,SEEK_END) )
233 DALI_LOG_ERROR("Error seeking WBMP data\n");
236 long positionIndicator = InternalFile::ftell(fp);
238 unsigned int fsize( 0u );
239 if( positionIndicator > -1L )
241 fsize = static_cast<unsigned int>(positionIndicator);
249 if( InternalFile::fseek(fp, 0, SEEK_SET) )
251 DALI_LOG_ERROR("Error seeking WBMP data\n");
256 DALI_LOG_ERROR("Error: WBMP Raw Data Not Found!\n");
260 // type(1 byte) + fixedheader(1 byte) + width(uint) + height(uint)
261 unsigned int headerSize = 1 + 1 + 4 + 4;// 8 + 8 + 32 + 32;
262 headerSize = std::min(headerSize, fsize);
264 map.Resize(headerSize);
265 if( InternalFile::fread(&map[0], 1, headerSize, fp) != headerSize)
267 DALI_LOG_WARNING("image file read opeation error!\n");
271 if (extractMultiByteInteger(&type, &map[0], headerSize, &position) < 0)
273 DALI_LOG_ERROR("Error: unable to read type!\n");
276 position++; /* skipping one byte */
279 DALI_LOG_ERROR("Error: unknown format!\n");
282 if (extractMultiByteInteger(&w, &map[0], headerSize, &position) < 0)
284 DALI_LOG_ERROR("Error: can not read width!\n");
287 if (extractMultiByteInteger(&h, &map[0], headerSize, &position) < 0)
289 DALI_LOG_ERROR("Error: can not read height!\n");
293 if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) )
295 DALI_LOG_ERROR("Error: file size is not supported!\n");