#include "IcoFormat.h" #include #include #include #include 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