aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkGammas.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/SkGammas.h')
-rw-r--r--src/core/SkGammas.h129
1 files changed, 129 insertions, 0 deletions
diff --git a/src/core/SkGammas.h b/src/core/SkGammas.h
new file mode 100644
index 0000000000..b8b0abb83f
--- /dev/null
+++ b/src/core/SkGammas.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkGammas_DEFINED
+#define SkGammas_DEFINED
+
+#include "SkColorSpace.h"
+#include "SkData.h"
+#include "SkTemplates.h"
+
+struct SkGammas : SkRefCnt {
+
+ // There are four possible representations for gamma curves. kNone_Type is used
+ // as a placeholder until the struct is initialized. It is not a valid value.
+ enum class Type : uint8_t {
+ kNone_Type,
+ kNamed_Type,
+ kValue_Type,
+ kTable_Type,
+ kParam_Type,
+ };
+
+ // Contains information for a gamma table.
+ struct Table {
+ size_t fOffset;
+ int fSize;
+
+ const float* table(const SkGammas* base) const {
+ return SkTAddOffset<const float>(base, sizeof(SkGammas) + fOffset);
+ }
+ };
+
+ // Contains the actual gamma curve information. Should be interpreted
+ // based on the type of the gamma curve.
+ union Data {
+ Data()
+ : fTable{ 0, 0 }
+ {}
+
+ inline bool operator==(const Data& that) const {
+ return this->fTable.fOffset == that.fTable.fOffset &&
+ this->fTable.fSize == that.fTable.fSize;
+ }
+
+ inline bool operator!=(const Data& that) const {
+ return !(*this == that);
+ }
+
+ SkGammaNamed fNamed;
+ float fValue;
+ Table fTable;
+ size_t fParamOffset;
+
+ const SkColorSpaceTransferFn& params(const SkGammas* base) const {
+ return *SkTAddOffset<const SkColorSpaceTransferFn>(
+ base, sizeof(SkGammas) + fParamOffset);
+ }
+ };
+
+ bool isNamed(int i) const {
+ return Type::kNamed_Type == this->type(i);
+ }
+
+ bool isValue(int i) const {
+ return Type::kValue_Type == this->type(i);
+ }
+
+ bool isTable(int i) const {
+ return Type::kTable_Type == this->type(i);
+ }
+
+ bool isParametric(int i) const {
+ return Type::kParam_Type == this->type(i);
+ }
+
+ const Data& data(int i) const {
+ SkASSERT(i >= 0 && i < fChannels);
+ return fData[i];
+ }
+
+ const float* table(int i) const {
+ SkASSERT(isTable(i));
+ return this->data(i).fTable.table(this);
+ }
+
+ int tableSize(int i) const {
+ SkASSERT(isTable(i));
+ return this->data(i).fTable.fSize;
+ }
+
+ const SkColorSpaceTransferFn& params(int i) const {
+ SkASSERT(isParametric(i));
+ return this->data(i).params(this);
+ }
+
+ Type type(int i) const {
+ SkASSERT(i >= 0 && i < fChannels);
+ return fType[i];
+ }
+
+ uint8_t channels() const { return fChannels; }
+
+ SkGammas(uint8_t channels) : fChannels(channels) {
+ SkASSERT(channels <= SK_ARRAY_COUNT(fType));
+ for (Type& t : fType) {
+ t = Type::kNone_Type;
+ }
+ }
+
+ // These fields should only be modified when initializing the struct.
+ uint8_t fChannels;
+ Data fData[4];
+ Type fType[4];
+
+ // Objects of this type are sometimes created in a custom fashion using
+ // sk_malloc_throw and therefore must be sk_freed. We overload new to
+ // also call sk_malloc_throw so that memory can be unconditionally released
+ // using sk_free in an overloaded delete. Overloading regular new means we
+ // must also overload placement new.
+ void* operator new(size_t size) { return sk_malloc_throw(size); }
+ void* operator new(size_t, void* p) { return p; }
+ void operator delete(void* p) { sk_free(p); }
+};
+
+#endif