Add new SkImageGenerator::getPixels() API, deprecate the old
authorMatt Sarett <msarett@google.com>
Fri, 12 May 2017 15:41:27 +0000 (11:41 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Fri, 12 May 2017 16:48:17 +0000 (16:48 +0000)
This is fairly aggressive in that it will break any client
that is currently using SkImageGenerator with kIndex8.
I'm guessing that we don't have any clients doing that.

Bug: skia:6620
Change-Id: Ifd16f5232bb3a9f759c225315c57492d917ed9ca
Reviewed-on: https://skia-review.googlesource.com/16601
Commit-Queue: Matt Sarett <msarett@google.com>
Reviewed-by: Mike Reed <reed@google.com>
16 files changed:
dm/DMSrcSink.cpp
gm/image_pict.cpp
gm/imagemasksubset.cpp
include/core/SkImageGenerator.h
public.bzl
src/codec/SkCodecImageGenerator.cpp
src/codec/SkCodecImageGenerator.h
src/core/SkImageGenerator.cpp
src/core/SkPictureImageGenerator.cpp
src/core/SkPictureImageGenerator.h
src/ports/SkImageGeneratorCG.cpp
src/ports/SkImageGeneratorCG.h
src/ports/SkImageGeneratorWIC.cpp
src/ports/SkImageGeneratorWIC.h
tests/CachedDecodingPixelRefTest.cpp
tools/Resources.cpp

index c169b23..4e3884e 100644 (file)
@@ -951,10 +951,7 @@ Error ImageGenSrc::draw(SkCanvas* canvas) const {
     int bpp = SkColorTypeBytesPerPixel(decodeInfo.colorType());
     size_t rowBytes = decodeInfo.width() * bpp;
     SkAutoMalloc pixels(decodeInfo.height() * rowBytes);
-    SkPMColor colorPtr[256];
-    int colorCount = 256;
-
-    if (!gen->getPixels(decodeInfo, pixels.get(), rowBytes, colorPtr, &colorCount)) {
+    if (!gen->getPixels(decodeInfo, pixels.get(), rowBytes)) {
         SkString err =
                 SkStringPrintf("Image generator could not getPixels() for %s\n", fPath.c_str());
 
@@ -968,6 +965,8 @@ Error ImageGenSrc::draw(SkCanvas* canvas) const {
         return err;
     }
 
+    SkPMColor colorPtr[256];
+    int colorCount = 256;
     draw_to_canvas(canvas, decodeInfo, pixels.get(), rowBytes, colorPtr, colorCount,
                    CodecSrc::kGetFromCanvas_DstColorType);
     return "";
index 16ee896..fa4c726 100644 (file)
@@ -124,30 +124,10 @@ public:
 
 protected:
     bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
-                     SkPMColor* ctable, int* ctableCount) override {
+                     const Options&) override {
         SkASSERT(fBM.width() == info.width());
         SkASSERT(fBM.height() == info.height());
-
-        if (info.colorType() == kIndex_8_SkColorType) {
-            if (SkColorTable* ct = fBM.getColorTable()) {
-                if (ctable) {
-                    memcpy(ctable, ct->readColors(), ct->count() * sizeof(SkPMColor));
-                }
-                if (ctableCount) {
-                    *ctableCount = ct->count();
-                }
-
-                for (int y = 0; y < info.height(); ++y) {
-                    memcpy(pixels, fBM.getAddr8(0, y), fBM.width());
-                    pixels = (char*)pixels + rowBytes;
-                }
-                return true;
-            } else {
-                return false;
-            }
-        } else {
-            return fBM.readPixels(info, pixels, rowBytes, 0, 0);
-        }
+        return fBM.readPixels(info, pixels, rowBytes, 0, 0);
     }
 private:
     SkBitmap fBM;
@@ -162,53 +142,6 @@ static std::unique_ptr<SkImageGenerator> make_ras_generator(GrContext*, sk_sp<Sk
     return skstd::make_unique<RasterGenerator>(bm);
 }
 
-// so we can create a color-table
-static int find_closest(SkPMColor c, const SkPMColor table[], int count) {
-    const int cr = SkGetPackedR32(c);
-    const int cg = SkGetPackedG32(c);
-    const int cb = SkGetPackedB32(c);
-
-    int minDist = 999999999;
-    int index = 0;
-    for (int i = 0; i < count; ++i) {
-        int dr = SkAbs32((int)SkGetPackedR32(table[i]) - cr);
-        int dg = SkAbs32((int)SkGetPackedG32(table[i]) - cg);
-        int db = SkAbs32((int)SkGetPackedB32(table[i]) - cb);
-        int dist = dr + dg + db;
-        if (dist < minDist) {
-            minDist = dist;
-            index = i;
-        }
-    }
-    return index;
-}
-
-static std::unique_ptr<SkImageGenerator> make_ctable_generator(GrContext*, sk_sp<SkPicture> pic) {
-    SkBitmap bm;
-    bm.allocN32Pixels(100, 100);
-    SkCanvas canvas(bm);
-    canvas.clear(0);
-    canvas.translate(-100, -100);
-    canvas.drawPicture(pic);
-
-    const SkPMColor colors[] = {
-        SkPreMultiplyColor(SK_ColorRED),
-        SkPreMultiplyColor(0),
-        SkPreMultiplyColor(SK_ColorBLUE),
-    };
-    const int count = SK_ARRAY_COUNT(colors);
-    SkImageInfo info = SkImageInfo::Make(100, 100, kIndex_8_SkColorType, kPremul_SkAlphaType);
-
-    SkBitmap bm2;
-    bm2.allocPixels(info, SkColorTable::Make(colors, count));
-    for (int y = 0; y < info.height(); ++y) {
-        for (int x = 0; x < info.width(); ++x) {
-            *bm2.getAddr8(x, y) = find_closest(*bm.getAddr32(x, y), colors, count);
-        }
-    }
-    return skstd::make_unique<RasterGenerator>(bm2);
-}
-
 class EmptyGenerator : public SkImageGenerator {
 public:
     EmptyGenerator(const SkImageInfo& info) : SkImageGenerator(info) {}
@@ -399,7 +332,6 @@ private:
 };
 DEF_GM( return new ImageCacheratorGM("picture", make_pic_generator); )
 DEF_GM( return new ImageCacheratorGM("raster", make_ras_generator); )
-DEF_GM( return new ImageCacheratorGM("ctable", make_ctable_generator); )
 #if SK_SUPPORT_GPU
     DEF_GM( return new ImageCacheratorGM("texture", make_tex_generator); )
 #endif
index cdd85d1..9974af3 100644 (file)
@@ -28,12 +28,8 @@ class MaskGenerator final : public SkImageGenerator {
 public:
     MaskGenerator(const SkImageInfo& info) : INHERITED(info) {}
 
-    bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, SkPMColor*,
-                     int*) override {
-        if (info.colorType() == kIndex_8_SkColorType) {
-            return false;
-        }
-
+    bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options&)
+    override {
         SkImageInfo surfaceInfo = info;
         if (kAlpha_8_SkColorType == info.colorType()) {
             surfaceInfo = surfaceInfo.makeColorSpace(nullptr);
index 8e875da..8b2ca7d 100644 (file)
@@ -66,7 +66,7 @@ public:
      *  Repeated calls to this function should give the same results,
      *  allowing the PixelRef to be immutable.
      *
-     *  @param info A description of the format (config, size)
+     *  @param info A description of the format
      *         expected by the caller.  This can simply be identical
      *         to the info returned by getInfo().
      *
@@ -76,26 +76,31 @@ public:
      *
      *         A size that does not match getInfo() implies a request
      *         to scale. If the generator cannot perform this scale,
-     *         it will return kInvalidScale.
+     *         it will return false.
      *
-     *  If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
-     *  SkPMColor values in ctable. On success the generator must copy N colors into that storage,
-     *  (where N is the logical number of table entries) and set ctableCount to N.
-     *
-     *  If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount
-     *  is not null, it will be set to 0.
+     *         kIndex_8_SkColorType is not supported.
      *
      *  @return true on success.
      */
-    bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
-                   SkPMColor ctable[], int* ctableCount);
+    struct Options {
+        Options()
+            : fBehavior(SkTransferFunctionBehavior::kIgnore)
+        {}
+
+        SkTransferFunctionBehavior fBehavior;
+    };
+    bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options* options);
 
     /**
-     *  Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType and
-     *  uses the default Options.
+     *  Simplified version of getPixels() that uses the default Options.
      */
     bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
 
+#ifdef SK_SUPPORT_LEGACY_IMGEN_API
+    bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, SkPMColor ctable[],
+            int* ctableCount);
+#endif
+
     /**
      *  If decoding to YUV is supported, this returns true.  Otherwise, this
      *  returns false and does not modify any of the parameters.
@@ -171,30 +176,29 @@ protected:
 
     virtual SkData* onRefEncodedData() { return nullptr; }
 
-    virtual bool onGetPixels(const SkImageInfo&, void*, size_t, SkPMColor[], int*) { return false; }
+#ifdef SK_SUPPORT_LEGACY_IMGEN_API
+    virtual bool onGetPixels(const SkImageInfo&, void*, size_t, SkPMColor*, int*) {
+        return false;
+    }
+#endif
+
+#ifdef SK_SUPPORT_LEGACY_IMGEN_API
+    virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
+                             const Options&) {
+
+        return this->onGetPixels(info, pixels, rowBytes, nullptr, nullptr);
+    }
+#else
+    virtual bool onGetPixels(const SkImageInfo&, void*, size_t, const Options&) {
+        return false;
+    }
+#endif
 
     virtual bool onIsValid(GrContext*) const { return true; }
 
     virtual bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const { return false; }
     virtual bool onGetYUV8Planes(const SkYUVSizeInfo&, void*[3] /*planes*/) { return false; }
 
-    struct Options {
-        Options()
-            : fColorTable(nullptr)
-            , fColorTableCount(nullptr)
-            , fBehavior(SkTransferFunctionBehavior::kRespect)
-        {}
-
-        SkPMColor*                 fColorTable;
-        int*                       fColorTableCount;
-        SkTransferFunctionBehavior fBehavior;
-    };
-    bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options* opts);
-    virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
-                             const Options& opts) {
-        return this->onGetPixels(info, pixels, rowBytes, opts.fColorTable, opts.fColorTableCount);
-    }
-
 #if SK_SUPPORT_GPU
     virtual bool onCanGenerateTexture() const { return false; }
     virtual sk_sp<GrTextureProxy> onGenerateTexture(GrContext*, const SkImageInfo&,
index 1813af0..ba7e024 100644 (file)
@@ -659,6 +659,7 @@ DEFINES_ALL = [
     # Turn on a few Google3-specific build fixes.
     "GOOGLE3",
     # Staging flags for API changes
+    "SK_SUPPORT_LEGACY_IMGEN_API",
     # Temporarily Disable analytic AA for Google3
     "SK_NO_ANALYTIC_AA",
 ]
index d778bc7..bf794d6 100644 (file)
@@ -17,16 +17,21 @@ std::unique_ptr<SkImageGenerator> SkCodecImageGenerator::MakeFromEncodedCodec(sk
     return std::unique_ptr<SkImageGenerator>(new SkCodecImageGenerator(codec, data));
 }
 
-static SkImageInfo make_premul(const SkImageInfo& info) {
+static SkImageInfo adjust_info(const SkImageInfo& info) {
+    SkImageInfo newInfo = info;
     if (kUnpremul_SkAlphaType == info.alphaType()) {
-        return info.makeAlphaType(kPremul_SkAlphaType);
+        newInfo = newInfo.makeAlphaType(kPremul_SkAlphaType);
     }
 
-    return info;
+    if (kIndex_8_SkColorType == info.colorType()) {
+        newInfo = newInfo.makeColorType(kN32_SkColorType);
+    }
+
+    return newInfo;
 }
 
 SkCodecImageGenerator::SkCodecImageGenerator(SkCodec* codec, sk_sp<SkData> data)
-    : INHERITED(make_premul(codec->getInfo()))
+    : INHERITED(adjust_info(codec->getInfo()))
     , fCodec(codec)
     , fData(std::move(data))
 {}
@@ -36,20 +41,11 @@ SkData* SkCodecImageGenerator::onRefEncodedData() {
 }
 
 bool SkCodecImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
-        SkPMColor ctable[], int* ctableCount) {
-    Options opts;
-    opts.fColorTable = ctable;
-    opts.fColorTableCount = ctableCount;
-    opts.fBehavior = SkTransferFunctionBehavior::kRespect;
-    return this->onGetPixels(info, pixels, rowBytes, opts);
-}
-
-bool SkCodecImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
                                         const Options& opts) {
     SkCodec::Options codecOpts;
     codecOpts.fPremulBehavior = opts.fBehavior;
-    SkCodec::Result result = fCodec->getPixels(info, pixels, rowBytes, &codecOpts, opts.fColorTable,
-                                               opts.fColorTableCount);
+    SkCodec::Result result = fCodec->getPixels(info, pixels, rowBytes, &codecOpts, nullptr,
+                                               nullptr);
     switch (result) {
         case SkCodec::kSuccess:
         case SkCodec::kIncompleteInput:
index 832a7f3..4d0c078 100644 (file)
@@ -23,8 +23,6 @@ public:
 protected:
     SkData* onRefEncodedData() override;
 
-    bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, SkPMColor ctable[],
-                     int* ctableCount) override;
     bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options& opts)
                      override;
 
