skia2/gm/colorspace.cpp

87 lines
2.7 KiB
C++
Raw Normal View History

/*
* Copyright 2021 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkFont.h"
#include "tools/Resources.h"
static const skcms_TransferFunction gTFs[] = {
SkNamedTransferFn::kSRGB,
SkNamedTransferFn::k2Dot2,
SkNamedTransferFn::kLinear,
SkNamedTransferFn::kRec2020,
SkNamedTransferFn::kPQ,
SkNamedTransferFn::kHLG,
{-3.0f, 2.0f, 2.0f, 1/0.17883277f, 0.28466892f, 0.55991073f, 3.0f }, // HLG scaled 4x
};
static const skcms_Matrix3x3 gGamuts[] = {
SkNamedGamut::kSRGB,
SkNamedGamut::kAdobeRGB,
SkNamedGamut::kDisplayP3,
SkNamedGamut::kRec2020,
SkNamedGamut::kXYZ,
};
static const int W = 128,
H = 128;
// This GM demonstrates that our color space management is self-consistent.
// (Important to note, self-consistent, not necessarily correct in an objective sense.)
//
// Let's let,
//
// SkColorSpace* imgCS = img->colorSpace();
// SkColorSpace* dstCS = canvas->imageInfo().colorSpace();
//
// Ordinarily we'd just
//
// canvas->drawImage(img, 0,0);
//
// which would convert that img's pixels from imgCS to dstCS while drawing.
//
// But before we draw in this GM we convert the image to an arbitrarily different color space,
// letting midCS range over the cross-product gTFs × gGamuts:
//
// canvas->drawImage(img->makeColorSpace(midCS), 0,0);
//
// This converts img first from imgCS to midCS, treating midCS as a destination color space,
// and then draws that midCS image to the dstCS canvas, treating midCS as a source color space.
//
// This should draw a grid of images that look identical except for small precision loss.
DEF_SIMPLE_GM(colorspace, canvas, W*SK_ARRAY_COUNT(gTFs), H*SK_ARRAY_COUNT(gGamuts)) {
if (!canvas->imageInfo().colorSpace()) {
canvas->drawString("This GM only makes sense with color-managed drawing.",
W,H, SkFont{}, SkPaint{});
return;
}
sk_sp<SkImage> img = GetResourceAsImage("images/mandrill_128.png");
if (!img) {
canvas->drawString("Could not load our test image!",
W,H, SkFont{}, SkPaint{});
return;
}
SkASSERT(img->width() == W);
SkASSERT(img->height() == H);
SkASSERT(img->colorSpace());
for (skcms_Matrix3x3 gamut : gGamuts) {
canvas->save();
for (skcms_TransferFunction tf : gTFs) {
sk_sp<SkColorSpace> midCS = SkColorSpace::MakeRGB(tf, gamut);
canvas->drawImage(img->makeColorSpace(midCS), 0,0);
canvas->translate(W, 0);
}
canvas->restore();
canvas->translate(0, H);
}
}