[gimp] plug-ins: fix #6755 DDS RGB10A2 has Red and Blue swapped.



commit cad6273fed00cc30d2d1bac570d26c96210a96f1
Author: Jacob Boerema <jgboerema gmail com>
Date:   Fri Apr 23 14:26:35 2021 -0400

    plug-ins: fix #6755 DDS RGB10A2 has Red and Blue swapped.
    
    Looking at the documentation it is indeed red that should go
    in the lowest bits and blue in the highest bits so just
    reverse our code for red and blue.
    
    We also update the version of our GIMP DDS plug-in,
    this way we can catch and correct RGB10A2 images
    written by older versions of our plug-in and correct
    them.

 plug-ins/file-dds/color.h   |  4 ++--
 plug-ins/file-dds/dds.h     |  2 +-
 plug-ins/file-dds/ddsread.c | 23 ++++++++++++++++++++---
 3 files changed, 23 insertions(+), 6 deletions(-)
---
diff --git a/plug-ins/file-dds/color.h b/plug-ins/file-dds/color.h
index 699467773d..70bdb3a6e0 100644
--- a/plug-ins/file-dds/color.h
+++ b/plug-ins/file-dds/color.h
@@ -88,9 +88,9 @@ static inline unsigned int
 pack_rgb10a2 (int r, int g, int b, int a)
 {
   return ((unsigned int)((a >> 6) & 0x003) << 30) |
-         ((unsigned int)((r << 2) & 0x3ff) << 20) |
+         ((unsigned int)((b << 2) & 0x3ff) << 20) |
          ((unsigned int)((g << 2) & 0x3ff) << 10) |
-         ((unsigned int)((b << 2) & 0x3ff)      );
+         ((unsigned int)((r << 2) & 0x3ff)      );
 }
 
 #endif /* __COLOR_H__ */
diff --git a/plug-ins/file-dds/dds.h b/plug-ins/file-dds/dds.h
index 89bbe90890..6a0f909315 100644
--- a/plug-ins/file-dds/dds.h
+++ b/plug-ins/file-dds/dds.h
@@ -23,7 +23,7 @@
 
 #define DDS_PLUGIN_VERSION_MAJOR     3
 #define DDS_PLUGIN_VERSION_MINOR     9
-#define DDS_PLUGIN_VERSION_REVISION  91
+#define DDS_PLUGIN_VERSION_REVISION  92
 
 #define DDS_PLUGIN_VERSION \
    ((guint) (DDS_PLUGIN_VERSION_MAJOR << 16) | \
diff --git a/plug-ins/file-dds/ddsread.c b/plug-ins/file-dds/ddsread.c
index 1dad81ffed..2cd07d9d71 100644
--- a/plug-ins/file-dds/ddsread.c
+++ b/plug-ins/file-dds/ddsread.c
@@ -1073,6 +1073,23 @@ load_layer (FILE             *fp,
   if ((hdr->pixelfmt.flags & DDPF_RGB) ||
       (hdr->pixelfmt.flags & DDPF_ALPHA))
     {
+      guint ired  = 0;
+      guint iblue = 2;
+
+      if (hdr->reserved.gimp_dds_special.magic1 == FOURCC ('G','I','M','P') &&
+          hdr->reserved.gimp_dds_special.version <= 199003 &&
+          hdr->reserved.gimp_dds_special.version > 0 &&
+          d->bpp >= 3 && hdr->pixelfmt.amask == 0xc0000000)
+        {
+          /* GIMP dds plug-in versions before or equal to 199003 (3.9.91) wrote
+           * the red and green channels reversed for RGB10A2. We will fix that here.
+           */
+          g_printerr ("Switching incorrect red and green channels in RGB10A2 dds "
+                      "written by an older version of GIMP's dds plug-in.\n");
+          ired = 2;
+          iblue = 0;
+        }
+
       z = 0;
       for (y = 0, n = 0; y < height; ++y, ++n)
         {
@@ -1107,9 +1124,9 @@ load_layer (FILE             *fp,
                 {
                   if (hdr->pixelfmt.amask == 0xc0000000) /* handle RGB10A2 */
                     {
-                      pixels[pos + 0] = (pixel >> d->bshift) >> 2;
-                      pixels[pos + 1] = (pixel >> d->gshift) >> 2;
-                      pixels[pos + 2] = (pixel >> d->rshift) >> 2;
+                      pixels[pos + ired]  = (pixel >> d->rshift) >> 2;
+                      pixels[pos + 1]     = (pixel >> d->gshift) >> 2;
+                      pixels[pos + iblue] = (pixel >> d->bshift) >> 2;
                       if (hdr->pixelfmt.flags & DDPF_ALPHAPIXELS)
                         pixels[pos + 3] = (pixel >> d->ashift << (8 - d->abits) & d->amask) * 255 / d->amask;
                     }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]