Bug 948221 - Part 6: Make UnpremultiplyImageSurface work on surfaces that don't have matching strides. r=roc
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 12 Dec 2013 10:05:26 +1300
changeset 159965 524b83d6ff754eb32470cb6d5f812c42bcb43148
parent 159964 d4cceaf55796067ef26fe203e5854118d0f2852a
child 159966 491765fa039cb76a7a0433a72486a027e604945b
push id37468
push usermwoodrow@mozilla.com
push dateWed, 11 Dec 2013 21:06:07 +0000
treeherdermozilla-inbound@491765fa039c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs948221
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 948221 - Part 6: Make UnpremultiplyImageSurface work on surfaces that don't have matching strides. r=roc
gfx/thebes/gfxUtils.cpp
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -90,58 +90,57 @@ void
 gfxUtils::UnpremultiplyImageSurface(gfxImageSurface *aSourceSurface,
                                     gfxImageSurface *aDestSurface)
 {
     if (!aDestSurface)
         aDestSurface = aSourceSurface;
 
     MOZ_ASSERT(aSourceSurface->Format() == aDestSurface->Format() &&
                aSourceSurface->Width()  == aDestSurface->Width() &&
-               aSourceSurface->Height() == aDestSurface->Height() &&
-               aSourceSurface->Stride() == aDestSurface->Stride(),
+               aSourceSurface->Height() == aDestSurface->Height(),
                "Source and destination surfaces don't have identical characteristics");
 
-    MOZ_ASSERT(aSourceSurface->Stride() == aSourceSurface->Width() * 4,
-               "Source surface stride isn't tightly packed");
-
     // Only premultiply ARGB32
     if (aSourceSurface->Format() != gfxImageFormatARGB32) {
         if (aDestSurface != aSourceSurface) {
-            memcpy(aDestSurface->Data(), aSourceSurface->Data(),
-                   aSourceSurface->Stride() * aSourceSurface->Height());
+            aDestSurface->CopyFrom(aSourceSurface);
         }
         return;
     }
 
     uint8_t *src = aSourceSurface->Data();
     uint8_t *dst = aDestSurface->Data();
 
-    uint32_t dim = aSourceSurface->Width() * aSourceSurface->Height();
-    for (uint32_t i = 0; i < dim; ++i) {
+    for (int32_t i = 0; i < aSourceSurface->Height(); ++i) {
+        uint8_t *srcRow = src + (i * aSourceSurface->Stride());
+        uint8_t *dstRow = dst + (i * aDestSurface->Stride());
+
+        for (int32_t j = 0; j < aSourceSurface->Width(); ++j) {
 #ifdef IS_LITTLE_ENDIAN
-        uint8_t b = *src++;
-        uint8_t g = *src++;
-        uint8_t r = *src++;
-        uint8_t a = *src++;
+          uint8_t b = *srcRow++;
+          uint8_t g = *srcRow++;
+          uint8_t r = *srcRow++;
+          uint8_t a = *srcRow++;
 
-        *dst++ = UnpremultiplyValue(a, b);
-        *dst++ = UnpremultiplyValue(a, g);
-        *dst++ = UnpremultiplyValue(a, r);
-        *dst++ = a;
+          *dstRow++ = UnpremultiplyValue(a, b);
+          *dstRow++ = UnpremultiplyValue(a, g);
+          *dstRow++ = UnpremultiplyValue(a, r);
+          *dstRow++ = a;
 #else
-        uint8_t a = *src++;
-        uint8_t r = *src++;
-        uint8_t g = *src++;
-        uint8_t b = *src++;
+          uint8_t a = *srcRow++;
+          uint8_t r = *srcRow++;
+          uint8_t g = *srcRow++;
+          uint8_t b = *srcRow++;
 
-        *dst++ = a;
-        *dst++ = UnpremultiplyValue(a, r);
-        *dst++ = UnpremultiplyValue(a, g);
-        *dst++ = UnpremultiplyValue(a, b);
+          *dstRow++ = a;
+          *dstRow++ = UnpremultiplyValue(a, r);
+          *dstRow++ = UnpremultiplyValue(a, g);
+          *dstRow++ = UnpremultiplyValue(a, b);
 #endif
+        }
     }
 }
 
 void
 gfxUtils::ConvertBGRAtoRGBA(gfxImageSurface *aSourceSurface,
                             gfxImageSurface *aDestSurface) {
     if (!aDestSurface)
         aDestSurface = aSourceSurface;