skia2/include/core/SkICC.h
Matt Sarett 6f67fc29ed Add SkICC::rawTransferFnData()
BUG=skia:

Change-Id: I912b044a0091a4d396c954d1ad1d84f5f8d50f56
Reviewed-on: https://skia-review.googlesource.com/7366
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Matt Sarett <msarett@google.com>
2017-01-26 19:29:29 +00:00

109 lines
3.4 KiB
C++

/*
* 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 SkICC_DEFINED
#define SkICC_DEFINED
#include "SkData.h"
#include "SkRefCnt.h"
struct SkColorSpaceTransferFn;
class SkColorSpace;
class SkData;
class SkMatrix44;
class SK_API SkICC : public SkRefCnt {
public:
/**
* Parse an ICC profile.
*
* Returns nullptr if the data is not a valid ICC profile or if the profile
* input space is not RGB.
*/
static sk_sp<SkICC> Make(const void*, size_t);
/**
* If the gamut can be represented as transformation into XYZ D50, returns
* true and sets the proper values in |toXYZD50|.
*
* If not, returns false. This indicates that the ICC data is too complex
* to isolate a simple gamut transformation.
*/
bool toXYZD50(SkMatrix44* toXYZD50) const;
/**
* If the transfer function can be represented as coefficients to the standard
* equation, returns true and sets |fn| to the proper values.
*
* If not, returns false. This indicates one of the following:
* (1) The R, G, and B transfer functions are not the same.
* (2) The transfer function is represented as a table that we have not managed
* to match to a standard curve.
* (3) The ICC data is too complex to isolate a single transfer function.
*/
bool isNumericalTransferFn(SkColorSpaceTransferFn* fn) const;
/**
* Please do not call this unless isNumericalTransferFn() has been called and it
* fails. SkColorSpaceTransferFn is the preferred representation.
*
* If it is not possible to represent the R, G, and B transfer functions numerically
* and it is still necessary to get the transfer function, this will return the
* transfer functions as three tables (R, G, and B).
*
* If possible, this will return tables of the same length as they were specified in
* the ICC profile. This means that the lengths of the three tables are not
* guaranteed to be the same. If the ICC representation was not a table, the length
* will be chosen arbitrarily.
*
* Entries in the tables are guaranteed to be in [0, 1].
*
* This API may be deleted in favor of a numerical approximation of the raw data.
*
* This function may fail, indicating that the ICC profile does not have transfer
* functions.
*/
struct Channel {
// Byte offset of the start of the table in |fStorage|
size_t fOffset;
int fCount;
};
struct Tables {
Channel fRed;
Channel fGreen;
Channel fBlue;
const float* red() {
return (const float*) (fStorage->bytes() + fRed.fOffset);
}
const float* green() {
return (const float*) (fStorage->bytes() + fGreen.fOffset);
}
const float* blue() {
return (const float*) (fStorage->bytes() + fBlue.fOffset);
}
sk_sp<SkData> fStorage;
};
bool rawTransferFnData(Tables* tables) const;
/**
* Write an ICC profile with transfer function |fn| and gamut |toXYZD50|.
*/
static sk_sp<SkData> WriteToICC(const SkColorSpaceTransferFn& fn, const SkMatrix44& toXYZD50);
private:
SkICC(sk_sp<SkColorSpace> colorSpace);
sk_sp<SkColorSpace> fColorSpace;
friend class ICCTest;
};
#endif