index 35eaf89..d0d8f97 100644 (file)
@@ -14,6 +14,7 @@ SkImageGenerator::SkImageGenerator(const SkImageInfo& info, uint32_t uniqueID)
     , fUniqueID(kNeedNewImageUniqueID == uniqueID ? SkNextID::ImageID() : uniqueID)
 {}
 
+#ifdef SK_SUPPORT_LEGACY_IMGEN_API
 bool SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
                                  SkPMColor ctable[], int* ctableCount) {
     if (kUnknown_SkColorType == info.colorType()) {
@@ -44,9 +45,20 @@ bool SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t r
     }
     return success;
 }
+#endif
 
 bool SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
                                  const Options* opts) {
+    if (kUnknown_SkColorType == info.colorType() || kIndex_8_SkColorType == info.colorType()) {
+        return false;
+    }
+    if (nullptr == pixels) {
+        return false;
+    }
+    if (rowBytes < info.minRowBytes()) {
+        return false;
+    }
+
     Options defaultOpts;
     if (!opts) {
         opts = &defaultOpts;
@@ -55,11 +67,7 @@ bool SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t r
 }
 
 bool SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
-    SkASSERT(kIndex_8_SkColorType != info.colorType());
-    if (kIndex_8_SkColorType == info.colorType()) {
-        return false;
-    }
-    return this->getPixels(info, pixels, rowBytes, nullptr, nullptr);
+    return this->getPixels(info, pixels, rowBytes, nullptr);
 }
 
 bool SkImageGenerator::queryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const {
index 34046e9..86e98d8 100644 (file)
@@ -59,33 +59,25 @@ SkPictureImageGenerator::SkPictureImageGenerator(const SkImageInfo& info, sk_sp<
 }
 
 bool SkPictureImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
-                                          SkPMColor ctable[], int* ctableCount) {
-    // Rely on SkCanvas factory to know what configs can and cannot be drawn into.
-    auto canvas = SkCanvas::MakeRasterDirect(info, pixels, rowBytes);
-    if (!canvas) {
-        return false;
-    }
-    canvas->clear(0);
-    canvas->drawPicture(fPicture, &fMatrix, fPaint.getMaybeNull());
-    return true;
-}
-
-bool SkPictureImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
                                           const Options& opts) {
-    // No need to use the xform canvas if we want fully color correct behavior or if we do not
-    // have a destination color space.
-    if (SkTransferFunctionBehavior::kRespect == opts.fBehavior || !info.colorSpace()) {
-        return this->onGetPixels(info, pixels, rowBytes, opts.fColorTable, opts.fColorTableCount);
-    }
+    bool useXformCanvas =
+            SkTransferFunctionBehavior::kIgnore == opts.fBehavior && info.colorSpace();
 
-    auto canvas = SkCanvas::MakeRasterDirect(info.makeColorSpace(nullptr), pixels, rowBytes);
+    SkImageInfo canvasInfo = useXformCanvas ? info.makeColorSpace(nullptr) : info;
+    std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(canvasInfo, pixels, rowBytes);
     if (!canvas) {
         return false;
     }
     canvas->clear(0);
 
-    auto xformCanvas = SkCreateColorSpaceXformCanvas(canvas.get(), info.refColorSpace());
-    xformCanvas->drawPicture(fPicture, &fMatrix, fPaint.getMaybeNull());
+    SkCanvas* canvasPtr = canvas.get();
+    std::unique_ptr<SkCanvas> xformCanvas;
+    if (useXformCanvas) {
+        xformCanvas = SkCreateColorSpaceXformCanvas(canvas.get(), info.refColorSpace());
+        canvasPtr = xformCanvas.get();
+    }
+
+    canvasPtr->drawPicture(fPicture, &fMatrix, fPaint.getMaybeNull());
     return true;
 }
 
