gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] [SCM] Gnash branch, master, updated. release_0_8_9_start-


From: Benjamin Wolsey
Subject: [Gnash-commit] [SCM] Gnash branch, master, updated. release_0_8_9_start-521-gcb87566
Date: Wed, 06 Apr 2011 08:56:25 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Gnash".

The branch, master has been updated
       via  cb87566f744bef7b77cc7cba89d68fa3ba6df510 (commit)
      from  4562bf163f3fe0538c11da7df6bc90120349909c (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit//commit/?id=cb87566f744bef7b77cc7cba89d68fa3ba6df510


commit cb87566f744bef7b77cc7cba89d68fa3ba6df510
Author: Benjamin Wolsey <address@hidden>
Date:   Wed Apr 6 10:17:23 2011 +0200

    Implement BitmapData.copyChannel(); tests pass.

diff --git a/libcore/asobj/flash/display/BitmapData_as.cpp 
b/libcore/asobj/flash/display/BitmapData_as.cpp
index b598d79..711ee7f 100644
--- a/libcore/asobj/flash/display/BitmapData_as.cpp
+++ b/libcore/asobj/flash/display/BitmapData_as.cpp
@@ -98,6 +98,15 @@ namespace {
     /// @param w    The width of the rectangle.
     /// @param h    The height of the rectangle.
     void adjustRect(int& x, int& y, int& w, int& h, BitmapData_as& b);
+
+    boost::uint32_t setChannel(boost::uint32_t targ, boost::uint8_t bitmask,
+            boost::uint8_t value);
+
+    boost::uint8_t getChannel(boost::uint32_t src, boost::uint8_t bitmask);
+
+    inline bool oneBitSet(boost::uint8_t mask) {
+        return mask == (mask & -mask);
+    }
 }
 
 BitmapData_as::BitmapData_as(as_object* owner,
@@ -399,11 +408,187 @@ as_value
 bitmapdata_copyChannel(const fn_call& fn)
 {
        BitmapData_as* ptr = ensure<ThisIsNative<BitmapData_as> >(fn);
-       UNUSED(ptr);
-       LOG_ONCE( log_unimpl (__FUNCTION__) );
+
+    if (ptr->disposed()) return as_value();
+
+    if (fn.nargs < 5) {
+        // log error
+        return as_value();
+    }
+
+    as_object* o = toObject(fn.arg(0), getVM(fn));
+    BitmapData_as* source;
+    if (!isNativeType(o, source) || source->disposed()) {
+        // First argument is not a BitmapData or is disposed.
+        return as_value();
+    }
+
+    as_object* rect = toObject(fn.arg(1), getVM(fn));
+    if (!rect) {
+        // Second argument is not an object
+        return as_value();
+    }
+
+    as_value x, y, w, h;
+    
+    rect->get_member(NSV::PROP_X, &x);
+    rect->get_member(NSV::PROP_Y, &y);
+    rect->get_member(NSV::PROP_WIDTH, &w);
+    rect->get_member(NSV::PROP_HEIGHT, &h);    
+    
+    as_object* destpoint = toObject(fn.arg(2), getVM(fn));
+    as_value px, py;
+    
+    destpoint->get_member(NSV::PROP_X, &px);
+    destpoint->get_member(NSV::PROP_Y, &py);
+
+    // TODO: check what should happen if the argument overflows or
+    // is negative (currently it is truncated and made positive.
+
+    // The source channel mask
+    const boost::uint8_t srcchans = 
+        std::abs(toInt(fn.arg(3), getVM(fn))) & 15;
+
+    // The destination channel mask
+    const boost::uint8_t destchans = 
+        std::abs(toInt(fn.arg(4), getVM(fn))) & 15;
+
+    // If more than one destination channel is specified,
+    // nothing happens.
+    if (!oneBitSet(destchans)) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror("BitmapData.copyChannel(). Multiple "
+                "destination channels are not supported");
+        );
+        return as_value();
+    }
+
+    const bool multiple = !oneBitSet(srcchans);
+
+    // Find true source rect and true dest rect.
+    int sourceX = toInt(x, getVM(fn));
+    int sourceY = toInt(y, getVM(fn));
+    int sourceW = toInt(w, getVM(fn));
+    int sourceH = toInt(h, getVM(fn));
+
+    int destX = toInt(px, getVM(fn));
+    int destY = toInt(py, getVM(fn));
+
+    // Any part of the source rect that is not in the image (i.e.
+    // above or left) is concatenated to the destination offset.
+    if (sourceX < 0) destX -= sourceX;
+    if (sourceY < 0) destY -= sourceY;
+
+    adjustRect(sourceX, sourceY, sourceW, sourceH, *source);
+    if (sourceW == 0 || sourceH == 0) {
+        // The source rect does not overlap with source bitmap
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror("BitmapData.copyChannel(): no part of source rectangle"
+                "overlaps with the source BitmapData");
+        );
+        return as_value();
+    }
+
+    // The dest width starts the same as the adjusted source width.
+    int destW = sourceW;
+    int destH = sourceH;
+
+    adjustRect(destX, destY, destW, destH, *ptr);
+    if (destW == 0 || destH == 0) {
+        // The target rect does not overlap with source bitmap
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror("BitmapData.copyPixels(): destination area is "
+                "wholly outside the destination BitmapData");
+        );
+        return as_value();
+    }
+
+    BitmapData_as::iterator targ = pixelAt(*ptr, destX, destY);
+    BitmapData_as::iterator src = pixelAt(*source, sourceX, sourceY);
+
+    // Just being careful...
+    assert(sourceX + destW <= static_cast<int>(source->width()));
+    assert(sourceY + destH <= static_cast<int>(source->height()));
+    assert(destX + destW <= static_cast<int>(ptr->width()));
+    assert(destY + destH <= static_cast<int>(ptr->height()));
+
+    // Copy for the width and height of the *dest* image.
+    // We have already ensured that the copied area
+    // is inside both bitmapdatas.
+    for (int i = 0; i < destH; ++i) {
+
+        BitmapData_as::iterator s = src;
+        BitmapData_as::iterator d = targ;
+        for (int j = 0; j < destW; ++j, ++s, ++d) {
+
+            // If multiple source channels, we set the destination channel
+            // to black. Else to the value of the requested channel.
+            const boost::uint8_t val = multiple ? 0 : getChannel(*s, srcchans);
+            *d = setChannel(*d, destchans, val);
+
+        }
+        targ += ptr->width();
+        src += source->width();
+    }
+
+    ptr->updateObjects();
+
        return as_value();
 }
 
