Adding source/Graphics/Image/IcoFormat
This commit is contained in:
parent
b78531a570
commit
37d495fca3
3 changed files with 96 additions and 0 deletions
76
source/Graphics/Image/IcoFormat.cpp
Normal file
76
source/Graphics/Image/IcoFormat.cpp
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
|
||||
#include "IcoFormat.h"
|
||||
#include <Spectre/System/ByteOrder.h>
|
||||
#include <Spectre/Graphics/Image.h>
|
||||
#include <Spectre/System/Log.h>
|
||||
|
||||
#include "Format/ico.h"
|
||||
|
||||
namespace sp {
|
||||
namespace image {
|
||||
|
||||
ICONDIRENTRY* findLargestImage(ICONDIRENTRY *ent, uint16_t size) {
|
||||
|
||||
uint32_t idx = 0, lgsz = 0, sz;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
sz = ent[i].width * ent[i].height;
|
||||
if (sz > lgsz) {
|
||||
lgsz = sz;
|
||||
idx = i;
|
||||
}
|
||||
}
|
||||
return ent + idx;
|
||||
}
|
||||
|
||||
bool IcoFormat::decode(Image& img, const unsigned char *data, unsigned size)
|
||||
{
|
||||
uint8_t *pixels;
|
||||
PixelFormat format;
|
||||
ICONDIRENTRY *ent;
|
||||
ICONDIRENTRY *largest;
|
||||
uint16_t type;
|
||||
uint16_t num_ent;
|
||||
|
||||
type = system::ltoh16(data + 2);
|
||||
num_ent = system::ltoh16(data + 4);
|
||||
|
||||
// Type: 1 = ICO, 2 = CUR
|
||||
if (type != 0x0001 || num_ent < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allocate ICONDIRENT for all images in the file.
|
||||
ent = (ICONDIRENTRY *) malloc(sizeof(ICONDIRENTRY) * num_ent);
|
||||
if (!ent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_ent; i++) {
|
||||
unsigned int p = 6 + (i * ICONDIRENTRY_SIZE);
|
||||
ent[i].width = data[p + 0];
|
||||
ent[i].height = data[p + 1];
|
||||
ent[i].num_colors = data[p + 2];
|
||||
ent[i].color_planes = data[p + 4];
|
||||
ent[i].bpp = data[p + 6];
|
||||
ent[i].size = system::ltoh32(data + p + 8);
|
||||
ent[i].offset = system::ltoh32(data + p + 12);
|
||||
}
|
||||
|
||||
// Find Largest image
|
||||
largest = findLargestImage(ent, num_ent);
|
||||
|
||||
if (largest->bpp == 32) {
|
||||
format = PixelFormat::PF_32BGRA;
|
||||
} else {
|
||||
format = PixelFormat::PF_32BGR;
|
||||
}
|
||||
|
||||
// NOTE: plus 40 bytes here to skip over the DIB header.
|
||||
img.create(largest->width, largest->height, data + largest->offset + 40, format);
|
||||
free(ent);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}} // namespace sp::image
|
||||
Loading…
Add table
Add a link
Reference in a new issue