Allow BF and BRD clients to request an output color space
authorMatt Sarett <msarett@google.com>
Tue, 11 Apr 2017 13:51:32 +0000 (09:51 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Tue, 11 Apr 2017 14:27:28 +0000 (14:27 +0000)
Bug: skia:
Change-Id: I0f0d3bfdd5c47544ab71167fd7984ee8e8ac5903
Reviewed-on: https://skia-review.googlesource.com/11601
Commit-Queue: Matt Sarett <msarett@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Leon Scroggins <scroggo@google.com>
dm/DMSrcSink.cpp
include/android/SkBitmapRegionDecoder.h
include/codec/SkAndroidCodec.h
src/android/SkBitmapRegionCodec.cpp
src/android/SkBitmapRegionCodec.h
src/codec/SkAndroidCodec.cpp

index d34117b..6db8f26 100644 (file)
@@ -161,7 +161,7 @@ Error BRDSrc::draw(SkCanvas* canvas) const {
         case kFullImage_Mode: {
             SkBitmap bitmap;
             if (!brd->decodeRegion(&bitmap, nullptr, SkIRect::MakeXYWH(0, 0, width, height),
-                    fSampleSize, colorType, false)) {
+                    fSampleSize, colorType, false, SkColorSpace::MakeSRGB())) {
                 return "Cannot decode (full) region.";
             }
             alpha8_to_gray8(&bitmap);
@@ -215,7 +215,8 @@ Error BRDSrc::draw(SkCanvas* canvas) const {
                     const uint32_t decodeHeight = subsetHeight + unscaledBorder * 2;
                     SkBitmap bitmap;
                     if (!brd->decodeRegion(&bitmap, nullptr, SkIRect::MakeXYWH(decodeLeft,
-                            decodeTop, decodeWidth, decodeHeight), fSampleSize, colorType, false)) {
+                            decodeTop, decodeWidth, decodeHeight), fSampleSize, colorType, false,
+                            SkColorSpace::MakeSRGB())) {
                         return "Cannot decode region.";
                     }
 
index 660aa0a..841bf8d 100644 (file)
@@ -55,11 +55,14 @@ public:
      *                        if this color type is unsupported.
      * @param requireUnpremul If the image is not opaque, we will use this to determine the
      *                        alpha type to use.
+     * @param prefColorSpace  If non-null and supported, this is the color space that we will
+     *                        decode into.  Otherwise, we will choose a default.
      *
      */
     virtual bool decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocator,
                               const SkIRect& desiredSubset, int sampleSize,
-                              SkColorType colorType, bool requireUnpremul) = 0;
+                              SkColorType colorType, bool requireUnpremul,
+                              sk_sp<SkColorSpace> prefColorSpace = nullptr) = 0;
     /*
      * @param  Requested destination color type
      * @return true if we support the requested color type and false otherwise
index 8e9ad4e..87d514d 100644 (file)
@@ -76,11 +76,17 @@ public:
     SkAlphaType computeOutputAlphaType(bool requestedUnpremul);
 
     /**
-     *  @param outputColorType Color type that the client will decode to
+     *  @param outputColorType Color type that the client will decode to.
+     *  @param prefColorSpace  Preferred color space to decode to.
+     *                         This may not return |prefColorSpace| for a couple reasons.
+     *                         (1) Android Principles: 565 must be sRGB, F16 must be
+     *                             linear sRGB, transfer function must be parametric.
+     *                         (2) Codec Limitations: F16 requires a linear color space.
      *
      *  Returns the appropriate color space to decode to.
      */
-    sk_sp<SkColorSpace> computeOutputColorSpace(SkColorType outputColorType);
+    sk_sp<SkColorSpace> computeOutputColorSpace(SkColorType outputColorType,
+                                                sk_sp<SkColorSpace> prefColorSpace = nullptr);
 
     /**
      *  Returns the dimensions of the scaled output image, for an input
index ffe7ea8..7ce9d26 100644 (file)
@@ -18,7 +18,7 @@ SkBitmapRegionCodec::SkBitmapRegionCodec(SkAndroidCodec* codec)
 
 bool SkBitmapRegionCodec::decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocator,
         const SkIRect& desiredSubset, int sampleSize, SkColorType prefColorType,
-        bool requireUnpremul) {
+        bool requireUnpremul, sk_sp<SkColorSpace> prefColorSpace) {
 
     // Fix the input sampleSize if necessary.
     if (sampleSize < 1) {
@@ -52,7 +52,8 @@ bool SkBitmapRegionCodec::decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocat
     // Create the image info for the decode
     SkColorType dstColorType = fCodec->computeOutputColorType(prefColorType);
     SkAlphaType dstAlphaType = fCodec->computeOutputAlphaType(requireUnpremul);
-    sk_sp<SkColorSpace> dstColorSpace = fCodec->computeOutputColorSpace(dstColorType);
+    sk_sp<SkColorSpace> dstColorSpace = fCodec->computeOutputColorSpace(dstColorType,
+                                                                        prefColorSpace);
     SkImageInfo decodeInfo = SkImageInfo::Make(scaledSize.width(), scaledSize.height(),
                                                dstColorType, dstAlphaType, dstColorSpace);
 
index b3b0637..baaecc9 100644 (file)
@@ -25,7 +25,8 @@ public:
 
     bool decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocator,
                       const SkIRect& desiredSubset, int sampleSize,
-                      SkColorType colorType, bool requireUnpremul) override;
+                      SkColorType colorType, bool requireUnpremul,
+                      sk_sp<SkColorSpace> prefColorSpace) override;
 
     bool conversionSupported(SkColorType colorType) override;
 
index 6e1f4b8..96ad72a 100644 (file)
@@ -169,13 +169,19 @@ SkAlphaType SkAndroidCodec::computeOutputAlphaType(bool requestedUnpremul) {
     return requestedUnpremul ? kUnpremul_SkAlphaType : kPremul_SkAlphaType;
 }
 
-sk_sp<SkColorSpace> SkAndroidCodec::computeOutputColorSpace(SkColorType outputColorType) {
+sk_sp<SkColorSpace> SkAndroidCodec::computeOutputColorSpace(SkColorType outputColorType,
+                                                            sk_sp<SkColorSpace> prefColorSpace) {
     switch (outputColorType) {
         case kRGBA_8888_SkColorType:
         case kBGRA_8888_SkColorType:
         case kIndex_8_SkColorType: {
-            SkColorSpace* encodedSpace = fCodec->getInfo().colorSpace();
+            // If |prefColorSpace| is supported, choose it.
             SkColorSpaceTransferFn fn;
+            if (prefColorSpace && prefColorSpace->isNumericalTransferFn(&fn)) {
+                return prefColorSpace;
+            }
+
+            SkColorSpace* encodedSpace = fCodec->getInfo().colorSpace();
             if (encodedSpace->isNumericalTransferFn(&fn)) {
                 // Leave the pixels in the encoded color space.  Color space conversion
                 // will be handled after decode time.
@@ -190,8 +196,10 @@ sk_sp<SkColorSpace> SkAndroidCodec::computeOutputColorSpace(SkColorType outputCo
             return SkColorSpace::MakeSRGB();
         }
         case kRGBA_F16_SkColorType:
+            // Note that |prefColorSpace| is ignored, F16 is always linear sRGB.
             return SkColorSpace::MakeSRGBLinear();
         case kRGB_565_SkColorType:
+            // Note that |prefColorSpace| is ignored, 565 is always sRGB.
             return SkColorSpace::MakeSRGB();
         default:
             // Color correction not supported for kGray.