Index: src/pdf/SkPngPredictors.cpp |
diff --git a/src/pdf/SkPngPredictors.cpp b/src/pdf/SkPngPredictors.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2f01ef34ad8d49dc2ade16266f89ac8a9aec81bf |
--- /dev/null |
+++ b/src/pdf/SkPngPredictors.cpp |
@@ -0,0 +1,64 @@ |
+/* |
+ * Copyright 2016 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "SkPngPredictors.h" |
+#include "SkTypes.h" |
+ |
+namespace { |
+enum EncodeOrDecode { |
mtklein
2016/02/19 21:53:07
Please remove the dead kDecode path and all relate
|
+ kEncode, |
+ kDecode, |
+}; |
+} |
+ |
+// If encoding, prev == out is okay. |
+// If decoding, scanline == out is okay. |
+// prev can be null. |
+template<int COMPONENT_COUNT, EncodeOrDecode ENCODE_OR_DECODE> |
mtklein
2016/02/19 21:53:07
ALL_UPPPER_CASE_IS_FOR_MACROS_DUDE
This is genera
|
+static void paeth(int width, const uint8_t* prev, const uint8_t* scanline, uint8_t* out) { |
+ static_assert(COMPONENT_COUNT > 0, ""); |
+ // a = left, b = above, c = upper left |
+ if (prev) { |
+ uint8_t a[COMPONENT_COUNT]{}, c[COMPONENT_COUNT]{}; |
mtklein
2016/02/19 21:53:07
I think this would be easier to follow byte-by-byt
|
+ while (width-- > 0) { |
+ for (int cmp = 0; cmp < COMPONENT_COUNT; ++cmp) { |
+ uint8_t b = *prev++; |
+ uint8_t x = *scanline++; |
+ int pa = SkTAbs<int>(b - c[cmp]); |
+ int pb = SkTAbs<int>(a[cmp] - c[cmp]); |
+ int pc = SkTAbs<int>((b - c[cmp]) + (a[cmp] - c[cmp])); |
+ int smallest = SkTMin(pc, SkTMin(pa, pb)); |
mtklein
2016/02/19 21:53:07
For serial code, this is faster and simpler like t
|
+ uint8_t pred = smallest == pa ? a[cmp] : (smallest == pb ? b : c[cmp]); |
+ static_assert(ENCODE_OR_DECODE == kEncode || ENCODE_OR_DECODE == kDecode, ""); |
+ if (ENCODE_OR_DECODE == kEncode) { |
+ *out++ = x - pred; |
+ } else { |
+ *out++ = x + pred; |
+ } |
+ a[cmp] = x; |
+ c[cmp] = b; |
+ } |
+ } |
+ } else { |
mtklein
2016/02/19 21:53:07
Let's split this else case off as
static void s
|
+ uint8_t a[COMPONENT_COUNT]{}; |
+ while (width-- > 0) { |
+ for (int cmp = 0; cmp < COMPONENT_COUNT; ++cmp) { |
+ uint8_t x = *scanline++; |
+ *out++ = x - a[cmp]; |
mtklein
2016/02/19 21:53:07
This is why you should not land dead code.
|
+ a[cmp] = x; |
+ } |
+ } |
+ } |
+} |
+ |
+void SkPaethEncode3(int width, const uint8_t* prev, const uint8_t* scanline, uint8_t* out) { |
+ return paeth<3, kEncode>(width, prev, scanline, out); |
+} |
+ |
+void SkPaethEncode1(int width, const uint8_t* prev, const uint8_t* scanline, uint8_t* out) { |
+ return paeth<1, kEncode>(width, prev, scanline, out); |
+} |