mirror of https://github.com/GNOME/gimp.git
plug-ins: fix #10240 DDS saved as RGB10A2 loads incorrectly
There were 2 issues here: 1. When more than 8 bits per sample are used, a previous commit changed it so that we would be using 16-bit integer mode instead of 8-bit. However, the actual code for this specific format was not updated to reflect that. We fix this by computing 16-bits per channel values and upshifting the 10 and 2-bit samples to 16 bit per channel. 2. The computation of masks was incorrect. It computed each channel mask separately, based on whether it was <= 8 or not. However, if any channel needs more than 8 bits, all masks should be computed 16 bits since we will then 16-bit integer mode. We fix this by checking all channel bits together, and if any is higher than 8, but not more than 16, we use 16-bit masks. I also took this opportunity to add support for 32-bit masks if we ever need those.
This commit is contained in:
parent
e3b2f40ac2
commit
74adec7656
|
@ -227,22 +227,31 @@ read_dds (GFile *file,
|
||||||
d.gbits = color_bits (hdr.pixelfmt.gmask);
|
d.gbits = color_bits (hdr.pixelfmt.gmask);
|
||||||
d.bbits = color_bits (hdr.pixelfmt.bmask);
|
d.bbits = color_bits (hdr.pixelfmt.bmask);
|
||||||
d.abits = color_bits (hdr.pixelfmt.amask);
|
d.abits = color_bits (hdr.pixelfmt.amask);
|
||||||
if (d.rbits <= 8)
|
|
||||||
d.rmask = (hdr.pixelfmt.rmask >> d.rshift) << (8 - d.rbits);
|
if (d.rbits <= 8 && d.gbits <= 8 && d.bbits <= 8 && d.abits <= 8)
|
||||||
|
{
|
||||||
|
/* 8 bits per sample */
|
||||||
|
d.rmask = (hdr.pixelfmt.rmask >> d.rshift) << (8 - d.rbits);
|
||||||
|
d.gmask = (hdr.pixelfmt.gmask >> d.gshift) << (8 - d.gbits);
|
||||||
|
d.bmask = (hdr.pixelfmt.bmask >> d.bshift) << (8 - d.bbits);
|
||||||
|
d.amask = (hdr.pixelfmt.amask >> d.ashift) << (8 - d.abits);
|
||||||
|
}
|
||||||
|
else if (d.rbits <= 16 && d.gbits <= 16 && d.bbits <= 16 && d.abits <= 16)
|
||||||
|
{
|
||||||
|
/* 16 bits per sample */
|
||||||
|
d.rmask = (hdr.pixelfmt.rmask >> d.rshift) << (16 - d.rbits);
|
||||||
|
d.gmask = (hdr.pixelfmt.gmask >> d.gshift) << (16 - d.gbits);
|
||||||
|
d.bmask = (hdr.pixelfmt.bmask >> d.bshift) << (16 - d.bbits);
|
||||||
|
d.amask = (hdr.pixelfmt.amask >> d.ashift) << (16 - d.abits);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
d.rmask = (hdr.pixelfmt.rmask >> d.rshift) << (16 - d.rbits);
|
{
|
||||||
if (d.gbits <= 8)
|
/* 32 bits per sample in case we need this in the future */
|
||||||
d.gmask = (hdr.pixelfmt.gmask >> d.gshift) << (8 - d.gbits);
|
d.rmask = (hdr.pixelfmt.rmask >> d.rshift) << (32 - d.rbits);
|
||||||
else
|
d.gmask = (hdr.pixelfmt.gmask >> d.gshift) << (32 - d.gbits);
|
||||||
d.gmask = (hdr.pixelfmt.gmask >> d.gshift) << (16 - d.gbits);
|
d.bmask = (hdr.pixelfmt.bmask >> d.bshift) << (32 - d.bbits);
|
||||||
if (d.bbits <= 8)
|
d.amask = (hdr.pixelfmt.amask >> d.ashift) << (32 - d.abits);
|
||||||
d.bmask = (hdr.pixelfmt.bmask >> d.bshift) << (8 - d.bbits);
|
}
|
||||||
else
|
|
||||||
d.bmask = (hdr.pixelfmt.bmask >> d.bshift) << (16 - d.bbits);
|
|
||||||
if (d.abits <= 8)
|
|
||||||
d.amask = (hdr.pixelfmt.amask >> d.ashift) << (8 - d.abits);
|
|
||||||
else
|
|
||||||
d.amask = (hdr.pixelfmt.amask >> d.ashift) << (16 - d.abits);
|
|
||||||
|
|
||||||
d.gimp_bps = 1; /* Most formats will be converted to 1 byte per sample */
|
d.gimp_bps = 1; /* Most formats will be converted to 1 byte per sample */
|
||||||
if (hdr.pixelfmt.flags & DDPF_FOURCC)
|
if (hdr.pixelfmt.flags & DDPF_FOURCC)
|
||||||
|
@ -1230,11 +1239,15 @@ load_layer (FILE *fp,
|
||||||
{
|
{
|
||||||
if (hdr->pixelfmt.amask == 0xc0000000) /* handle RGB10A2 */
|
if (hdr->pixelfmt.amask == 0xc0000000) /* handle RGB10A2 */
|
||||||
{
|
{
|
||||||
pixels[pos + ired] = (pixel >> d->rshift) >> 2;
|
guint16 *pixels16 = (guint16 *) &pixels[pos];
|
||||||
pixels[pos + 1] = (pixel >> d->gshift) >> 2;
|
|
||||||
pixels[pos + iblue] = (pixel >> d->bshift) >> 2;
|
pixels16[ired] = (guint16) (pixel >> d->rshift << (16 - d->rbits));
|
||||||
|
pixels16[1] = (guint16) (pixel >> d->gshift << (16 - d->gbits));
|
||||||
|
pixels16[iblue] = (guint16) (pixel >> d->bshift << (16 - d->bbits));
|
||||||
if (hdr->pixelfmt.flags & DDPF_ALPHAPIXELS)
|
if (hdr->pixelfmt.flags & DDPF_ALPHAPIXELS)
|
||||||
pixels[pos + 3] = (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask;
|
{
|
||||||
|
pixels16[3] = (guint16) ((pixel >> d->ashift << (16 - d->abits) & d->amask) * 65535 / d->amask);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (d->rmask > 0 && d->gmask > 0 && d->bmask > 0)
|
else if (d->rmask > 0 && d->gmask > 0 && d->bmask > 0)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue