// SPDX-License-Identifier: MIT // // EmulationStation Desktop Edition // ImageIO.cpp // // Image I/O functions. // #include "ImageIO.h" #include "Log.h" #include #include std::vector ImageIO::loadFromMemoryRGBA32(const unsigned char* data, const size_t size, size_t & width, size_t & height) { std::vector rawData; width = 0; height = 0; FIMEMORY * fiMemory = FreeImage_OpenMemory((BYTE *)data, (DWORD)size); if (fiMemory != nullptr) { // Detect the filetype from data. FREE_IMAGE_FORMAT format = FreeImage_GetFileTypeFromMemory(fiMemory); if (format != FIF_UNKNOWN && FreeImage_FIFSupportsReading(format)) { // File type is supported. load image, FIBITMAP * fiBitmap = FreeImage_LoadFromMemory(format, fiMemory); if (fiBitmap != nullptr) { // Loaded. convert to 32bit if necessary. if (FreeImage_GetBPP(fiBitmap) != 32) { FIBITMAP * fiConverted = FreeImage_ConvertTo32Bits(fiBitmap); if (fiConverted != nullptr) { //free original bitmap data FreeImage_Unload(fiBitmap); fiBitmap = fiConverted; } } if (fiBitmap != nullptr) { width = FreeImage_GetWidth(fiBitmap); height = FreeImage_GetHeight(fiBitmap); // Loop through scanlines and add all pixel data to the return vector. // This is necessary, because width*height*bpp might not be == pitch. unsigned char * tempData = new unsigned char[width * height * 4]; for (size_t i = 0; i < height; i++) { const BYTE * scanLine = FreeImage_GetScanLine(fiBitmap, static_cast(i)); memcpy(tempData + (i * width * 4), scanLine, width * 4); } // Convert from BGRA to RGBA. for (size_t i = 0; i < width*height; i++) { RGBQUAD bgra = reinterpret_cast(tempData)[i]; RGBQUAD rgba; rgba.rgbBlue = bgra.rgbRed; rgba.rgbGreen = bgra.rgbGreen; rgba.rgbRed = bgra.rgbBlue; rgba.rgbReserved = bgra.rgbReserved; reinterpret_cast(tempData)[i] = rgba; } rawData = std::vector(tempData, tempData + width * height * 4); // Free bitmap data. FreeImage_Unload(fiBitmap); delete[] tempData; } } else { LOG(LogError) << "Failed to load image from memory!"; } } else { LOG(LogError) << "Couldn't load image, file is missing or the file type is " << // it's not existing or the file type " << (format == FIF_UNKNOWN ? "unknown" : "unsupported") << "!"; } // Free fiMemory again FreeImage_CloseMemory(fiMemory); } return rawData; } void ImageIO::flipPixelsVert(unsigned char* imagePx, const size_t& width, const size_t& height) { unsigned int temp; unsigned int* arr = reinterpret_cast(imagePx); for (size_t y = 0; y < height / 2; y++) { for (size_t x = 0; x < width; x++) { temp = arr[x + (y * width)]; arr[x + (y * width)] = arr[x + (height * width) - ((y + 1) * width)]; arr[x + (height * width) - ((y + 1) * width)] = temp; } } }