source/Graphics/Image/IcoFormat.cpp: use new PixelFormat. source/Graphics/Image.cpp: update to confirm with new PixelFormat Spectre/Graphics/PixelFormat: add PF_getNumChannels() Spectre/Graphics/PixelFormat: Rework the enum with proper naming convention and documentation.
76 lines
1.6 KiB
C++
76 lines
1.6 KiB
C++
|
|
#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_BGRA;
|
|
} else {
|
|
format = PixelFormat::PF_BGR;
|
|
}
|
|
|
|
// 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
|