bool readImage(SImage& image, MemChunk& data, int index) { // Get image info SImage::info_t info; FIBITMAP* bm = getFIInfo(data, info); // Check it created/read ok if (!bm) { Global::error = "Unable to read image data (unsupported format?)"; return false; } // Get image palette if it exists RGBQUAD* bm_pal = FreeImage_GetPalette(bm); Palette8bit palette; if (bm_pal) { int a = 0; int b = FreeImage_GetColorsUsed(bm); if (b > 256) b = 256; for (; a < b; a++) palette.setColour(a, rgba_t(bm_pal[a].rgbRed, bm_pal[a].rgbGreen, bm_pal[a].rgbBlue, 255)); } // Create image if (info.has_palette) image.create(info, &palette); else image.create(info); uint8_t* img_data = imageData(image); // Convert to 32bpp & flip vertically FIBITMAP* rgba = FreeImage_ConvertTo32Bits(bm); FreeImage_FlipVertical(rgba); // Load raw RGBA data uint8_t* bits_rgba = FreeImage_GetBits(rgba); int c = 0; for (int a = 0; a < info.width * info.height; a++) { img_data[c++] = bits_rgba[a * 4 + 2]; // Red img_data[c++] = bits_rgba[a * 4 + 1]; // Green img_data[c++] = bits_rgba[a * 4]; // Blue img_data[c++] = bits_rgba[a * 4 + 3]; // Alpha } // Free memory FreeImage_Unload(rgba); FreeImage_Unload(bm); return true; }
/* SImage::shrinkPalette * Shifts all the used colours to the beginning of the palette *******************************************************************/ void SImage::shrinkPalette(Palette8bit* pal) { // If the picture is not paletted, stop. if (type != PALMASK) return; // Get palette to use if (has_palette || !pal) pal = &palette; // Init variables Palette8bit newpal; bool* usedcolours = new bool[256]; int* remap = new int[256]; memset(usedcolours, 0, 256); size_t used = 0; // Count all color indices actually used on the picture for (int a = 0; a < width*height; ++a) { usedcolours[data[a]] = true; } // Create palette remapping information for (size_t b = 0; b < 256; ++b) { if (usedcolours[b]) { newpal.setColour(used, pal->colour(b)); remap[b] = used; ++used; } } // Remap image to new palette indices for (int c = 0; c < width*height; ++c) { data[c] = remap[data[c]]; } pal->copyPalette(&newpal); // Cleanup delete[] usedcolours; delete[] remap; }