ES-DE/es-core/src/ImageIO.cpp

94 lines
3.8 KiB
C++
Raw Normal View History

// SPDX-License-Identifier: MIT
//
// EmulationStation Desktop Edition
// ImageIO.cpp
//
// Image I/O functions.
//
#include "ImageIO.h"
#include "Log.h"
2017-11-01 22:21:10 +00:00
#include <FreeImage.h>
#include <string.h>
2020-09-04 17:05:48 +00:00
std::vector<unsigned char> ImageIO::loadFromMemoryRGBA32(const unsigned char* data,
const size_t size,
size_t& width,
size_t& height)
{
std::vector<unsigned char> rawData;
width = 0;
height = 0;
2022-01-16 17:18:28 +00:00
FIMEMORY* fiMemory {FreeImage_OpenMemory(const_cast<BYTE*>(data), static_cast<DWORD>(size))};
if (fiMemory != nullptr) {
// Detect the filetype from data.
2022-09-02 18:52:49 +00:00
FREE_IMAGE_FORMAT format {FreeImage_GetFileTypeFromMemory(fiMemory)};
if (format != FIF_UNKNOWN && FreeImage_FIFSupportsReading(format)) {
2021-01-15 17:47:01 +00:00
// File type is supported, load image.
2022-09-02 18:52:49 +00:00
FIBITMAP* fiBitmap {FreeImage_LoadFromMemory(format, fiMemory)};
if (fiBitmap != nullptr) {
2021-01-15 17:47:01 +00:00
// Loaded. convert to 32-bit if necessary.
if (FreeImage_GetBPP(fiBitmap) != 32) {
2022-09-02 18:52:49 +00:00
FIBITMAP* fiConverted {FreeImage_ConvertTo32Bits(fiBitmap)};
if (fiConverted != nullptr) {
2021-01-15 17:47:01 +00:00
// 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.
2022-09-02 18:52:49 +00:00
unsigned char* tempData {new unsigned char[width * height * 4]};
for (size_t i = 0; i < height; ++i) {
2022-09-02 18:52:49 +00:00
const BYTE* scanLine {FreeImage_GetScanLine(fiBitmap, static_cast<int>(i))};
memcpy(tempData + (i * width * 4), scanLine, width * 4);
}
// Convert from BGRA to RGBA.
for (size_t i = 0; i < width * height; ++i) {
2022-09-02 18:52:49 +00:00
RGBQUAD bgra {reinterpret_cast<RGBQUAD*>(tempData)[i]};
RGBQUAD rgba;
rgba.rgbBlue = bgra.rgbRed;
rgba.rgbGreen = bgra.rgbGreen;
rgba.rgbRed = bgra.rgbBlue;
rgba.rgbReserved = bgra.rgbReserved;
reinterpret_cast<RGBQUAD*>(tempData)[i] = rgba;
}
2022-09-02 18:52:49 +00:00
rawData = std::vector<unsigned char> {tempData, tempData + width * height * 4};
// Free bitmap data.
FreeImage_Unload(fiBitmap);
delete[] tempData;
}
}
else {
2021-01-15 17:47:01 +00:00
LOG(LogError) << "Failed to load image from memory";
}
}
else {
LOG(LogError) << "Couldn't load image, file is missing or the file type is "
<< (format == FIF_UNKNOWN ? "unknown" : "unsupported");
}
2021-01-15 17:47:01 +00:00
// 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;
2022-09-02 18:52:49 +00:00
unsigned int* arr {reinterpret_cast<unsigned int*>(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;
}
}
}