1
0
Fork 0

Adding source/Graphics/Image/IcoFormat

This commit is contained in:
Henrik Hautakoski 2020-10-22 17:07:42 +02:00
parent b78531a570
commit 37d495fca3
3 changed files with 96 additions and 0 deletions

View file

@ -99,6 +99,7 @@ local graphics_module = Module("source/Graphics", {
-- Image
"Image.cpp",
"ImageLoader.cpp",
"Image/IcoFormat.cpp",
"OpenGL.cpp",
"GL/glad.c",

View 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

View file

@ -0,0 +1,19 @@
#ifndef SPECTRE_GRAPHICS_IMAGE_ICOFORMAT_H
#define SPECTRE_GRAPHICS_IMAGE_ICOFORMAT_H
#include <Spectre/Graphics/Image.h>
namespace sp {
namespace image {
class IcoFormat
{
public :
bool decode(Image& img, const unsigned char *data, unsigned size);
};
}} // namespace sp::image
#endif /* SPECTRE_GRAPHICS_IMAGE_ICOFORMAT_H */