Bug 125944

Summary: on ppc, when zoom is < 100% green and red channels are interpreted as alpha
Product: [Applications] krita Reporter: Cyrille Berger <cberger>
Component: GeneralAssignee: Halla Rempt <halla>
Status: RESOLVED FIXED    
Severity: normal CC: madcoder
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: unspecified   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Cyrille Berger 2006-04-20 10:38:46 UTC
Version:           svn branch/1.5 (using KDE KDE 3.5.2)

This bug only happen with krita on a PowerPC. (I have only test with rgb). Load an image, zoom out to have a zoom level bellow 100% (for instance 66%), then the blue channel is correctly displayed, but red and green are interpreted as alpha.
Comment 1 Cyrille Berger 2006-05-25 12:43:26 UTC
*** Bug 127296 has been marked as a duplicate of this bug. ***
Comment 2 Cyrille Berger 2006-05-25 12:44:42 UTC
and while I am at it, for the lms colorspace, it's when zoom is > 100% that there is a problem.
Comment 3 Cyrille Berger 2006-06-02 18:51:07 UTC
SVN commit 547586 by berger:

fix: displaying on ppc
(warning not test yet on ppc, but I didn't broke anything on x86...)
CCBUG:125944


 M  +0 -7      colorspaces/lms_f32/kis_lms_f32_colorspace.cc  
 M  +0 -7      colorspaces/rgb_f16half/kis_rgb_f16half_colorspace.cc  
 M  +0 -7      colorspaces/rgb_f32/kis_rgb_f32_colorspace.cc  
 M  +15 -0     core/kis_image.cc  


--- branches/koffice/1.5/koffice/krita/colorspaces/lms_f32/kis_lms_f32_colorspace.cc #547585:547586
@@ -201,17 +201,10 @@
         double l = *( data + i + PIXEL_LONGWAVE );
         double m = *( data + i + PIXEL_MIDDLEWAVE );
         double s = *( data + i + PIXEL_SHORTWAVE );
-#ifdef __BIG_ENDIAN__
-        *( j + 0)  = FLOAT_TO_UINT8(*( data + i + PIXEL_ALPHA ));
-        *( j + 1 ) = computeRed(l,m,s);
-        *( j + 2 ) = computeGreen(l,m,s);
-        *( j + 3 ) = computeBlue(l,m,s);
-#else
         *( j + 3)  = FLOAT_TO_UINT8(*( data + i + PIXEL_ALPHA ));
         *( j + 2 ) = computeRed(l,m,s);
         *( j + 1 ) = computeGreen(l,m,s);
         *( j + 0 ) = computeBlue(l,m,s);
-#endif
         i += MAX_CHANNEL_LMSA;
         j += MAX_CHANNEL_LMSA;
     }
--- branches/koffice/1.5/koffice/krita/colorspaces/rgb_f16half/kis_rgb_f16half_colorspace.cc #547585:547586
@@ -280,17 +280,10 @@
     float exposureFactor = powf(2, exposure + 2.47393);
 
     while ( i < width * height * MAX_CHANNEL_RGBA) {
-#ifdef __BIG_ENDIAN__
-        *( j + 0)  = HALF_TO_UINT8(*( data + i + PIXEL_ALPHA ));
-        *( j + 1 ) = convertToDisplay(*( data + i + PIXEL_RED ), exposureFactor, gamma);
-        *( j + 2 ) = convertToDisplay(*( data + i + PIXEL_GREEN ), exposureFactor, gamma);
-        *( j + 3 ) = convertToDisplay(*( data + i + PIXEL_BLUE ), exposureFactor, gamma);
-#else
         *( j + 3)  = HALF_TO_UINT8(*( data + i + PIXEL_ALPHA ));
         *( j + 2 ) = convertToDisplay(*( data + i + PIXEL_RED ), exposureFactor, gamma);
         *( j + 1 ) = convertToDisplay(*( data + i + PIXEL_GREEN ), exposureFactor, gamma);
         *( j + 0 ) = convertToDisplay(*( data + i + PIXEL_BLUE ), exposureFactor, gamma);
-#endif
         i += MAX_CHANNEL_RGBA;
         j += MAX_CHANNEL_RGBA;
     }
--- branches/koffice/1.5/koffice/krita/colorspaces/rgb_f32/kis_rgb_f32_colorspace.cc #547585:547586
@@ -279,17 +279,10 @@
     float exposureFactor = powf(2, exposure + 2.47393);
 
     while ( i < width * height * MAX_CHANNEL_RGBA) {
-#ifdef __BIG_ENDIAN__
-        *( j + 0)  = FLOAT_TO_UINT8(*( data + i + PIXEL_ALPHA ));
-        *( j + 1 ) = convertToDisplay(*( data + i + PIXEL_RED ), exposureFactor, gamma);
-        *( j + 2 ) = convertToDisplay(*( data + i + PIXEL_GREEN ), exposureFactor, gamma);
-        *( j + 3 ) = convertToDisplay(*( data + i + PIXEL_BLUE ), exposureFactor, gamma);
-#else
         *( j + 3)  = FLOAT_TO_UINT8(*( data + i + PIXEL_ALPHA ));
         *( j + 2 ) = convertToDisplay(*( data + i + PIXEL_RED ), exposureFactor, gamma);
         *( j + 1 ) = convertToDisplay(*( data + i + PIXEL_GREEN ), exposureFactor, gamma);
         *( j + 0 ) = convertToDisplay(*( data + i + PIXEL_BLUE ), exposureFactor, gamma);
-#endif
         i += MAX_CHANNEL_RGBA;
         j += MAX_CHANNEL_RGBA;
     }
