add colortable param to newrastercopy
authorreed <reed@chromium.org>
Sat, 4 Jul 2015 04:01:10 +0000 (21:01 -0700)
committerCommit bot <commit-bot@chromium.org>
Sat, 4 Jul 2015 04:01:10 +0000 (21:01 -0700)
BUG=skia:
TBR=
NOTREECHECKS=True

Review URL: https://codereview.chromium.org/1222683004

include/core/SkImage.h
src/image/SkImagePriv.h
src/image/SkImage_Raster.cpp
tests/ImageTest.cpp

index 28b1803..7557e8e 100644 (file)
@@ -17,6 +17,7 @@
 
 class SkData;
 class SkCanvas;
+class SkColorTable;
 class SkImageGenerator;
 class SkPaint;
 class SkString;
@@ -44,7 +45,8 @@ public:
     typedef SkImageInfo Info;
     typedef void* ReleaseContext;
 
-    static SkImage* NewRasterCopy(const Info&, const void* pixels, size_t rowBytes);
+    static SkImage* NewRasterCopy(const Info&, const void* pixels, size_t rowBytes,
+                                  SkColorTable* ctable = NULL);
     static SkImage* NewRasterData(const Info&, SkData* pixels, size_t rowBytes);
 
     typedef void (*RasterReleaseProc)(const void* pixels, ReleaseContext);
