Cleanup issues related to SkBitmap getSize()/extractSubset().
authorwjmaclean@chromium.org <wjmaclean@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 22 Feb 2011 22:32:14 +0000 (22:32 +0000)
committerwjmaclean@chromium.org <wjmaclean@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 22 Feb 2011 22:32:14 +0000 (22:32 +0000)
Some minor revisions to do cleanup regarding getSize() and extractSubset(). All
are related to avoid read/write past end of the pixel buffer when getSize() is
used on a bitmap that is the result of a call to extractSubset().

git-svn-id: http://skia.googlecode.com/svn/trunk@835 2bbb7eff-a529-9590-31e7-b0007b416f81

src/core/SkBitmap.cpp
src/utils/win/SkOSWindow_Win.cpp

index 3e26639..a0ab52d 100644 (file)
@@ -1321,7 +1321,14 @@ void SkBitmap::flatten(SkFlattenableWriteBuffer& buffer) const {
         } else {
             buffer.write8(SERIALIZE_PIXELTYPE_RAW_NO_CTABLE);
         }
-        buffer.writePad(fPixels, this->getSize());
+        buffer.writePad(fPixels, this->getSafeSize());
+        // There is no writeZeroPad() fcn, so write individual bytes.
+        if (this->getSize() > this->getSafeSize()) {
+            size_t deltaSize = this->getSize() - this->getSafeSize();
+            // Need aligned pointer to write into due to internal implementa-
+            // tion of SkWriter32.
+            memset(buffer.reserve(SkAlign4(deltaSize)), 0, deltaSize);
+        }
     } else {
         buffer.write8(SERIALIZE_PIXELTYPE_NONE);
     }
@@ -1338,7 +1345,6 @@ void SkBitmap::unflatten(SkFlattenableReadBuffer& buffer) {
     this->setConfig((Config)config, width, height, rowBytes);
     this->setIsOpaque(buffer.readBool());
 
-    size_t size = this->getSize();
     int reftype = buffer.readU8();
     switch (reftype) {
         case SERIALIZE_PIXELTYPE_REF_PTR: {
@@ -1360,10 +1366,13 @@ void SkBitmap::unflatten(SkFlattenableReadBuffer& buffer) {
             if (SERIALIZE_PIXELTYPE_RAW_WITH_CTABLE == reftype) {
                 ctable = SkNEW_ARGS(SkColorTable, (buffer));
             }
+            size_t size = this->getSize();
             if (this->allocPixels(ctable)) {
                 this->lockPixels();
-                buffer.read(this->getPixels(), this->getSafeSize()); // Just read what we need.
-                buffer.skip(size - this->getSafeSize()); // Keep aligned for subsequent reads.
+                // Just read what we need.
+                buffer.read(this->getPixels(), this->getSafeSize());
+                // Keep aligned for subsequent reads.
+                buffer.skip(size - this->getSafeSize());
                 this->unlockPixels();
             } else {
                 buffer.skip(size); // Still skip the full-sized buffer though.
index d0e6cc3..3594c2f 100644 (file)
@@ -149,6 +149,12 @@ void SkOSWindow::doPaint(void* ctx) {
         // 
         // Do the SetDIBitsToDevice. 
         // 
+        // TODO(wjmaclean):
+        //       Fix this call to handle SkBitmaps that have rowBytes != width,
+        //       i.e. may have padding at the end of lines. The SkASSERT below
+        //       may be ignored by builds, and the only obviously safe option
+        //       seems to be to copy the bitmap to a temporary (contiguous)
+        //       buffer before passing to SetDIBitsToDevice().
         SkASSERT(bitmap.width() * bitmap.bytesPerPixel() == bitmap.rowBytes());
         bitmap.lockPixels();
         int iRet = SetDIBitsToDevice(hdc,