1
0
Fork 0
spectre/source/Graphics/Image/IcoFormat.cpp
2020-10-21 12:59:55 +02:00

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