+boost::uint8_t
+getChannel(boost::uint32_t src, boost::uint8_t bitmask)
+{
+    if (bitmask & 1) {
+        // Red
+        return (src >> 16) & 0xff;
+    }
+    if (bitmask & 2) {
+        // Green
+        return (src >> 8) & 0xff;
+    }
+    if (bitmask & 4) {
+        // Blue
+        return src & 0xff;
+    }
+    if (bitmask & 8) {
+        // Alpha
+        return src >> 24;
+    }
+    return 0;
+}
+
+boost::uint32_t
+setChannel(boost::uint32_t targ, boost::uint8_t bitmask, boost::uint8_t value)
+{
+    boost::uint32_t bytemask = 0;
+    boost::uint32_t valmask = 0;
+    if (bitmask & 1) {
+        // Red
+        bytemask = 0xff0000;
+        valmask = value << 16;
+    }
+    else if (bitmask & 2) {
+        // Green
+        bytemask = 0xff00;
+        valmask = value << 8;
+    }
+    else if (bitmask & 4) {
+        // Blue
+        bytemask = 0xff;
+        valmask = value;
+    }
+    else if (bitmask & 8) {
+        // Alpha
+        bytemask = 0xff000000;
+        valmask = value << 24;
+    }
+    targ &= ~bytemask;
+    targ |= valmask;
+    return targ;
+}
+
+
 // sourceBitmap: BitmapData,
 // sourceRect: Rectangle,
 // destPoint: Point,
@@ -495,9 +680,6 @@ bitmapdata_copyPixels(const fn_call& fn)
     BitmapData_as::iterator targ = pixelAt(*ptr, destX, destY);
     BitmapData_as::iterator src = pixelAt(*source, sourceX, sourceY);
 
-    log_debug("Source rect: %sx%s, w: %s, h: %s", sourceX, sourceY, destW, 
destH);
-    log_debug("Target rect: %sx%s, w: %s, h: %s", destX, destY, destW, destH);
-
     // Just being careful...
     assert(sourceX + destW <= static_cast<int>(source->width()));
     assert(sourceY + destH <= static_cast<int>(source->height()));
diff --git a/testsuite/actionscript.all/BitmapData.as 
b/testsuite/actionscript.all/BitmapData.as
index 8e60c68..84c0190 100644
--- a/testsuite/actionscript.all/BitmapData.as
+++ b/testsuite/actionscript.all/BitmapData.as
@@ -648,12 +648,13 @@ dest.copyPixels(source, new Rect(0, 0, 100, 100), new 
Point(200, 50));
 // This function seems to work as expected for single channel to single 
 // channel.
 // When the destination is a combination of channels, nothing happens. When
-// it is a single channel, it is set to 0!
+// it is a single channel and the source is a combination of channels, it
+// is set to 0!
 
 // Source:
 //    ---------------------
 //    |         |         |
-//    |   R     |    RG   |
+//    |   R     |    BG   |
 //    |         |         |
 //    |         |         |
 //    ---------------------
@@ -673,9 +674,9 @@ src.fillRect(new Rect(50, 50, 50, 50), 0xff007f00); // 
Green channel
 // Copy red channel to green channel
 dest = new flash.display.BitmapData(100, 100, true, 0xff000000);
 dest.copyChannel(src, new Rect(0, 0, 100, 100), new Point(0, 0), 1, 2);