index 95eeb88..6dba29c 100644 (file)
@@ -17,8 +17,6 @@ public:
                                                   sk_sp<SkColorSpace>);
 
 protected:
-    bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, SkPMColor ctable[],
-                     int* ctableCount) override;
     bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options& opts)
                      override;
 
index 7aa1f28..a2fe6a4 100644 (file)
@@ -80,7 +80,7 @@ SkData* SkImageGeneratorCG::onRefEncodedData() {
 }
 
 bool SkImageGeneratorCG::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
-        SkPMColor ctable[], int* ctableCount) {
+        const Options&) {
     if (kN32_SkColorType != info.colorType()) {
         // FIXME: Support other colorTypes.
         return false;
index 2c20c5c..65300a6 100644 (file)
@@ -24,8 +24,8 @@ public:
 protected:
     SkData* onRefEncodedData() override;
 
-    bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, SkPMColor ctable[],
-            int* ctableCount) override;
+    bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options&)
+    override;
 
 private:
     /*
index 358d993..e69b2ee 100644 (file)
@@ -137,7 +137,7 @@ SkData* SkImageGeneratorWIC::onRefEncodedData() {
 }
 
 bool SkImageGeneratorWIC::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
-        SkPMColor ctable[], int* ctableCount) {
+        const Options&) {
     if (kN32_SkColorType != info.colorType()) {
         return false;
     }
index 0a5c9d3..4770ee2 100644 (file)
@@ -41,8 +41,8 @@ public:
 protected:
     SkData* onRefEncodedData() override;
 
-    bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, SkPMColor ctable[],
-            int* ctableCount) override;
+    bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options&)
+    override;
 
 private:
     /*
index c423441..8878d6d 100644 (file)
@@ -46,7 +46,7 @@ protected:
     }
 
     bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
-                     SkPMColor ctable[], int* ctableCount) override {
+                     const Options& options) override {
         REPORTER_ASSERT(fReporter, pixels != nullptr);
         REPORTER_ASSERT(fReporter, rowBytes >= info.minRowBytes());
         if (fType != kSucceedGetPixels_TestType) {
@@ -64,14 +64,6 @@ protected:
                     bytePtr += rowBytes;
                 }
                 break;
-            case kIndex_8_SkColorType:
-                *ctableCount = 1;
-                ctable[0] = TestImageGenerator::PMColor();
-                for (int y = 0; y < info.height(); ++y) {
-                    memset(bytePtr, 0, info.width());
-                    bytePtr += rowBytes;
-                }
-                break;
             case kRGB_565_SkColorType:
                 for (int y = 0; y < info.height(); ++y) {
                     sk_memset16((uint16_t*)bytePtr,
@@ -101,7 +93,6 @@ DEF_TEST(Image_NewFromGenerator, r) {
     };
     const SkColorType testColorTypes[] = {
         kN32_SkColorType,
-        kIndex_8_SkColorType,
         kRGB_565_SkColorType
     };
     for (size_t i = 0; i < SK_ARRAY_COUNT(testTypes); ++i) {
index 224bf3f..f93cf24 100644 (file)
@@ -33,13 +33,9 @@ bool GetResourceAsBitmap(const char* resource, SkBitmap* dst) {
     if (!gen) {
         return false;
     }
-    SkPMColor ctStorage[256];
-    auto ctable = SkColorTable::Make(ctStorage, 256);
-    int count = ctable->count();
-    // ICK -- gotta clean up this pattern of writing to the ctable
-    return dst->tryAllocPixels(gen->getInfo(), ctable) &&
+    return dst->tryAllocPixels(gen->getInfo()) &&
         gen->getPixels(gen->getInfo().makeColorSpace(nullptr), dst->getPixels(), dst->rowBytes(),
-                       const_cast<SkPMColor*>(ctable->readColors()), &count);
+                       nullptr);
 }
 
 sk_sp<SkImage> GetResourceAsImage(const char* resource) {