131d097e865f266c8398f45114e4c75c0dfdef058msarett/*
231d097e865f266c8398f45114e4c75c0dfdef058msarett * Copyright 2016 Google Inc.
331d097e865f266c8398f45114e4c75c0dfdef058msarett *
431d097e865f266c8398f45114e4c75c0dfdef058msarett * Use of this source code is governed by a BSD-style license that can be
531d097e865f266c8398f45114e4c75c0dfdef058msarett * found in the LICENSE file.
631d097e865f266c8398f45114e4c75c0dfdef058msarett */
731d097e865f266c8398f45114e4c75c0dfdef058msarett
831d097e865f266c8398f45114e4c75c0dfdef058msarett#ifndef SkColorSpaceXform_Base_DEFINED
931d097e865f266c8398f45114e4c75c0dfdef058msarett#define SkColorSpaceXform_Base_DEFINED
1031d097e865f266c8398f45114e4c75c0dfdef058msarett
1131d097e865f266c8398f45114e4c75c0dfdef058msarett#include "SkColorSpace.h"
1231d097e865f266c8398f45114e4c75c0dfdef058msarett#include "SkColorSpaceXform.h"
13f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett#include "SkResourceCache.h"
14f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett
159488833428e83c93a7e6002f4d056084fb57112fraftiasclass SkColorSpace_XYZ;
169488833428e83c93a7e6002f4d056084fb57112fraftias
17f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettclass SkColorSpaceXform_Base : public SkColorSpaceXform {
18f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettpublic:
1998156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein    // A somewhat more powerful SkColorSpaceXform::New() that allows tweaking premulBehavior.
2098156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein    static std::unique_ptr<SkColorSpaceXform> New(SkColorSpace* srcSpace,
2198156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein                                                  SkColorSpace* dstSpace,
22cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett                                                  SkTransferFunctionBehavior premulBehavior);
23cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett
2498156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein    static constexpr int kDstGammaTableSize = 1024;
2598156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein    static void BuildDstGammaTables(const uint8_t* outGammaTables[3],
2698156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein                                    uint8_t* gammaTableStorage,
2798156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein                                    const SkColorSpace_XYZ* space,
2898156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein                                    bool gammasAreMatching);
2998156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein
30f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett    virtual bool onApply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src,
31f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett                         int count, SkAlphaType alphaType) const = 0;
32f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett};
3331d097e865f266c8398f45114e4c75c0dfdef058msarett
3431d097e865f266c8398f45114e4c75c0dfdef058msarettenum SrcGamma {
3531d097e865f266c8398f45114e4c75c0dfdef058msarett    kLinear_SrcGamma,
3631d097e865f266c8398f45114e4c75c0dfdef058msarett    kTable_SrcGamma,
37379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett    kSRGB_SrcGamma,
3831d097e865f266c8398f45114e4c75c0dfdef058msarett};
3931d097e865f266c8398f45114e4c75c0dfdef058msarett
4031d097e865f266c8398f45114e4c75c0dfdef058msarettenum DstGamma {
4131d097e865f266c8398f45114e4c75c0dfdef058msarett    kLinear_DstGamma,
4231d097e865f266c8398f45114e4c75c0dfdef058msarett    kSRGB_DstGamma,
4331d097e865f266c8398f45114e4c75c0dfdef058msarett    k2Dot2_DstGamma,
4431d097e865f266c8398f45114e4c75c0dfdef058msarett    kTable_DstGamma,
4531d097e865f266c8398f45114e4c75c0dfdef058msarett};
4631d097e865f266c8398f45114e4c75c0dfdef058msarett
47f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettclass SkColorSpaceXform_XYZ : public SkColorSpaceXform_Base {
4898156c4592d98b7ee50dfb47bf64efe8660b14adMike Kleinpublic:
4998156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein    SkColorSpaceXform_XYZ(SkColorSpace_XYZ* src, SkColorSpace_XYZ* dst, SkTransferFunctionBehavior);
5031d097e865f266c8398f45114e4c75c0dfdef058msarett
5198156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein    bool onApply(ColorFormat dstFormat, void* dst,
5298156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein                 ColorFormat srcFormat, const void* src,
5398156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein                 int count, SkAlphaType alphaType) const override;
5426a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett
5598156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein    void pretendNotToBeIdentityForTesting() {
5698156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein        fSrcToDstIsIdentity = false;
5798156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein    }
5831d097e865f266c8398f45114e4c75c0dfdef058msarett
5998156c4592d98b7ee50dfb47bf64efe8660b14adMike Kleinprivate:
6098156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein    // These tables pointers may point into fSrcStorage/fDstStorage or into pre-baked tables.
61cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett    const float*               fSrcGammaTables[3];
62cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett    const uint8_t*             fDstGammaTables[3];
6398156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein    SkAutoTMalloc<float>       fSrcStorage;
64cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett    sk_sp<SkData>              fDstStorage;
6531d097e865f266c8398f45114e4c75c0dfdef058msarett
6698156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein    float                      fSrcToDst[12];
6798156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein    bool                       fSrcToDstIsIdentity;
6898156c4592d98b7ee50dfb47bf64efe8660b14adMike Klein    bool                       fColorSpacesAreIdentical;
69cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett    SrcGamma                   fSrcGamma;
70cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett    DstGamma                   fDstGamma;
71cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett    SkTransferFunctionBehavior fPremulBehavior;
7231d097e865f266c8398f45114e4c75c0dfdef058msarett};
7331d097e865f266c8398f45114e4c75c0dfdef058msarett
74f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarettstruct LoadTablesContext {
75379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett    const void*  fSrc;
76379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett    const float* fR;
77379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett    const float* fG;
78379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett    const float* fB;
79f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett};
80f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett
81e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett// Must be kept in sync with "Tables" struct in RasterPipeline_opts byte_tables_rgb.
82e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarettstruct TablesContext {
83f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett    const uint8_t* fR;
84f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett    const uint8_t* fG;
85f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett    const uint8_t* fB;
86f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett    int            fCount;
87f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett};
88f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett
8931d097e865f266c8398f45114e4c75c0dfdef058msarett// For testing.  Bypasses opts for when src and dst color spaces are equal.
909488833428e83c93a7e6002f4d056084fb57112fraftiasstd::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace_XYZ* space);
9131d097e865f266c8398f45114e4c75c0dfdef058msarett
9231d097e865f266c8398f45114e4c75c0dfdef058msarett#endif
93