- xcheck_equals(dest.getPixel(25, 25), 0x00ff00); // Green
+ check_equals(dest.getPixel(25, 25), 0x00ff00); // Was red, now green
  check_equals(dest.getPixel(75, 25), 0x000000); // Nothing
- xcheck_equals(dest.getPixel(25, 75), 0x00ff00); // Was red, now green
+ check_equals(dest.getPixel(25, 75), 0x00ff00); // Was red/blue, now green
  check_equals(dest.getPixel(75, 75), 0x000000); // Nothing
 
 // Copy red channel to green and blue channels
@@ -741,9 +742,9 @@ dest.copyChannel(src, new Rect(0, 0, 100, 100), new 
Point(0, 0), 2, 3);
 dest = new flash.display.BitmapData(100, 100, true, 0xff000000);
 dest.copyChannel(src, new Rect(0, 0, 100, 100), new Point(0, 0), 2, 4);
  check_equals(dest.getPixel(25, 25), 0x000000); // Nothing
- xcheck_equals(dest.getPixel(75, 25), 0x0000ff); // Blue
+ check_equals(dest.getPixel(75, 25), 0x0000ff); // Blue
  check_equals(dest.getPixel(25, 75), 0x000000); // Nothing
- xcheck_equals(dest.getPixel(75, 75), 0x00007f); // Half blue
+ check_equals(dest.getPixel(75, 75), 0x00007f); // Half blue
 
 // -------------------
 // Without alpha
@@ -766,10 +767,10 @@ dest.copyChannel(src, new Rect(0, 0, 100, 100), new 
Point(0, 0), 3, 3);
 // Copy red and green to red
 dest = new flash.display.BitmapData(100, 100, false);
 dest.copyChannel(src, new Rect(0, 0, 100, 100), new Point(0, 0), 3, 1);
- xcheck_equals(dest.getPixel(25, 25), 0x00ffff); // Cyan
- xcheck_equals(dest.getPixel(75, 25), 0x00ffff); // Cyan
- xcheck_equals(dest.getPixel(25, 75), 0x00ffff); // Cyan
- xcheck_equals(dest.getPixel(75, 75), 0x00ffff); // Cyan
+ check_equals(dest.getPixel(25, 25), 0x00ffff); // Cyan
+ check_equals(dest.getPixel(75, 25), 0x00ffff); // Cyan
+ check_equals(dest.getPixel(25, 75), 0x00ffff); // Cyan
+ check_equals(dest.getPixel(75, 75), 0x00ffff); // Cyan
 
 // Copy green to red and blue
 dest = new flash.display.BitmapData(100, 100, false);
@@ -782,18 +783,18 @@ dest.copyChannel(src, new Rect(0, 0, 100, 100), new 
Point(0, 0), 2, 5);
 // Copy red and blue to green
 dest = new flash.display.BitmapData(100, 100, false);
 dest.copyChannel(src, new Rect(0, 0, 100, 100), new Point(0, 0), 5, 2);
- xcheck_equals(dest.getPixel(25, 25), 0xff00ff); // White
- xcheck_equals(dest.getPixel(75, 25), 0xff00ff); // White
- xcheck_equals(dest.getPixel(25, 75), 0xff00ff); // White
- xcheck_equals(dest.getPixel(75, 75), 0xff00ff); // White
+ check_equals(dest.getPixel(25, 25), 0xff00ff); // Magenta
+ check_equals(dest.getPixel(75, 25), 0xff00ff); // Magenta
+ check_equals(dest.getPixel(25, 75), 0xff00ff); // Magenta
+ check_equals(dest.getPixel(75, 75), 0xff00ff); // Magenta
 
 // Copy green and blue to blue
 dest = new flash.display.BitmapData(100, 100, false);
 dest.copyChannel(src, new Rect(0, 0, 100, 100), new Point(0, 0), 6, 4);
- xcheck_equals(dest.getPixel(25, 25), 0xffff00); // Yellow
- xcheck_equals(dest.getPixel(75, 25), 0xffff00); // Yellow
- xcheck_equals(dest.getPixel(25, 75), 0xffff00); // Yellow
- xcheck_equals(dest.getPixel(75, 75), 0xffff00); // Yellow
+ check_equals(dest.getPixel(25, 25), 0xffff00); // Yellow
+ check_equals(dest.getPixel(75, 25), 0xffff00); // Yellow
+ check_equals(dest.getPixel(25, 75), 0xffff00); // Yellow
+ check_equals(dest.getPixel(75, 75), 0xffff00); // Yellow
 
 // clone();
 

-----------------------------------------------------------------------

Summary of changes:
 libcore/asobj/flash/display/BitmapData_as.cpp |  192 ++++++++++++++++++++++++-
 testsuite/actionscript.all/BitmapData.as      |   37 +++---
 2 files changed, 206 insertions(+), 23 deletions(-)


hooks/post-receive
-- 
Gnash



reply via email to

[Prev in Thread] Current Thread [Next in Thread]