Adding source/Graphics/Image/IcoFormat
This commit is contained in:
parent
b78531a570
commit
37d495fca3
3 changed files with 96 additions and 0 deletions
|
|
@ -99,6 +99,7 @@ local graphics_module = Module("source/Graphics", {
|
||||||
-- Image
|
-- Image
|
||||||
"Image.cpp",
|
"Image.cpp",
|
||||||
"ImageLoader.cpp",
|
"ImageLoader.cpp",
|
||||||
|
"Image/IcoFormat.cpp",
|
||||||
|
|
||||||
"OpenGL.cpp",
|
"OpenGL.cpp",
|
||||||
"GL/glad.c",
|
"GL/glad.c",
|
||||||
|
|
|
||||||
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
|
||||||
19
source/Graphics/Image/IcoFormat.h
Normal file
19
source/Graphics/Image/IcoFormat.h
Normal 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 */
|
||||||
Loading…
Add table
Add a link
Reference in a new issue