2 * Copyright (c) 2022 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/devel-api/adaptor-framework/pixel-buffer.h>
28 #include <dali/integration-api/debug.h>
32 namespace TizenPlatform
36 #if defined(DEBUG_ENABLED)
37 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_LOADER_WBMP");
40 #define IMG_MAX_SIZE 65536
42 #define IMG_TOO_BIG(w, h) \
43 ((((unsigned long long)w) * ((unsigned long long)h)) >= \
44 ((1ULL << (29)) - 2048))
46 //extract multiple bytes integer , and saved in *data
47 int extractMultiByteInteger(unsigned int* data, void* map, size_t length, size_t* position)
49 // the header field contains an image type indentifier of multi-byte length(TypeField), an octet of general header info(FixHeaderField)
50 //, a multi-byte width field(Width) and a multi-byte height field(Height) and so on.
51 // The actual organisation of the image data depends on the image type
52 // for Ext Headers flag (7th bit), 1 = More will follow, 0 = Last octet
53 // so in the for loop, if(buf & 0x80 == 0), loop will be exited
54 int targetMultiByteInteger = 0, readBufCount;
57 for(readBufCount = 0;;)
59 // readBufCount means the count that fetched data from map
60 // extractMultiByteInteger() is to fetch wbmp type , width, and height
61 // for wbmp type, when readBufCount == 1, buf = 0x00, it will exit the loop
62 // for width, it have 4 bytes, so when readBufCount == 4, it must exit the loop
63 // for general width and height, if(buf & 0x80) == 0, then the next byte does not need to fetch again
64 // first step, readBufCount = 1 , read int(4 bytes) to buf, if buf & 0x80 !=0, the buf need to continue to fetch
65 // second step, readBufCount = 2, read next( 4 bytes) to buf, if buf & 0x80 == 0, then assigned the buf to target
66 if((readBufCount++) == 4)
70 if(*position > length)
74 buf = reinterpret_cast<unsigned char*>(map)[(*position)++];
75 targetMultiByteInteger = (targetMultiByteInteger << 7) | (buf & 0x7f);
79 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "position: %d, readBufCount: %d\n", *position, readBufCount);
83 *data = targetMultiByteInteger;
87 } // end unnamed namespace
89 bool LoadBitmapFromWbmp(const Dali::ImageLoader::Input& input, Dali::Devel::PixelBuffer& bitmap)
91 FILE* const fp = input.file;
94 DALI_LOG_ERROR("Error loading bitmap\n");
97 Dali::Vector<unsigned char> map;
98 Dali::Vector<unsigned char> surface; //unsigned int
103 unsigned int line_length;
104 unsigned char* line = NULL;
105 unsigned int cur = 0, x, y;
107 if(fseek(fp, 0, SEEK_END))
109 DALI_LOG_ERROR("Error seeking WBMP data\n");
112 long positionIndicator = ftell(fp);
114 unsigned int fsize(0u);
115 if(positionIndicator > -1L)
117 fsize = static_cast<unsigned int>(positionIndicator);
122 DALI_LOG_ERROR("Error: filesize is 0!\n");
126 if(fseek(fp, 0, SEEK_SET))
128 DALI_LOG_ERROR("Error seeking WBMP data\n");
133 DALI_LOG_ERROR("Error: WBMP Raw Data Not Found!\n");
136 if(fsize > 4096 * 4096 * 4)
138 DALI_LOG_ERROR("Error: WBMP size is too large!\n");
141 map.ResizeUninitialized(fsize);
143 if(fread(&map[0], 1, fsize, fp) != fsize)
145 DALI_LOG_WARNING("image file read opeation error!\n");
149 if(extractMultiByteInteger(&type, &map[0], fsize, &position) < 0)
154 position++; /* skipping one byte */
156 if(extractMultiByteInteger(&w, &map[0], fsize, &position) < 0)
160 if(extractMultiByteInteger(&h, &map[0], fsize, &position) < 0)
166 DALI_LOG_ERROR("Unknown Format!\n");
170 if((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE))
175 surface.ResizeUninitialized(w * h); //(w * h * 4);
176 memset(&surface[0], 0, w * h); // w * h * 4
178 line_length = (w + 7) >> 3;
179 for(y = 0; y < h; y++)
181 if(position + line_length > fsize)
185 line = &map[0] + position;
186 position += line_length;
187 for(x = 0; x < w; x++)
190 int offset = 1 << (0x07 - (x & 0x07));
191 if(line[idx] & offset)
193 surface[cur] = 0xff; //0xffffffff;
197 surface[cur] = 0x00; //0xff000000;
202 auto pixels = (bitmap = Dali::Devel::PixelBuffer::New(w, h, Pixel::L8)).GetBuffer();
204 memcpy(pixels, &surface[0], w * h); //w * h * 4
209 bool LoadWbmpHeader(const Dali::ImageLoader::Input& input, unsigned int& width, unsigned int& height)
211 FILE* const fp = input.file;
214 DALI_LOG_ERROR("Error loading bitmap\n");
217 Dali::Vector<unsigned char> map;
222 if(fseek(fp, 0, SEEK_END))
224 DALI_LOG_ERROR("Error seeking WBMP data\n");
227 long positionIndicator = ftell(fp);
229 unsigned int fsize(0u);
230 if(positionIndicator > -1L)
232 fsize = static_cast<unsigned int>(positionIndicator);
240 if(fseek(fp, 0, SEEK_SET))
242 DALI_LOG_ERROR("Error seeking WBMP data\n");
247 DALI_LOG_ERROR("Error: WBMP Raw Data Not Found!\n");
251 // type(1 byte) + fixedheader(1 byte) + width(uint) + height(uint)
252 unsigned int headerSize = 1 + 1 + 4 + 4; // 8 + 8 + 32 + 32;
253 headerSize = std::min(headerSize, fsize);
255 map.ResizeUninitialized(headerSize);
256 if(fread(&map[0], 1, headerSize, fp) != headerSize)
258 DALI_LOG_WARNING("image file read opeation error!\n");
262 if(extractMultiByteInteger(&type, &map[0], headerSize, &position) < 0)
264 DALI_LOG_ERROR("Error: unable to read type!\n");
267 position++; /* skipping one byte */
270 DALI_LOG_ERROR("Error: unknown format!\n");
273 if(extractMultiByteInteger(&w, &map[0], headerSize, &position) < 0)
275 DALI_LOG_ERROR("Error: can not read width!\n");
278 if(extractMultiByteInteger(&h, &map[0], headerSize, &position) < 0)
280 DALI_LOG_ERROR("Error: can not read height!\n");
284 if((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE))
286 DALI_LOG_ERROR("Error: file size is not supported!\n");
295 } // namespace TizenPlatform