Skip to content

Commit

Permalink
libgui|Image: Converting indexed image data to plain RGBA
Browse files Browse the repository at this point in the history
  • Loading branch information
skyjake committed Mar 30, 2016
1 parent c83216f commit f0185ee
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
20 changes: 20 additions & 0 deletions doomsday/sdk/libgui/include/de/graphics/image.h
Expand Up @@ -173,6 +173,26 @@ class LIBGUI_PUBLIC Image : public ISerializable
/// @copydoc fromData()
static Image fromData(Block const &data, String const &formatHint = "");

static Image fromIndexedData(Image::Size const &size, IByteArray const &image,
IByteArray const &palette);

/**
* Converts a color indexed 8-bit image to RGBA_8888.
*
* @param size Dimensions of the image.
* @param imageAndMask Image content. This is w*h 8-bit palette indices followed
* by w*h 8-bit alpha components, i.e., the alpha mask is
* stored as a separate layer following the indices.
* @param palette RGB palette containing 8-bit color triplets. The size of the
* palette must be big enough to contain all the color indices
* used in the image data.
*
* @return Image in RGBA_8888 format.
*/
static Image fromMaskedIndexedData(Image::Size const &size,
IByteArray const &imageAndMask,
IByteArray const &palette);

/**
* Attempts to recognize if a file contains a supported image content format.
* @param file File whose contents to recognize.
Expand Down
56 changes: 56 additions & 0 deletions doomsday/sdk/libgui/src/graphics/image.cpp
Expand Up @@ -803,6 +803,62 @@ Image Image::fromData(Block const &data, String const &formatHint)
return QImage::fromData(data).convertToFormat(QImage::Format_ARGB32);
}

Image Image::fromIndexedData(Size const &size, IByteArray const &image, IByteArray const &palette)
{
QImage rgba(size.x, size.y, QImage::Format_ARGB32);

// Process the source data by row.
Block color(size.x);
for(duint y = 0; y < size.y; ++y)
{
duint32 *dest = reinterpret_cast<duint32 *>(rgba.bits() + y * rgba.bytesPerLine());

image.get(size.x * y, color.data(), color.size());
auto const *srcColor = color.dataConst();

for(duint x = 0; x < size.x; ++x)
{
duint8 paletteColor[3];
palette.get(*srcColor++ * 3, paletteColor, 3);
*dest++ = qRgba(paletteColor[0], paletteColor[1], paletteColor[2], 255);
}
}

return rgba;
}

Image Image::fromMaskedIndexedData(Size const &size, IByteArray const &imageAndMask,
IByteArray const &palette)
{
duint const layerSize = size.x * size.y;

QImage rgba(size.x, size.y, QImage::Format_ARGB32);

// Process the source data by row.
Block color(size.x);
Block alpha(size.x);

for(duint y = 0; y < size.y; ++y)
{
duint32 *dest = reinterpret_cast<duint32 *>(rgba.bits() + y * rgba.bytesPerLine());

imageAndMask.get(size.x * y, color.data(), color.size());
imageAndMask.get(size.x * y + layerSize, alpha.data(), alpha.size());

auto const *srcColor = color.dataConst();
auto const *srcAlpha = color.dataConst();

for(duint x = 0; x < size.x; ++x)
{
duint8 paletteColor[3];
palette.get(*srcColor++ * 3, paletteColor, 3);
*dest++ = qRgba(paletteColor[0], paletteColor[1], paletteColor[2], *srcAlpha++);
}
}

return rgba;
}

bool Image::recognize(File const &file)
{
String const ext = file.name().fileNameExtension().toLower();
Expand Down

0 comments on commit f0185ee

Please sign in to comment.