index 3a5c59a..d3b1c79 100644 (file)
@@ -30,7 +30,11 @@ extern SkImage* SkNewImageFromPixelRef(const SkImageInfo&, SkPixelRef*,
 extern SkImage* SkNewImageFromBitmap(const SkBitmap&, bool canSharePixelRef, const SkSurfaceProps*);
 
 static inline size_t SkImageMinRowBytes(const SkImageInfo& info) {
-    return SkAlign4(info.minRowBytes());
+    size_t minRB = info.minRowBytes();
+    if (kIndex_8_SkColorType != info.colorType()) {
+        minRB = SkAlign4(minRB);
+    }
+    return minRB;
 }
 
 // Given an image created from SkNewImageFromBitmap, return its pixelref. This
index ab37659..0316d53 100644 (file)
@@ -8,6 +8,7 @@
 #include "SkImage_Base.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
+#include "SkColorTable.h"
 #include "SkData.h"
 #include "SkImageGeneratorPriv.h"
 #include "SkImagePriv.h"
@@ -16,7 +17,8 @@
 
 class SkImage_Raster : public SkImage_Base {
 public:
-    static bool ValidArgs(const Info& info, size_t rowBytes, size_t* minSize) {
+    static bool ValidArgs(const Info& info, size_t rowBytes, SkColorTable* ctable,
+                          size_t* minSize) {
         const int maxDimension = SK_MaxS32 >> 2;
 
         if (info.width() <= 0 || info.height() <= 0) {
@@ -36,7 +38,11 @@ public:
             return false;
         }
 
-        // TODO: check colorspace
+        const bool needsCT = kIndex_8_SkColorType == info.colorType();
+        const bool hasCT = NULL != ctable;
+        if (needsCT != hasCT) {
+            return false;
+        }
 
         if (rowBytes < SkImageMinRowBytes(info)) {
             return false;
@@ -53,7 +59,7 @@ public:
         return true;
     }
 
-    SkImage_Raster(const SkImageInfo&, SkData*, size_t rb, const SkSurfaceProps*);
+    SkImage_Raster(const SkImageInfo&, SkData*, size_t rb, SkColorTable*, const SkSurfaceProps*);
     virtual ~SkImage_Raster();
 
     SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) const override;
@@ -94,12 +100,11 @@ static void release_data(void* addr, void* context) {
 }
 
 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes,
-                               const SkSurfaceProps* props)
+                               SkColorTable* ctable, const SkSurfaceProps* props)
     : INHERITED(info.width(), info.height(), props)
 {
     data->ref();
     void* addr = const_cast<void*>(data->data());
-    SkColorTable* ctable = NULL;
 
     fBitmap.installPixels(info, addr, rowBytes, ctable, release_data, data);
     fBitmap.setImmutable();
@@ -161,21 +166,22 @@ bool SkImage_Raster::getROPixels(SkBitmap* dst) const {
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) {
+SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes,
+                                SkColorTable* ctable) {
     size_t size;
-    if (!SkImage_Raster::ValidArgs(info, rowBytes, &size) || !pixels) {
+    if (!SkImage_Raster::ValidArgs(info, rowBytes, ctable, &size) || !pixels) {
         return NULL;
     }
 
     // Here we actually make a copy of the caller's pixel data
     SkAutoDataUnref data(SkData::NewWithCopy(pixels, size));
-    return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, NULL));
+    return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, ctable, NULL));
 }
 
 
 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t rowBytes) {
     size_t size;
-    if (!SkImage_Raster::ValidArgs(info, rowBytes, &size) || !data) {
+    if (!SkImage_Raster::ValidArgs(info, rowBytes, NULL, &size) || !data) {
         return NULL;
     }
 
@@ -184,18 +190,20 @@ SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t ro
         return NULL;
     }
 
-    return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, NULL));
+    SkColorTable* ctable = NULL;
+    return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, ctable, NULL));
 }
 
 SkImage* SkImage::NewFromRaster(const SkImageInfo& info, const void* pixels, size_t rowBytes,
                                 RasterReleaseProc proc, ReleaseContext ctx) {
     size_t size;
-    if (!SkImage_Raster::ValidArgs(info, rowBytes, &size) || !pixels) {
+    if (!SkImage_Raster::ValidArgs(info, rowBytes, NULL, &size) || !pixels) {
         return NULL;
     }
 
+    SkColorTable* ctable = NULL;
     SkAutoDataUnref data(SkData::NewWithProc(pixels, size, proc, ctx));
-    return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, NULL));
+    return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, ctable, NULL));
 }
 
 SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator, const SkIRect* subset) {
@@ -213,7 +221,7 @@ SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator, const SkIRect* s
 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
                                 const SkIPoint& pixelRefOrigin, size_t rowBytes,
                                 const SkSurfaceProps* props) {
-    if (!SkImage_Raster::ValidArgs(info, rowBytes, NULL)) {
+    if (!SkImage_Raster::ValidArgs(info, rowBytes, NULL, NULL)) {
         return NULL;
     }
     return SkNEW_ARGS(SkImage_Raster, (info, pr, pixelRefOrigin, rowBytes, props));
@@ -221,7 +229,7 @@ SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
 
 SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef,
                               const SkSurfaceProps* props) {
-    if (!SkImage_Raster::ValidArgs(bm.info(), bm.rowBytes(), NULL)) {
+    if (!SkImage_Raster::ValidArgs(bm.info(), bm.rowBytes(), NULL, NULL)) {
         return NULL;
     }
 
index b196ca8..eb8f761 100644 (file)
@@ -103,3 +103,30 @@ DEF_GPUTEST(Image_Encode_Gpu, reporter, factory) {
     test_encode(reporter, ctx);
 }
 #endif
+
+DEF_TEST(Image_NewRasterCopy, reporter) {
+    const SkPMColor red =   SkPackARGB32(0xFF, 0xFF, 0, 0);
+    const SkPMColor green = SkPackARGB32(0xFF, 0, 0xFF, 0);
+    const SkPMColor blue =  SkPackARGB32(0xFF, 0, 0, 0xFF);
+    SkPMColor colors[] = { red, green, blue, 0 };
+    SkAutoTUnref<SkColorTable> ctable(SkNEW_ARGS(SkColorTable, (colors, SK_ARRAY_COUNT(colors))));
+    // The colortable made a copy, so we can trash the original colors
+    memset(colors, 0xFF, sizeof(colors));
+
+    const SkImageInfo srcInfo = SkImageInfo::Make(2, 2, kIndex_8_SkColorType, kPremul_SkAlphaType);
+    const size_t srcRowBytes = 2 * sizeof(uint8_t);
+    uint8_t indices[] = { 0, 1, 2, 3 };
+    SkAutoTUnref<SkImage> image(SkImage::NewRasterCopy(srcInfo, indices, srcRowBytes, ctable));
+    // The image made a copy, so we can trash the original indices
+    memset(indices, 0xFF, sizeof(indices));
+
+    const SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(2, 2);
+    const size_t dstRowBytes = 2 * sizeof(SkPMColor);
+    SkPMColor pixels[4];
+    memset(pixels, 0xFF, sizeof(pixels));   // init with values we don't expect
+    image->readPixels(dstInfo, pixels, dstRowBytes, 0, 0);
+    REPORTER_ASSERT(reporter, red == pixels[0]);
+    REPORTER_ASSERT(reporter, green == pixels[1]);
+    REPORTER_ASSERT(reporter, blue == pixels[2]);
+    REPORTER_ASSERT(reporter, 0 == pixels[3]);
+}