SkColorSpaceXform.cpp revision 197e311ac9d15696fae929d8f5fcf9d93ec55e18
19876ac5b3016e5353c072378ac1545a0a2270757msarett/* 29876ac5b3016e5353c072378ac1545a0a2270757msarett * Copyright 2016 Google Inc. 39876ac5b3016e5353c072378ac1545a0a2270757msarett * 49876ac5b3016e5353c072378ac1545a0a2270757msarett * Use of this source code is governed by a BSD-style license that can be 59876ac5b3016e5353c072378ac1545a0a2270757msarett * found in the LICENSE file. 69876ac5b3016e5353c072378ac1545a0a2270757msarett */ 79876ac5b3016e5353c072378ac1545a0a2270757msarett 89876ac5b3016e5353c072378ac1545a0a2270757msarett#include "SkColorPriv.h" 99488833428e83c93a7e6002f4d056084fb57112fraftias#include "SkColorSpace_A2B.h" 109876ac5b3016e5353c072378ac1545a0a2270757msarett#include "SkColorSpace_Base.h" 119488833428e83c93a7e6002f4d056084fb57112fraftias#include "SkColorSpace_XYZ.h" 12200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett#include "SkColorSpacePriv.h" 132563601fc2b0505619f905f86bd249ae630197ccraftias#include "SkColorSpaceXform_A2B.h" 1431d097e865f266c8398f45114e4c75c0dfdef058msarett#include "SkColorSpaceXform_Base.h" 152563601fc2b0505619f905f86bd249ae630197ccraftias#include "SkColorSpaceXformPriv.h" 16200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett#include "SkHalf.h" 17200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett#include "SkOpts.h" 18f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett#include "SkRasterPipeline.h" 19ac41bac40f5a80d2bc5ccec584c23478a6900179mtklein#include "SkSRGB.h" 209876ac5b3016e5353c072378ac1545a0a2270757msarett 21f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett#if defined(SK_DEBUG) && defined(SK_BUILD_FOR_UNIX) 22f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarettstatic constexpr bool kUseRasterPipeline = true; 23f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett#else 24f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarettstatic constexpr bool kUseRasterPipeline = false; 25f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett#endif 26f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 276006f678e78af7b6f67a454cd4bc213048983f9dmsarettstatic constexpr float sk_linear_from_2dot2[256] = { 28b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000000000000000000f, 0.000005077051900662f, 0.000023328004666099f, 0.000056921765712193f, 29b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000107187362341244f, 0.000175123977503027f, 0.000261543754548491f, 0.000367136269815943f, 30b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000492503787191433f, 0.000638182842167022f, 0.000804658499513058f, 0.000992374304074325f, 31b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.001201739522438400f, 0.001433134589671860f, 0.001686915316789280f, 0.001963416213396470f, 32b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.002262953160706430f, 0.002585825596234170f, 0.002932318323938360f, 0.003302703032003640f, 33b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.003697239578900130f, 0.004116177093282750f, 0.004559754922526020f, 0.005028203456855540f, 34b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.005521744850239660f, 0.006040593654849810f, 0.006584957382581690f, 0.007155037004573030f, 35b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.007751027397660610f, 0.008373117745148580f, 0.009021491898012130f, 0.009696328701658230f, 36b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.010397802292555300f, 0.011126082368383200f, 0.011881334434813700f, 0.012663720031582100f, 37b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.013473396940142600f, 0.014310519374884100f, 0.015175238159625200f, 0.016067700890886900f, 38b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.016988052089250000f, 0.017936433339950200f, 0.018912983423721500f, 0.019917838438785700f, 39b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.020951131914781100f, 0.022012994919336500f, 0.023103556157921400f, 0.024222942067534200f, 40b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.025371276904734600f, 0.026548682828472900f, 0.027755279978126000f, 0.028991186547107800f, 41b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.030256518852388700f, 0.031551391400226400f, 0.032875916948383800f, 0.034230206565082000f, 42b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.035614369684918800f, 0.037028514161960200f, 0.038472746320194600f, 0.039947171001525600f, 43b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.041451891611462500f, 0.042987010162657100f, 0.044552627316421400f, 0.046148842422351000f, 44b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.047775753556170600f, 0.049433457555908000f, 0.051122050056493400f, 0.052841625522879000f, 45b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.054592277281760300f, 0.056374097551979800f, 0.058187177473685400f, 0.060031607136313200f, 46b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.061907475605455800f, 0.063814870948677200f, 0.065753880260330100f, 0.067724589685424300f, 47b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.069727084442598800f, 0.071761448846239100f, 0.073827766327784600f, 0.075926119456264800f, 48b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.078056589958101900f, 0.080219258736215100f, 0.082414205888459200f, 0.084641510725429500f, 49b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.086901251787660300f, 0.089193506862247800f, 0.091518352998919500f, 0.093875866525577800f, 50b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.096266123063339700f, 0.098689197541094500f, 0.101145164209600000f, 0.103634096655137000f, 51b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.106156067812744000f, 0.108711149979039000f, 0.111299414824660000f, 0.113920933406333000f, 52b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.116575776178572000f, 0.119264013005047000f, 0.121985713169619000f, 0.124740945387051000f, 53b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.127529777813422000f, 0.130352278056244000f, 0.133208513184300000f, 0.136098549737202000f, 54b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.139022453734703000f, 0.141980290685736000f, 0.144972125597231000f, 0.147998022982685000f, 55b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.151058046870511000f, 0.154152260812165000f, 0.157280727890073000f, 0.160443510725344000f, 56b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.163640671485290000f, 0.166872271890766000f, 0.170138373223312000f, 0.173439036332135000f, 57b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.176774321640903000f, 0.180144289154390000f, 0.183548998464951000f, 0.186988508758844000f, 58b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.190462878822409000f, 0.193972167048093000f, 0.197516431440340000f, 0.201095729621346000f, 59b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.204710118836677000f, 0.208359655960767000f, 0.212044397502288000f, 0.215764399609395000f, 60b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.219519718074868000f, 0.223310408341127000f, 0.227136525505149000f, 0.230998124323267000f, 61b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.234895259215880000f, 0.238827984272048000f, 0.242796353254002000f, 0.246800419601550000f, 62b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.250840236436400000f, 0.254915856566385000f, 0.259027332489606000f, 0.263174716398492000f, 63b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.267358060183772000f, 0.271577415438375000f, 0.275832833461245000f, 0.280124365261085000f, 64b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.284452061560024000f, 0.288815972797219000f, 0.293216149132375000f, 0.297652640449211000f, 65b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.302125496358853000f, 0.306634766203158000f, 0.311180499057984000f, 0.315762743736397000f, 66b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.320381548791810000f, 0.325036962521076000f, 0.329729032967515000f, 0.334457807923889000f, 67b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.339223334935327000f, 0.344025661302187000f, 0.348864834082879000f, 0.353740900096629000f, 68b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.358653905926199000f, 0.363603897920553000f, 0.368590922197487000f, 0.373615024646202000f, 69b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.378676250929840000f, 0.383774646487975000f, 0.388910256539059000f, 0.394083126082829000f, 70b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.399293299902674000f, 0.404540822567962000f, 0.409825738436323000f, 0.415148091655907000f, 71b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.420507926167587000f, 0.425905285707146000f, 0.431340213807410000f, 0.436812753800359000f, 72b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.442322948819202000f, 0.447870841800410000f, 0.453456475485731000f, 0.459079892424160000f, 73b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.464741134973889000f, 0.470440245304218000f, 0.476177265397440000f, 0.481952237050698000f, 74b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.487765201877811000f, 0.493616201311074000f, 0.499505276603030000f, 0.505432468828216000f, 75b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.511397818884880000f, 0.517401367496673000f, 0.523443155214325000f, 0.529523222417277000f, 76b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.535641609315311000f, 0.541798355950137000f, 0.547993502196972000f, 0.554227087766085000f, 77b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.560499152204328000f, 0.566809734896638000f, 0.573158875067523000f, 0.579546611782525000f, 78b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.585972983949661000f, 0.592438030320847000f, 0.598941789493296000f, 0.605484299910907000f, 79b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.612065599865624000f, 0.618685727498780000f, 0.625344720802427000f, 0.632042617620641000f, 80b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.638779455650817000f, 0.645555272444935000f, 0.652370105410821000f, 0.659223991813387000f, 81b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.666116968775851000f, 0.673049073280942000f, 0.680020342172095000f, 0.687030812154625000f, 82b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.694080519796882000f, 0.701169501531402000f, 0.708297793656032000f, 0.715465432335048000f, 83b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.722672453600255000f, 0.729918893352071000f, 0.737204787360605000f, 0.744530171266715000f, 84b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.751895080583051000f, 0.759299550695091000f, 0.766743616862161000f, 0.774227314218442000f, 85b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.781750677773962000f, 0.789313742415586000f, 0.796916542907978000f, 0.804559113894567000f, 86b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.812241489898490000f, 0.819963705323528000f, 0.827725794455034000f, 0.835527791460841000f, 87b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.843369730392169000f, 0.851251645184515000f, 0.859173569658532000f, 0.867135537520905000f, 88b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.875137582365205000f, 0.883179737672745000f, 0.891262036813419000f, 0.899384513046529000f, 89b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.907547199521614000f, 0.915750129279253000f, 0.923993335251873000f, 0.932276850264543000f, 90b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.940600707035753000f, 0.948964938178195000f, 0.957369576199527000f, 0.965814653503130000f, 91b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.974300202388861000f, 0.982826255053791000f, 0.991392843592940000f, 1.000000000000000000f, 92b39067696ad08a26bbe49b71a71f0546dc42a075msarett}; 93b39067696ad08a26bbe49b71a71f0546dc42a075msarett 946006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 956006f678e78af7b6f67a454cd4bc213048983f9dmsarett 9615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, float exponent) { 9715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 9815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = powf(x, exponent); 9915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 10015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 10115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 10215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett// outTable is always 256 entries, inTable may be larger or smaller. 10315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, const float* inTable, 10415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett int inTableSize) { 10515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett if (256 == inTableSize) { 10615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett memcpy(outTable, inTable, sizeof(float) * 256); 10715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett return; 10815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 10915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 11015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 11115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = interp_lut(x, inTable, inTableSize); 11215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 11315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 11415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 115aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett 11615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, float g, float a, float b, float c, 11715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett float d, float e, float f) { 11815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett // Y = (aX + b)^g + c for X >= d 11915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett // Y = eX + f otherwise 12015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 12115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett if (x >= d) { 122aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett *outTable++ = clamp_0_1(powf(a * x + b, g) + c); 12315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } else { 124aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett *outTable++ = clamp_0_1(e * x + f); 12515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 12615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 12715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 12815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 12915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 13015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 131f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettstatic const int kDstGammaTableSize = SkColorSpaceXform_Base::kDstGammaTableSize; 1323418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett 1331b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, float exponent) { 134b39067696ad08a26bbe49b71a71f0546dc42a075msarett float toGammaExp = 1.0f / exponent; 135b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1363418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett for (int i = 0; i < kDstGammaTableSize; i++) { 1373418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1))); 138b39067696ad08a26bbe49b71a71f0546dc42a075msarett outTable[i] = clamp_normalized_float_to_byte(powf(x, toGammaExp)); 139b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 140dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett} 141dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 1421b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, const float* inTable, 143b39067696ad08a26bbe49b71a71f0546dc42a075msarett int inTableSize) { 144197e311ac9d15696fae929d8f5fcf9d93ec55e18raftias invert_table_gamma(nullptr, outTable, kDstGammaTableSize, inTable, inTableSize); 145b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 146dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 147b39067696ad08a26bbe49b71a71f0546dc42a075msarettstatic float inverse_parametric(float x, float g, float a, float b, float c, float d, float e, 148b39067696ad08a26bbe49b71a71f0546dc42a075msarett float f) { 149b39067696ad08a26bbe49b71a71f0546dc42a075msarett // We need to take the inverse of the following piecewise function. 150b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Y = (aX + b)^g + c for X >= d 151b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Y = eX + f otherwise 152b39067696ad08a26bbe49b71a71f0546dc42a075msarett 153b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Assume that the gamma function is continuous, or this won't make much sense anyway. 154b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Plug in |d| to the first equation to calculate the new piecewise interval. 155b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Then simply use the inverse of the original functions. 156b39067696ad08a26bbe49b71a71f0546dc42a075msarett float interval = e * d + f; 157b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (x < interval) { 158b39067696ad08a26bbe49b71a71f0546dc42a075msarett // X = (Y - F) / E 159b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (0.0f == e) { 160b39067696ad08a26bbe49b71a71f0546dc42a075msarett // The gamma curve for this segment is constant, so the inverse is undefined. 161b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Since this is the lower segment, guess zero. 162b39067696ad08a26bbe49b71a71f0546dc42a075msarett return 0.0f; 163b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 164b39067696ad08a26bbe49b71a71f0546dc42a075msarett 165b39067696ad08a26bbe49b71a71f0546dc42a075msarett return (x - f) / e; 166b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 167b39067696ad08a26bbe49b71a71f0546dc42a075msarett 168b39067696ad08a26bbe49b71a71f0546dc42a075msarett // X = ((Y - C)^(1 / G) - B) / A 169b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (0.0f == a || 0.0f == g) { 170b39067696ad08a26bbe49b71a71f0546dc42a075msarett // The gamma curve for this segment is constant, so the inverse is undefined. 171b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Since this is the upper segment, guess one. 172b39067696ad08a26bbe49b71a71f0546dc42a075msarett return 1.0f; 173b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 174b39067696ad08a26bbe49b71a71f0546dc42a075msarett 175b39067696ad08a26bbe49b71a71f0546dc42a075msarett return (powf(x - c, 1.0f / g) - b) / a; 176b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 177b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1781b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, float g, float a, 179b39067696ad08a26bbe49b71a71f0546dc42a075msarett float b, float c, float d, float e, float f) { 1803418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett for (int i = 0; i < kDstGammaTableSize; i++) { 1813418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1))); 182b39067696ad08a26bbe49b71a71f0546dc42a075msarett float y = inverse_parametric(x, g, a, b, c, d, e, f); 183b39067696ad08a26bbe49b71a71f0546dc42a075msarett outTable[i] = clamp_normalized_float_to_byte(y); 184b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 185b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 186b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1876006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 1886006f678e78af7b6f67a454cd4bc213048983f9dmsarett 1891b93bd1e6eba3d14593490e4e24a34546638c8damsaretttemplate <typename T> 1901b93bd1e6eba3d14593490e4e24a34546638c8damsarettstruct GammaFns { 1911b93bd1e6eba3d14593490e4e24a34546638c8damsarett const T* fSRGBTable; 1921b93bd1e6eba3d14593490e4e24a34546638c8damsarett const T* f2Dot2Table; 1931b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromValue)(T*, float); 1941b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromTable)(T*, const float*, int); 1951b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromParam)(T*, float, float, float, float, float, float, float); 1961b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 1971b93bd1e6eba3d14593490e4e24a34546638c8damsarett 1981b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic const GammaFns<float> kToLinear { 1991b93bd1e6eba3d14593490e4e24a34546638c8damsarett sk_linear_from_srgb, 2001b93bd1e6eba3d14593490e4e24a34546638c8damsarett sk_linear_from_2dot2, 2011b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 2021b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 2031b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 2041b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 2051b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2061b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic const GammaFns<uint8_t> kFromLinear { 20755bcc8e0af3415601b3d62252a0d579fbe87c85amsarett nullptr, 20855bcc8e0af3415601b3d62252a0d579fbe87c85amsarett nullptr, 2091b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 2101b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 2111b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 2121b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 2131b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2141b93bd1e6eba3d14593490e4e24a34546638c8damsarett// Build tables to transform src gamma to linear. 2151b93bd1e6eba3d14593490e4e24a34546638c8damsaretttemplate <typename T> 2161b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_gamma_tables(const T* outGammaTables[3], T* gammaTableStorage, int gammaTableSize, 2179488833428e83c93a7e6002f4d056084fb57112fraftias const SkColorSpace_XYZ* space, const GammaFns<T>& fns, 218f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett bool gammasAreMatching) 2194be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett{ 2209488833428e83c93a7e6002f4d056084fb57112fraftias switch (space->gammaNamed()) { 221600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 2221b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.fSRGBTable; 2231b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 224600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 2251b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.f2Dot2Table; 2261b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 227600c737b64eae2c7379442ae2c852853cce3a278msarett case kLinear_SkGammaNamed: 2288bbcd5aab81dc0742c3367479c0c9d97363b1203msarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = nullptr; 2291b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 2301b93bd1e6eba3d14593490e4e24a34546638c8damsarett default: { 2319488833428e83c93a7e6002f4d056084fb57112fraftias const SkGammas* gammas = space->gammas(); 2321b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(gammas); 2331b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2347bbda991af353fbe6b34132132d211d23a3dba8cmsarett auto build_table = [=](int i) { 2351b93bd1e6eba3d14593490e4e24a34546638c8damsarett if (gammas->isNamed(i)) { 2361b93bd1e6eba3d14593490e4e24a34546638c8damsarett switch (gammas->data(i).fNamed) { 237600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 23855bcc8e0af3415601b3d62252a0d579fbe87c85amsarett (*fns.fBuildFromParam)(&gammaTableStorage[i * gammaTableSize], 2.4f, 23955bcc8e0af3415601b3d62252a0d579fbe87c85amsarett (1.0f / 1.055f), (0.055f / 1.055f), 0.0f, 24055bcc8e0af3415601b3d62252a0d579fbe87c85amsarett 0.04045f, (1.0f / 12.92f), 0.0f); 24155bcc8e0af3415601b3d62252a0d579fbe87c85amsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2421b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 243600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 24455bcc8e0af3415601b3d62252a0d579fbe87c85amsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 2.2f); 24555bcc8e0af3415601b3d62252a0d579fbe87c85amsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2461b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 247600c737b64eae2c7379442ae2c852853cce3a278msarett case kLinear_SkGammaNamed: 2481b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 1.0f); 2491b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2501b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 2511b93bd1e6eba3d14593490e4e24a34546638c8damsarett default: 2521b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(false); 2531b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 2541b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2551b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else if (gammas->isValue(i)) { 2561b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 2571b93bd1e6eba3d14593490e4e24a34546638c8damsarett gammas->data(i).fValue); 2581b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2591b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else if (gammas->isTable(i)) { 2601b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromTable)(&gammaTableStorage[i * gammaTableSize], gammas->table(i), 2611b93bd1e6eba3d14593490e4e24a34546638c8damsarett gammas->data(i).fTable.fSize); 2621b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2631b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else { 2641b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(gammas->isParametric(i)); 265df44fc5f2bb282557df291e20dbd26c070533aa6Matt Sarett const SkColorSpaceTransferFn& params = gammas->params(i); 2661b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromParam)(&gammaTableStorage[i * gammaTableSize], params.fG, 2671b93bd1e6eba3d14593490e4e24a34546638c8damsarett params.fA, params.fB, params.fC, params.fD, params.fE, 2681b93bd1e6eba3d14593490e4e24a34546638c8damsarett params.fF); 2691b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2701b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2717bbda991af353fbe6b34132132d211d23a3dba8cmsarett }; 2727bbda991af353fbe6b34132132d211d23a3dba8cmsarett 2737bbda991af353fbe6b34132132d211d23a3dba8cmsarett if (gammasAreMatching) { 2747bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(0); 2757bbda991af353fbe6b34132132d211d23a3dba8cmsarett outGammaTables[1] = outGammaTables[0]; 2767bbda991af353fbe6b34132132d211d23a3dba8cmsarett outGammaTables[2] = outGammaTables[0]; 2777bbda991af353fbe6b34132132d211d23a3dba8cmsarett } else { 2787bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(0); 2797bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(1); 2807bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(2); 2811b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2827bbda991af353fbe6b34132132d211d23a3dba8cmsarett 2837bbda991af353fbe6b34132132d211d23a3dba8cmsarett break; 2841b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2851b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2861b93bd1e6eba3d14593490e4e24a34546638c8damsarett} 2871b93bd1e6eba3d14593490e4e24a34546638c8damsarett 288f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettvoid SkColorSpaceXform_Base::BuildDstGammaTables(const uint8_t* dstGammaTables[3], 2899488833428e83c93a7e6002f4d056084fb57112fraftias uint8_t* dstStorage, 2909488833428e83c93a7e6002f4d056084fb57112fraftias const SkColorSpace_XYZ* space, 291f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett bool gammasAreMatching) { 292f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett build_gamma_tables(dstGammaTables, dstStorage, kDstGammaTableSize, space, kFromLinear, 293f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett gammasAreMatching); 294f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett} 295f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett 2961b93bd1e6eba3d14593490e4e24a34546638c8damsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 2971b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2984be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarettstd::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(SkColorSpace* srcSpace, 2994be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett SkColorSpace* dstSpace) { 3006006f678e78af7b6f67a454cd4bc213048983f9dmsarett if (!srcSpace || !dstSpace) { 3016006f678e78af7b6f67a454cd4bc213048983f9dmsarett // Invalid input 3026006f678e78af7b6f67a454cd4bc213048983f9dmsarett return nullptr; 3036006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 3046006f678e78af7b6f67a454cd4bc213048983f9dmsarett 3059488833428e83c93a7e6002f4d056084fb57112fraftias if (SkColorSpace_Base::Type::kA2B == as_CSB(dstSpace)->type()) { 3062563601fc2b0505619f905f86bd249ae630197ccraftias SkCSXformPrintf("A2B destinations not supported\n"); 3079488833428e83c93a7e6002f4d056084fb57112fraftias return nullptr; 3089488833428e83c93a7e6002f4d056084fb57112fraftias } 3099488833428e83c93a7e6002f4d056084fb57112fraftias 3109488833428e83c93a7e6002f4d056084fb57112fraftias if (SkColorSpace_Base::Type::kA2B == as_CSB(srcSpace)->type()) { 3112563601fc2b0505619f905f86bd249ae630197ccraftias SkColorSpace_A2B* src = static_cast<SkColorSpace_A2B*>(srcSpace); 3122563601fc2b0505619f905f86bd249ae630197ccraftias SkColorSpace_XYZ* dst = static_cast<SkColorSpace_XYZ*>(dstSpace); 3132563601fc2b0505619f905f86bd249ae630197ccraftias return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_A2B(src, dst)); 3149488833428e83c93a7e6002f4d056084fb57112fraftias } 3159488833428e83c93a7e6002f4d056084fb57112fraftias SkColorSpace_XYZ* srcSpaceXYZ = static_cast<SkColorSpace_XYZ*>(srcSpace); 3169488833428e83c93a7e6002f4d056084fb57112fraftias SkColorSpace_XYZ* dstSpaceXYZ = static_cast<SkColorSpace_XYZ*>(dstSpace); 3179488833428e83c93a7e6002f4d056084fb57112fraftias 318200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett ColorSpaceMatch csm = kNone_ColorSpaceMatch; 3196006f678e78af7b6f67a454cd4bc213048983f9dmsarett SkMatrix44 srcToDst(SkMatrix44::kUninitialized_Constructor); 3204be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett if (SkColorSpace::Equals(srcSpace, dstSpace)) { 321200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcToDst.setIdentity(); 322200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett csm = kFull_ColorSpaceMatch; 323971cd496b9e25f87f3a75a0015c203322907136abrianosman } else { 324bbf251bf225489a0939fff6df938035a290f4d16Brian Osman if (srcSpaceXYZ->toXYZD50Hash() == dstSpaceXYZ->toXYZD50Hash()) { 325bbf251bf225489a0939fff6df938035a290f4d16Brian Osman SkASSERT(*srcSpaceXYZ->toXYZD50() == *dstSpaceXYZ->toXYZD50() && "Hash collision"); 326971cd496b9e25f87f3a75a0015c203322907136abrianosman srcToDst.setIdentity(); 327971cd496b9e25f87f3a75a0015c203322907136abrianosman csm = kGamut_ColorSpaceMatch; 328bbf251bf225489a0939fff6df938035a290f4d16Brian Osman } else { 329bbf251bf225489a0939fff6df938035a290f4d16Brian Osman srcToDst.setConcat(*dstSpaceXYZ->fromXYZD50(), *srcSpaceXYZ->toXYZD50()); 330971cd496b9e25f87f3a75a0015c203322907136abrianosman } 3316006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 3326006f678e78af7b6f67a454cd4bc213048983f9dmsarett 333f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if (kUseRasterPipeline) { 334f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett SrcGamma srcGamma = srcSpaceXYZ->gammaIsLinear() ? kLinear_SrcGamma : kTable_SrcGamma; 335f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett DstGamma dstGamma; 336f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett switch (dstSpaceXYZ->gammaNamed()) { 337f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kSRGB_SkGammaNamed: 338f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett dstGamma = kSRGB_DstGamma; 339f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 340f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case k2Dot2Curve_SkGammaNamed: 341f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett dstGamma = k2Dot2_DstGamma; 342f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 343f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kLinear_SkGammaNamed: 344f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett dstGamma = kLinear_DstGamma; 345f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 346f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett default: 347f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett dstGamma = kTable_DstGamma; 348f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 349f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 350f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Pipeline( 351f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett srcSpaceXYZ, srcToDst, dstSpaceXYZ, csm, srcGamma, dstGamma)); 352f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 353f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 354200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett switch (csm) { 355200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kNone_ColorSpaceMatch: 3569488833428e83c93a7e6002f4d056084fb57112fraftias switch (dstSpaceXYZ->gammaNamed()) { 357600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 3589488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 359f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3608bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kSRGB_DstGamma, kNone_ColorSpaceMatch> 3619488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3628bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 363f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3648bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kSRGB_DstGamma, kNone_ColorSpaceMatch> 3659488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3668bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 367600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 3689488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 369f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3708bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, k2Dot2_DstGamma, kNone_ColorSpaceMatch> 3719488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3728bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 373f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3748bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, k2Dot2_DstGamma, kNone_ColorSpaceMatch> 3759488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3768bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 3778bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_SkGammaNamed: 3789488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 379f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3808bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kLinear_DstGamma, kNone_ColorSpaceMatch> 3819488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3828bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 383f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3848bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kLinear_DstGamma, kNone_ColorSpaceMatch> 3859488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3868bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 387200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 3889488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 389f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3908bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch> 3919488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3928bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 393f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3948bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch> 3959488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3968bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 397200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 398200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kGamut_ColorSpaceMatch: 3999488833428e83c93a7e6002f4d056084fb57112fraftias switch (dstSpaceXYZ->gammaNamed()) { 400600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 4019488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 402f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4038bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kSRGB_DstGamma, kGamut_ColorSpaceMatch> 4049488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4058bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 406f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4078bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kSRGB_DstGamma, kGamut_ColorSpaceMatch> 4089488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4098bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 410600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 4119488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 412f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4138bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, k2Dot2_DstGamma, kGamut_ColorSpaceMatch> 4149488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4158bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 416f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4178bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, k2Dot2_DstGamma, kGamut_ColorSpaceMatch> 4189488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4198bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 4208bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_SkGammaNamed: 4219488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 422f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4238bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kLinear_DstGamma, kGamut_ColorSpaceMatch> 4249488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4258bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 426f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4278bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kLinear_DstGamma, kGamut_ColorSpaceMatch> 4289488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4298bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 430200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 4319488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 432f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4338bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kTable_DstGamma, kGamut_ColorSpaceMatch> 4349488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4358bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 436f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4378bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kTable_DstGamma, kGamut_ColorSpaceMatch> 4389488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4398bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 440200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 441200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kFull_ColorSpaceMatch: 4429488833428e83c93a7e6002f4d056084fb57112fraftias switch (dstSpaceXYZ->gammaNamed()) { 443600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 444f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4458bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kSRGB_DstGamma, kFull_ColorSpaceMatch> 4469488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 447600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 448f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4498bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, k2Dot2_DstGamma, kFull_ColorSpaceMatch> 4509488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4518bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_SkGammaNamed: 452f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4538bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kLinear_DstGamma, kFull_ColorSpaceMatch> 4549488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 455200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 456f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4578bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kTable_DstGamma, kFull_ColorSpaceMatch> 4589488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 459200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 4603418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett default: 461200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkASSERT(false); 462200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return nullptr; 4636006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 4646006f678e78af7b6f67a454cd4bc213048983f9dmsarett} 4656006f678e78af7b6f67a454cd4bc213048983f9dmsarett 4666006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 4676006f678e78af7b6f67a454cd4bc213048983f9dmsarett 468df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett#define AI SK_ALWAYS_INLINE 469df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett 470df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_matrix(const float matrix[16], 471df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rXgXbX, Sk4f& rYgYbY, Sk4f& rZgZbZ, Sk4f& rTgTbT) { 472200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rXgXbX = Sk4f::Load(matrix + 0); 473200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rYgYbY = Sk4f::Load(matrix + 4); 474200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rZgZbZ = Sk4f::Load(matrix + 8); 475200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rTgTbT = Sk4f::Load(matrix + 12); 476200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 477200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 478cf7b877d62537672b67449bc96858cc1262be5f8msarettenum Order { 479cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_Order, 480cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_Order, 481cf7b877d62537672b67449bc96858cc1262be5f8msarett}; 482cf7b877d62537672b67449bc96858cc1262be5f8msarett 483df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void set_rb_shifts(Order kOrder, int* kRShift, int* kBShift) { 484cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kRGBA_Order == kOrder) { 485cf7b877d62537672b67449bc96858cc1262be5f8msarett *kRShift = 0; 486cf7b877d62537672b67449bc96858cc1262be5f8msarett *kBShift = 16; 487cf7b877d62537672b67449bc96858cc1262be5f8msarett } else { 488cf7b877d62537672b67449bc96858cc1262be5f8msarett *kRShift = 16; 489cf7b877d62537672b67449bc96858cc1262be5f8msarett *kBShift = 0; 490cf7b877d62537672b67449bc96858cc1262be5f8msarett } 491cf7b877d62537672b67449bc96858cc1262be5f8msarett} 492cf7b877d62537672b67449bc96858cc1262be5f8msarett 493cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 494df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgb_from_tables(const uint32_t* src, 495df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 496df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 497cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 498cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 499cf7b877d62537672b67449bc96858cc1262be5f8msarett r = { srcTables[0][(src[0] >> kRShift) & 0xFF], 500cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[1] >> kRShift) & 0xFF], 501cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[2] >> kRShift) & 0xFF], 502cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[3] >> kRShift) & 0xFF], }; 503cf7b877d62537672b67449bc96858cc1262be5f8msarett g = { srcTables[1][(src[0] >> kGShift) & 0xFF], 504cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[1] >> kGShift) & 0xFF], 505cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[2] >> kGShift) & 0xFF], 506cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[3] >> kGShift) & 0xFF], }; 507cf7b877d62537672b67449bc96858cc1262be5f8msarett b = { srcTables[2][(src[0] >> kBShift) & 0xFF], 508cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[1] >> kBShift) & 0xFF], 509cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[2] >> kBShift) & 0xFF], 510cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[3] >> kBShift) & 0xFF], }; 511200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett a = 0.0f; // Don't let the compiler complain that |a| is uninitialized. 512200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 513200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 514cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 515df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgba_from_tables(const uint32_t* src, 516df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 517df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 518cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 519cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 520cf7b877d62537672b67449bc96858cc1262be5f8msarett r = { srcTables[0][(src[0] >> kRShift) & 0xFF], 521cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[1] >> kRShift) & 0xFF], 522cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[2] >> kRShift) & 0xFF], 523cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[3] >> kRShift) & 0xFF], }; 5245414be06935ce0f990a2df5dccaf9ddec78ec553msarett g = { srcTables[1][(src[0] >> kGShift) & 0xFF], 525cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[1] >> kGShift) & 0xFF], 526cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[2] >> kGShift) & 0xFF], 527cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[3] >> kGShift) & 0xFF], }; 528cf7b877d62537672b67449bc96858cc1262be5f8msarett b = { srcTables[2][(src[0] >> kBShift) & 0xFF], 529cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[1] >> kBShift) & 0xFF], 530cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[2] >> kBShift) & 0xFF], 531cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[3] >> kBShift) & 0xFF], }; 532200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett a = (1.0f / 255.0f) * SkNx_cast<float>(Sk4u::Load(src) >> 24); 533200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 534200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 535cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 5362563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void load_rgb_linear(const uint32_t* src, Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 537df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const[3]) { 538cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 539cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 540cf7b877d62537672b67449bc96858cc1262be5f8msarett r = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kRShift) & 0xFF); 541cf7b877d62537672b67449bc96858cc1262be5f8msarett g = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kGShift) & 0xFF); 542cf7b877d62537672b67449bc96858cc1262be5f8msarett b = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kBShift) & 0xFF); 543be362774f9b9e8964544a579281603ed995e6e5amsarett a = 0.0f; // Don't let the compiler complain that |a| is uninitialized. 5448bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 5458bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 546cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 5472563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void load_rgba_linear(const uint32_t* src, Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 548df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const[3]) { 549cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 550cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 551cf7b877d62537672b67449bc96858cc1262be5f8msarett r = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kRShift) & 0xFF); 552cf7b877d62537672b67449bc96858cc1262be5f8msarett g = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kGShift) & 0xFF); 553cf7b877d62537672b67449bc96858cc1262be5f8msarett b = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kBShift) & 0xFF); 554cf7b877d62537672b67449bc96858cc1262be5f8msarett a = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> 24)); 5558bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 5568bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 557cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 558df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgb_from_tables_1(const uint32_t* src, 559df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 560df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 561cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 562cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 563cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f(srcTables[0][(*src >> kRShift) & 0xFF]); 564cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f(srcTables[1][(*src >> kGShift) & 0xFF]); 565cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f(srcTables[2][(*src >> kBShift) & 0xFF]); 566a9f64dec63b6f4169ba16f8b6c63fff5a6494029Matt Sarett a = 0.0f; // Don't let MSAN complain that |a| is uninitialized. 567200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 568200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 569cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 570df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgba_from_tables_1(const uint32_t* src, 571df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 572df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 573cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 574cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 575cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f(srcTables[0][(*src >> kRShift) & 0xFF]); 576cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f(srcTables[1][(*src >> kGShift) & 0xFF]); 577cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f(srcTables[2][(*src >> kBShift) & 0xFF]); 578200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett a = (1.0f / 255.0f) * Sk4f(*src >> 24); 579200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 580200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 581cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 582df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgb_linear_1(const uint32_t* src, 583df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 584df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 585cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 586cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 587cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f((1.0f / 255.0f) * ((*src >> kRShift) & 0xFF)); 588cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f((1.0f / 255.0f) * ((*src >> kGShift) & 0xFF)); 589cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f((1.0f / 255.0f) * ((*src >> kBShift) & 0xFF)); 590a9f64dec63b6f4169ba16f8b6c63fff5a6494029Matt Sarett a = 0.0f; // Don't let MSAN complain that |a| is uninitialized. 5918bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 5928bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 593cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 594df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgba_linear_1(const uint32_t* src, 595df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 596df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 597cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 598cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 599cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f((1.0f / 255.0f) * ((*src >> kRShift) & 0xFF)); 600cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f((1.0f / 255.0f) * ((*src >> kGShift) & 0xFF)); 601cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f((1.0f / 255.0f) * ((*src >> kBShift) & 0xFF)); 602cf7b877d62537672b67449bc96858cc1262be5f8msarett a = Sk4f((1.0f / 255.0f) * ((*src >> 24))); 6038bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 6048bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 605df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void transform_gamut(const Sk4f& r, const Sk4f& g, const Sk4f& b, const Sk4f& a, 606df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const Sk4f& rXgXbX, const Sk4f& rYgYbY, const Sk4f& rZgZbZ, 607df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da) { 608200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = rXgXbX[0]*r + rYgYbY[0]*g + rZgZbZ[0]*b; 609200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = rXgXbX[1]*r + rYgYbY[1]*g + rZgZbZ[1]*b; 610200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = rXgXbX[2]*r + rYgYbY[2]*g + rZgZbZ[2]*b; 611200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett da = a; 612200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 613200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 614df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void transform_gamut_1(const Sk4f& r, const Sk4f& g, const Sk4f& b, 615df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const Sk4f& rXgXbX, const Sk4f& rYgYbY, const Sk4f& rZgZbZ, 616df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba) { 617200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = rXgXbX*r + rYgYbY*g + rZgZbZ*b; 618200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 619200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 620df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void translate_gamut(const Sk4f& rTgTbT, Sk4f& dr, Sk4f& dg, Sk4f& db) { 621200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = dr + rTgTbT[0]; 622200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = dg + rTgTbT[1]; 623200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = db + rTgTbT[2]; 624200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 625200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 626df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void translate_gamut_1(const Sk4f& rTgTbT, Sk4f& rgba) { 627200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = rgba + rTgTbT; 628200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 629200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 630df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void premultiply(Sk4f& dr, Sk4f& dg, Sk4f& db, const Sk4f& da) { 631200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = da * dr; 632200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = da * dg; 633200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = da * db; 634200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 635200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 636df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void premultiply_1(const Sk4f& a, Sk4f& rgba) { 637200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = a * rgba; 638200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 639200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 640cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 6412563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_srgb(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 642df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 643cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 644cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 645200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = sk_linear_to_srgb_needs_trunc(dr); 646200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = sk_linear_to_srgb_needs_trunc(dg); 647200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = sk_linear_to_srgb_needs_trunc(db); 648200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 64917e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dr = sk_clamp_0_255(dr); 65017e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dg = sk_clamp_0_255(dg); 65117e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett db = sk_clamp_0_255(db); 65217e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett 653200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 654200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 655200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i rgba = (SkNx_cast<int>(dr) << kRShift) 656200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (SkNx_cast<int>(dg) << kGShift) 657200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (SkNx_cast<int>(db) << kBShift) 658200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (da ); 659200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba.store(dst); 660200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 661200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 662cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 663df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_srgb_1(void* dst, const uint32_t* src, 664df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f&, 665df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 66617e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett rgba = sk_clamp_0_255(sk_linear_to_srgb_needs_trunc(rgba)); 667200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 668200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint32_t tmp; 669200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkNx_cast<uint8_t>(SkNx_cast<int32_t>(rgba)).store(&tmp); 670200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = (*src & 0xFF000000) | (tmp & 0x00FFFFFF); 671cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kBGRA_Order == kOrder) { 672200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = SkSwizzle_RB(tmp); 673200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 674200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 675200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *(uint32_t*)dst = tmp; 676200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 677200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 678df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI Sk4f linear_to_2dot2(const Sk4f& x) { 679200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // x^(29/64) is a very good approximation of the true value, x^(1/2.2). 680200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett auto x2 = x.rsqrt(), // x^(-1/2) 681200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett x32 = x2.rsqrt().rsqrt().rsqrt().rsqrt(), // x^(-1/32) 682200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett x64 = x32.rsqrt(); // x^(+1/64) 683200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 684200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // 29 = 32 - 2 - 1 685200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return 255.0f * x2.invert() * x32 * x64.invert(); 686200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 687200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 688cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 6892563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_2dot2(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 690df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 691cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 692cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 693200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = linear_to_2dot2(dr); 694200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = linear_to_2dot2(dg); 695200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = linear_to_2dot2(db); 696200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 69717e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dr = sk_clamp_0_255(dr); 69817e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dg = sk_clamp_0_255(dg); 69917e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett db = sk_clamp_0_255(db); 70017e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett 701200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 702200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 703200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i rgba = (Sk4f_round(dr) << kRShift) 704200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (Sk4f_round(dg) << kGShift) 705200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (Sk4f_round(db) << kBShift) 706200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (da ); 707200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba.store(dst); 708200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 709200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 710cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 711df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_2dot2_1(void* dst, const uint32_t* src, 712df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f&, 713df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 71417e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett rgba = sk_clamp_0_255(linear_to_2dot2(rgba)); 715200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 716200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint32_t tmp; 717200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkNx_cast<uint8_t>(Sk4f_round(rgba)).store(&tmp); 718200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = (*src & 0xFF000000) | (tmp & 0x00FFFFFF); 719cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kBGRA_Order == kOrder) { 720200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = SkSwizzle_RB(tmp); 721200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 722200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 723200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *(uint32_t*)dst = tmp; 724200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 725200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 726cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 7272563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_linear(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 728df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 729cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 730cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 73117e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dr = sk_clamp_0_255(255.0f * dr); 73217e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dg = sk_clamp_0_255(255.0f * dg); 73317e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett db = sk_clamp_0_255(255.0f * db); 7348bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7358bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 7368bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7378bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Sk4i rgba = (Sk4f_round(dr) << kRShift) 7388bbcd5aab81dc0742c3367479c0c9d97363b1203msarett | (Sk4f_round(dg) << kGShift) 7398bbcd5aab81dc0742c3367479c0c9d97363b1203msarett | (Sk4f_round(db) << kBShift) 7408bbcd5aab81dc0742c3367479c0c9d97363b1203msarett | (da ); 7418bbcd5aab81dc0742c3367479c0c9d97363b1203msarett rgba.store(dst); 7428bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 7438bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 744cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 745df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_linear_1(void* dst, const uint32_t* src, 746df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f&, 747df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 74817e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett rgba = sk_clamp_0_255(255.0f * rgba); 7498bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7508bbcd5aab81dc0742c3367479c0c9d97363b1203msarett uint32_t tmp; 7518bbcd5aab81dc0742c3367479c0c9d97363b1203msarett SkNx_cast<uint8_t>(Sk4f_round(rgba)).store(&tmp); 7528bbcd5aab81dc0742c3367479c0c9d97363b1203msarett tmp = (*src & 0xFF000000) | (tmp & 0x00FFFFFF); 753cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kBGRA_Order == kOrder) { 7548bbcd5aab81dc0742c3367479c0c9d97363b1203msarett tmp = SkSwizzle_RB(tmp); 7558bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 7568bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7578bbcd5aab81dc0742c3367479c0c9d97363b1203msarett *(uint32_t*)dst = tmp; 7588bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 7598bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 760cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 7612563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_f16(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da, 7622563601fc2b0505619f905f86bd249ae630197ccraftias const uint8_t* const[3]) { 76333cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein Sk4h::Store4(dst, SkFloatToHalf_finite_ftz(dr), 76433cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(dg), 76533cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(db), 76633cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(da)); 767200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 768200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 769cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 770df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_f16_1(void* dst, const uint32_t* src, 771df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f& a, 772df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 773200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = Sk4f(rgba[0], rgba[1], rgba[2], a[3]); 7748ae991e433d2c0814ea5579613f00173805ff057mtklein SkFloatToHalf_finite_ftz(rgba).store((uint64_t*) dst); 775200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 776200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 777cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 7782563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_f32(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da, 779df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 78033cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein Sk4f::Store4(dst, dr, dg, db, da); 781c0444615ed76360f680619ad4d1f92cda6181a50msarett} 782c0444615ed76360f680619ad4d1f92cda6181a50msarett 783cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 784df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_f32_1(void* dst, const uint32_t* src, 785df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f& a, 786df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 787c0444615ed76360f680619ad4d1f92cda6181a50msarett rgba = Sk4f(rgba[0], rgba[1], rgba[2], a[3]); 788c0444615ed76360f680619ad4d1f92cda6181a50msarett rgba.store((float*) dst); 789c0444615ed76360f680619ad4d1f92cda6181a50msarett} 790c0444615ed76360f680619ad4d1f92cda6181a50msarett 791cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 7922563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_f16_opaque(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, 7932563601fc2b0505619f905f86bd249ae630197ccraftias Sk4f&, const uint8_t* const[3]) { 79433cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein Sk4h::Store4(dst, SkFloatToHalf_finite_ftz(dr), 79533cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(dg), 79633cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(db), 79733cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SK_Half1); 798200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 799200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 800cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 801df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_f16_1_opaque(void* dst, const uint32_t* src, 802df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f&, 803df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 804200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint64_t tmp; 8058ae991e433d2c0814ea5579613f00173805ff057mtklein SkFloatToHalf_finite_ftz(rgba).store(&tmp); 806200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp |= static_cast<uint64_t>(SK_Half1) << 48; 807200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *((uint64_t*) dst) = tmp; 808200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 809200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 810cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 8112563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_generic(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 8122563601fc2b0505619f905f86bd249ae630197ccraftias const uint8_t* const dstTables[3]) { 813cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 814cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 81517e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dr = Sk4f::Min(Sk4f::Max(1023.0f * dr, 0.0f), 1023.0f); 81617e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dg = Sk4f::Min(Sk4f::Max(1023.0f * dg, 0.0f), 1023.0f); 81717e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett db = Sk4f::Min(Sk4f::Max(1023.0f * db, 0.0f), 1023.0f); 818200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 819200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i ir = Sk4f_round(dr); 820200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i ig = Sk4f_round(dg); 821200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i ib = Sk4f_round(db); 822200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 823200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 824200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 825200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint32_t* dst32 = (uint32_t*) dst; 826200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[0] = dstTables[0][ir[0]] << kRShift 827200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[0]] << kGShift 828200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[0]] << kBShift 829200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[0]; 830200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[1] = dstTables[0][ir[1]] << kRShift 831200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[1]] << kGShift 832200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[1]] << kBShift 833200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[1]; 834200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[2] = dstTables[0][ir[2]] << kRShift 835200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[2]] << kGShift 836200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[2]] << kBShift 837200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[2]; 838200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[3] = dstTables[0][ir[3]] << kRShift 839200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[3]] << kGShift 840200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[3]] << kBShift 841200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[3]; 842200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 843200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 844cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 845df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_generic_1(void* dst, const uint32_t* src, 846df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f&, 847df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const dstTables[3]) { 848cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 849cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 85017e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett rgba = Sk4f::Min(Sk4f::Max(1023.0f * rgba, 0.0f), 1023.0f); 851200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 852200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i indices = Sk4f_round(rgba); 853200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 8549dc6cf6b8833d36c29a23d2519989b069745fcd5msarett *((uint32_t*) dst) = dstTables[0][indices[0]] << kRShift 8559dc6cf6b8833d36c29a23d2519989b069745fcd5msarett | dstTables[1][indices[1]] << kGShift 8569dc6cf6b8833d36c29a23d2519989b069745fcd5msarett | dstTables[2][indices[2]] << kBShift 857200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (*src & 0xFF000000); 858200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 859200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 860cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(load_rgb_from_tables<kRGBA_Order> )* LoadFn; 861cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(load_rgb_from_tables_1<kRGBA_Order>)* Load1Fn; 862cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(store_generic<kRGBA_Order> )* StoreFn; 863cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(store_generic_1<kRGBA_Order> )* Store1Fn; 8648bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 8658bbcd5aab81dc0742c3367479c0c9d97363b1203msarettenum SrcFormat { 8668bbcd5aab81dc0742c3367479c0c9d97363b1203msarett kRGBA_8888_Linear_SrcFormat, 8678bbcd5aab81dc0742c3367479c0c9d97363b1203msarett kRGBA_8888_Table_SrcFormat, 868cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Linear_SrcFormat, 869cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Table_SrcFormat, 8708bbcd5aab81dc0742c3367479c0c9d97363b1203msarett}; 8718bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 8728bbcd5aab81dc0742c3367479c0c9d97363b1203msarettenum DstFormat { 873cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_Linear_DstFormat, 874cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_SRGB_DstFormat, 875cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_2Dot2_DstFormat, 876cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_Table_DstFormat, 877cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Linear_DstFormat, 878cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_SRGB_DstFormat, 879cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_2Dot2_DstFormat, 880cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Table_DstFormat, 8818bbcd5aab81dc0742c3367479c0c9d97363b1203msarett kF16_Linear_DstFormat, 882c0444615ed76360f680619ad4d1f92cda6181a50msarett kF32_Linear_DstFormat, 8838bbcd5aab81dc0742c3367479c0c9d97363b1203msarett}; 8848bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 8858bbcd5aab81dc0742c3367479c0c9d97363b1203msaretttemplate <SrcFormat kSrc, 8868bbcd5aab81dc0742c3367479c0c9d97363b1203msarett DstFormat kDst, 8878bbcd5aab81dc0742c3367479c0c9d97363b1203msarett SkAlphaType kAlphaType, 888cf7b877d62537672b67449bc96858cc1262be5f8msarett ColorSpaceMatch kCSM> 8895934646b4937a05d5e8297448ea6613a89f8903aMatt Sarettstatic void color_xform_RGBA(void* dst, const void* vsrc, int len, 8905934646b4937a05d5e8297448ea6613a89f8903aMatt Sarett const float* const srcTables[3], const float matrix[16], 8915934646b4937a05d5e8297448ea6613a89f8903aMatt Sarett const uint8_t* const dstTables[3]) { 8928bbcd5aab81dc0742c3367479c0c9d97363b1203msarett LoadFn load; 8938bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Load1Fn load_1; 894c0444615ed76360f680619ad4d1f92cda6181a50msarett static constexpr bool loadAlpha = (kPremul_SkAlphaType == kAlphaType) || 895c0444615ed76360f680619ad4d1f92cda6181a50msarett (kF16_Linear_DstFormat == kDst) || 896c0444615ed76360f680619ad4d1f92cda6181a50msarett (kF32_Linear_DstFormat == kDst); 8978bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kSrc) { 8988bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kRGBA_8888_Linear_SrcFormat: 899c0444615ed76360f680619ad4d1f92cda6181a50msarett if (loadAlpha) { 900cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_linear<kRGBA_Order>; 901cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_linear_1<kRGBA_Order>; 9028bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 903cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_linear<kRGBA_Order>; 904cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_linear_1<kRGBA_Order>; 9058bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 9068bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 9078bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kRGBA_8888_Table_SrcFormat: 908c0444615ed76360f680619ad4d1f92cda6181a50msarett if (loadAlpha) { 909cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_from_tables<kRGBA_Order>; 910cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_from_tables_1<kRGBA_Order>; 9118bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 912cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_from_tables<kRGBA_Order>; 913cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_from_tables_1<kRGBA_Order>; 914cf7b877d62537672b67449bc96858cc1262be5f8msarett } 915cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 916cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Linear_SrcFormat: 917cf7b877d62537672b67449bc96858cc1262be5f8msarett if (loadAlpha) { 918cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_linear<kBGRA_Order>; 919cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_linear_1<kBGRA_Order>; 920cf7b877d62537672b67449bc96858cc1262be5f8msarett } else { 921cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_linear<kBGRA_Order>; 922cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_linear_1<kBGRA_Order>; 923cf7b877d62537672b67449bc96858cc1262be5f8msarett } 924cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 925cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Table_SrcFormat: 926cf7b877d62537672b67449bc96858cc1262be5f8msarett if (loadAlpha) { 927cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_from_tables<kBGRA_Order>; 928cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_from_tables_1<kBGRA_Order>; 929cf7b877d62537672b67449bc96858cc1262be5f8msarett } else { 930cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_from_tables<kBGRA_Order>; 931cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_from_tables_1<kBGRA_Order>; 9328bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 9338bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 9348bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 9358bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 9368bbcd5aab81dc0742c3367479c0c9d97363b1203msarett StoreFn store; 9378bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Store1Fn store_1; 9388bbcd5aab81dc0742c3367479c0c9d97363b1203msarett size_t sizeOfDstPixel; 9398bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kDst) { 940cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_Linear_DstFormat: 941cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_linear<kRGBA_Order>; 942cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_linear_1<kRGBA_Order>; 943cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 944cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 945cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_SRGB_DstFormat: 946cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_srgb<kRGBA_Order>; 947cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_srgb_1<kRGBA_Order>; 948cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 949cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 950cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_2Dot2_DstFormat: 951cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_2dot2<kRGBA_Order>; 952cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_2dot2_1<kRGBA_Order>; 9538bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 9548bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 955cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_Table_DstFormat: 956cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_generic<kRGBA_Order>; 957cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_generic_1<kRGBA_Order>; 9588bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 9598bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 960cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Linear_DstFormat: 961cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_linear<kBGRA_Order>; 962cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_linear_1<kBGRA_Order>; 9638bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 9648bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 965cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_SRGB_DstFormat: 966cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_srgb<kBGRA_Order>; 967cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_srgb_1<kBGRA_Order>; 968cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 969cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 970cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_2Dot2_DstFormat: 971cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_2dot2<kBGRA_Order>; 972cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_2dot2_1<kBGRA_Order>; 973cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 974cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 975cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Table_DstFormat: 976cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_generic<kBGRA_Order>; 977cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_generic_1<kBGRA_Order>; 9788bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 9798bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 9808bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kF16_Linear_DstFormat: 981cf7b877d62537672b67449bc96858cc1262be5f8msarett store = (kOpaque_SkAlphaType == kAlphaType) ? store_f16_opaque<kRGBA_Order> : 982cf7b877d62537672b67449bc96858cc1262be5f8msarett store_f16<kRGBA_Order>; 983cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = (kOpaque_SkAlphaType == kAlphaType) ? store_f16_1_opaque<kRGBA_Order> : 984cf7b877d62537672b67449bc96858cc1262be5f8msarett store_f16_1<kRGBA_Order>; 9858bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 8; 9868bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 987c0444615ed76360f680619ad4d1f92cda6181a50msarett case kF32_Linear_DstFormat: 988cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_f32<kRGBA_Order>; 989cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_f32_1<kRGBA_Order>; 990c0444615ed76360f680619ad4d1f92cda6181a50msarett sizeOfDstPixel = 16; 991c0444615ed76360f680619ad4d1f92cda6181a50msarett break; 9928bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 9938bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 994d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett const uint32_t* src = (const uint32_t*) vsrc; 995d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f rXgXbX, rYgYbY, rZgZbZ, rTgTbT; 996d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load_matrix(matrix, rXgXbX, rYgYbY, rZgZbZ, rTgTbT); 997d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 998d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (len >= 4) { 999d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett // Naively this would be a loop of load-transform-store, but we found it faster to 1000d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett // move the N+1th load ahead of the Nth store. We don't bother doing this for N<4. 1001d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f r, g, b, a; 1002d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load(src, r, g, b, a, srcTables); 1003d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett src += 4; 1004d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett len -= 4; 1005d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1006d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f dr, dg, db, da; 1007d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett while (len >= 4) { 1008d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kNone_ColorSpaceMatch == kCSM) { 1009d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett transform_gamut(r, g, b, a, rXgXbX, rYgYbY, rZgZbZ, dr, dg, db, da); 1010d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett translate_gamut(rTgTbT, dr, dg, db); 1011d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } else { 1012d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dr = r; 1013d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dg = g; 1014d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett db = b; 1015d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett da = a; 1016d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1017d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1018d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kPremul_SkAlphaType == kAlphaType) { 1019d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett premultiply(dr, dg, db, da); 1020d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1021d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1022d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load(src, r, g, b, a, srcTables); 1023d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1024d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett store(dst, src - 4, dr, dg, db, da, dstTables); 1025d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dst = SkTAddOffset<void>(dst, 4 * sizeOfDstPixel); 1026d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett src += 4; 1027d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett len -= 4; 1028d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1029d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1030d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kNone_ColorSpaceMatch == kCSM) { 1031d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett transform_gamut(r, g, b, a, rXgXbX, rYgYbY, rZgZbZ, dr, dg, db, da); 1032d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett translate_gamut(rTgTbT, dr, dg, db); 1033d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } else { 1034d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dr = r; 1035d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dg = g; 1036d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett db = b; 1037d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett da = a; 1038d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1039d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1040d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kPremul_SkAlphaType == kAlphaType) { 1041d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett premultiply(dr, dg, db, da); 1042d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1043d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1044d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett store(dst, src - 4, dr, dg, db, da, dstTables); 1045d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dst = SkTAddOffset<void>(dst, 4 * sizeOfDstPixel); 1046d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1047d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1048d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett while (len > 0) { 1049d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f r, g, b, a; 1050d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load_1(src, r, g, b, a, srcTables); 1051d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1052d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f rgba; 1053d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kNone_ColorSpaceMatch == kCSM) { 1054d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett transform_gamut_1(r, g, b, rXgXbX, rYgYbY, rZgZbZ, rgba); 1055d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett translate_gamut_1(rTgTbT, rgba); 1056d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } else { 1057d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett rgba = Sk4f(r[0], g[0], b[0], a[0]); 1058d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1059d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1060d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kPremul_SkAlphaType == kAlphaType) { 1061d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett premultiply_1(a, rgba); 1062d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1063d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1064d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett store_1(dst, src, rgba, a, dstTables); 1065d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1066d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett src += 1; 1067d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett len -= 1; 1068d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dst = SkTAddOffset<void>(dst, sizeOfDstPixel); 1069d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 10708bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 10718bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 10723418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett/////////////////////////////////////////////////////////////////////////////////////////////////// 10730f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 10742563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI int num_tables(SkColorSpace_XYZ* space) { 10759488833428e83c93a7e6002f4d056084fb57112fraftias switch (space->gammaNamed()) { 10767bbda991af353fbe6b34132132d211d23a3dba8cmsarett case kSRGB_SkGammaNamed: 10777bbda991af353fbe6b34132132d211d23a3dba8cmsarett case k2Dot2Curve_SkGammaNamed: 10787bbda991af353fbe6b34132132d211d23a3dba8cmsarett case kLinear_SkGammaNamed: 10797bbda991af353fbe6b34132132d211d23a3dba8cmsarett return 0; 10807bbda991af353fbe6b34132132d211d23a3dba8cmsarett default: { 10819488833428e83c93a7e6002f4d056084fb57112fraftias const SkGammas* gammas = space->gammas(); 10827bbda991af353fbe6b34132132d211d23a3dba8cmsarett SkASSERT(gammas); 10837bbda991af353fbe6b34132132d211d23a3dba8cmsarett 10847bbda991af353fbe6b34132132d211d23a3dba8cmsarett bool gammasAreMatching = (gammas->type(0) == gammas->type(1)) && 10857bbda991af353fbe6b34132132d211d23a3dba8cmsarett (gammas->data(0) == gammas->data(1)) && 10867bbda991af353fbe6b34132132d211d23a3dba8cmsarett (gammas->type(0) == gammas->type(2)) && 10877bbda991af353fbe6b34132132d211d23a3dba8cmsarett (gammas->data(0) == gammas->data(2)); 10887bbda991af353fbe6b34132132d211d23a3dba8cmsarett 10897bbda991af353fbe6b34132132d211d23a3dba8cmsarett // It's likely that each component will have the same gamma. In this case, 10907bbda991af353fbe6b34132132d211d23a3dba8cmsarett // we only need to build one table. 10917bbda991af353fbe6b34132132d211d23a3dba8cmsarett return gammasAreMatching ? 1 : 3; 10927bbda991af353fbe6b34132132d211d23a3dba8cmsarett } 10937bbda991af353fbe6b34132132d211d23a3dba8cmsarett } 10947bbda991af353fbe6b34132132d211d23a3dba8cmsarett} 10957bbda991af353fbe6b34132132d211d23a3dba8cmsarett 10968bbcd5aab81dc0742c3367479c0c9d97363b1203msaretttemplate <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM> 1097f489886915034093278353d06c6f1973b2e8b7d2Matt SarettSkColorSpaceXform_XYZ<kSrc, kDst, kCSM> 10989488833428e83c93a7e6002f4d056084fb57112fraftias::SkColorSpaceXform_XYZ(SkColorSpace_XYZ* srcSpace, const SkMatrix44& srcToDst, 10999488833428e83c93a7e6002f4d056084fb57112fraftias SkColorSpace_XYZ* dstSpace) 11003418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett{ 1101de68d6c4616d86621373d88100002ddfdb9c08e3brianosman srcToDst.asColMajorf(fSrcToDst); 11027bbda991af353fbe6b34132132d211d23a3dba8cmsarett 11034be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett const int numSrcTables = num_tables(srcSpace); 1104f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett const size_t srcEntries = numSrcTables * 256; 11057bbda991af353fbe6b34132132d211d23a3dba8cmsarett const bool srcGammasAreMatching = (1 >= numSrcTables); 1106f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett fSrcStorage.reset(srcEntries); 1107f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett build_gamma_tables(fSrcGammaTables, fSrcStorage.get(), 256, srcSpace, kToLinear, 1108f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett srcGammasAreMatching); 1109f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett 1110f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett const int numDstTables = num_tables(dstSpace); 11119488833428e83c93a7e6002f4d056084fb57112fraftias dstSpace->toDstGammaTables(fDstGammaTables, &fDstStorage, numDstTables); 11123418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett} 1113dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 11147bbda991af353fbe6b34132132d211d23a3dba8cmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 11157bbda991af353fbe6b34132132d211d23a3dba8cmsarett 1116cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <SrcFormat kSrc, DstFormat kDst, ColorSpaceMatch kCSM> 1117df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI bool apply_set_alpha(void* dst, const void* src, int len, SkAlphaType alphaType, 1118df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3], const float matrix[16], 1119df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const dstTables[3]) { 11208bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (alphaType) { 11218bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kOpaque_SkAlphaType: 112231d097e865f266c8398f45114e4c75c0dfdef058msarett color_xform_RGBA<kSrc, kDst, kOpaque_SkAlphaType, kCSM> 11238bbcd5aab81dc0742c3367479c0c9d97363b1203msarett (dst, src, len, srcTables, matrix, dstTables); 112431d097e865f266c8398f45114e4c75c0dfdef058msarett return true; 11258bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kPremul_SkAlphaType: 112631d097e865f266c8398f45114e4c75c0dfdef058msarett color_xform_RGBA<kSrc, kDst, kPremul_SkAlphaType, kCSM> 11278bbcd5aab81dc0742c3367479c0c9d97363b1203msarett (dst, src, len, srcTables, matrix, dstTables); 112831d097e865f266c8398f45114e4c75c0dfdef058msarett return true; 11298bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kUnpremul_SkAlphaType: 113031d097e865f266c8398f45114e4c75c0dfdef058msarett color_xform_RGBA<kSrc, kDst, kUnpremul_SkAlphaType, kCSM> 11318bbcd5aab81dc0742c3367479c0c9d97363b1203msarett (dst, src, len, srcTables, matrix, dstTables); 113231d097e865f266c8398f45114e4c75c0dfdef058msarett return true; 11338bbcd5aab81dc0742c3367479c0c9d97363b1203msarett default: 113431d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 11358bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 11368bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 11378bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 1138cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <SrcGamma kSrc, DstFormat kDst, ColorSpaceMatch kCSM> 1139df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI bool apply_set_src(void* dst, const void* src, int len, SkAlphaType alphaType, 1140df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3], const float matrix[16], 1141df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const dstTables[3], 1142df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett SkColorSpaceXform::ColorFormat srcColorFormat) { 1143cf7b877d62537672b67449bc96858cc1262be5f8msarett switch (srcColorFormat) { 1144cf7b877d62537672b67449bc96858cc1262be5f8msarett case SkColorSpaceXform::kRGBA_8888_ColorFormat: 1145cf7b877d62537672b67449bc96858cc1262be5f8msarett switch (kSrc) { 1146cf7b877d62537672b67449bc96858cc1262be5f8msarett case kLinear_SrcGamma: 1147cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kRGBA_8888_Linear_SrcFormat, kDst, kCSM> 1148cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, nullptr, matrix, dstTables); 1149cf7b877d62537672b67449bc96858cc1262be5f8msarett case kTable_SrcGamma: 1150cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kRGBA_8888_Table_SrcFormat, kDst, kCSM> 1151cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, srcTables, matrix, dstTables); 1152cf7b877d62537672b67449bc96858cc1262be5f8msarett } 1153cf7b877d62537672b67449bc96858cc1262be5f8msarett case SkColorSpaceXform::kBGRA_8888_ColorFormat: 1154cf7b877d62537672b67449bc96858cc1262be5f8msarett switch (kSrc) { 1155cf7b877d62537672b67449bc96858cc1262be5f8msarett case kLinear_SrcGamma: 1156cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kBGRA_8888_Linear_SrcFormat, kDst, kCSM> 1157cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, nullptr, matrix, dstTables); 1158cf7b877d62537672b67449bc96858cc1262be5f8msarett case kTable_SrcGamma: 1159cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kBGRA_8888_Table_SrcFormat, kDst, kCSM> 1160cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, srcTables, matrix, dstTables); 1161cf7b877d62537672b67449bc96858cc1262be5f8msarett } 1162cf7b877d62537672b67449bc96858cc1262be5f8msarett default: 116331d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 11648bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 11658bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 11668bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 1167df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett#undef AI 1168df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett 11698bbcd5aab81dc0742c3367479c0c9d97363b1203msaretttemplate <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM> 1170f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettbool SkColorSpaceXform_XYZ<kSrc, kDst, kCSM> 117131d097e865f266c8398f45114e4c75c0dfdef058msarett::onApply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, const void* src, 117231d097e865f266c8398f45114e4c75c0dfdef058msarett int len, SkAlphaType alphaType) const 11733418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett{ 1174200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kFull_ColorSpaceMatch == kCSM) { 117517e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett switch (alphaType) { 117617e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett case kPremul_SkAlphaType: 117717e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett // We can't skip the xform since we need to perform a premultiply in the 117817e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett // linear space. 117917e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett break; 118017e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett default: 118117e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett switch (dstColorFormat) { 118217e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett case kRGBA_8888_ColorFormat: 118317e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett memcpy(dst, src, len * sizeof(uint32_t)); 118417e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett return true; 118517e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett case kBGRA_8888_ColorFormat: 118617e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett SkOpts::RGBA_to_BGRA((uint32_t*) dst, src, len); 118717e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett return true; 118817e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett case kRGBA_F16_ColorFormat: 118917e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett case kRGBA_F32_ColorFormat: 119017e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett // There's still work to do to xform to linear floats. 119117e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett break; 119217e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett default: 119317e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett return false; 119417e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett } 1195200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1196200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1197200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1198c0444615ed76360f680619ad4d1f92cda6181a50msarett switch (dstColorFormat) { 1199c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_8888_ColorFormat: 12008bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kDst) { 12018bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_DstGamma: 1202cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kRGBA_8888_Linear_DstFormat, kCSM> 1203cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1204cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12058bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kSRGB_DstGamma: 1206cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kRGBA_8888_SRGB_DstFormat, kCSM> 1207cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1208cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12098bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case k2Dot2_DstGamma: 1210cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kRGBA_8888_2Dot2_DstFormat, kCSM> 1211cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1212cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12138bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kTable_DstGamma: 1214cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kRGBA_8888_Table_DstFormat, kCSM> 1215cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, fDstGammaTables, 1216cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 1217d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 1218c0444615ed76360f680619ad4d1f92cda6181a50msarett case kBGRA_8888_ColorFormat: 12198bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kDst) { 12208bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_DstGamma: 1221cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kBGRA_8888_Linear_DstFormat, kCSM> 1222cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1223cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12248bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kSRGB_DstGamma: 1225cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kBGRA_8888_SRGB_DstFormat, kCSM> 1226cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1227cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12288bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case k2Dot2_DstGamma: 1229cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kBGRA_8888_2Dot2_DstFormat, kCSM> 1230cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1231cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12328bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kTable_DstGamma: 1233cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kBGRA_8888_Table_DstFormat, kCSM> 1234cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, fDstGammaTables, 1235cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 1236d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 1237c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_F16_ColorFormat: 12388bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kDst) { 12398bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_DstGamma: 1240cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kF16_Linear_DstFormat, kCSM> 1241cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1242cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 1243d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett default: 124431d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 1245d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 1246c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_F32_ColorFormat: 1247c0444615ed76360f680619ad4d1f92cda6181a50msarett switch (kDst) { 1248c0444615ed76360f680619ad4d1f92cda6181a50msarett case kLinear_DstGamma: 1249cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kF32_Linear_DstFormat, kCSM> 1250cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1251cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 1252c0444615ed76360f680619ad4d1f92cda6181a50msarett default: 125331d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 1254c0444615ed76360f680619ad4d1f92cda6181a50msarett } 1255d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett default: 125631d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 1257d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 12589ce3a543c92a73e6daca420defc042886b3f2019msarett} 12599dc6cf6b8833d36c29a23d2519989b069745fcd5msarett 1260f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettbool SkColorSpaceXform::apply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, 1261f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett const void* src, int len, SkAlphaType alphaType) const { 1262f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return ((SkColorSpaceXform_Base*) this)->onApply(dstColorFormat, dst, srcColorFormat, src, len, 1263f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett alphaType); 1264f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett} 1265f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett 12667bbda991af353fbe6b34132132d211d23a3dba8cmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 12677bbda991af353fbe6b34132132d211d23a3dba8cmsarett 1268f6878baba8c7cd347e185361bac2eabaef863bfaMatt SarettSkColorSpaceXform_Pipeline::SkColorSpaceXform_Pipeline(SkColorSpace_XYZ* srcSpace, 1269f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett const SkMatrix44& srcToDst, 1270f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett SkColorSpace_XYZ* dstSpace, 1271f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett ColorSpaceMatch csm, 1272f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett SrcGamma srcGamma, 1273f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett DstGamma dstGamma) 1274f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett : fCSM(csm) 1275f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett , fSrcGamma(srcGamma) 1276f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett , fDstGamma(dstGamma) 1277f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett{ 1278f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett fSrcToDst[ 0] = srcToDst.get(0, 0); 1279f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett fSrcToDst[ 1] = srcToDst.get(1, 0); 1280f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett fSrcToDst[ 2] = srcToDst.get(2, 0); 1281f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett fSrcToDst[ 3] = srcToDst.get(0, 1); 1282f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett fSrcToDst[ 4] = srcToDst.get(1, 1); 1283f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett fSrcToDst[ 5] = srcToDst.get(2, 1); 1284f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett fSrcToDst[ 6] = srcToDst.get(0, 2); 1285f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett fSrcToDst[ 7] = srcToDst.get(1, 2); 1286f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett fSrcToDst[ 8] = srcToDst.get(2, 2); 1287f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett fSrcToDst[ 9] = srcToDst.get(0, 3); 1288f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett fSrcToDst[10] = srcToDst.get(1, 3); 1289f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett fSrcToDst[11] = srcToDst.get(2, 3); 1290f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1291f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett const int numSrcTables = num_tables(srcSpace); 1292f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett const size_t srcEntries = numSrcTables * 256; 1293f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett const bool srcGammasAreMatching = (1 >= numSrcTables); 1294f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett fSrcStorage.reset(srcEntries); 1295f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett build_gamma_tables(fSrcGammaTables, fSrcStorage.get(), 256, srcSpace, kToLinear, 1296f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett srcGammasAreMatching); 1297f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1298f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett const int numDstTables = num_tables(dstSpace); 1299f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett dstSpace->toDstGammaTables(fDstGammaTables, &fDstStorage, numDstTables); 1300f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett} 1301f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1302f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarettbool SkColorSpaceXform_Pipeline::onApply(ColorFormat dstColorFormat, void* dst, 1303f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett ColorFormat srcColorFormat, const void* src, int len, 1304f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett SkAlphaType alphaType) const { 1305f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if (kFull_ColorSpaceMatch == fCSM) { 1306f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if (kPremul_SkAlphaType != alphaType) { 1307f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if ((kRGBA_8888_ColorFormat == dstColorFormat && 1308f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett kRGBA_8888_ColorFormat == srcColorFormat) || 1309f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett (kBGRA_8888_ColorFormat == dstColorFormat && 1310f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett kBGRA_8888_ColorFormat == srcColorFormat)) 1311f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett { 1312f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett memcpy(dst, src, len * sizeof(uint32_t)); 1313f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett return true; 1314f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1315f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1316f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if ((kRGBA_8888_ColorFormat == dstColorFormat && 1317f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett kBGRA_8888_ColorFormat == srcColorFormat) || 1318f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett (kBGRA_8888_ColorFormat == dstColorFormat && 1319f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett kRGBA_8888_ColorFormat == srcColorFormat)) 1320f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett { 1321f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett SkOpts::RGBA_to_BGRA((uint32_t*) dst, src, len); 1322f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett return true; 1323f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1324f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1325f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1326f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1327f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if (kRGBA_F16_ColorFormat == srcColorFormat || kRGBA_F32_ColorFormat == srcColorFormat) { 1328f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett return false; 1329f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1330f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1331f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett SkRasterPipeline pipeline; 1332f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1333f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett LoadTablesContext loadTables; 1334f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if (kLinear_SrcGamma == fSrcGamma) { 1335f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::load_8888, &src); 1336f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if (kBGRA_8888_ColorFormat == srcColorFormat) { 1337f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::swap_rb); 1338f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1339f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } else { 1340f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett loadTables.fSrc = (const uint32_t*) src; 1341f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett loadTables.fG = fSrcGammaTables[1]; 1342f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if (kRGBA_8888_ColorFormat == srcColorFormat) { 1343f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett loadTables.fR = fSrcGammaTables[0]; 1344f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett loadTables.fB = fSrcGammaTables[2]; 1345f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::load_tables, &loadTables); 1346f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } else { 1347f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett loadTables.fR = fSrcGammaTables[2]; 1348f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett loadTables.fB = fSrcGammaTables[0]; 1349f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::load_tables, &loadTables); 1350f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::swap_rb); 1351f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1352f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1353f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1354f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if (kNone_ColorSpaceMatch == fCSM) { 1355f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::matrix_3x4, fSrcToDst); 1356f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1357f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1358f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if (kRGBA_8888_ColorFormat == dstColorFormat || kBGRA_8888_ColorFormat == dstColorFormat) { 1359f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::clamp_0); 1360f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::clamp_1); 1361f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1362f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1363f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if (kPremul_SkAlphaType == alphaType) { 1364f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::premul); 1365f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1366f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1367f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett StoreTablesContext storeTables; 1368f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett switch (fDstGamma) { 1369f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kSRGB_DstGamma: 1370f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::to_srgb); 1371f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 1372f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case k2Dot2_DstGamma: 1373f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::to_2dot2); 1374f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 1375f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett default: 1376f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 1377f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1378f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1379f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett switch (dstColorFormat) { 1380f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kRGBA_8888_ColorFormat: 1381f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if (kTable_DstGamma == fDstGamma) { 1382f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett storeTables.fDst = (uint32_t*) dst; 1383f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett storeTables.fR = fDstGammaTables[0]; 1384f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett storeTables.fG = fDstGammaTables[1]; 1385f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett storeTables.fB = fDstGammaTables[2]; 1386f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett storeTables.fCount = SkColorSpaceXform_Base::kDstGammaTableSize; 1387f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::store_tables, &storeTables); 1388f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } else { 1389f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::store_8888, &dst); 1390f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1391f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 1392f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kBGRA_8888_ColorFormat: 1393f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if (kTable_DstGamma == fDstGamma) { 1394f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett storeTables.fDst = (uint32_t*) dst; 1395f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett storeTables.fR = fDstGammaTables[2]; 1396f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett storeTables.fG = fDstGammaTables[1]; 1397f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett storeTables.fB = fDstGammaTables[0]; 1398f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett storeTables.fCount = SkColorSpaceXform_Base::kDstGammaTableSize; 1399f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::swap_rb); 1400f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::store_tables, &storeTables); 1401f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } else { 1402f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::swap_rb); 1403f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::store_8888, &dst); 1404f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1405f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 1406f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kRGBA_F16_ColorFormat: 1407f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if (kLinear_DstGamma != fDstGamma) { 1408f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett return false; 1409f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1410f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::store_f16, &dst); 1411f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 1412f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kRGBA_F32_ColorFormat: 1413f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if (kLinear_DstGamma != fDstGamma) { 1414f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett return false; 1415f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1416f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::store_f32, &dst); 1417f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 1418f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1419f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1420f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.run(0, 0, len); 1421f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett return true; 1422f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett} 1423f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1424f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett/////////////////////////////////////////////////////////////////////////////////////////////////// 1425f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 14269488833428e83c93a7e6002f4d056084fb57112fraftiasstd::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace_XYZ* space) { 1427f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett if (kUseRasterPipeline) { 1428f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Pipeline( 1429f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett space, SkMatrix::I(), space, kNone_ColorSpaceMatch, kTable_SrcGamma, 1430f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett kTable_DstGamma)); 1431f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } else { 1432f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 14338bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch> 14349dc6cf6b8833d36c29a23d2519989b069745fcd5msarett (space, SkMatrix::I(), space)); 1435f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 14369dc6cf6b8833d36c29a23d2519989b069745fcd5msarett} 1437