SkColorSpaceXform.cpp revision 2563601fc2b0505619f905f86bd249ae630197cc
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" 18ac41bac40f5a80d2bc5ccec584c23478a6900179mtklein#include "SkSRGB.h" 199876ac5b3016e5353c072378ac1545a0a2270757msarett 206006f678e78af7b6f67a454cd4bc213048983f9dmsarettstatic constexpr float sk_linear_from_2dot2[256] = { 21b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000000000000000000f, 0.000005077051900662f, 0.000023328004666099f, 0.000056921765712193f, 22b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000107187362341244f, 0.000175123977503027f, 0.000261543754548491f, 0.000367136269815943f, 23b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000492503787191433f, 0.000638182842167022f, 0.000804658499513058f, 0.000992374304074325f, 24b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.001201739522438400f, 0.001433134589671860f, 0.001686915316789280f, 0.001963416213396470f, 25b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.002262953160706430f, 0.002585825596234170f, 0.002932318323938360f, 0.003302703032003640f, 26b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.003697239578900130f, 0.004116177093282750f, 0.004559754922526020f, 0.005028203456855540f, 27b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.005521744850239660f, 0.006040593654849810f, 0.006584957382581690f, 0.007155037004573030f, 28b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.007751027397660610f, 0.008373117745148580f, 0.009021491898012130f, 0.009696328701658230f, 29b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.010397802292555300f, 0.011126082368383200f, 0.011881334434813700f, 0.012663720031582100f, 30b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.013473396940142600f, 0.014310519374884100f, 0.015175238159625200f, 0.016067700890886900f, 31b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.016988052089250000f, 0.017936433339950200f, 0.018912983423721500f, 0.019917838438785700f, 32b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.020951131914781100f, 0.022012994919336500f, 0.023103556157921400f, 0.024222942067534200f, 33b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.025371276904734600f, 0.026548682828472900f, 0.027755279978126000f, 0.028991186547107800f, 34b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.030256518852388700f, 0.031551391400226400f, 0.032875916948383800f, 0.034230206565082000f, 35b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.035614369684918800f, 0.037028514161960200f, 0.038472746320194600f, 0.039947171001525600f, 36b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.041451891611462500f, 0.042987010162657100f, 0.044552627316421400f, 0.046148842422351000f, 37b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.047775753556170600f, 0.049433457555908000f, 0.051122050056493400f, 0.052841625522879000f, 38b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.054592277281760300f, 0.056374097551979800f, 0.058187177473685400f, 0.060031607136313200f, 39b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.061907475605455800f, 0.063814870948677200f, 0.065753880260330100f, 0.067724589685424300f, 40b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.069727084442598800f, 0.071761448846239100f, 0.073827766327784600f, 0.075926119456264800f, 41b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.078056589958101900f, 0.080219258736215100f, 0.082414205888459200f, 0.084641510725429500f, 42b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.086901251787660300f, 0.089193506862247800f, 0.091518352998919500f, 0.093875866525577800f, 43b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.096266123063339700f, 0.098689197541094500f, 0.101145164209600000f, 0.103634096655137000f, 44b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.106156067812744000f, 0.108711149979039000f, 0.111299414824660000f, 0.113920933406333000f, 45b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.116575776178572000f, 0.119264013005047000f, 0.121985713169619000f, 0.124740945387051000f, 46b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.127529777813422000f, 0.130352278056244000f, 0.133208513184300000f, 0.136098549737202000f, 47b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.139022453734703000f, 0.141980290685736000f, 0.144972125597231000f, 0.147998022982685000f, 48b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.151058046870511000f, 0.154152260812165000f, 0.157280727890073000f, 0.160443510725344000f, 49b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.163640671485290000f, 0.166872271890766000f, 0.170138373223312000f, 0.173439036332135000f, 50b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.176774321640903000f, 0.180144289154390000f, 0.183548998464951000f, 0.186988508758844000f, 51b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.190462878822409000f, 0.193972167048093000f, 0.197516431440340000f, 0.201095729621346000f, 52b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.204710118836677000f, 0.208359655960767000f, 0.212044397502288000f, 0.215764399609395000f, 53b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.219519718074868000f, 0.223310408341127000f, 0.227136525505149000f, 0.230998124323267000f, 54b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.234895259215880000f, 0.238827984272048000f, 0.242796353254002000f, 0.246800419601550000f, 55b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.250840236436400000f, 0.254915856566385000f, 0.259027332489606000f, 0.263174716398492000f, 56b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.267358060183772000f, 0.271577415438375000f, 0.275832833461245000f, 0.280124365261085000f, 57b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.284452061560024000f, 0.288815972797219000f, 0.293216149132375000f, 0.297652640449211000f, 58b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.302125496358853000f, 0.306634766203158000f, 0.311180499057984000f, 0.315762743736397000f, 59b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.320381548791810000f, 0.325036962521076000f, 0.329729032967515000f, 0.334457807923889000f, 60b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.339223334935327000f, 0.344025661302187000f, 0.348864834082879000f, 0.353740900096629000f, 61b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.358653905926199000f, 0.363603897920553000f, 0.368590922197487000f, 0.373615024646202000f, 62b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.378676250929840000f, 0.383774646487975000f, 0.388910256539059000f, 0.394083126082829000f, 63b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.399293299902674000f, 0.404540822567962000f, 0.409825738436323000f, 0.415148091655907000f, 64b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.420507926167587000f, 0.425905285707146000f, 0.431340213807410000f, 0.436812753800359000f, 65b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.442322948819202000f, 0.447870841800410000f, 0.453456475485731000f, 0.459079892424160000f, 66b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.464741134973889000f, 0.470440245304218000f, 0.476177265397440000f, 0.481952237050698000f, 67b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.487765201877811000f, 0.493616201311074000f, 0.499505276603030000f, 0.505432468828216000f, 68b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.511397818884880000f, 0.517401367496673000f, 0.523443155214325000f, 0.529523222417277000f, 69b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.535641609315311000f, 0.541798355950137000f, 0.547993502196972000f, 0.554227087766085000f, 70b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.560499152204328000f, 0.566809734896638000f, 0.573158875067523000f, 0.579546611782525000f, 71b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.585972983949661000f, 0.592438030320847000f, 0.598941789493296000f, 0.605484299910907000f, 72b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.612065599865624000f, 0.618685727498780000f, 0.625344720802427000f, 0.632042617620641000f, 73b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.638779455650817000f, 0.645555272444935000f, 0.652370105410821000f, 0.659223991813387000f, 74b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.666116968775851000f, 0.673049073280942000f, 0.680020342172095000f, 0.687030812154625000f, 75b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.694080519796882000f, 0.701169501531402000f, 0.708297793656032000f, 0.715465432335048000f, 76b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.722672453600255000f, 0.729918893352071000f, 0.737204787360605000f, 0.744530171266715000f, 77b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.751895080583051000f, 0.759299550695091000f, 0.766743616862161000f, 0.774227314218442000f, 78b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.781750677773962000f, 0.789313742415586000f, 0.796916542907978000f, 0.804559113894567000f, 79b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.812241489898490000f, 0.819963705323528000f, 0.827725794455034000f, 0.835527791460841000f, 80b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.843369730392169000f, 0.851251645184515000f, 0.859173569658532000f, 0.867135537520905000f, 81b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.875137582365205000f, 0.883179737672745000f, 0.891262036813419000f, 0.899384513046529000f, 82b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.907547199521614000f, 0.915750129279253000f, 0.923993335251873000f, 0.932276850264543000f, 83b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.940600707035753000f, 0.948964938178195000f, 0.957369576199527000f, 0.965814653503130000f, 84b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.974300202388861000f, 0.982826255053791000f, 0.991392843592940000f, 1.000000000000000000f, 85b39067696ad08a26bbe49b71a71f0546dc42a075msarett}; 86b39067696ad08a26bbe49b71a71f0546dc42a075msarett 876006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 886006f678e78af7b6f67a454cd4bc213048983f9dmsarett 8915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, float exponent) { 9015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 9115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = powf(x, exponent); 9215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 9315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 9415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 9515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett// outTable is always 256 entries, inTable may be larger or smaller. 9615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, const float* inTable, 9715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett int inTableSize) { 9815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett if (256 == inTableSize) { 9915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett memcpy(outTable, inTable, sizeof(float) * 256); 10015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett return; 10115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 10215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 10315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 10415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = interp_lut(x, inTable, inTableSize); 10515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 10615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 10715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 108aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarettstatic inline float clamp_0_1(float v) { 109aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett if (v >= 1.0f) { 110aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett return 1.0f; 111aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett } else if (v >= 0.0f) { 112aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett return v; 113aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett } else { 114aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett return 0.0f; 115aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett } 116aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett} 117aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett 11815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, float g, float a, float b, float c, 11915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett float d, float e, float f) { 12015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett // Y = (aX + b)^g + c for X >= d 12115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett // Y = eX + f otherwise 12215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 12315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett if (x >= d) { 124aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett *outTable++ = clamp_0_1(powf(a * x + b, g) + c); 12515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } else { 126aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett *outTable++ = clamp_0_1(e * x + f); 12715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 12815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 12915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 13015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 13115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 13215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 133a9e878c836994bce695274b4c28890290139dcdfmsarett// Expand range from 0-1 to 0-255, then convert. 134b39067696ad08a26bbe49b71a71f0546dc42a075msarettstatic uint8_t clamp_normalized_float_to_byte(float v) { 135dea0340cadb759932e53416a657f5ea75fee8b5fmsarett // The ordering of the logic is a little strange here in order 136dea0340cadb759932e53416a657f5ea75fee8b5fmsarett // to make sure we convert NaNs to 0. 1379876ac5b3016e5353c072378ac1545a0a2270757msarett v = v * 255.0f; 138a9e878c836994bce695274b4c28890290139dcdfmsarett if (v >= 254.5f) { 1399876ac5b3016e5353c072378ac1545a0a2270757msarett return 255; 140dea0340cadb759932e53416a657f5ea75fee8b5fmsarett } else if (v >= 0.5f) { 1419876ac5b3016e5353c072378ac1545a0a2270757msarett return (uint8_t) (v + 0.5f); 142dea0340cadb759932e53416a657f5ea75fee8b5fmsarett } else { 143dea0340cadb759932e53416a657f5ea75fee8b5fmsarett return 0; 1449876ac5b3016e5353c072378ac1545a0a2270757msarett } 1459876ac5b3016e5353c072378ac1545a0a2270757msarett} 1469876ac5b3016e5353c072378ac1545a0a2270757msarett 147f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettstatic const int kDstGammaTableSize = SkColorSpaceXform_Base::kDstGammaTableSize; 1483418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett 1491b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, float exponent) { 150b39067696ad08a26bbe49b71a71f0546dc42a075msarett float toGammaExp = 1.0f / exponent; 151b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1523418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett for (int i = 0; i < kDstGammaTableSize; i++) { 1533418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1))); 154b39067696ad08a26bbe49b71a71f0546dc42a075msarett outTable[i] = clamp_normalized_float_to_byte(powf(x, toGammaExp)); 155b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 156dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett} 157dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 1581b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, const float* inTable, 159b39067696ad08a26bbe49b71a71f0546dc42a075msarett int inTableSize) { 1603418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett for (int i = 0; i < kDstGammaTableSize; i++) { 1613418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1))); 162b39067696ad08a26bbe49b71a71f0546dc42a075msarett float y = inverse_interp_lut(x, inTable, inTableSize); 163b39067696ad08a26bbe49b71a71f0546dc42a075msarett outTable[i] = clamp_normalized_float_to_byte(y); 164b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 165b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 166dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 167b39067696ad08a26bbe49b71a71f0546dc42a075msarettstatic float inverse_parametric(float x, float g, float a, float b, float c, float d, float e, 168b39067696ad08a26bbe49b71a71f0546dc42a075msarett float f) { 169b39067696ad08a26bbe49b71a71f0546dc42a075msarett // We need to take the inverse of the following piecewise function. 170b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Y = (aX + b)^g + c for X >= d 171b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Y = eX + f otherwise 172b39067696ad08a26bbe49b71a71f0546dc42a075msarett 173b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Assume that the gamma function is continuous, or this won't make much sense anyway. 174b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Plug in |d| to the first equation to calculate the new piecewise interval. 175b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Then simply use the inverse of the original functions. 176b39067696ad08a26bbe49b71a71f0546dc42a075msarett float interval = e * d + f; 177b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (x < interval) { 178b39067696ad08a26bbe49b71a71f0546dc42a075msarett // X = (Y - F) / E 179b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (0.0f == e) { 180b39067696ad08a26bbe49b71a71f0546dc42a075msarett // The gamma curve for this segment is constant, so the inverse is undefined. 181b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Since this is the lower segment, guess zero. 182b39067696ad08a26bbe49b71a71f0546dc42a075msarett return 0.0f; 183b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 184b39067696ad08a26bbe49b71a71f0546dc42a075msarett 185b39067696ad08a26bbe49b71a71f0546dc42a075msarett return (x - f) / e; 186b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 187b39067696ad08a26bbe49b71a71f0546dc42a075msarett 188b39067696ad08a26bbe49b71a71f0546dc42a075msarett // X = ((Y - C)^(1 / G) - B) / A 189b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (0.0f == a || 0.0f == g) { 190b39067696ad08a26bbe49b71a71f0546dc42a075msarett // The gamma curve for this segment is constant, so the inverse is undefined. 191b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Since this is the upper segment, guess one. 192b39067696ad08a26bbe49b71a71f0546dc42a075msarett return 1.0f; 193b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 194b39067696ad08a26bbe49b71a71f0546dc42a075msarett 195b39067696ad08a26bbe49b71a71f0546dc42a075msarett return (powf(x - c, 1.0f / g) - b) / a; 196b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 197b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1981b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, float g, float a, 199b39067696ad08a26bbe49b71a71f0546dc42a075msarett float b, float c, float d, float e, float f) { 2003418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett for (int i = 0; i < kDstGammaTableSize; i++) { 2013418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1))); 202b39067696ad08a26bbe49b71a71f0546dc42a075msarett float y = inverse_parametric(x, g, a, b, c, d, e, f); 203b39067696ad08a26bbe49b71a71f0546dc42a075msarett outTable[i] = clamp_normalized_float_to_byte(y); 204b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 205b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 206b39067696ad08a26bbe49b71a71f0546dc42a075msarett 2076006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 2086006f678e78af7b6f67a454cd4bc213048983f9dmsarett 2091b93bd1e6eba3d14593490e4e24a34546638c8damsaretttemplate <typename T> 2101b93bd1e6eba3d14593490e4e24a34546638c8damsarettstruct GammaFns { 2111b93bd1e6eba3d14593490e4e24a34546638c8damsarett const T* fSRGBTable; 2121b93bd1e6eba3d14593490e4e24a34546638c8damsarett const T* f2Dot2Table; 2131b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromValue)(T*, float); 2141b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromTable)(T*, const float*, int); 2151b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromParam)(T*, float, float, float, float, float, float, float); 2161b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 2171b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2181b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic const GammaFns<float> kToLinear { 2191b93bd1e6eba3d14593490e4e24a34546638c8damsarett sk_linear_from_srgb, 2201b93bd1e6eba3d14593490e4e24a34546638c8damsarett sk_linear_from_2dot2, 2211b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 2221b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 2231b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 2241b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 2251b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2261b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic const GammaFns<uint8_t> kFromLinear { 22755bcc8e0af3415601b3d62252a0d579fbe87c85amsarett nullptr, 22855bcc8e0af3415601b3d62252a0d579fbe87c85amsarett nullptr, 2291b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 2301b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 2311b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 2321b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 2331b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2341b93bd1e6eba3d14593490e4e24a34546638c8damsarett// Build tables to transform src gamma to linear. 2351b93bd1e6eba3d14593490e4e24a34546638c8damsaretttemplate <typename T> 2361b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_gamma_tables(const T* outGammaTables[3], T* gammaTableStorage, int gammaTableSize, 2379488833428e83c93a7e6002f4d056084fb57112fraftias const SkColorSpace_XYZ* space, const GammaFns<T>& fns, 238f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett bool gammasAreMatching) 2394be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett{ 2409488833428e83c93a7e6002f4d056084fb57112fraftias switch (space->gammaNamed()) { 241600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 2421b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.fSRGBTable; 2431b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 244600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 2451b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.f2Dot2Table; 2461b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 247600c737b64eae2c7379442ae2c852853cce3a278msarett case kLinear_SkGammaNamed: 2488bbcd5aab81dc0742c3367479c0c9d97363b1203msarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = nullptr; 2491b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 2501b93bd1e6eba3d14593490e4e24a34546638c8damsarett default: { 2519488833428e83c93a7e6002f4d056084fb57112fraftias const SkGammas* gammas = space->gammas(); 2521b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(gammas); 2531b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2547bbda991af353fbe6b34132132d211d23a3dba8cmsarett auto build_table = [=](int i) { 2551b93bd1e6eba3d14593490e4e24a34546638c8damsarett if (gammas->isNamed(i)) { 2561b93bd1e6eba3d14593490e4e24a34546638c8damsarett switch (gammas->data(i).fNamed) { 257600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 25855bcc8e0af3415601b3d62252a0d579fbe87c85amsarett (*fns.fBuildFromParam)(&gammaTableStorage[i * gammaTableSize], 2.4f, 25955bcc8e0af3415601b3d62252a0d579fbe87c85amsarett (1.0f / 1.055f), (0.055f / 1.055f), 0.0f, 26055bcc8e0af3415601b3d62252a0d579fbe87c85amsarett 0.04045f, (1.0f / 12.92f), 0.0f); 26155bcc8e0af3415601b3d62252a0d579fbe87c85amsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2621b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 263600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 26455bcc8e0af3415601b3d62252a0d579fbe87c85amsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 2.2f); 26555bcc8e0af3415601b3d62252a0d579fbe87c85amsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2661b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 267600c737b64eae2c7379442ae2c852853cce3a278msarett case kLinear_SkGammaNamed: 2681b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 1.0f); 2691b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2701b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 2711b93bd1e6eba3d14593490e4e24a34546638c8damsarett default: 2721b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(false); 2731b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 2741b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2751b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else if (gammas->isValue(i)) { 2761b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 2771b93bd1e6eba3d14593490e4e24a34546638c8damsarett gammas->data(i).fValue); 2781b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2791b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else if (gammas->isTable(i)) { 2801b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromTable)(&gammaTableStorage[i * gammaTableSize], gammas->table(i), 2811b93bd1e6eba3d14593490e4e24a34546638c8damsarett gammas->data(i).fTable.fSize); 2821b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2831b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else { 2841b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(gammas->isParametric(i)); 285df44fc5f2bb282557df291e20dbd26c070533aa6Matt Sarett const SkColorSpaceTransferFn& params = gammas->params(i); 2861b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromParam)(&gammaTableStorage[i * gammaTableSize], params.fG, 2871b93bd1e6eba3d14593490e4e24a34546638c8damsarett params.fA, params.fB, params.fC, params.fD, params.fE, 2881b93bd1e6eba3d14593490e4e24a34546638c8damsarett params.fF); 2891b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2901b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2917bbda991af353fbe6b34132132d211d23a3dba8cmsarett }; 2927bbda991af353fbe6b34132132d211d23a3dba8cmsarett 2937bbda991af353fbe6b34132132d211d23a3dba8cmsarett if (gammasAreMatching) { 2947bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(0); 2957bbda991af353fbe6b34132132d211d23a3dba8cmsarett outGammaTables[1] = outGammaTables[0]; 2967bbda991af353fbe6b34132132d211d23a3dba8cmsarett outGammaTables[2] = outGammaTables[0]; 2977bbda991af353fbe6b34132132d211d23a3dba8cmsarett } else { 2987bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(0); 2997bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(1); 3007bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(2); 3011b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 3027bbda991af353fbe6b34132132d211d23a3dba8cmsarett 3037bbda991af353fbe6b34132132d211d23a3dba8cmsarett break; 3041b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 3051b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 3061b93bd1e6eba3d14593490e4e24a34546638c8damsarett} 3071b93bd1e6eba3d14593490e4e24a34546638c8damsarett 308f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettvoid SkColorSpaceXform_Base::BuildDstGammaTables(const uint8_t* dstGammaTables[3], 3099488833428e83c93a7e6002f4d056084fb57112fraftias uint8_t* dstStorage, 3109488833428e83c93a7e6002f4d056084fb57112fraftias const SkColorSpace_XYZ* space, 311f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett bool gammasAreMatching) { 312f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett build_gamma_tables(dstGammaTables, dstStorage, kDstGammaTableSize, space, kFromLinear, 313f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett gammasAreMatching); 314f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett} 315f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett 3161b93bd1e6eba3d14593490e4e24a34546638c8damsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 3171b93bd1e6eba3d14593490e4e24a34546638c8damsarett 3184be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarettstd::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(SkColorSpace* srcSpace, 3194be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett SkColorSpace* dstSpace) { 3206006f678e78af7b6f67a454cd4bc213048983f9dmsarett if (!srcSpace || !dstSpace) { 3216006f678e78af7b6f67a454cd4bc213048983f9dmsarett // Invalid input 3226006f678e78af7b6f67a454cd4bc213048983f9dmsarett return nullptr; 3236006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 3246006f678e78af7b6f67a454cd4bc213048983f9dmsarett 3259488833428e83c93a7e6002f4d056084fb57112fraftias if (SkColorSpace_Base::Type::kA2B == as_CSB(dstSpace)->type()) { 3262563601fc2b0505619f905f86bd249ae630197ccraftias SkCSXformPrintf("A2B destinations not supported\n"); 3279488833428e83c93a7e6002f4d056084fb57112fraftias return nullptr; 3289488833428e83c93a7e6002f4d056084fb57112fraftias } 3299488833428e83c93a7e6002f4d056084fb57112fraftias 3309488833428e83c93a7e6002f4d056084fb57112fraftias if (SkColorSpace_Base::Type::kA2B == as_CSB(srcSpace)->type()) { 3312563601fc2b0505619f905f86bd249ae630197ccraftias SkColorSpace_A2B* src = static_cast<SkColorSpace_A2B*>(srcSpace); 3322563601fc2b0505619f905f86bd249ae630197ccraftias SkColorSpace_XYZ* dst = static_cast<SkColorSpace_XYZ*>(dstSpace); 3332563601fc2b0505619f905f86bd249ae630197ccraftias return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_A2B(src, dst)); 3349488833428e83c93a7e6002f4d056084fb57112fraftias } 3359488833428e83c93a7e6002f4d056084fb57112fraftias SkColorSpace_XYZ* srcSpaceXYZ = static_cast<SkColorSpace_XYZ*>(srcSpace); 3369488833428e83c93a7e6002f4d056084fb57112fraftias SkColorSpace_XYZ* dstSpaceXYZ = static_cast<SkColorSpace_XYZ*>(dstSpace); 3379488833428e83c93a7e6002f4d056084fb57112fraftias 338200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett ColorSpaceMatch csm = kNone_ColorSpaceMatch; 3396006f678e78af7b6f67a454cd4bc213048983f9dmsarett SkMatrix44 srcToDst(SkMatrix44::kUninitialized_Constructor); 3404be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett if (SkColorSpace::Equals(srcSpace, dstSpace)) { 341200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcToDst.setIdentity(); 342200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett csm = kFull_ColorSpaceMatch; 343971cd496b9e25f87f3a75a0015c203322907136abrianosman } else { 344bbf251bf225489a0939fff6df938035a290f4d16Brian Osman if (srcSpaceXYZ->toXYZD50Hash() == dstSpaceXYZ->toXYZD50Hash()) { 345bbf251bf225489a0939fff6df938035a290f4d16Brian Osman SkASSERT(*srcSpaceXYZ->toXYZD50() == *dstSpaceXYZ->toXYZD50() && "Hash collision"); 346971cd496b9e25f87f3a75a0015c203322907136abrianosman srcToDst.setIdentity(); 347971cd496b9e25f87f3a75a0015c203322907136abrianosman csm = kGamut_ColorSpaceMatch; 348bbf251bf225489a0939fff6df938035a290f4d16Brian Osman } else { 349bbf251bf225489a0939fff6df938035a290f4d16Brian Osman srcToDst.setConcat(*dstSpaceXYZ->fromXYZD50(), *srcSpaceXYZ->toXYZD50()); 350971cd496b9e25f87f3a75a0015c203322907136abrianosman } 3516006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 3526006f678e78af7b6f67a454cd4bc213048983f9dmsarett 353200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett switch (csm) { 354200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kNone_ColorSpaceMatch: 3559488833428e83c93a7e6002f4d056084fb57112fraftias switch (dstSpaceXYZ->gammaNamed()) { 356600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 3579488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 358f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3598bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kSRGB_DstGamma, kNone_ColorSpaceMatch> 3609488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3618bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 362f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3638bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kSRGB_DstGamma, kNone_ColorSpaceMatch> 3649488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3658bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 366600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 3679488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 368f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3698bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, k2Dot2_DstGamma, kNone_ColorSpaceMatch> 3709488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3718bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 372f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3738bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, k2Dot2_DstGamma, kNone_ColorSpaceMatch> 3749488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3758bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 3768bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_SkGammaNamed: 3779488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 378f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3798bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kLinear_DstGamma, kNone_ColorSpaceMatch> 3809488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3818bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 382f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3838bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kLinear_DstGamma, kNone_ColorSpaceMatch> 3849488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3858bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 386200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 3879488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 388f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3898bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch> 3909488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3918bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 392f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3938bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch> 3949488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 3958bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 396200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 397200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kGamut_ColorSpaceMatch: 3989488833428e83c93a7e6002f4d056084fb57112fraftias switch (dstSpaceXYZ->gammaNamed()) { 399600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 4009488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 401f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4028bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kSRGB_DstGamma, kGamut_ColorSpaceMatch> 4039488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4048bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 405f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4068bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kSRGB_DstGamma, kGamut_ColorSpaceMatch> 4079488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4088bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 409600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 4109488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 411f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4128bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, k2Dot2_DstGamma, kGamut_ColorSpaceMatch> 4139488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4148bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 415f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4168bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, k2Dot2_DstGamma, kGamut_ColorSpaceMatch> 4179488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4188bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 4198bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_SkGammaNamed: 4209488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 421f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4228bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kLinear_DstGamma, kGamut_ColorSpaceMatch> 4239488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4248bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 425f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4268bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kLinear_DstGamma, kGamut_ColorSpaceMatch> 4279488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4288bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 429200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 4309488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 431f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4328bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kTable_DstGamma, kGamut_ColorSpaceMatch> 4339488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4348bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 435f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4368bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kTable_DstGamma, kGamut_ColorSpaceMatch> 4379488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4388bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 439200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 440200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kFull_ColorSpaceMatch: 4419488833428e83c93a7e6002f4d056084fb57112fraftias switch (dstSpaceXYZ->gammaNamed()) { 442600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 443f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4448bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kSRGB_DstGamma, kFull_ColorSpaceMatch> 4459488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 446600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 447f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4488bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, k2Dot2_DstGamma, kFull_ColorSpaceMatch> 4499488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4508bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_SkGammaNamed: 451f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4528bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kLinear_DstGamma, kFull_ColorSpaceMatch> 4539488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 454200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 455f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4568bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kTable_DstGamma, kFull_ColorSpaceMatch> 4579488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 458200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 4593418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett default: 460200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkASSERT(false); 461200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return nullptr; 4626006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 4636006f678e78af7b6f67a454cd4bc213048983f9dmsarett} 4646006f678e78af7b6f67a454cd4bc213048983f9dmsarett 4656006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 4666006f678e78af7b6f67a454cd4bc213048983f9dmsarett 467df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett#define AI SK_ALWAYS_INLINE 468df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett 469df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_matrix(const float matrix[16], 470df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rXgXbX, Sk4f& rYgYbY, Sk4f& rZgZbZ, Sk4f& rTgTbT) { 471200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rXgXbX = Sk4f::Load(matrix + 0); 472200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rYgYbY = Sk4f::Load(matrix + 4); 473200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rZgZbZ = Sk4f::Load(matrix + 8); 474200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rTgTbT = Sk4f::Load(matrix + 12); 475200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 476200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 477cf7b877d62537672b67449bc96858cc1262be5f8msarettenum Order { 478cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_Order, 479cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_Order, 480cf7b877d62537672b67449bc96858cc1262be5f8msarett}; 481cf7b877d62537672b67449bc96858cc1262be5f8msarett 482df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void set_rb_shifts(Order kOrder, int* kRShift, int* kBShift) { 483cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kRGBA_Order == kOrder) { 484cf7b877d62537672b67449bc96858cc1262be5f8msarett *kRShift = 0; 485cf7b877d62537672b67449bc96858cc1262be5f8msarett *kBShift = 16; 486cf7b877d62537672b67449bc96858cc1262be5f8msarett } else { 487cf7b877d62537672b67449bc96858cc1262be5f8msarett *kRShift = 16; 488cf7b877d62537672b67449bc96858cc1262be5f8msarett *kBShift = 0; 489cf7b877d62537672b67449bc96858cc1262be5f8msarett } 490cf7b877d62537672b67449bc96858cc1262be5f8msarett} 491cf7b877d62537672b67449bc96858cc1262be5f8msarett 492cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 493df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgb_from_tables(const uint32_t* src, 494df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 495df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 496cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 497cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 498cf7b877d62537672b67449bc96858cc1262be5f8msarett r = { srcTables[0][(src[0] >> kRShift) & 0xFF], 499cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[1] >> kRShift) & 0xFF], 500cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[2] >> kRShift) & 0xFF], 501cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[3] >> kRShift) & 0xFF], }; 502cf7b877d62537672b67449bc96858cc1262be5f8msarett g = { srcTables[1][(src[0] >> kGShift) & 0xFF], 503cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[1] >> kGShift) & 0xFF], 504cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[2] >> kGShift) & 0xFF], 505cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[3] >> kGShift) & 0xFF], }; 506cf7b877d62537672b67449bc96858cc1262be5f8msarett b = { srcTables[2][(src[0] >> kBShift) & 0xFF], 507cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[1] >> kBShift) & 0xFF], 508cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[2] >> kBShift) & 0xFF], 509cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[3] >> kBShift) & 0xFF], }; 510200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett a = 0.0f; // Don't let the compiler complain that |a| is uninitialized. 511200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 512200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 513cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 514df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgba_from_tables(const uint32_t* src, 515df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 516df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 517cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 518cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 519cf7b877d62537672b67449bc96858cc1262be5f8msarett r = { srcTables[0][(src[0] >> kRShift) & 0xFF], 520cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[1] >> kRShift) & 0xFF], 521cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[2] >> kRShift) & 0xFF], 522cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[3] >> kRShift) & 0xFF], }; 5235414be06935ce0f990a2df5dccaf9ddec78ec553msarett g = { srcTables[1][(src[0] >> kGShift) & 0xFF], 524cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[1] >> kGShift) & 0xFF], 525cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[2] >> kGShift) & 0xFF], 526cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[3] >> kGShift) & 0xFF], }; 527cf7b877d62537672b67449bc96858cc1262be5f8msarett b = { srcTables[2][(src[0] >> kBShift) & 0xFF], 528cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[1] >> kBShift) & 0xFF], 529cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[2] >> kBShift) & 0xFF], 530cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[3] >> kBShift) & 0xFF], }; 531200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett a = (1.0f / 255.0f) * SkNx_cast<float>(Sk4u::Load(src) >> 24); 532200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 533200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 534cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 5352563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void load_rgb_linear(const uint32_t* src, Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 536df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const[3]) { 537cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 538cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 539cf7b877d62537672b67449bc96858cc1262be5f8msarett r = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kRShift) & 0xFF); 540cf7b877d62537672b67449bc96858cc1262be5f8msarett g = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kGShift) & 0xFF); 541cf7b877d62537672b67449bc96858cc1262be5f8msarett b = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kBShift) & 0xFF); 542be362774f9b9e8964544a579281603ed995e6e5amsarett a = 0.0f; // Don't let the compiler complain that |a| is uninitialized. 5438bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 5448bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 545cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 5462563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void load_rgba_linear(const uint32_t* src, Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 547df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const[3]) { 548cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 549cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 550cf7b877d62537672b67449bc96858cc1262be5f8msarett r = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kRShift) & 0xFF); 551cf7b877d62537672b67449bc96858cc1262be5f8msarett g = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kGShift) & 0xFF); 552cf7b877d62537672b67449bc96858cc1262be5f8msarett b = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kBShift) & 0xFF); 553cf7b877d62537672b67449bc96858cc1262be5f8msarett a = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> 24)); 5548bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 5558bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 556cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 557df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgb_from_tables_1(const uint32_t* src, 558df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 559df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 560cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 561cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 562cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f(srcTables[0][(*src >> kRShift) & 0xFF]); 563cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f(srcTables[1][(*src >> kGShift) & 0xFF]); 564cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f(srcTables[2][(*src >> kBShift) & 0xFF]); 565a9f64dec63b6f4169ba16f8b6c63fff5a6494029Matt Sarett a = 0.0f; // Don't let MSAN complain that |a| is uninitialized. 566200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 567200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 568cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 569df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgba_from_tables_1(const uint32_t* src, 570df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 571df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 572cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 573cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 574cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f(srcTables[0][(*src >> kRShift) & 0xFF]); 575cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f(srcTables[1][(*src >> kGShift) & 0xFF]); 576cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f(srcTables[2][(*src >> kBShift) & 0xFF]); 577200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett a = (1.0f / 255.0f) * Sk4f(*src >> 24); 578200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 579200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 580cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 581df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgb_linear_1(const uint32_t* src, 582df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 583df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 584cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 585cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 586cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f((1.0f / 255.0f) * ((*src >> kRShift) & 0xFF)); 587cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f((1.0f / 255.0f) * ((*src >> kGShift) & 0xFF)); 588cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f((1.0f / 255.0f) * ((*src >> kBShift) & 0xFF)); 589a9f64dec63b6f4169ba16f8b6c63fff5a6494029Matt Sarett a = 0.0f; // Don't let MSAN complain that |a| is uninitialized. 5908bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 5918bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 592cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 593df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgba_linear_1(const uint32_t* src, 594df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 595df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 596cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 597cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 598cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f((1.0f / 255.0f) * ((*src >> kRShift) & 0xFF)); 599cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f((1.0f / 255.0f) * ((*src >> kGShift) & 0xFF)); 600cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f((1.0f / 255.0f) * ((*src >> kBShift) & 0xFF)); 601cf7b877d62537672b67449bc96858cc1262be5f8msarett a = Sk4f((1.0f / 255.0f) * ((*src >> 24))); 6028bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 6038bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 604df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void transform_gamut(const Sk4f& r, const Sk4f& g, const Sk4f& b, const Sk4f& a, 605df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const Sk4f& rXgXbX, const Sk4f& rYgYbY, const Sk4f& rZgZbZ, 606df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da) { 607200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = rXgXbX[0]*r + rYgYbY[0]*g + rZgZbZ[0]*b; 608200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = rXgXbX[1]*r + rYgYbY[1]*g + rZgZbZ[1]*b; 609200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = rXgXbX[2]*r + rYgYbY[2]*g + rZgZbZ[2]*b; 610200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett da = a; 611200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 612200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 613df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void transform_gamut_1(const Sk4f& r, const Sk4f& g, const Sk4f& b, 614df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const Sk4f& rXgXbX, const Sk4f& rYgYbY, const Sk4f& rZgZbZ, 615df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba) { 616200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = rXgXbX*r + rYgYbY*g + rZgZbZ*b; 617200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 618200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 619df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void translate_gamut(const Sk4f& rTgTbT, Sk4f& dr, Sk4f& dg, Sk4f& db) { 620200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = dr + rTgTbT[0]; 621200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = dg + rTgTbT[1]; 622200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = db + rTgTbT[2]; 623200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 624200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 625df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void translate_gamut_1(const Sk4f& rTgTbT, Sk4f& rgba) { 626200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = rgba + rTgTbT; 627200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 628200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 629df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void premultiply(Sk4f& dr, Sk4f& dg, Sk4f& db, const Sk4f& da) { 630200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = da * dr; 631200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = da * dg; 632200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = da * db; 633200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 634200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 635df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void premultiply_1(const Sk4f& a, Sk4f& rgba) { 636200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = a * rgba; 637200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 638200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 639cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 6402563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_srgb(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 641df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 642cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 643cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 644200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = sk_linear_to_srgb_needs_trunc(dr); 645200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = sk_linear_to_srgb_needs_trunc(dg); 646200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = sk_linear_to_srgb_needs_trunc(db); 647200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 648200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = sk_clamp_0_255(dr); 649200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = sk_clamp_0_255(dg); 650200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = sk_clamp_0_255(db); 651200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 652200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 653200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 654200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i rgba = (SkNx_cast<int>(dr) << kRShift) 655200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (SkNx_cast<int>(dg) << kGShift) 656200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (SkNx_cast<int>(db) << kBShift) 657200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (da ); 658200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba.store(dst); 659200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 660200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 661cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 662df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_srgb_1(void* dst, const uint32_t* src, 663df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f&, 664df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 665200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = sk_clamp_0_255(sk_linear_to_srgb_needs_trunc(rgba)); 666200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 667200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint32_t tmp; 668200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkNx_cast<uint8_t>(SkNx_cast<int32_t>(rgba)).store(&tmp); 669200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = (*src & 0xFF000000) | (tmp & 0x00FFFFFF); 670cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kBGRA_Order == kOrder) { 671200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = SkSwizzle_RB(tmp); 672200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 673200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 674200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *(uint32_t*)dst = tmp; 675200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 676200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 677df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI Sk4f linear_to_2dot2(const Sk4f& x) { 678200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // x^(29/64) is a very good approximation of the true value, x^(1/2.2). 679200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett auto x2 = x.rsqrt(), // x^(-1/2) 680200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett x32 = x2.rsqrt().rsqrt().rsqrt().rsqrt(), // x^(-1/32) 681200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett x64 = x32.rsqrt(); // x^(+1/64) 682200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 683200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // 29 = 32 - 2 - 1 684200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return 255.0f * x2.invert() * x32 * x64.invert(); 685200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 686200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 687cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 6882563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_2dot2(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 689df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 690cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 691cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 692200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = linear_to_2dot2(dr); 693200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = linear_to_2dot2(dg); 694200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = linear_to_2dot2(db); 695200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 696200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = sk_clamp_0_255(dr); 697200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = sk_clamp_0_255(dg); 698200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = sk_clamp_0_255(db); 699200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 700200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 701200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 702200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i rgba = (Sk4f_round(dr) << kRShift) 703200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (Sk4f_round(dg) << kGShift) 704200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (Sk4f_round(db) << kBShift) 705200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (da ); 706200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba.store(dst); 707200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 708200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 709cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 710df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_2dot2_1(void* dst, const uint32_t* src, 711df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f&, 712df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 713200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = sk_clamp_0_255(linear_to_2dot2(rgba)); 714200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 715200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint32_t tmp; 716200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkNx_cast<uint8_t>(Sk4f_round(rgba)).store(&tmp); 717200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = (*src & 0xFF000000) | (tmp & 0x00FFFFFF); 718cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kBGRA_Order == kOrder) { 719200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = SkSwizzle_RB(tmp); 720200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 721200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 722200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *(uint32_t*)dst = tmp; 723200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 724200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 725cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 7262563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_linear(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 727df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 728cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 729cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 730591971d02a8e22dac0955c0f07b7cf500a89d5ccmsarett dr = sk_clamp_0_255(255.0f * dr); 731591971d02a8e22dac0955c0f07b7cf500a89d5ccmsarett dg = sk_clamp_0_255(255.0f * dg); 732591971d02a8e22dac0955c0f07b7cf500a89d5ccmsarett db = sk_clamp_0_255(255.0f * db); 7338bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7348bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 7358bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7368bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Sk4i rgba = (Sk4f_round(dr) << kRShift) 7378bbcd5aab81dc0742c3367479c0c9d97363b1203msarett | (Sk4f_round(dg) << kGShift) 7388bbcd5aab81dc0742c3367479c0c9d97363b1203msarett | (Sk4f_round(db) << kBShift) 7398bbcd5aab81dc0742c3367479c0c9d97363b1203msarett | (da ); 7408bbcd5aab81dc0742c3367479c0c9d97363b1203msarett rgba.store(dst); 7418bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 7428bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 743cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 744df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_linear_1(void* dst, const uint32_t* src, 745df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f&, 746df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 747591971d02a8e22dac0955c0f07b7cf500a89d5ccmsarett rgba = sk_clamp_0_255(255.0f * rgba); 7488bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7498bbcd5aab81dc0742c3367479c0c9d97363b1203msarett uint32_t tmp; 7508bbcd5aab81dc0742c3367479c0c9d97363b1203msarett SkNx_cast<uint8_t>(Sk4f_round(rgba)).store(&tmp); 7518bbcd5aab81dc0742c3367479c0c9d97363b1203msarett tmp = (*src & 0xFF000000) | (tmp & 0x00FFFFFF); 752cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kBGRA_Order == kOrder) { 7538bbcd5aab81dc0742c3367479c0c9d97363b1203msarett tmp = SkSwizzle_RB(tmp); 7548bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 7558bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7568bbcd5aab81dc0742c3367479c0c9d97363b1203msarett *(uint32_t*)dst = tmp; 7578bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 7588bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 759cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 7602563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_f16(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da, 7612563601fc2b0505619f905f86bd249ae630197ccraftias const uint8_t* const[3]) { 76233cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein Sk4h::Store4(dst, SkFloatToHalf_finite_ftz(dr), 76333cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(dg), 76433cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(db), 76533cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(da)); 766200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 767200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 768cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 769df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_f16_1(void* dst, const uint32_t* src, 770df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f& a, 771df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 772200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = Sk4f(rgba[0], rgba[1], rgba[2], a[3]); 7738ae991e433d2c0814ea5579613f00173805ff057mtklein SkFloatToHalf_finite_ftz(rgba).store((uint64_t*) dst); 774200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 775200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 776cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 7772563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_f32(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da, 778df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 77933cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein Sk4f::Store4(dst, dr, dg, db, da); 780c0444615ed76360f680619ad4d1f92cda6181a50msarett} 781c0444615ed76360f680619ad4d1f92cda6181a50msarett 782cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 783df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_f32_1(void* dst, const uint32_t* src, 784df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f& a, 785df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 786c0444615ed76360f680619ad4d1f92cda6181a50msarett rgba = Sk4f(rgba[0], rgba[1], rgba[2], a[3]); 787c0444615ed76360f680619ad4d1f92cda6181a50msarett rgba.store((float*) dst); 788c0444615ed76360f680619ad4d1f92cda6181a50msarett} 789c0444615ed76360f680619ad4d1f92cda6181a50msarett 790cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 7912563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_f16_opaque(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, 7922563601fc2b0505619f905f86bd249ae630197ccraftias Sk4f&, const uint8_t* const[3]) { 79333cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein Sk4h::Store4(dst, SkFloatToHalf_finite_ftz(dr), 79433cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(dg), 79533cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(db), 79633cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SK_Half1); 797200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 798200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 799cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 800df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_f16_1_opaque(void* dst, const uint32_t* src, 801df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f&, 802df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 803200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint64_t tmp; 8048ae991e433d2c0814ea5579613f00173805ff057mtklein SkFloatToHalf_finite_ftz(rgba).store(&tmp); 805200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp |= static_cast<uint64_t>(SK_Half1) << 48; 806200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *((uint64_t*) dst) = tmp; 807200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 808200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 809cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 8102563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_generic(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 8112563601fc2b0505619f905f86bd249ae630197ccraftias const uint8_t* const dstTables[3]) { 812cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 813cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 814200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = Sk4f::Min(Sk4f::Max(1023.0f * dr, 0.0f), 1023.0f); 815200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = Sk4f::Min(Sk4f::Max(1023.0f * dg, 0.0f), 1023.0f); 816200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = Sk4f::Min(Sk4f::Max(1023.0f * db, 0.0f), 1023.0f); 817200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 818200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i ir = Sk4f_round(dr); 819200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i ig = Sk4f_round(dg); 820200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i ib = Sk4f_round(db); 821200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 822200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 823200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 824200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint32_t* dst32 = (uint32_t*) dst; 825200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[0] = dstTables[0][ir[0]] << kRShift 826200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[0]] << kGShift 827200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[0]] << kBShift 828200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[0]; 829200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[1] = dstTables[0][ir[1]] << kRShift 830200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[1]] << kGShift 831200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[1]] << kBShift 832200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[1]; 833200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[2] = dstTables[0][ir[2]] << kRShift 834200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[2]] << kGShift 835200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[2]] << kBShift 836200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[2]; 837200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[3] = dstTables[0][ir[3]] << kRShift 838200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[3]] << kGShift 839200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[3]] << kBShift 840200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[3]; 841200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 842200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 843cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 844df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_generic_1(void* dst, const uint32_t* src, 845df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f&, 846df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const dstTables[3]) { 847cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 848cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 849200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = Sk4f::Min(Sk4f::Max(1023.0f * rgba, 0.0f), 1023.0f); 850200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 851200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i indices = Sk4f_round(rgba); 852200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 8539dc6cf6b8833d36c29a23d2519989b069745fcd5msarett *((uint32_t*) dst) = dstTables[0][indices[0]] << kRShift 8549dc6cf6b8833d36c29a23d2519989b069745fcd5msarett | dstTables[1][indices[1]] << kGShift 8559dc6cf6b8833d36c29a23d2519989b069745fcd5msarett | dstTables[2][indices[2]] << kBShift 856200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (*src & 0xFF000000); 857200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 858200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 859cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(load_rgb_from_tables<kRGBA_Order> )* LoadFn; 860cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(load_rgb_from_tables_1<kRGBA_Order>)* Load1Fn; 861cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(store_generic<kRGBA_Order> )* StoreFn; 862cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(store_generic_1<kRGBA_Order> )* Store1Fn; 8638bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 8648bbcd5aab81dc0742c3367479c0c9d97363b1203msarettenum SrcFormat { 8658bbcd5aab81dc0742c3367479c0c9d97363b1203msarett kRGBA_8888_Linear_SrcFormat, 8668bbcd5aab81dc0742c3367479c0c9d97363b1203msarett kRGBA_8888_Table_SrcFormat, 867cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Linear_SrcFormat, 868cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Table_SrcFormat, 8698bbcd5aab81dc0742c3367479c0c9d97363b1203msarett}; 8708bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 8718bbcd5aab81dc0742c3367479c0c9d97363b1203msarettenum DstFormat { 872cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_Linear_DstFormat, 873cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_SRGB_DstFormat, 874cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_2Dot2_DstFormat, 875cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_Table_DstFormat, 876cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Linear_DstFormat, 877cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_SRGB_DstFormat, 878cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_2Dot2_DstFormat, 879cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Table_DstFormat, 8808bbcd5aab81dc0742c3367479c0c9d97363b1203msarett kF16_Linear_DstFormat, 881c0444615ed76360f680619ad4d1f92cda6181a50msarett kF32_Linear_DstFormat, 8828bbcd5aab81dc0742c3367479c0c9d97363b1203msarett}; 8838bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 8848bbcd5aab81dc0742c3367479c0c9d97363b1203msaretttemplate <SrcFormat kSrc, 8858bbcd5aab81dc0742c3367479c0c9d97363b1203msarett DstFormat kDst, 8868bbcd5aab81dc0742c3367479c0c9d97363b1203msarett SkAlphaType kAlphaType, 887cf7b877d62537672b67449bc96858cc1262be5f8msarett ColorSpaceMatch kCSM> 8885934646b4937a05d5e8297448ea6613a89f8903aMatt Sarettstatic void color_xform_RGBA(void* dst, const void* vsrc, int len, 8895934646b4937a05d5e8297448ea6613a89f8903aMatt Sarett const float* const srcTables[3], const float matrix[16], 8905934646b4937a05d5e8297448ea6613a89f8903aMatt Sarett const uint8_t* const dstTables[3]) { 8918bbcd5aab81dc0742c3367479c0c9d97363b1203msarett LoadFn load; 8928bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Load1Fn load_1; 893c0444615ed76360f680619ad4d1f92cda6181a50msarett static constexpr bool loadAlpha = (kPremul_SkAlphaType == kAlphaType) || 894c0444615ed76360f680619ad4d1f92cda6181a50msarett (kF16_Linear_DstFormat == kDst) || 895c0444615ed76360f680619ad4d1f92cda6181a50msarett (kF32_Linear_DstFormat == kDst); 8968bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kSrc) { 8978bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kRGBA_8888_Linear_SrcFormat: 898c0444615ed76360f680619ad4d1f92cda6181a50msarett if (loadAlpha) { 899cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_linear<kRGBA_Order>; 900cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_linear_1<kRGBA_Order>; 9018bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 902cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_linear<kRGBA_Order>; 903cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_linear_1<kRGBA_Order>; 9048bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 9058bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 9068bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kRGBA_8888_Table_SrcFormat: 907c0444615ed76360f680619ad4d1f92cda6181a50msarett if (loadAlpha) { 908cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_from_tables<kRGBA_Order>; 909cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_from_tables_1<kRGBA_Order>; 9108bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 911cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_from_tables<kRGBA_Order>; 912cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_from_tables_1<kRGBA_Order>; 913cf7b877d62537672b67449bc96858cc1262be5f8msarett } 914cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 915cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Linear_SrcFormat: 916cf7b877d62537672b67449bc96858cc1262be5f8msarett if (loadAlpha) { 917cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_linear<kBGRA_Order>; 918cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_linear_1<kBGRA_Order>; 919cf7b877d62537672b67449bc96858cc1262be5f8msarett } else { 920cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_linear<kBGRA_Order>; 921cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_linear_1<kBGRA_Order>; 922cf7b877d62537672b67449bc96858cc1262be5f8msarett } 923cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 924cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Table_SrcFormat: 925cf7b877d62537672b67449bc96858cc1262be5f8msarett if (loadAlpha) { 926cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_from_tables<kBGRA_Order>; 927cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_from_tables_1<kBGRA_Order>; 928cf7b877d62537672b67449bc96858cc1262be5f8msarett } else { 929cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_from_tables<kBGRA_Order>; 930cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_from_tables_1<kBGRA_Order>; 9318bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 9328bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 9338bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 9348bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 9358bbcd5aab81dc0742c3367479c0c9d97363b1203msarett StoreFn store; 9368bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Store1Fn store_1; 9378bbcd5aab81dc0742c3367479c0c9d97363b1203msarett size_t sizeOfDstPixel; 9388bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kDst) { 939cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_Linear_DstFormat: 940cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_linear<kRGBA_Order>; 941cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_linear_1<kRGBA_Order>; 942cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 943cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 944cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_SRGB_DstFormat: 945cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_srgb<kRGBA_Order>; 946cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_srgb_1<kRGBA_Order>; 947cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 948cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 949cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_2Dot2_DstFormat: 950cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_2dot2<kRGBA_Order>; 951cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_2dot2_1<kRGBA_Order>; 9528bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 9538bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 954cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_Table_DstFormat: 955cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_generic<kRGBA_Order>; 956cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_generic_1<kRGBA_Order>; 9578bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 9588bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 959cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Linear_DstFormat: 960cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_linear<kBGRA_Order>; 961cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_linear_1<kBGRA_Order>; 9628bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 9638bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 964cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_SRGB_DstFormat: 965cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_srgb<kBGRA_Order>; 966cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_srgb_1<kBGRA_Order>; 967cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 968cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 969cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_2Dot2_DstFormat: 970cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_2dot2<kBGRA_Order>; 971cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_2dot2_1<kBGRA_Order>; 972cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 973cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 974cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Table_DstFormat: 975cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_generic<kBGRA_Order>; 976cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_generic_1<kBGRA_Order>; 9778bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 9788bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 9798bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kF16_Linear_DstFormat: 980cf7b877d62537672b67449bc96858cc1262be5f8msarett store = (kOpaque_SkAlphaType == kAlphaType) ? store_f16_opaque<kRGBA_Order> : 981cf7b877d62537672b67449bc96858cc1262be5f8msarett store_f16<kRGBA_Order>; 982cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = (kOpaque_SkAlphaType == kAlphaType) ? store_f16_1_opaque<kRGBA_Order> : 983cf7b877d62537672b67449bc96858cc1262be5f8msarett store_f16_1<kRGBA_Order>; 9848bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 8; 9858bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 986c0444615ed76360f680619ad4d1f92cda6181a50msarett case kF32_Linear_DstFormat: 987cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_f32<kRGBA_Order>; 988cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_f32_1<kRGBA_Order>; 989c0444615ed76360f680619ad4d1f92cda6181a50msarett sizeOfDstPixel = 16; 990c0444615ed76360f680619ad4d1f92cda6181a50msarett break; 9918bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 9928bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 993d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett const uint32_t* src = (const uint32_t*) vsrc; 994d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f rXgXbX, rYgYbY, rZgZbZ, rTgTbT; 995d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load_matrix(matrix, rXgXbX, rYgYbY, rZgZbZ, rTgTbT); 996d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 997d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (len >= 4) { 998d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett // Naively this would be a loop of load-transform-store, but we found it faster to 999d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett // move the N+1th load ahead of the Nth store. We don't bother doing this for N<4. 1000d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f r, g, b, a; 1001d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load(src, r, g, b, a, srcTables); 1002d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett src += 4; 1003d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett len -= 4; 1004d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1005d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f dr, dg, db, da; 1006d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett while (len >= 4) { 1007d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kNone_ColorSpaceMatch == kCSM) { 1008d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett transform_gamut(r, g, b, a, rXgXbX, rYgYbY, rZgZbZ, dr, dg, db, da); 1009d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett translate_gamut(rTgTbT, dr, dg, db); 1010d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } else { 1011d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dr = r; 1012d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dg = g; 1013d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett db = b; 1014d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett da = a; 1015d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1016d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1017d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kPremul_SkAlphaType == kAlphaType) { 1018d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett premultiply(dr, dg, db, da); 1019d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1020d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1021d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load(src, r, g, b, a, srcTables); 1022d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1023d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett store(dst, src - 4, dr, dg, db, da, dstTables); 1024d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dst = SkTAddOffset<void>(dst, 4 * sizeOfDstPixel); 1025d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett src += 4; 1026d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett len -= 4; 1027d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1028d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1029d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kNone_ColorSpaceMatch == kCSM) { 1030d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett transform_gamut(r, g, b, a, rXgXbX, rYgYbY, rZgZbZ, dr, dg, db, da); 1031d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett translate_gamut(rTgTbT, dr, dg, db); 1032d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } else { 1033d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dr = r; 1034d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dg = g; 1035d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett db = b; 1036d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett da = a; 1037d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1038d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1039d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kPremul_SkAlphaType == kAlphaType) { 1040d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett premultiply(dr, dg, db, da); 1041d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1042d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1043d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett store(dst, src - 4, dr, dg, db, da, dstTables); 1044d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dst = SkTAddOffset<void>(dst, 4 * sizeOfDstPixel); 1045d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1046d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1047d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett while (len > 0) { 1048d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f r, g, b, a; 1049d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load_1(src, r, g, b, a, srcTables); 1050d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1051d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f rgba; 1052d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kNone_ColorSpaceMatch == kCSM) { 1053d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett transform_gamut_1(r, g, b, rXgXbX, rYgYbY, rZgZbZ, rgba); 1054d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett translate_gamut_1(rTgTbT, rgba); 1055d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } else { 1056d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett rgba = Sk4f(r[0], g[0], b[0], a[0]); 1057d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1058d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1059d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kPremul_SkAlphaType == kAlphaType) { 1060d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett premultiply_1(a, rgba); 1061d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1062d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1063d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett store_1(dst, src, rgba, a, dstTables); 1064d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1065d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett src += 1; 1066d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett len -= 1; 1067d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dst = SkTAddOffset<void>(dst, sizeOfDstPixel); 1068d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 10698bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 10708bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 10713418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett/////////////////////////////////////////////////////////////////////////////////////////////////// 10720f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 10732563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI int num_tables(SkColorSpace_XYZ* space) { 10749488833428e83c93a7e6002f4d056084fb57112fraftias switch (space->gammaNamed()) { 10757bbda991af353fbe6b34132132d211d23a3dba8cmsarett case kSRGB_SkGammaNamed: 10767bbda991af353fbe6b34132132d211d23a3dba8cmsarett case k2Dot2Curve_SkGammaNamed: 10777bbda991af353fbe6b34132132d211d23a3dba8cmsarett case kLinear_SkGammaNamed: 10787bbda991af353fbe6b34132132d211d23a3dba8cmsarett return 0; 10797bbda991af353fbe6b34132132d211d23a3dba8cmsarett default: { 10809488833428e83c93a7e6002f4d056084fb57112fraftias const SkGammas* gammas = space->gammas(); 10817bbda991af353fbe6b34132132d211d23a3dba8cmsarett SkASSERT(gammas); 10827bbda991af353fbe6b34132132d211d23a3dba8cmsarett 10837bbda991af353fbe6b34132132d211d23a3dba8cmsarett bool gammasAreMatching = (gammas->type(0) == gammas->type(1)) && 10847bbda991af353fbe6b34132132d211d23a3dba8cmsarett (gammas->data(0) == gammas->data(1)) && 10857bbda991af353fbe6b34132132d211d23a3dba8cmsarett (gammas->type(0) == gammas->type(2)) && 10867bbda991af353fbe6b34132132d211d23a3dba8cmsarett (gammas->data(0) == gammas->data(2)); 10877bbda991af353fbe6b34132132d211d23a3dba8cmsarett 10887bbda991af353fbe6b34132132d211d23a3dba8cmsarett // It's likely that each component will have the same gamma. In this case, 10897bbda991af353fbe6b34132132d211d23a3dba8cmsarett // we only need to build one table. 10907bbda991af353fbe6b34132132d211d23a3dba8cmsarett return gammasAreMatching ? 1 : 3; 10917bbda991af353fbe6b34132132d211d23a3dba8cmsarett } 10927bbda991af353fbe6b34132132d211d23a3dba8cmsarett } 10937bbda991af353fbe6b34132132d211d23a3dba8cmsarett} 10947bbda991af353fbe6b34132132d211d23a3dba8cmsarett 10958bbcd5aab81dc0742c3367479c0c9d97363b1203msaretttemplate <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM> 1096f489886915034093278353d06c6f1973b2e8b7d2Matt SarettSkColorSpaceXform_XYZ<kSrc, kDst, kCSM> 10979488833428e83c93a7e6002f4d056084fb57112fraftias::SkColorSpaceXform_XYZ(SkColorSpace_XYZ* srcSpace, const SkMatrix44& srcToDst, 10989488833428e83c93a7e6002f4d056084fb57112fraftias SkColorSpace_XYZ* dstSpace) 10993418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett{ 1100de68d6c4616d86621373d88100002ddfdb9c08e3brianosman srcToDst.asColMajorf(fSrcToDst); 11017bbda991af353fbe6b34132132d211d23a3dba8cmsarett 11024be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett const int numSrcTables = num_tables(srcSpace); 1103f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett const size_t srcEntries = numSrcTables * 256; 11047bbda991af353fbe6b34132132d211d23a3dba8cmsarett const bool srcGammasAreMatching = (1 >= numSrcTables); 1105f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett fSrcStorage.reset(srcEntries); 1106f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett build_gamma_tables(fSrcGammaTables, fSrcStorage.get(), 256, srcSpace, kToLinear, 1107f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett srcGammasAreMatching); 1108f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett 1109f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett const int numDstTables = num_tables(dstSpace); 11109488833428e83c93a7e6002f4d056084fb57112fraftias dstSpace->toDstGammaTables(fDstGammaTables, &fDstStorage, numDstTables); 11113418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett} 1112dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 11137bbda991af353fbe6b34132132d211d23a3dba8cmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 11147bbda991af353fbe6b34132132d211d23a3dba8cmsarett 1115cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <SrcFormat kSrc, DstFormat kDst, ColorSpaceMatch kCSM> 1116df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI bool apply_set_alpha(void* dst, const void* src, int len, SkAlphaType alphaType, 1117df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3], const float matrix[16], 1118df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const dstTables[3]) { 11198bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (alphaType) { 11208bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kOpaque_SkAlphaType: 112131d097e865f266c8398f45114e4c75c0dfdef058msarett color_xform_RGBA<kSrc, kDst, kOpaque_SkAlphaType, kCSM> 11228bbcd5aab81dc0742c3367479c0c9d97363b1203msarett (dst, src, len, srcTables, matrix, dstTables); 112331d097e865f266c8398f45114e4c75c0dfdef058msarett return true; 11248bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kPremul_SkAlphaType: 112531d097e865f266c8398f45114e4c75c0dfdef058msarett color_xform_RGBA<kSrc, kDst, kPremul_SkAlphaType, kCSM> 11268bbcd5aab81dc0742c3367479c0c9d97363b1203msarett (dst, src, len, srcTables, matrix, dstTables); 112731d097e865f266c8398f45114e4c75c0dfdef058msarett return true; 11288bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kUnpremul_SkAlphaType: 112931d097e865f266c8398f45114e4c75c0dfdef058msarett color_xform_RGBA<kSrc, kDst, kUnpremul_SkAlphaType, kCSM> 11308bbcd5aab81dc0742c3367479c0c9d97363b1203msarett (dst, src, len, srcTables, matrix, dstTables); 113131d097e865f266c8398f45114e4c75c0dfdef058msarett return true; 11328bbcd5aab81dc0742c3367479c0c9d97363b1203msarett default: 113331d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 11348bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 11358bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 11368bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 1137cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <SrcGamma kSrc, DstFormat kDst, ColorSpaceMatch kCSM> 1138df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI bool apply_set_src(void* dst, const void* src, int len, SkAlphaType alphaType, 1139df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3], const float matrix[16], 1140df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const dstTables[3], 1141df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett SkColorSpaceXform::ColorFormat srcColorFormat) { 1142cf7b877d62537672b67449bc96858cc1262be5f8msarett switch (srcColorFormat) { 1143cf7b877d62537672b67449bc96858cc1262be5f8msarett case SkColorSpaceXform::kRGBA_8888_ColorFormat: 1144cf7b877d62537672b67449bc96858cc1262be5f8msarett switch (kSrc) { 1145cf7b877d62537672b67449bc96858cc1262be5f8msarett case kLinear_SrcGamma: 1146cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kRGBA_8888_Linear_SrcFormat, kDst, kCSM> 1147cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, nullptr, matrix, dstTables); 1148cf7b877d62537672b67449bc96858cc1262be5f8msarett case kTable_SrcGamma: 1149cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kRGBA_8888_Table_SrcFormat, kDst, kCSM> 1150cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, srcTables, matrix, dstTables); 1151cf7b877d62537672b67449bc96858cc1262be5f8msarett } 1152cf7b877d62537672b67449bc96858cc1262be5f8msarett case SkColorSpaceXform::kBGRA_8888_ColorFormat: 1153cf7b877d62537672b67449bc96858cc1262be5f8msarett switch (kSrc) { 1154cf7b877d62537672b67449bc96858cc1262be5f8msarett case kLinear_SrcGamma: 1155cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kBGRA_8888_Linear_SrcFormat, kDst, kCSM> 1156cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, nullptr, matrix, dstTables); 1157cf7b877d62537672b67449bc96858cc1262be5f8msarett case kTable_SrcGamma: 1158cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kBGRA_8888_Table_SrcFormat, kDst, kCSM> 1159cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, srcTables, matrix, dstTables); 1160cf7b877d62537672b67449bc96858cc1262be5f8msarett } 1161cf7b877d62537672b67449bc96858cc1262be5f8msarett default: 116231d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 11638bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 11648bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 11658bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 1166df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett#undef AI 1167df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett 11688bbcd5aab81dc0742c3367479c0c9d97363b1203msaretttemplate <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM> 1169f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettbool SkColorSpaceXform_XYZ<kSrc, kDst, kCSM> 117031d097e865f266c8398f45114e4c75c0dfdef058msarett::onApply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, const void* src, 117131d097e865f266c8398f45114e4c75c0dfdef058msarett int len, SkAlphaType alphaType) const 11723418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett{ 1173200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kFull_ColorSpaceMatch == kCSM) { 11748bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (alphaType) { 1175200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kPremul_SkAlphaType: 1176200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // We can't skip the xform since we need to perform a premultiply in the 1177200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // linear space. 1178200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett break; 1179200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 1180c0444615ed76360f680619ad4d1f92cda6181a50msarett switch (dstColorFormat) { 1181c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_8888_ColorFormat: 118231d097e865f266c8398f45114e4c75c0dfdef058msarett memcpy(dst, src, len * sizeof(uint32_t)); 118331d097e865f266c8398f45114e4c75c0dfdef058msarett return true; 1184c0444615ed76360f680619ad4d1f92cda6181a50msarett case kBGRA_8888_ColorFormat: 118531d097e865f266c8398f45114e4c75c0dfdef058msarett SkOpts::RGBA_to_BGRA((uint32_t*) dst, src, len); 118631d097e865f266c8398f45114e4c75c0dfdef058msarett return true; 1187c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_F16_ColorFormat: 1188c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_F32_ColorFormat: 1189c0444615ed76360f680619ad4d1f92cda6181a50msarett // There's still work to do to xform to linear floats. 1190200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett break; 1191200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 119231d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 1193200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1194200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1195200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1196200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1197c0444615ed76360f680619ad4d1f92cda6181a50msarett switch (dstColorFormat) { 1198c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_8888_ColorFormat: 11998bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kDst) { 12008bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_DstGamma: 1201cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kRGBA_8888_Linear_DstFormat, kCSM> 1202cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1203cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12048bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kSRGB_DstGamma: 1205cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kRGBA_8888_SRGB_DstFormat, kCSM> 1206cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1207cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12088bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case k2Dot2_DstGamma: 1209cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kRGBA_8888_2Dot2_DstFormat, kCSM> 1210cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1211cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12128bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kTable_DstGamma: 1213cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kRGBA_8888_Table_DstFormat, kCSM> 1214cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, fDstGammaTables, 1215cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 1216d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 1217c0444615ed76360f680619ad4d1f92cda6181a50msarett case kBGRA_8888_ColorFormat: 12188bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kDst) { 12198bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_DstGamma: 1220cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kBGRA_8888_Linear_DstFormat, kCSM> 1221cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1222cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12238bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kSRGB_DstGamma: 1224cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kBGRA_8888_SRGB_DstFormat, kCSM> 1225cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1226cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12278bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case k2Dot2_DstGamma: 1228cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kBGRA_8888_2Dot2_DstFormat, kCSM> 1229cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1230cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12318bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kTable_DstGamma: 1232cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kBGRA_8888_Table_DstFormat, kCSM> 1233cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, fDstGammaTables, 1234cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 1235d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 1236c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_F16_ColorFormat: 12378bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kDst) { 12388bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_DstGamma: 1239cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kF16_Linear_DstFormat, kCSM> 1240cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1241cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 1242d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett default: 124331d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 1244d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 1245c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_F32_ColorFormat: 1246c0444615ed76360f680619ad4d1f92cda6181a50msarett switch (kDst) { 1247c0444615ed76360f680619ad4d1f92cda6181a50msarett case kLinear_DstGamma: 1248cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kF32_Linear_DstFormat, kCSM> 1249cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1250cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 1251c0444615ed76360f680619ad4d1f92cda6181a50msarett default: 125231d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 1253c0444615ed76360f680619ad4d1f92cda6181a50msarett } 1254d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett default: 125531d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 1256d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 12579ce3a543c92a73e6daca420defc042886b3f2019msarett} 12589dc6cf6b8833d36c29a23d2519989b069745fcd5msarett 1259f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettbool SkColorSpaceXform::apply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, 1260f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett const void* src, int len, SkAlphaType alphaType) const { 1261f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return ((SkColorSpaceXform_Base*) this)->onApply(dstColorFormat, dst, srcColorFormat, src, len, 1262f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett alphaType); 1263f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett} 1264f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett 12657bbda991af353fbe6b34132132d211d23a3dba8cmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 12667bbda991af353fbe6b34132132d211d23a3dba8cmsarett 12679488833428e83c93a7e6002f4d056084fb57112fraftiasstd::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace_XYZ* space) { 1268f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 12698bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch> 12709dc6cf6b8833d36c29a23d2519989b069745fcd5msarett (space, SkMatrix::I(), space)); 12719dc6cf6b8833d36c29a23d2519989b069745fcd5msarett} 1272