replace gamma_correct with gamut/transfer_fn in DM

gamma_correct as is (really meaning, linear blending) isn't super
useful, in that it doesn't distinguish gamuts or transfer functions
except between identity and non-identity.

This replaces it with fields that describe the gamut and TF.

Change-Id: Ied08c2df537be61ee1903ef6cc279991326271a2
Reviewed-on: https://skia-review.googlesource.com/c/191573
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Stephan Altmueller <stephana@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
This commit is contained in:
Mike Klein 2019-02-12 13:03:54 -05:00 committed by Skia Commit-Bot
parent 7c8643859d
commit 66f09a7299
3 changed files with 68 additions and 10 deletions

View File

@ -826,9 +826,11 @@ static bool gather_srcs() {
return true;
}
static constexpr skcms_TransferFunction k2020_TF =
{2.22222f, 0.909672f, 0.0903276f, 0.222222f, 0.0812429f, 0, 0};
static sk_sp<SkColorSpace> rec2020() {
return SkColorSpace::MakeRGB({2.22222f, 0.909672f, 0.0903276f, 0.222222f, 0.0812429f, 0, 0},
SkNamedGamut::kRec2020);
return SkColorSpace::MakeRGB(k2020_TF, SkNamedGamut::kRec2020);
}
static void push_sink(const SkCommandLineConfig& config, Sink* s) {
@ -1187,14 +1189,66 @@ struct Task {
done(task.sink.tag.c_str(), task.src.tag.c_str(), task.src.options.c_str(), name.c_str());
}
static SkString identify_gamut(SkColorSpace* cs) {
if (!cs) {
return SkString("untagged");
}
skcms_Matrix3x3 gamut;
if (cs->toXYZD50(&gamut)) {
auto eq = [](skcms_Matrix3x3 x, skcms_Matrix3x3 y) {
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) {
if (x.vals[i][j] != y.vals[i][j]) { return false; }
}
return true;
};
if (eq(gamut, SkNamedGamut::kSRGB )) { return SkString("sRGB"); }
if (eq(gamut, SkNamedGamut::kAdobeRGB)) { return SkString("Adobe"); }
if (eq(gamut, SkNamedGamut::kDCIP3 )) { return SkString("P3"); }
if (eq(gamut, SkNamedGamut::kRec2020 )) { return SkString("2020"); }
if (eq(gamut, SkNamedGamut::kXYZ )) { return SkString("XYZ"); }
if (eq(gamut, gNarrow_toXYZD50 )) { return SkString("narrow"); }
return SkString("other");
}
return SkString("non-XYZ");
}
static SkString identify_transfer_fn(SkColorSpace* cs) {
if (!cs) {
return SkString("untagged");
}
skcms_TransferFunction tf;
if (cs->isNumericalTransferFn(&tf)) {
auto eq = [](skcms_TransferFunction x, skcms_TransferFunction y) {
return x.g == y.g
&& x.a == y.a
&& x.b == y.b
&& x.c == y.c
&& x.d == y.d
&& x.e == y.e
&& x.f == y.f;
};
if (tf.a == 1 && tf.b == 0 && tf.c == 0 && tf.d == 0 && tf.e == 0 && tf.f == 0) {
return SkStringPrintf("gamma %.3g", tf.g);
}
if (eq(tf, SkNamedTransferFn::kSRGB)) { return SkString("sRGB"); }
if (eq(tf, k2020_TF )) { return SkString("2020"); }
return SkStringPrintf("%.3g %.3g %.3g %.3g %.3g %.3g %.3g",
tf.g, tf.a, tf.b, tf.c, tf.d, tf.e, tf.f);
}
return SkString("non-numeric");
}
static void WriteToDisk(const Task& task,
SkString md5,
const char* ext,
SkStream* data, size_t len,
const SkBitmap* bitmap) {
bool gammaCorrect = bitmap &&
bitmap->info().colorSpace() &&
bitmap->info().colorSpace()->gammaIsLinear();
SkColorSpace* cs = bitmap ? bitmap->info().colorSpace() : nullptr;
JsonWriter::BitmapResult result;
result.name = task.src->name();
@ -1202,7 +1256,8 @@ struct Task {
result.sourceType = task.src.tag;
result.sourceOptions = task.src.options;
result.ext = ext;
result.gammaCorrect = gammaCorrect;
result.gamut = identify_gamut(cs);
result.transferFn = identify_transfer_fn(cs);
result.md5 = md5;
JsonWriter::AddBitmapResult(result);

View File

@ -82,8 +82,9 @@ void JsonWriter::DumpJson() {
writer.endObject(); // key
writer.beginObject("options");
writer.appendString("ext" , gBitmapResults[i].ext.c_str());
writer.appendString("gamma_correct", gBitmapResults[i].gammaCorrect ? "yes" : "no");
writer.appendString("ext" , gBitmapResults[i].ext.c_str());
writer.appendString("gamut", gBitmapResults[i].gamut.c_str());
writer.appendString("transfer_fn", gBitmapResults[i].transferFn.c_str());
writer.endObject(); // options
writer.appendString("md5", gBitmapResults[i].md5.c_str());
@ -144,7 +145,8 @@ bool JsonWriter::ReadJson(const char* path, void(*callback)(BitmapResult)) {
br.config = key["config"].as<StringValue>().begin();
br.sourceType = key["source_type"].as<StringValue>().begin();
br.ext = options["ext"].as<StringValue>().begin();
br.gammaCorrect = 0 == strcmp("yes", options["gamma_correct"].as<StringValue>().begin());
br.gamut = options["gamut"].as<StringValue>().begin();
br.transferFn = options["transfer_fn"].as<StringValue>().begin();
br.md5 = (*r)["md5"].as<StringValue>().begin();
if (const StringValue* so = key["source_options"]) {

View File

@ -29,7 +29,8 @@ public:
SkString sourceOptions; // "image", "codec", "subset", "scanline"
SkString md5; // In ASCII, so 32 bytes long.
SkString ext; // Extension of file we wrote: "png", "pdf", ...
bool gammaCorrect; // Old configs are not gamma correct, some new ones are.
SkString gamut;
SkString transferFn;
};
/**