89 lines
2 KiB
C++
89 lines
2 KiB
C++
|
|
#include "IcoFormat.h"
|
|
#include <Spectre/System/ByteOrder.h>
|
|
#include <Spectre/Graphics/Image.h>
|
|
#include <Spectre/System/Log.h>
|
|
#include <cstdint>
|
|
|
|
namespace sp {
|
|
namespace image {
|
|
|
|
struct ICONDIRENT {
|
|
uint8_t width; // pos 0
|
|
uint8_t height; // pos 1
|
|
uint8_t num_colors; // pos 2
|
|
uint16_t color_planes; // pos 4
|
|
uint16_t bpp; // pos 6
|
|
uint32_t size; // pos 8
|
|
uint32_t offset; // pos 12
|
|
};
|
|
|
|
struct ICONDIR {
|
|
uint16_t reseved;
|
|
uint16_t type;
|
|
uint16_t num_images;
|
|
};
|
|
|
|
struct ICONDIRENT* findLargestImage(struct ICONDIRENT *ent, unsigned short size) {
|
|
|
|
int cur_index = 0;
|
|
unsigned int cur_size = 0;
|
|
|
|
for (int i = 0; i < size; i++) {
|
|
unsigned int sz = ent[i].width * ent[i].height;
|
|
if (sz > cur_size) {
|
|
cur_size = sz;
|
|
cur_index = i;
|
|
}
|
|
}
|
|
|
|
return ent + cur_index;
|
|
}
|
|
|
|
bool IcoFormat::decode(Image& img, const unsigned char *data, unsigned size)
|
|
{
|
|
struct ICONDIRENT *ent;
|
|
struct ICONDIRENT *largest;
|
|
unsigned short type; // pos 2
|
|
unsigned short num_images; // pos 4
|
|
|
|
type = data[2] + data[3];
|
|
num_images = data[4] + data[5];
|
|
|
|
// 1 = ICO, 2 = CUR
|
|
if (type != 0x0001 || num_images < 1) {
|
|
return false;
|
|
}
|
|
|
|
// Allocate ICONDIRENT for all images in the file.
|
|
ent = (struct ICONDIRENT *) malloc(sizeof(struct ICONDIRENT) * num_images);
|
|
if (!ent) {
|
|
return false;
|
|
}
|
|
|
|
for (int i = 0; i < num_images; i++) {
|
|
unsigned int pos = 6 + (i*16);
|
|
ent[i].width = data[pos + 0];
|
|
ent[i].height = data[pos + 1];
|
|
ent[i].num_colors = data[pos + 2];
|
|
ent[i].color_planes = data[pos + 4];
|
|
ent[i].bpp = data[pos + 6];
|
|
ent[i].size = system::ltoh16(data + pos + 8);
|
|
ent[i].offset = system::ltoh16(data + pos + 12);
|
|
}
|
|
|
|
// Find Largest image
|
|
largest = findLargestImage(ent, num_images);
|
|
|
|
sp::Log::info("%i, %i, %i, %i", largest->num_colors, largest->height, largest->offset, largest->size);
|
|
sp::Log::info("%i", largest->bpp);
|
|
|
|
|
|
img.loadFromMemory(data + largest->offset, largest->size);
|
|
//img.create(PF_RGBA, largest->width, largest->height, data + largest->offset);
|
|
|
|
free(ent);
|
|
return true;
|
|
}
|
|
|
|
}} // namespace sp::image
|