| 366 | } |
| 367 | |
| 368 | std::shared_ptr<U8[]> parseIcon(BReadFile& f, IconInfo& info, int* width, int* height) { |
| 369 | U32 palette[256]; |
| 370 | f.setPos(info.fileOffset+sizeof(BitmapInfoHeader)); |
| 371 | readPalette(info.bih, f, palette); |
| 372 | info.bih.biHeight/=2; |
| 373 | std::shared_ptr<U8[]> color = loadData(info.bih, f); |
| 374 | U8* pColor = color.get(); |
| 375 | int bpp = info.bih.biBitCount; |
| 376 | info.bih.biBitCount = 1; |
| 377 | std::shared_ptr<U8[]> maskData = loadData(info.bih, f); |
| 378 | U8* pMaskData = maskData.get(); |
| 379 | |
| 380 | if (bpp==32) { |
| 381 | swapRGB(color.get(), info.bih.biWidth, info.bih.biHeight); |
| 382 | *width = info.bih.biWidth; |
| 383 | *height = info.bih.biHeight; |
| 384 | return color; |
| 385 | } else if (bpp==4) { |
| 386 | int maskStride = (info.bih.biWidth + 31) / 32 * 4; |
| 387 | *width = info.bih.biWidth; |
| 388 | *height = info.bih.biHeight; |
| 389 | std::shared_ptr<U8[]> result = std::make_shared<U8[]>(info.bih.biWidth * info.bih.biHeight * 4); |
| 390 | U8* pResult = result.get(); |
| 391 | for (int y=0;y<info.bih.biHeight;y++) { |
| 392 | for (int x=0;x<info.bih.biWidth;x++) { |
| 393 | int maskIndex = y * maskStride + x / 8; |
| 394 | int index = y*info.bih.biWidth*4+x*4; |
| 395 | U32 byteIndex = y*info.bih.biWidth+x; |
| 396 | U8 paletteIndex = pColor[byteIndex/2]; |
| 397 | if (byteIndex & 1) { |
| 398 | paletteIndex = paletteIndex & 0xF; |
| 399 | } else { |
| 400 | paletteIndex = (paletteIndex >> 4) & 0xF; |
| 401 | } |
| 402 | U32 c = palette[paletteIndex]; |
| 403 | pResult[index+2] = c & 0xFF; |
| 404 | pResult[index+1] = (c >> 8) & 0xFF; |
| 405 | pResult[index] = (c >> 16) & 0xFF; |
| 406 | if (pMaskData[maskIndex] & (1 << (7-(x % 8)))) { |
| 407 | pResult[index+3] = 0; |
| 408 | } else { |
| 409 | pResult[index+3] = 0xFF; |
| 410 | } |
| 411 | } |
| 412 | } |
| 413 | return result; |
| 414 | } else if (bpp==8) { |
| 415 | int maskStride = (info.bih.biWidth + 31) / 32 * 4; |
| 416 | *width = info.bih.biWidth; |
| 417 | *height = info.bih.biHeight; |
| 418 | std::shared_ptr<U8[]> result = std::make_shared<U8[]>(info.bih.biWidth * info.bih.biHeight * 4); |
| 419 | U8* pResult = result.get(); |
| 420 | for (int y=0;y<info.bih.biHeight;y++) { |
| 421 | for (int x=0;x<info.bih.biWidth;x++) { |
| 422 | int maskIndex = y * maskStride + x / 8; |
| 423 | int index = y*info.bih.biWidth*4+x*4; // index into 32-bit result |
| 424 | int byteIndex = y*info.bih.biWidth+x; // index into icon |
| 425 | U32 c = palette[pColor[byteIndex]]; |
no test coverage detected