--- branches/koffice/1.5/koffice/krita/core/kis_image.cc #547585:547586
@@ -1463,6 +1463,21 @@
             m_activeLayer->paintMaskInactiveLayers(img, x1, y1, w, h);
         }
     }*/
+#ifdef __BIG_ENDIAN__
+    uchar * data = img.bits();
+    for (int i = 0; i < w * h; ++i) {
+        uchar r, g, b, a;
+        a = data[0];
+        b = data[1];
+        g = data[2];
+        r = data[3];
+        data[0] = r;
+        data[1] = g;
+        data[2] = b;
+        data[3] = a;
+        data += 4;
+    }
+#endif
 
     return image;
 }
Comment 4 Halla Rempt 2006-06-07 13:35:55 UTC
This fix should have been enough. Unfortunately, we are not able to test it. Anyone with a ppc machine who can confirm is welcome to re-open.
Comment 5 Cyrille Berger 2006-06-07 15:08:29 UTC
unfortunately it is not, isaac ask someone to test it, and it doesn't work, I hope to be able to build krita on mac os x soon, but it hangs strangely in linking kritacolor :(
Comment 6 Cyrille Berger 2006-06-14 21:26:33 UTC
I confirm, the fix is not enought, I have no idea what to do next to fix that :( the only progress is that lms and other float colorspaces have now the same behaviour. Either gdb was in a bad mood or KisImage::convertToQImage(...) is never called.
Comment 7 Halla Rempt 2006-06-15 09:30:53 UTC
The scaled version of convertToQImage (line 1393 ) is called from KisView, 
line 978: 

if (zoom() > 1.0 - EPSILON) {
...
	m_image->renderToPainter(wr.left(), wr.top(),
        	wr.right(), wr.bottom(), gc, monitorProfile(),
                paintFlags, HDRExposure());
} else {
...
	QImage image = m_image->convertToQImage(scaledImageRect, scaledImageSize,
        	monitorProfile(), paintFlags, HDRExposure());
...
}

renderToPainter calls the unscaled version of convertToQImage (line 1356).

Did you already commit the addition of the __BIG_ENDIAN__ block to the scaled 
verison of converToQImage?
Comment 8 Cyrille Berger 2006-06-15 09:43:55 UTC
yes in revision 547586
Comment 9 Halla Rempt 2006-06-15 09:54:56 UTC
Okay... I'll test it today, got a luminous idea: if I use ifndef instead of 
ifdef, I should get the ppc code on my x86, which means that all colours 
should be wrong, if everything is right :-)
Comment 10 Halla Rempt 2006-06-15 10:35:55 UTC
Curious if I test the channel-swapping code on x86, I do get channels swapped 
both when zoom < 100& and when zoom > 100%, so that's correct. I guess I'll 
have to dust off the old powerbook tonight to check there.
Comment 11 Cyrille Berger 2006-06-15 23:07:09 UTC
ok I did some additional test, I am close to have found the problem, but I don't why. After adding some debug, I see that when zoom > 100% img.hasAlphaBuffer() == true and zoom < 100% image.hasAlphaBuffer() == false, I do wonder if that's not part of the problem. But then I don't know why the alpha buffer isn't set when zoom < 100%
Comment 12 Halla Rempt 2006-06-15 23:17:47 UTC
Hm. Alpha is something we have to set explicitly in Qt3 on a QImage. I guess
we don't do that for zoom < 100%.
Comment 13 Cyrille Berger 2006-06-20 21:05:56 UTC
SVN commit 553334 by berger:

fix the ppc displaying

BUG:125944



 M  +17 -17    kis_image.cc  


--- branches/koffice/1.5/koffice/krita/core/kis_image.cc #553333:553334
@@ -1367,9 +1367,8 @@
     QImage img = dev->convertToQImage(profile, x1, y1, w, h, exposure);
 
     if (!img.isNull()) {
-
 #ifdef __BIG_ENDIAN__
-        uchar * data = img.bits();
+    uchar * data = img.bits();
         for (int i = 0; i < w * h; ++i) {
             uchar r, g, b, a;
             a = data[0];
@@ -1447,6 +1446,22 @@
     QImage image = colorSpace()->convertToQImage(scaledImageData, r.width(), r.height(), profile, INTENT_PERCEPTUAL, exposure);
     delete [] scaledImageData;
 
+#ifdef __BIG_ENDIAN__
+    uchar * data = image.bits();
+    for (int i = 0; i < image.width() * image.height(); ++i) {
+      uchar r, g, b, a;
+      a = data[0];
+      b = data[1];
+      g = data[2];
+      r = data[3];
+      data[0] = r;
+      data[1] = g;
+      data[2] = b;
+      data[3] = a;
+      data += 4;
+    }
+#endif
+    
     if (paintFlags & PAINT_BACKGROUND) {
         m_bkg->paintBackground(image, r, scaledImageSize, QSize(imageWidth, imageHeight));
         image.setAlphaBuffer(false);
@@ -1463,21 +1478,6 @@
             m_activeLayer->paintMaskInactiveLayers(img, x1, y1, w, h);
         }
     }*/
-#ifdef __BIG_ENDIAN__
-    uchar * data = image.bits();
-    for (int i = 0; i < image.width() * image.height(); ++i) {
-        uchar r, g, b, a;
-        a = data[0];
-        b = data[1];
-        g = data[2];
-        r = data[3];
-        data[0] = r;
-        data[1] = g;
-        data[2] = b;
-        data[3] = a;
-        data += 4;
-    }
-#endif
 
     return image;
 }