SkColorSpaceXform: clamp before table lookups

The fuzzer has built a single test case that causes out-of-bounds
reads on both the src and dst tables.  I'm glad we have it.

Next follow ups may include:
    - have byte_tables_rgb do its own clamping
    - replace table_{r,g,b} here with a single stage analogous
      to byte_tables_rgb that looks up the three float tables
      safely
    - maybe replace byte_tables_rgb with that.  I'm not really
      sure why src->XYZ tables are floats but XYZ->dst are bytes.

I'm going to try some of these out before attempting to reland
in Chrome.  As usual, rebaselining Blink makes things a pain.

Bug: chromium:772684, skia:7114
Change-Id: Id8759e766330e1c7689c0847bf2cd35d422ebbcd
Reviewed-on: https://skia-review.googlesource.com/57760
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
diff --git a/src/core/SkColorSpaceXform.cpp b/src/core/SkColorSpaceXform.cpp
index 887b0a0..e2aa773 100644
--- a/src/core/SkColorSpaceXform.cpp
+++ b/src/core/SkColorSpaceXform.cpp
@@ -611,7 +611,9 @@
     switch (fSrcGamma) {
         case kLinear_SrcGamma:                                                       break;
         case   kSRGB_SrcGamma: pipeline.append_from_srgb(kUnpremul_SkAlphaType);     break;
-        case  kTable_SrcGamma: pipeline.append(SkRasterPipeline::table_r, &table_r);
+        case  kTable_SrcGamma: pipeline.append(SkRasterPipeline::clamp_0);
+                               pipeline.append(SkRasterPipeline::clamp_1);
+                               pipeline.append(SkRasterPipeline::table_r, &table_r);
                                pipeline.append(SkRasterPipeline::table_g, &table_g);
                                pipeline.append(SkRasterPipeline::table_b, &table_b); break;
     }
@@ -642,7 +644,9 @@
         case kLinear_DstGamma:                                                              break;
         case kSRGB_DstGamma:   pipeline.append(SkRasterPipeline::to_srgb);                  break;
         case k2Dot2_DstGamma:  pipeline.append(SkRasterPipeline::gamma, &to_2dot2);         break;
-        case kTable_DstGamma:  pipeline.append(SkRasterPipeline::byte_tables_rgb, &tables); break;
+        case kTable_DstGamma:  pipeline.append(SkRasterPipeline::clamp_0);
+                               pipeline.append(SkRasterPipeline::clamp_1);
+                               pipeline.append(SkRasterPipeline::byte_tables_rgb, &tables); break;
     }
     if (kPremul_SkAlphaType == alphaType && SkTransferFunctionBehavior::kIgnore == fPremulBehavior)
     {