zero output_channels to skip B2A CLUT

We check output_channels to know whether to skip B2A CLUTs:

    if (dstProfile->B2A.output_channels) {
        *ops++  = Op_clamp;
        *ops++  = Op_clut_B2A;
        *args++ = &dstProfile->B2A;
        ...

This fixes the added fuzz case, a B2A profile with no CLUT.

The new profile doesn't quite dump the same when using MSVC's C stdlib,
so I've disabled it when defined(_MSC_VER).  Will follow up.

Bug: oss-fuzz:33396
Change-Id: I0c7e73ab5dfde652fd5f72e3f31429b2c249f7d9
Reviewed-on: https://skia-review.googlesource.com/c/skcms/+/399042
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
diff --git a/profiles/fuzz/b2a_no_clut.icc b/profiles/fuzz/b2a_no_clut.icc
new file mode 100644
index 0000000..7f29deb
--- /dev/null
+++ b/profiles/fuzz/b2a_no_clut.icc
Binary files differ
diff --git a/profiles/fuzz/b2a_no_clut.icc.txt b/profiles/fuzz/b2a_no_clut.icc.txt
new file mode 100644
index 0000000..63d5188
--- /dev/null
+++ b/profiles/fuzz/b2a_no_clut.icc.txt
@@ -0,0 +1,92 @@
+                Size : 0x00001625 : 5669
+    Data color space : 0x52474220 : 'RGB '
+                 PCS : 0x58595A20 : 'XYZ '
+           Tag count : 0x00000009 : 9
+
+ Tag    : Type   : Size   : Offset
+ ------ : ------ : ------ : --------
+ 'cprt' : 'mluc' :    110 : 264
+ 'desc' : 'mluc' :     40 : 376
+ 'wtpt' : 'XYZ ' :     20 : 416
+ 'bkpt' : 'XYZ ' :     20 : 436
+ 'chad' : 'sf32' :     44 : 456
+ 'A2B0' : 'mAB ' :   1688 : 500
+ 'A2B2' : 'mAB ' :   1688 : 500
+ 'A2B1' : '' :   1688 : 2188
+ 'B2A1' : 'mBA ' :   1792 : 3876
+
+ A2B : "A", CLUT, "M", Matrix, "B"
+ "A" : 1 inputs
+  A0 : 16-bit table with 2 entries
+  ~= : 1, 0.1757687, 0, 0, 0, 0, 0 (Max error: 1.02224) (f(1) = 0.17577)
+CLUT : 2 (8 bpp)
+ "M" : 3 inputs
+  M0 : 16-bit table with 2 entries
+  ~= : 1, 0.1757687, 0, 0, 0, 0, 0 (Max error: 1.02224) (f(1) = 0.17577)
+  M1 : 16-bit table with 2 entries
+  ~= : 1, 0.1445182, 0, 0, 0, 0, 0 (Max error: 0.00012207) (f(1) = 0.144499)
+  M2 : 1, 1, 0, 0, 0, 0, 0 (f(1) = 1) (~Identity)
+Mtrx : | 49907.2383 519.882812 0.00149533851 2.00708008 |
+       | 0.00012206845 0.00149533851 0.000976547599 1.65762854 |
+       | 0.00149533851 1028.01941 1.91552866 710.906677 |
+ "B" : 3 outputs
+  B0 : 16-bit table with 2 entries
+  ~= : 1, 0.1757687, 0, 0, 0, 0, 0 (Max error: 1.02224) (f(1) = 0.17577)
+  B1 : 16-bit table with 2 entries
+  ~= : 1, 0.1445182, 0, 0, 0, 0, 0 (Max error: 0.00012207) (f(1) = 0.144499)
+  B2 : 1, 1, 0, 0, 0, 0, 0 (f(1) = 1) (~Identity)
+ B2A : "B"
+ "B" : 3 inputs
+  B0 : 16-bit table with 2 entries
+  ~= : 1, 0.1757687, 0, 0, 0, 0, 0 (Max error: 1.02224) (f(1) = 0.17577)
+  B1 : 1, 1, 0, 0, 0, 0, 0 (f(1) = 1) (~Identity)
+  B2 : 16-bit table with 251 entries
+CHAD : | 1.0478363 0.0021972656 12800.363 |
+       | 256.00347 -27520.398 25421.347 |
+       | 19553.382 6400.4335 3216.2836 |
+WTPT : | 0.9642028 1. 0.8249054 |
+252 random bytes transformed to 84 linear XYZD50 pixels:
+     0.18  0.14  806.98     0.18  0.14  807.34     0.18  0.14  807.21     0.18  0.14  807.15
+     0.18  0.14  807.15     0.18  0.14  807.36     0.18  0.14  806.98     0.18  0.14  807.40
+     0.18  0.14  807.18     0.18  0.14  807.39     0.18  0.14  807.41     0.18  0.14  807.25
+     0.18  0.14  807.06     0.18  0.14  807.25     0.18  0.14  807.40     0.18  0.14  807.07
+     0.18  0.14  807.31     0.18  0.14  807.20     0.18  0.14  807.21     0.18  0.14  807.41
+     0.18  0.14  807.41     0.18  0.14  807.42     0.18  0.14  807.00     0.18  0.14  807.40
+     0.18  0.14  807.41     0.18  0.14  807.29     0.18  0.14  807.12     0.18  0.14  807.10
+     0.18  0.14  807.25     0.18  0.14  807.23     0.18  0.14  807.17     0.18  0.14  807.34
+     0.18  0.14  807.22     0.18  0.14  807.42     0.18  0.14  807.05     0.18  0.14  807.23
+     0.18  0.14  807.17     0.18  0.14  807.38     0.18  0.14  807.00     0.18  0.14  807.04
+     0.18  0.14  807.01     0.18  0.14  807.07     0.18  0.14  807.06     0.18  0.14  807.20
+     0.18  0.14  807.06     0.18  0.14  807.03     0.18  0.14  807.10     0.18  0.14  807.34
+     0.18  0.14  807.39     0.18  0.14  807.42     0.18  0.14  807.42     0.18  0.14  807.37
+     0.18  0.14  807.02     0.18  0.14  807.07     0.18  0.14  807.18     0.18  0.14  807.04
+     0.18  0.14  807.14     0.18  0.14  807.39     0.18  0.14  807.19     0.18  0.14  807.25
+     0.18  0.14  807.02     0.18  0.14  807.01     0.18  0.14  807.29     0.18  0.14  807.30
+     0.18  0.14  807.31     0.18  0.14  807.09     0.18  0.14  807.33     0.18  0.14  807.26
+     0.18  0.14  807.11     0.18  0.14  807.21     0.18  0.14  807.09     0.18  0.14  807.15
+     0.18  0.14  807.08     0.18  0.14  807.38     0.18  0.14  807.13     0.18  0.14  806.97
+     0.18  0.14  807.13     0.18  0.14  807.12     0.18  0.14  807.30     0.18  0.14  807.17
+     0.18  0.14  807.36     0.18  0.14  807.04     0.18  0.14  807.33     0.18  0.14  807.15
+247 max error transforming back from XYZ:
+     38 142 126 158 216  36  88 147  66  56   5 136  53   2 167 169  82  24  43 186  93
+    193  15 130  68  37  79 188  60 114 198 168  28 108 136  10   5 122 120 107  24 224
+    190 141 227   9 144 218 145 157 158  80 131  80  85  19 178 199 126  20 200  32 233
+    206  20 106  32  31 150 194 218 169 196  17 225 131 201  94  39  21 209  24 163 147
+    109 109 125  99  63 149  63  18 163 162 158 162  91 217 180 202  27 199   1 172   3
+    101 170 208  67 125  81 179  28  29  31 194 113   9  21  51  22  12 195  10  83 170
+      2  16 212  83  74   9   4 150 194  12  23 101  25 107  45 157  40  78 186 103 220
+    204 169 164 201 102 247 175  35 104  19 162 115   8 182 133  72   3  77   5 214  44
+     47 175  90 187 111  26  75  26 121 112  68  57  17   5 141  23  37 105 130  50 102
+    137 119 191 143  53 186  19 153  15 152  30 184 115  36 122  32  88 168  87 137 216
+     21 120  73  55  52 215  16   4 139 182  12  33  45 193   2  44  24  71  40 130 235
+     38 206  42 139  29 128  64 113 140 170  51 110  10 187 134 156  39  92  52 138 211
+81 edge-case pixels transformed to sRGB 8888 (unpremul):
+	00ffff00 00ffff00 00ffff00  00ffff00 00ffff00 00ffff00  00ffff00 00ffff00 00ffff00
+	00ffff00 00ffff00 00ffff00  00ffff00 00ffff00 00ffff00  00ffff00 00ffff00 00ffff00
+	00ffff00 00ffff00 00ffff00  00ffff00 00ffff00 00ffff00  00ffff00 00ffff00 00ffff00
+	7fffff00 7fffff00 7fffff00  7fffff00 7fffff00 7fffff00  7fffff00 7fffff00 7fffff00
+	7fffff00 7fffff00 7fffff00  7fffff00 7fffff00 7fffff00  7fffff00 7fffff00 7fffff00
+	7fffff00 7fffff00 7fffff00  7fffff00 7fffff00 7fffff00  7fffff00 7fffff00 7fffff00
+	ffffff00 ffffff00 ffffff00  ffffff00 ffffff00 ffffff00  ffffff00 ffffff00 ffffff00
+	ffffff00 ffffff00 ffffff00  ffffff00 ffffff00 ffffff00  ffffff00 ffffff00 ffffff00
+	ffffff00 ffffff00 ffffff00  ffffff00 ffffff00 ffffff00  ffffff00 ffffff00 ffffff00
diff --git a/skcms.cc b/skcms.cc
index 0b2c781..1b643f4 100644
--- a/skcms.cc
+++ b/skcms.cc
@@ -1042,7 +1042,8 @@
             return false;
         }
 
-        b2a->input_channels = 0;
+        // Zero out *output* channels to skip this stage.
+        b2a->output_channels = 0;
     }
     return true;
 }
diff --git a/tests.c b/tests.c
index e6bc1fc..0506a33 100644
--- a/tests.c
+++ b/tests.c
@@ -652,6 +652,11 @@
     "profiles/fuzz/negative_g_para.icc",              // chromium:836634
     "profiles/fuzz/b2a_too_few_output_channels.icc",  // oss-fuzz:33281
 
+#if !defined(_MSC_VER)  // TODO(mtklein): profile dump float rounding woes :(
+    // A B2A profile with no CLUT.
+    "profiles/fuzz/b2a_no_clut.icc",  // oss-fuzz:33396
+#endif
+
     // Caused skcms_PolyTF fit to round trip indices outside the range of int.
     "profiles/fuzz/infinite_roundtrip.icc",           // oss-fuzz:8101
     "profiles/fuzz/polytf_big_float_to_int_cast.icc", // oss-fuzz:8142