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" 185e15961fa77281540a80ac0d036fefe071c11574Mike Klein#include "SkPM4fPriv.h" 19f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett#include "SkRasterPipeline.h" 20ac41bac40f5a80d2bc5ccec584c23478a6900179mtklein#include "SkSRGB.h" 219876ac5b3016e5353c072378ac1545a0a2270757msarett 226006f678e78af7b6f67a454cd4bc213048983f9dmsarettstatic constexpr float sk_linear_from_2dot2[256] = { 23b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000000000000000000f, 0.000005077051900662f, 0.000023328004666099f, 0.000056921765712193f, 24b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000107187362341244f, 0.000175123977503027f, 0.000261543754548491f, 0.000367136269815943f, 25b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000492503787191433f, 0.000638182842167022f, 0.000804658499513058f, 0.000992374304074325f, 26b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.001201739522438400f, 0.001433134589671860f, 0.001686915316789280f, 0.001963416213396470f, 27b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.002262953160706430f, 0.002585825596234170f, 0.002932318323938360f, 0.003302703032003640f, 28b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.003697239578900130f, 0.004116177093282750f, 0.004559754922526020f, 0.005028203456855540f, 29b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.005521744850239660f, 0.006040593654849810f, 0.006584957382581690f, 0.007155037004573030f, 30b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.007751027397660610f, 0.008373117745148580f, 0.009021491898012130f, 0.009696328701658230f, 31b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.010397802292555300f, 0.011126082368383200f, 0.011881334434813700f, 0.012663720031582100f, 32b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.013473396940142600f, 0.014310519374884100f, 0.015175238159625200f, 0.016067700890886900f, 33b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.016988052089250000f, 0.017936433339950200f, 0.018912983423721500f, 0.019917838438785700f, 34b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.020951131914781100f, 0.022012994919336500f, 0.023103556157921400f, 0.024222942067534200f, 35b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.025371276904734600f, 0.026548682828472900f, 0.027755279978126000f, 0.028991186547107800f, 36b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.030256518852388700f, 0.031551391400226400f, 0.032875916948383800f, 0.034230206565082000f, 37b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.035614369684918800f, 0.037028514161960200f, 0.038472746320194600f, 0.039947171001525600f, 38b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.041451891611462500f, 0.042987010162657100f, 0.044552627316421400f, 0.046148842422351000f, 39b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.047775753556170600f, 0.049433457555908000f, 0.051122050056493400f, 0.052841625522879000f, 40b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.054592277281760300f, 0.056374097551979800f, 0.058187177473685400f, 0.060031607136313200f, 41b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.061907475605455800f, 0.063814870948677200f, 0.065753880260330100f, 0.067724589685424300f, 42b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.069727084442598800f, 0.071761448846239100f, 0.073827766327784600f, 0.075926119456264800f, 43b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.078056589958101900f, 0.080219258736215100f, 0.082414205888459200f, 0.084641510725429500f, 44b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.086901251787660300f, 0.089193506862247800f, 0.091518352998919500f, 0.093875866525577800f, 45b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.096266123063339700f, 0.098689197541094500f, 0.101145164209600000f, 0.103634096655137000f, 46b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.106156067812744000f, 0.108711149979039000f, 0.111299414824660000f, 0.113920933406333000f, 47b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.116575776178572000f, 0.119264013005047000f, 0.121985713169619000f, 0.124740945387051000f, 48b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.127529777813422000f, 0.130352278056244000f, 0.133208513184300000f, 0.136098549737202000f, 49b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.139022453734703000f, 0.141980290685736000f, 0.144972125597231000f, 0.147998022982685000f, 50b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.151058046870511000f, 0.154152260812165000f, 0.157280727890073000f, 0.160443510725344000f, 51b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.163640671485290000f, 0.166872271890766000f, 0.170138373223312000f, 0.173439036332135000f, 52b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.176774321640903000f, 0.180144289154390000f, 0.183548998464951000f, 0.186988508758844000f, 53b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.190462878822409000f, 0.193972167048093000f, 0.197516431440340000f, 0.201095729621346000f, 54b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.204710118836677000f, 0.208359655960767000f, 0.212044397502288000f, 0.215764399609395000f, 55b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.219519718074868000f, 0.223310408341127000f, 0.227136525505149000f, 0.230998124323267000f, 56b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.234895259215880000f, 0.238827984272048000f, 0.242796353254002000f, 0.246800419601550000f, 57b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.250840236436400000f, 0.254915856566385000f, 0.259027332489606000f, 0.263174716398492000f, 58b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.267358060183772000f, 0.271577415438375000f, 0.275832833461245000f, 0.280124365261085000f, 59b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.284452061560024000f, 0.288815972797219000f, 0.293216149132375000f, 0.297652640449211000f, 60b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.302125496358853000f, 0.306634766203158000f, 0.311180499057984000f, 0.315762743736397000f, 61b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.320381548791810000f, 0.325036962521076000f, 0.329729032967515000f, 0.334457807923889000f, 62b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.339223334935327000f, 0.344025661302187000f, 0.348864834082879000f, 0.353740900096629000f, 63b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.358653905926199000f, 0.363603897920553000f, 0.368590922197487000f, 0.373615024646202000f, 64b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.378676250929840000f, 0.383774646487975000f, 0.388910256539059000f, 0.394083126082829000f, 65b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.399293299902674000f, 0.404540822567962000f, 0.409825738436323000f, 0.415148091655907000f, 66b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.420507926167587000f, 0.425905285707146000f, 0.431340213807410000f, 0.436812753800359000f, 67b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.442322948819202000f, 0.447870841800410000f, 0.453456475485731000f, 0.459079892424160000f, 68b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.464741134973889000f, 0.470440245304218000f, 0.476177265397440000f, 0.481952237050698000f, 69b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.487765201877811000f, 0.493616201311074000f, 0.499505276603030000f, 0.505432468828216000f, 70b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.511397818884880000f, 0.517401367496673000f, 0.523443155214325000f, 0.529523222417277000f, 71b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.535641609315311000f, 0.541798355950137000f, 0.547993502196972000f, 0.554227087766085000f, 72b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.560499152204328000f, 0.566809734896638000f, 0.573158875067523000f, 0.579546611782525000f, 73b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.585972983949661000f, 0.592438030320847000f, 0.598941789493296000f, 0.605484299910907000f, 74b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.612065599865624000f, 0.618685727498780000f, 0.625344720802427000f, 0.632042617620641000f, 75b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.638779455650817000f, 0.645555272444935000f, 0.652370105410821000f, 0.659223991813387000f, 76b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.666116968775851000f, 0.673049073280942000f, 0.680020342172095000f, 0.687030812154625000f, 77b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.694080519796882000f, 0.701169501531402000f, 0.708297793656032000f, 0.715465432335048000f, 78b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.722672453600255000f, 0.729918893352071000f, 0.737204787360605000f, 0.744530171266715000f, 79b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.751895080583051000f, 0.759299550695091000f, 0.766743616862161000f, 0.774227314218442000f, 80b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.781750677773962000f, 0.789313742415586000f, 0.796916542907978000f, 0.804559113894567000f, 81b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.812241489898490000f, 0.819963705323528000f, 0.827725794455034000f, 0.835527791460841000f, 82b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.843369730392169000f, 0.851251645184515000f, 0.859173569658532000f, 0.867135537520905000f, 83b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.875137582365205000f, 0.883179737672745000f, 0.891262036813419000f, 0.899384513046529000f, 84b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.907547199521614000f, 0.915750129279253000f, 0.923993335251873000f, 0.932276850264543000f, 85b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.940600707035753000f, 0.948964938178195000f, 0.957369576199527000f, 0.965814653503130000f, 86b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.974300202388861000f, 0.982826255053791000f, 0.991392843592940000f, 1.000000000000000000f, 87b39067696ad08a26bbe49b71a71f0546dc42a075msarett}; 88b39067696ad08a26bbe49b71a71f0546dc42a075msarett 896006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 906006f678e78af7b6f67a454cd4bc213048983f9dmsarett 9115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, float exponent) { 9215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 9315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = powf(x, exponent); 9415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 9515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 9615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 9715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett// outTable is always 256 entries, inTable may be larger or smaller. 9815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, const float* inTable, 9915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett int inTableSize) { 10015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett if (256 == inTableSize) { 10115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett memcpy(outTable, inTable, sizeof(float) * 256); 10215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett return; 10315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 10415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 10515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 10615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = interp_lut(x, inTable, inTableSize); 10715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 10815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 10915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 110aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett 11115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, float g, float a, float b, float c, 11215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett float d, float e, float f) { 1132410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett // Y = (aX + b)^g + e for X >= d 1142410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett // Y = cX + f otherwise 11515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 11615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett if (x >= d) { 1172410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett *outTable++ = clamp_0_1(powf(a * x + b, g) + e); 11815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } else { 1192410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett *outTable++ = clamp_0_1(c * x + f); 12015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 12115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 12215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 12315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 12415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 12515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 126f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettstatic const int kDstGammaTableSize = SkColorSpaceXform_Base::kDstGammaTableSize; 1273418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett 1281b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, float exponent) { 129b39067696ad08a26bbe49b71a71f0546dc42a075msarett float toGammaExp = 1.0f / exponent; 130b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1313418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett for (int i = 0; i < kDstGammaTableSize; i++) { 1323418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1))); 133b39067696ad08a26bbe49b71a71f0546dc42a075msarett outTable[i] = clamp_normalized_float_to_byte(powf(x, toGammaExp)); 134b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 135dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett} 136dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 1371b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, const float* inTable, 138b39067696ad08a26bbe49b71a71f0546dc42a075msarett int inTableSize) { 139197e311ac9d15696fae929d8f5fcf9d93ec55e18raftias invert_table_gamma(nullptr, outTable, kDstGammaTableSize, inTable, inTableSize); 140b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 141dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 142b39067696ad08a26bbe49b71a71f0546dc42a075msarettstatic float inverse_parametric(float x, float g, float a, float b, float c, float d, float e, 143b39067696ad08a26bbe49b71a71f0546dc42a075msarett float f) { 144b39067696ad08a26bbe49b71a71f0546dc42a075msarett // We need to take the inverse of the following piecewise function. 145b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Y = (aX + b)^g + c for X >= d 146b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Y = eX + f otherwise 147b39067696ad08a26bbe49b71a71f0546dc42a075msarett 148b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Assume that the gamma function is continuous, or this won't make much sense anyway. 149b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Plug in |d| to the first equation to calculate the new piecewise interval. 150b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Then simply use the inverse of the original functions. 1512410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett float interval = c * d + f; 152b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (x < interval) { 1532410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett // X = (Y - F) / C 1542410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett if (0.0f == c) { 155b39067696ad08a26bbe49b71a71f0546dc42a075msarett // The gamma curve for this segment is constant, so the inverse is undefined. 156b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Since this is the lower segment, guess zero. 157b39067696ad08a26bbe49b71a71f0546dc42a075msarett return 0.0f; 158b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 159b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1602410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett return (x - f) / c; 161b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 162b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1632410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett // X = ((Y - E)^(1 / G) - B) / A 164b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (0.0f == a || 0.0f == g) { 165b39067696ad08a26bbe49b71a71f0546dc42a075msarett // The gamma curve for this segment is constant, so the inverse is undefined. 166b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Since this is the upper segment, guess one. 167b39067696ad08a26bbe49b71a71f0546dc42a075msarett return 1.0f; 168b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 169b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1702410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett return (powf(x - e, 1.0f / g) - b) / a; 171b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 172b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1731b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, float g, float a, 174b39067696ad08a26bbe49b71a71f0546dc42a075msarett float b, float c, float d, float e, float f) { 1753418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett for (int i = 0; i < kDstGammaTableSize; i++) { 1763418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1))); 177b39067696ad08a26bbe49b71a71f0546dc42a075msarett float y = inverse_parametric(x, g, a, b, c, d, e, f); 178b39067696ad08a26bbe49b71a71f0546dc42a075msarett outTable[i] = clamp_normalized_float_to_byte(y); 179b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 180b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 181b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1826006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 1836006f678e78af7b6f67a454cd4bc213048983f9dmsarett 1841b93bd1e6eba3d14593490e4e24a34546638c8damsaretttemplate <typename T> 1851b93bd1e6eba3d14593490e4e24a34546638c8damsarettstruct GammaFns { 1861b93bd1e6eba3d14593490e4e24a34546638c8damsarett const T* fSRGBTable; 1871b93bd1e6eba3d14593490e4e24a34546638c8damsarett const T* f2Dot2Table; 1881b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromValue)(T*, float); 1891b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromTable)(T*, const float*, int); 1901b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromParam)(T*, float, float, float, float, float, float, float); 1911b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 1921b93bd1e6eba3d14593490e4e24a34546638c8damsarett 1931b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic const GammaFns<float> kToLinear { 1941b93bd1e6eba3d14593490e4e24a34546638c8damsarett sk_linear_from_srgb, 1951b93bd1e6eba3d14593490e4e24a34546638c8damsarett sk_linear_from_2dot2, 1961b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 1971b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 1981b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 1991b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 2001b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2011b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic const GammaFns<uint8_t> kFromLinear { 20255bcc8e0af3415601b3d62252a0d579fbe87c85amsarett nullptr, 20355bcc8e0af3415601b3d62252a0d579fbe87c85amsarett nullptr, 2041b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 2051b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 2061b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 2071b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 2081b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2091b93bd1e6eba3d14593490e4e24a34546638c8damsarett// Build tables to transform src gamma to linear. 2101b93bd1e6eba3d14593490e4e24a34546638c8damsaretttemplate <typename T> 2111b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_gamma_tables(const T* outGammaTables[3], T* gammaTableStorage, int gammaTableSize, 2129488833428e83c93a7e6002f4d056084fb57112fraftias const SkColorSpace_XYZ* space, const GammaFns<T>& fns, 213f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett bool gammasAreMatching) 2144be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett{ 2159488833428e83c93a7e6002f4d056084fb57112fraftias switch (space->gammaNamed()) { 216600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 2171b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.fSRGBTable; 2181b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 219600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 2201b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.f2Dot2Table; 2211b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 222600c737b64eae2c7379442ae2c852853cce3a278msarett case kLinear_SkGammaNamed: 2238bbcd5aab81dc0742c3367479c0c9d97363b1203msarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = nullptr; 2241b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 2251b93bd1e6eba3d14593490e4e24a34546638c8damsarett default: { 2269488833428e83c93a7e6002f4d056084fb57112fraftias const SkGammas* gammas = space->gammas(); 2271b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(gammas); 2281b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2297bbda991af353fbe6b34132132d211d23a3dba8cmsarett auto build_table = [=](int i) { 2301b93bd1e6eba3d14593490e4e24a34546638c8damsarett if (gammas->isNamed(i)) { 2311b93bd1e6eba3d14593490e4e24a34546638c8damsarett switch (gammas->data(i).fNamed) { 232600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 23355bcc8e0af3415601b3d62252a0d579fbe87c85amsarett (*fns.fBuildFromParam)(&gammaTableStorage[i * gammaTableSize], 2.4f, 2342410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett (1.0f / 1.055f), (0.055f / 1.055f), 2352410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett (1.0f / 12.92f), 0.04045f, 0.0f, 0.0f); 23655bcc8e0af3415601b3d62252a0d579fbe87c85amsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2371b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 238600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 23955bcc8e0af3415601b3d62252a0d579fbe87c85amsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 2.2f); 24055bcc8e0af3415601b3d62252a0d579fbe87c85amsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2411b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 242600c737b64eae2c7379442ae2c852853cce3a278msarett case kLinear_SkGammaNamed: 2431b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 1.0f); 2441b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2451b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 2461b93bd1e6eba3d14593490e4e24a34546638c8damsarett default: 2471b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(false); 2481b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 2491b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2501b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else if (gammas->isValue(i)) { 2511b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 2521b93bd1e6eba3d14593490e4e24a34546638c8damsarett gammas->data(i).fValue); 2531b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2541b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else if (gammas->isTable(i)) { 2551b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromTable)(&gammaTableStorage[i * gammaTableSize], gammas->table(i), 2561b93bd1e6eba3d14593490e4e24a34546638c8damsarett gammas->data(i).fTable.fSize); 2571b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2581b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else { 2591b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(gammas->isParametric(i)); 260df44fc5f2bb282557df291e20dbd26c070533aa6Matt Sarett const SkColorSpaceTransferFn& params = gammas->params(i); 2611b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromParam)(&gammaTableStorage[i * gammaTableSize], params.fG, 2621b93bd1e6eba3d14593490e4e24a34546638c8damsarett params.fA, params.fB, params.fC, params.fD, params.fE, 2631b93bd1e6eba3d14593490e4e24a34546638c8damsarett params.fF); 2641b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2651b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2667bbda991af353fbe6b34132132d211d23a3dba8cmsarett }; 2677bbda991af353fbe6b34132132d211d23a3dba8cmsarett 2687bbda991af353fbe6b34132132d211d23a3dba8cmsarett if (gammasAreMatching) { 2697bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(0); 2707bbda991af353fbe6b34132132d211d23a3dba8cmsarett outGammaTables[1] = outGammaTables[0]; 2717bbda991af353fbe6b34132132d211d23a3dba8cmsarett outGammaTables[2] = outGammaTables[0]; 2727bbda991af353fbe6b34132132d211d23a3dba8cmsarett } else { 2737bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(0); 2747bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(1); 2757bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(2); 2761b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2777bbda991af353fbe6b34132132d211d23a3dba8cmsarett 2787bbda991af353fbe6b34132132d211d23a3dba8cmsarett break; 2791b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2801b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2811b93bd1e6eba3d14593490e4e24a34546638c8damsarett} 2821b93bd1e6eba3d14593490e4e24a34546638c8damsarett 283f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettvoid SkColorSpaceXform_Base::BuildDstGammaTables(const uint8_t* dstGammaTables[3], 2849488833428e83c93a7e6002f4d056084fb57112fraftias uint8_t* dstStorage, 2859488833428e83c93a7e6002f4d056084fb57112fraftias const SkColorSpace_XYZ* space, 286f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett bool gammasAreMatching) { 287f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett build_gamma_tables(dstGammaTables, dstStorage, kDstGammaTableSize, space, kFromLinear, 288f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett gammasAreMatching); 289f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett} 290f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett 2911b93bd1e6eba3d14593490e4e24a34546638c8damsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 2921b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2934be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarettstd::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(SkColorSpace* srcSpace, 2944be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett SkColorSpace* dstSpace) { 295cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett return SkColorSpaceXform_Base::New(srcSpace, dstSpace, SkTransferFunctionBehavior::kRespect); 296cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett} 297cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett 298cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarettstd::unique_ptr<SkColorSpaceXform> SkColorSpaceXform_Base::New(SkColorSpace* srcSpace, 299cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett SkColorSpace* dstSpace, SkTransferFunctionBehavior premulBehavior) { 300cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett 3016006f678e78af7b6f67a454cd4bc213048983f9dmsarett if (!srcSpace || !dstSpace) { 3026006f678e78af7b6f67a454cd4bc213048983f9dmsarett // Invalid input 3036006f678e78af7b6f67a454cd4bc213048983f9dmsarett return nullptr; 3046006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 3056006f678e78af7b6f67a454cd4bc213048983f9dmsarett 3069488833428e83c93a7e6002f4d056084fb57112fraftias if (SkColorSpace_Base::Type::kA2B == as_CSB(dstSpace)->type()) { 3072563601fc2b0505619f905f86bd249ae630197ccraftias SkCSXformPrintf("A2B destinations not supported\n"); 3089488833428e83c93a7e6002f4d056084fb57112fraftias return nullptr; 3099488833428e83c93a7e6002f4d056084fb57112fraftias } 3109488833428e83c93a7e6002f4d056084fb57112fraftias 3119488833428e83c93a7e6002f4d056084fb57112fraftias if (SkColorSpace_Base::Type::kA2B == as_CSB(srcSpace)->type()) { 3122563601fc2b0505619f905f86bd249ae630197ccraftias SkColorSpace_A2B* src = static_cast<SkColorSpace_A2B*>(srcSpace); 3132563601fc2b0505619f905f86bd249ae630197ccraftias SkColorSpace_XYZ* dst = static_cast<SkColorSpace_XYZ*>(dstSpace); 3142563601fc2b0505619f905f86bd249ae630197ccraftias return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_A2B(src, dst)); 3159488833428e83c93a7e6002f4d056084fb57112fraftias } 3169488833428e83c93a7e6002f4d056084fb57112fraftias SkColorSpace_XYZ* srcSpaceXYZ = static_cast<SkColorSpace_XYZ*>(srcSpace); 3179488833428e83c93a7e6002f4d056084fb57112fraftias SkColorSpace_XYZ* dstSpaceXYZ = static_cast<SkColorSpace_XYZ*>(dstSpace); 3189488833428e83c93a7e6002f4d056084fb57112fraftias 319200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett ColorSpaceMatch csm = kNone_ColorSpaceMatch; 3206006f678e78af7b6f67a454cd4bc213048983f9dmsarett SkMatrix44 srcToDst(SkMatrix44::kUninitialized_Constructor); 321f3880933092c3226cd7ffd1690fe72c9c0cc376cMatt Sarett if (SkColorSpace::Equals(srcSpace, dstSpace)) { 322200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcToDst.setIdentity(); 323200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett csm = kFull_ColorSpaceMatch; 324971cd496b9e25f87f3a75a0015c203322907136abrianosman } else { 325bbf251bf225489a0939fff6df938035a290f4d16Brian Osman if (srcSpaceXYZ->toXYZD50Hash() == dstSpaceXYZ->toXYZD50Hash()) { 326bbf251bf225489a0939fff6df938035a290f4d16Brian Osman SkASSERT(*srcSpaceXYZ->toXYZD50() == *dstSpaceXYZ->toXYZD50() && "Hash collision"); 327971cd496b9e25f87f3a75a0015c203322907136abrianosman srcToDst.setIdentity(); 328971cd496b9e25f87f3a75a0015c203322907136abrianosman csm = kGamut_ColorSpaceMatch; 329bbf251bf225489a0939fff6df938035a290f4d16Brian Osman } else { 330bbf251bf225489a0939fff6df938035a290f4d16Brian Osman srcToDst.setConcat(*dstSpaceXYZ->fromXYZD50(), *srcSpaceXYZ->toXYZD50()); 331971cd496b9e25f87f3a75a0015c203322907136abrianosman } 3326006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 3336006f678e78af7b6f67a454cd4bc213048983f9dmsarett 334200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett switch (csm) { 335200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kNone_ColorSpaceMatch: 336379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 337cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett <kNone_ColorSpaceMatch>(srcSpaceXYZ, srcToDst, dstSpaceXYZ, premulBehavior)); 338200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kGamut_ColorSpaceMatch: 339379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 340cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett <kGamut_ColorSpaceMatch>(srcSpaceXYZ, srcToDst, dstSpaceXYZ, premulBehavior)); 341200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kFull_ColorSpaceMatch: 342379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 343cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett <kFull_ColorSpaceMatch>(srcSpaceXYZ, srcToDst, dstSpaceXYZ, premulBehavior)); 3443418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett default: 345200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkASSERT(false); 346200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return nullptr; 3476006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 3486006f678e78af7b6f67a454cd4bc213048983f9dmsarett} 3496006f678e78af7b6f67a454cd4bc213048983f9dmsarett 3506006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 3516006f678e78af7b6f67a454cd4bc213048983f9dmsarett 352df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett#define AI SK_ALWAYS_INLINE 353df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett 35426a0543579cf7473de2099ce0d056ac8aba83811Matt Sarettstatic AI void load_matrix(const float matrix[13], 355df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rXgXbX, Sk4f& rYgYbY, Sk4f& rZgZbZ, Sk4f& rTgTbT) { 35626a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett rXgXbX = Sk4f::Load(matrix + 0); 35726a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett rYgYbY = Sk4f::Load(matrix + 3); 35826a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett rZgZbZ = Sk4f::Load(matrix + 6); 35926a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett rTgTbT = Sk4f::Load(matrix + 9); 360200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 361200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 362cf7b877d62537672b67449bc96858cc1262be5f8msarettenum Order { 363cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_Order, 364cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_Order, 365cf7b877d62537672b67449bc96858cc1262be5f8msarett}; 366cf7b877d62537672b67449bc96858cc1262be5f8msarett 367df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void set_rb_shifts(Order kOrder, int* kRShift, int* kBShift) { 368cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kRGBA_Order == kOrder) { 369cf7b877d62537672b67449bc96858cc1262be5f8msarett *kRShift = 0; 370cf7b877d62537672b67449bc96858cc1262be5f8msarett *kBShift = 16; 371cf7b877d62537672b67449bc96858cc1262be5f8msarett } else { 372cf7b877d62537672b67449bc96858cc1262be5f8msarett *kRShift = 16; 373cf7b877d62537672b67449bc96858cc1262be5f8msarett *kBShift = 0; 374cf7b877d62537672b67449bc96858cc1262be5f8msarett } 375cf7b877d62537672b67449bc96858cc1262be5f8msarett} 376cf7b877d62537672b67449bc96858cc1262be5f8msarett 377cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 378df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgb_from_tables(const uint32_t* src, 379df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 380df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 381cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 382cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 383cf7b877d62537672b67449bc96858cc1262be5f8msarett r = { srcTables[0][(src[0] >> kRShift) & 0xFF], 384cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[1] >> kRShift) & 0xFF], 385cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[2] >> kRShift) & 0xFF], 386cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[3] >> kRShift) & 0xFF], }; 387cf7b877d62537672b67449bc96858cc1262be5f8msarett g = { srcTables[1][(src[0] >> kGShift) & 0xFF], 388cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[1] >> kGShift) & 0xFF], 389cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[2] >> kGShift) & 0xFF], 390cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[3] >> kGShift) & 0xFF], }; 391cf7b877d62537672b67449bc96858cc1262be5f8msarett b = { srcTables[2][(src[0] >> kBShift) & 0xFF], 392cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[1] >> kBShift) & 0xFF], 393cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[2] >> kBShift) & 0xFF], 394cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[3] >> kBShift) & 0xFF], }; 395200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett a = 0.0f; // Don't let the compiler complain that |a| is uninitialized. 396200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 397200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 398cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 399df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgba_from_tables(const uint32_t* src, 400df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 401df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 402cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 403cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 404cf7b877d62537672b67449bc96858cc1262be5f8msarett r = { srcTables[0][(src[0] >> kRShift) & 0xFF], 405cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[1] >> kRShift) & 0xFF], 406cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[2] >> kRShift) & 0xFF], 407cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[3] >> kRShift) & 0xFF], }; 4085414be06935ce0f990a2df5dccaf9ddec78ec553msarett g = { srcTables[1][(src[0] >> kGShift) & 0xFF], 409cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[1] >> kGShift) & 0xFF], 410cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[2] >> kGShift) & 0xFF], 411cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[3] >> kGShift) & 0xFF], }; 412cf7b877d62537672b67449bc96858cc1262be5f8msarett b = { srcTables[2][(src[0] >> kBShift) & 0xFF], 413cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[1] >> kBShift) & 0xFF], 414cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[2] >> kBShift) & 0xFF], 415cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[3] >> kBShift) & 0xFF], }; 416200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett a = (1.0f / 255.0f) * SkNx_cast<float>(Sk4u::Load(src) >> 24); 417200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 418200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 419cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 4202563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void load_rgb_linear(const uint32_t* src, Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 421df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const[3]) { 422cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 423cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 424cf7b877d62537672b67449bc96858cc1262be5f8msarett r = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kRShift) & 0xFF); 425cf7b877d62537672b67449bc96858cc1262be5f8msarett g = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kGShift) & 0xFF); 426cf7b877d62537672b67449bc96858cc1262be5f8msarett b = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kBShift) & 0xFF); 427be362774f9b9e8964544a579281603ed995e6e5amsarett a = 0.0f; // Don't let the compiler complain that |a| is uninitialized. 4288bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 4298bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 430cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 4312563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void load_rgba_linear(const uint32_t* src, Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 432df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const[3]) { 433cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 434cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 435cf7b877d62537672b67449bc96858cc1262be5f8msarett r = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kRShift) & 0xFF); 436cf7b877d62537672b67449bc96858cc1262be5f8msarett g = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kGShift) & 0xFF); 437cf7b877d62537672b67449bc96858cc1262be5f8msarett b = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kBShift) & 0xFF); 438cf7b877d62537672b67449bc96858cc1262be5f8msarett a = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> 24)); 4398bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 4408bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 441cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 442df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgb_from_tables_1(const uint32_t* src, 443df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 444df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 445cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 446cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 447cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f(srcTables[0][(*src >> kRShift) & 0xFF]); 448cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f(srcTables[1][(*src >> kGShift) & 0xFF]); 449cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f(srcTables[2][(*src >> kBShift) & 0xFF]); 450a9f64dec63b6f4169ba16f8b6c63fff5a6494029Matt Sarett a = 0.0f; // Don't let MSAN complain that |a| is uninitialized. 451200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 452200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 453cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 454df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgba_from_tables_1(const uint32_t* src, 455df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 456df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 457cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 458cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 459cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f(srcTables[0][(*src >> kRShift) & 0xFF]); 460cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f(srcTables[1][(*src >> kGShift) & 0xFF]); 461cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f(srcTables[2][(*src >> kBShift) & 0xFF]); 462200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett a = (1.0f / 255.0f) * Sk4f(*src >> 24); 463200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 464200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 465cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 466df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgb_linear_1(const uint32_t* src, 467df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 468df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 469cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 470cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 471cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f((1.0f / 255.0f) * ((*src >> kRShift) & 0xFF)); 472cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f((1.0f / 255.0f) * ((*src >> kGShift) & 0xFF)); 473cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f((1.0f / 255.0f) * ((*src >> kBShift) & 0xFF)); 474a9f64dec63b6f4169ba16f8b6c63fff5a6494029Matt Sarett a = 0.0f; // Don't let MSAN complain that |a| is uninitialized. 4758bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 4768bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 477cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 478df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void load_rgba_linear_1(const uint32_t* src, 479df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 480df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const float* const srcTables[3]) { 481cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 482cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 483cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f((1.0f / 255.0f) * ((*src >> kRShift) & 0xFF)); 484cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f((1.0f / 255.0f) * ((*src >> kGShift) & 0xFF)); 485cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f((1.0f / 255.0f) * ((*src >> kBShift) & 0xFF)); 486cf7b877d62537672b67449bc96858cc1262be5f8msarett a = Sk4f((1.0f / 255.0f) * ((*src >> 24))); 4878bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 4888bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 489df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void transform_gamut(const Sk4f& r, const Sk4f& g, const Sk4f& b, const Sk4f& a, 490df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const Sk4f& rXgXbX, const Sk4f& rYgYbY, const Sk4f& rZgZbZ, 491df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da) { 492200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = rXgXbX[0]*r + rYgYbY[0]*g + rZgZbZ[0]*b; 493200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = rXgXbX[1]*r + rYgYbY[1]*g + rZgZbZ[1]*b; 494200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = rXgXbX[2]*r + rYgYbY[2]*g + rZgZbZ[2]*b; 495200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett da = a; 496200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 497200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 498df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void transform_gamut_1(const Sk4f& r, const Sk4f& g, const Sk4f& b, 499df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const Sk4f& rXgXbX, const Sk4f& rYgYbY, const Sk4f& rZgZbZ, 500df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba) { 501200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = rXgXbX*r + rYgYbY*g + rZgZbZ*b; 502200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 503200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 504df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void translate_gamut(const Sk4f& rTgTbT, Sk4f& dr, Sk4f& dg, Sk4f& db) { 505200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = dr + rTgTbT[0]; 506200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = dg + rTgTbT[1]; 507200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = db + rTgTbT[2]; 508200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 509200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 510df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void translate_gamut_1(const Sk4f& rTgTbT, Sk4f& rgba) { 511200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = rgba + rTgTbT; 512200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 513200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 514cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 5152563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_srgb(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 516df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 517cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 518cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 519200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = sk_linear_to_srgb_needs_trunc(dr); 520200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = sk_linear_to_srgb_needs_trunc(dg); 521200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = sk_linear_to_srgb_needs_trunc(db); 522200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 52317e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dr = sk_clamp_0_255(dr); 52417e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dg = sk_clamp_0_255(dg); 52517e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett db = sk_clamp_0_255(db); 52617e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett 527200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 528200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 529200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i rgba = (SkNx_cast<int>(dr) << kRShift) 530200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (SkNx_cast<int>(dg) << kGShift) 531200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (SkNx_cast<int>(db) << kBShift) 532200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (da ); 533200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba.store(dst); 534200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 535200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 536cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 537df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_srgb_1(void* dst, const uint32_t* src, 538df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f&, 539df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 54017e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett rgba = sk_clamp_0_255(sk_linear_to_srgb_needs_trunc(rgba)); 541200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 542200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint32_t tmp; 543200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkNx_cast<uint8_t>(SkNx_cast<int32_t>(rgba)).store(&tmp); 544200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = (*src & 0xFF000000) | (tmp & 0x00FFFFFF); 545cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kBGRA_Order == kOrder) { 546200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = SkSwizzle_RB(tmp); 547200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 548200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 549200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *(uint32_t*)dst = tmp; 550200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 551200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 552df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI Sk4f linear_to_2dot2(const Sk4f& x) { 553200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // x^(29/64) is a very good approximation of the true value, x^(1/2.2). 554200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett auto x2 = x.rsqrt(), // x^(-1/2) 555200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett x32 = x2.rsqrt().rsqrt().rsqrt().rsqrt(), // x^(-1/32) 556200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett x64 = x32.rsqrt(); // x^(+1/64) 557200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 558200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // 29 = 32 - 2 - 1 559200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return 255.0f * x2.invert() * x32 * x64.invert(); 560200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 561200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 562cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 5632563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_2dot2(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 564df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 565cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 566cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 567200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = linear_to_2dot2(dr); 568200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = linear_to_2dot2(dg); 569200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = linear_to_2dot2(db); 570200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 57117e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dr = sk_clamp_0_255(dr); 57217e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dg = sk_clamp_0_255(dg); 57317e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett db = sk_clamp_0_255(db); 57417e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett 575200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 576200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 577200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i rgba = (Sk4f_round(dr) << kRShift) 578200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (Sk4f_round(dg) << kGShift) 579200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (Sk4f_round(db) << kBShift) 580200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (da ); 581200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba.store(dst); 582200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 583200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 584cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 585df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_2dot2_1(void* dst, const uint32_t* src, 586df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f&, 587df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 58817e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett rgba = sk_clamp_0_255(linear_to_2dot2(rgba)); 589200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 590200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint32_t tmp; 591200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkNx_cast<uint8_t>(Sk4f_round(rgba)).store(&tmp); 592200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = (*src & 0xFF000000) | (tmp & 0x00FFFFFF); 593cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kBGRA_Order == kOrder) { 594200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = SkSwizzle_RB(tmp); 595200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 596200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 597200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *(uint32_t*)dst = tmp; 598200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 599200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 600cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 6012563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_linear(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 602df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 603cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 604cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 60517e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dr = sk_clamp_0_255(255.0f * dr); 60617e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dg = sk_clamp_0_255(255.0f * dg); 60717e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett db = sk_clamp_0_255(255.0f * db); 6088bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 6098bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 6108bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 6118bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Sk4i rgba = (Sk4f_round(dr) << kRShift) 6128bbcd5aab81dc0742c3367479c0c9d97363b1203msarett | (Sk4f_round(dg) << kGShift) 6138bbcd5aab81dc0742c3367479c0c9d97363b1203msarett | (Sk4f_round(db) << kBShift) 6148bbcd5aab81dc0742c3367479c0c9d97363b1203msarett | (da ); 6158bbcd5aab81dc0742c3367479c0c9d97363b1203msarett rgba.store(dst); 6168bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 6178bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 618cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 619df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_linear_1(void* dst, const uint32_t* src, 620df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f&, 621df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 62217e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett rgba = sk_clamp_0_255(255.0f * rgba); 6238bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 6248bbcd5aab81dc0742c3367479c0c9d97363b1203msarett uint32_t tmp; 6258bbcd5aab81dc0742c3367479c0c9d97363b1203msarett SkNx_cast<uint8_t>(Sk4f_round(rgba)).store(&tmp); 6268bbcd5aab81dc0742c3367479c0c9d97363b1203msarett tmp = (*src & 0xFF000000) | (tmp & 0x00FFFFFF); 627cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kBGRA_Order == kOrder) { 6288bbcd5aab81dc0742c3367479c0c9d97363b1203msarett tmp = SkSwizzle_RB(tmp); 6298bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 6308bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 6318bbcd5aab81dc0742c3367479c0c9d97363b1203msarett *(uint32_t*)dst = tmp; 6328bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 6338bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 634cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 6352563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_f16(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da, 6362563601fc2b0505619f905f86bd249ae630197ccraftias const uint8_t* const[3]) { 63733cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein Sk4h::Store4(dst, SkFloatToHalf_finite_ftz(dr), 63833cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(dg), 63933cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(db), 64033cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(da)); 641200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 642200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 643cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 644df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_f16_1(void* dst, const uint32_t* src, 645df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f& a, 646df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 647200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = Sk4f(rgba[0], rgba[1], rgba[2], a[3]); 6488ae991e433d2c0814ea5579613f00173805ff057mtklein SkFloatToHalf_finite_ftz(rgba).store((uint64_t*) dst); 649200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 650200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 651cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 6522563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_f16_opaque(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, 6532563601fc2b0505619f905f86bd249ae630197ccraftias Sk4f&, const uint8_t* const[3]) { 65433cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein Sk4h::Store4(dst, SkFloatToHalf_finite_ftz(dr), 65533cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(dg), 65633cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(db), 65733cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SK_Half1); 658200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 659200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 660cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 661df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_f16_1_opaque(void* dst, const uint32_t* src, 662df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f&, 663df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const[3]) { 664200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint64_t tmp; 6658ae991e433d2c0814ea5579613f00173805ff057mtklein SkFloatToHalf_finite_ftz(rgba).store(&tmp); 666e980155dd5d0cb6a10c9823c351763d50993a08dMatt Sarett tmp &= 0x0000FFFFFFFFFFFF; 667200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp |= static_cast<uint64_t>(SK_Half1) << 48; 668200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *((uint64_t*) dst) = tmp; 669200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 670200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 671cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 6722563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI void store_generic(void* dst, const uint32_t* src, Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 6732563601fc2b0505619f905f86bd249ae630197ccraftias const uint8_t* const dstTables[3]) { 674cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 675cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 67617e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dr = Sk4f::Min(Sk4f::Max(1023.0f * dr, 0.0f), 1023.0f); 67717e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett dg = Sk4f::Min(Sk4f::Max(1023.0f * dg, 0.0f), 1023.0f); 67817e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett db = Sk4f::Min(Sk4f::Max(1023.0f * db, 0.0f), 1023.0f); 679200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 680200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i ir = Sk4f_round(dr); 681200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i ig = Sk4f_round(dg); 682200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i ib = Sk4f_round(db); 683200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 684200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 685200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 686200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint32_t* dst32 = (uint32_t*) dst; 687200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[0] = dstTables[0][ir[0]] << kRShift 688200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[0]] << kGShift 689200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[0]] << kBShift 690200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[0]; 691200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[1] = dstTables[0][ir[1]] << kRShift 692200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[1]] << kGShift 693200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[1]] << kBShift 694200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[1]; 695200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[2] = dstTables[0][ir[2]] << kRShift 696200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[2]] << kGShift 697200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[2]] << kBShift 698200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[2]; 699200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[3] = dstTables[0][ir[3]] << kRShift 700200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[3]] << kGShift 701200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[3]] << kBShift 702200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[3]; 703200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 704200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 705cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 706df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI void store_generic_1(void* dst, const uint32_t* src, 707df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett Sk4f& rgba, const Sk4f&, 708df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const dstTables[3]) { 709cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 710cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 71117e494070ab1c76b2e5e4c0780b7a83c737dd84cMatt Sarett rgba = Sk4f::Min(Sk4f::Max(1023.0f * rgba, 0.0f), 1023.0f); 712200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 713200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i indices = Sk4f_round(rgba); 714200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 7159dc6cf6b8833d36c29a23d2519989b069745fcd5msarett *((uint32_t*) dst) = dstTables[0][indices[0]] << kRShift 7169dc6cf6b8833d36c29a23d2519989b069745fcd5msarett | dstTables[1][indices[1]] << kGShift 7179dc6cf6b8833d36c29a23d2519989b069745fcd5msarett | dstTables[2][indices[2]] << kBShift 718200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (*src & 0xFF000000); 719200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 720200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 721cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(load_rgb_from_tables<kRGBA_Order> )* LoadFn; 722cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(load_rgb_from_tables_1<kRGBA_Order>)* Load1Fn; 723cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(store_generic<kRGBA_Order> )* StoreFn; 724cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(store_generic_1<kRGBA_Order> )* Store1Fn; 7258bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7268bbcd5aab81dc0742c3367479c0c9d97363b1203msarettenum SrcFormat { 7278bbcd5aab81dc0742c3367479c0c9d97363b1203msarett kRGBA_8888_Linear_SrcFormat, 7288bbcd5aab81dc0742c3367479c0c9d97363b1203msarett kRGBA_8888_Table_SrcFormat, 729cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Linear_SrcFormat, 730cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Table_SrcFormat, 7318bbcd5aab81dc0742c3367479c0c9d97363b1203msarett}; 7328bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7338bbcd5aab81dc0742c3367479c0c9d97363b1203msarettenum DstFormat { 734cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_Linear_DstFormat, 735cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_SRGB_DstFormat, 736cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_2Dot2_DstFormat, 737cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_Table_DstFormat, 738cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Linear_DstFormat, 739cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_SRGB_DstFormat, 740cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_2Dot2_DstFormat, 741cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Table_DstFormat, 7428bbcd5aab81dc0742c3367479c0c9d97363b1203msarett kF16_Linear_DstFormat, 7438bbcd5aab81dc0742c3367479c0c9d97363b1203msarett}; 7448bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7458bbcd5aab81dc0742c3367479c0c9d97363b1203msaretttemplate <SrcFormat kSrc, 7468bbcd5aab81dc0742c3367479c0c9d97363b1203msarett DstFormat kDst, 7478bbcd5aab81dc0742c3367479c0c9d97363b1203msarett SkAlphaType kAlphaType, 748cf7b877d62537672b67449bc96858cc1262be5f8msarett ColorSpaceMatch kCSM> 7495934646b4937a05d5e8297448ea6613a89f8903aMatt Sarettstatic void color_xform_RGBA(void* dst, const void* vsrc, int len, 75026a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett const float* const srcTables[3], const float matrix[13], 7515934646b4937a05d5e8297448ea6613a89f8903aMatt Sarett const uint8_t* const dstTables[3]) { 7528bbcd5aab81dc0742c3367479c0c9d97363b1203msarett LoadFn load; 7538bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Load1Fn load_1; 754e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett const bool kLoadAlpha = kF16_Linear_DstFormat == kDst && kOpaque_SkAlphaType != kAlphaType; 7558bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kSrc) { 7568bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kRGBA_8888_Linear_SrcFormat: 757abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett if (kLoadAlpha) { 758cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_linear<kRGBA_Order>; 759cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_linear_1<kRGBA_Order>; 7608bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 761cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_linear<kRGBA_Order>; 762cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_linear_1<kRGBA_Order>; 7638bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 7648bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 7658bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kRGBA_8888_Table_SrcFormat: 766abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett if (kLoadAlpha) { 767cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_from_tables<kRGBA_Order>; 768cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_from_tables_1<kRGBA_Order>; 7698bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 770cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_from_tables<kRGBA_Order>; 771cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_from_tables_1<kRGBA_Order>; 772cf7b877d62537672b67449bc96858cc1262be5f8msarett } 773cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 774cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Linear_SrcFormat: 775abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett if (kLoadAlpha) { 776cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_linear<kBGRA_Order>; 777cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_linear_1<kBGRA_Order>; 778cf7b877d62537672b67449bc96858cc1262be5f8msarett } else { 779cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_linear<kBGRA_Order>; 780cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_linear_1<kBGRA_Order>; 781cf7b877d62537672b67449bc96858cc1262be5f8msarett } 782cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 783cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Table_SrcFormat: 784abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett if (kLoadAlpha) { 785cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_from_tables<kBGRA_Order>; 786cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_from_tables_1<kBGRA_Order>; 787cf7b877d62537672b67449bc96858cc1262be5f8msarett } else { 788cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_from_tables<kBGRA_Order>; 789cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_from_tables_1<kBGRA_Order>; 7908bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 7918bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 7928bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 7938bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7948bbcd5aab81dc0742c3367479c0c9d97363b1203msarett StoreFn store; 7958bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Store1Fn store_1; 7968bbcd5aab81dc0742c3367479c0c9d97363b1203msarett size_t sizeOfDstPixel; 7978bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kDst) { 798cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_Linear_DstFormat: 799cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_linear<kRGBA_Order>; 800cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_linear_1<kRGBA_Order>; 801cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 802cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 803cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_SRGB_DstFormat: 804cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_srgb<kRGBA_Order>; 805cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_srgb_1<kRGBA_Order>; 806cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 807cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 808cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_2Dot2_DstFormat: 809cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_2dot2<kRGBA_Order>; 810cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_2dot2_1<kRGBA_Order>; 8118bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 8128bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 813cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_Table_DstFormat: 814cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_generic<kRGBA_Order>; 815cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_generic_1<kRGBA_Order>; 8168bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 8178bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 818cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Linear_DstFormat: 819cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_linear<kBGRA_Order>; 820cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_linear_1<kBGRA_Order>; 8218bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 8228bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 823cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_SRGB_DstFormat: 824cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_srgb<kBGRA_Order>; 825cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_srgb_1<kBGRA_Order>; 826cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 827cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 828cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_2Dot2_DstFormat: 829cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_2dot2<kBGRA_Order>; 830cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_2dot2_1<kBGRA_Order>; 831cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 832cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 833cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Table_DstFormat: 834cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_generic<kBGRA_Order>; 835cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_generic_1<kBGRA_Order>; 8368bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 8378bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 8388bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kF16_Linear_DstFormat: 839cf7b877d62537672b67449bc96858cc1262be5f8msarett store = (kOpaque_SkAlphaType == kAlphaType) ? store_f16_opaque<kRGBA_Order> : 840cf7b877d62537672b67449bc96858cc1262be5f8msarett store_f16<kRGBA_Order>; 841cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = (kOpaque_SkAlphaType == kAlphaType) ? store_f16_1_opaque<kRGBA_Order> : 842cf7b877d62537672b67449bc96858cc1262be5f8msarett store_f16_1<kRGBA_Order>; 8438bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 8; 8448bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 8458bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 8468bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 847d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett const uint32_t* src = (const uint32_t*) vsrc; 848d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f rXgXbX, rYgYbY, rZgZbZ, rTgTbT; 849d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load_matrix(matrix, rXgXbX, rYgYbY, rZgZbZ, rTgTbT); 850d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 851d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (len >= 4) { 852d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett // Naively this would be a loop of load-transform-store, but we found it faster to 853d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett // move the N+1th load ahead of the Nth store. We don't bother doing this for N<4. 854d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f r, g, b, a; 855d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load(src, r, g, b, a, srcTables); 856d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett src += 4; 857d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett len -= 4; 858d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 859d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f dr, dg, db, da; 860d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett while (len >= 4) { 861d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kNone_ColorSpaceMatch == kCSM) { 862d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett transform_gamut(r, g, b, a, rXgXbX, rYgYbY, rZgZbZ, dr, dg, db, da); 863d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett translate_gamut(rTgTbT, dr, dg, db); 864d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } else { 865d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dr = r; 866d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dg = g; 867d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett db = b; 868d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett da = a; 869d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 870d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 871d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load(src, r, g, b, a, srcTables); 872d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 873d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett store(dst, src - 4, dr, dg, db, da, dstTables); 874d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dst = SkTAddOffset<void>(dst, 4 * sizeOfDstPixel); 875d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett src += 4; 876d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett len -= 4; 877d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 878d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 879d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kNone_ColorSpaceMatch == kCSM) { 880d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett transform_gamut(r, g, b, a, rXgXbX, rYgYbY, rZgZbZ, dr, dg, db, da); 881d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett translate_gamut(rTgTbT, dr, dg, db); 882d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } else { 883d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dr = r; 884d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dg = g; 885d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett db = b; 886d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett da = a; 887d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 888d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 889d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett store(dst, src - 4, dr, dg, db, da, dstTables); 890d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dst = SkTAddOffset<void>(dst, 4 * sizeOfDstPixel); 891d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 892d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 893d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett while (len > 0) { 894d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f r, g, b, a; 895d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load_1(src, r, g, b, a, srcTables); 896d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 897d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f rgba; 898d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kNone_ColorSpaceMatch == kCSM) { 899d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett transform_gamut_1(r, g, b, rXgXbX, rYgYbY, rZgZbZ, rgba); 900d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett translate_gamut_1(rTgTbT, rgba); 901d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } else { 902d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett rgba = Sk4f(r[0], g[0], b[0], a[0]); 903d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 904d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 905d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett store_1(dst, src, rgba, a, dstTables); 906d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 907d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett src += 1; 908d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett len -= 1; 909d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dst = SkTAddOffset<void>(dst, sizeOfDstPixel); 910d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 9118bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 9128bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 9133418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett/////////////////////////////////////////////////////////////////////////////////////////////////// 9140f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 9152563601fc2b0505619f905f86bd249ae630197ccraftiasstatic AI int num_tables(SkColorSpace_XYZ* space) { 9169488833428e83c93a7e6002f4d056084fb57112fraftias switch (space->gammaNamed()) { 9177bbda991af353fbe6b34132132d211d23a3dba8cmsarett case kSRGB_SkGammaNamed: 9187bbda991af353fbe6b34132132d211d23a3dba8cmsarett case k2Dot2Curve_SkGammaNamed: 9197bbda991af353fbe6b34132132d211d23a3dba8cmsarett case kLinear_SkGammaNamed: 9207bbda991af353fbe6b34132132d211d23a3dba8cmsarett return 0; 9217bbda991af353fbe6b34132132d211d23a3dba8cmsarett default: { 9229488833428e83c93a7e6002f4d056084fb57112fraftias const SkGammas* gammas = space->gammas(); 9237bbda991af353fbe6b34132132d211d23a3dba8cmsarett SkASSERT(gammas); 9247bbda991af353fbe6b34132132d211d23a3dba8cmsarett 9257bbda991af353fbe6b34132132d211d23a3dba8cmsarett bool gammasAreMatching = (gammas->type(0) == gammas->type(1)) && 9267bbda991af353fbe6b34132132d211d23a3dba8cmsarett (gammas->data(0) == gammas->data(1)) && 9277bbda991af353fbe6b34132132d211d23a3dba8cmsarett (gammas->type(0) == gammas->type(2)) && 9287bbda991af353fbe6b34132132d211d23a3dba8cmsarett (gammas->data(0) == gammas->data(2)); 9297bbda991af353fbe6b34132132d211d23a3dba8cmsarett 9307bbda991af353fbe6b34132132d211d23a3dba8cmsarett // It's likely that each component will have the same gamma. In this case, 9317bbda991af353fbe6b34132132d211d23a3dba8cmsarett // we only need to build one table. 9327bbda991af353fbe6b34132132d211d23a3dba8cmsarett return gammasAreMatching ? 1 : 3; 9337bbda991af353fbe6b34132132d211d23a3dba8cmsarett } 9347bbda991af353fbe6b34132132d211d23a3dba8cmsarett } 9357bbda991af353fbe6b34132132d211d23a3dba8cmsarett} 9367bbda991af353fbe6b34132132d211d23a3dba8cmsarett 937379938e47bc9edb6edfd21aabefa01aed71dd135Matt Saretttemplate <ColorSpaceMatch kCSM> 938379938e47bc9edb6edfd21aabefa01aed71dd135Matt SarettSkColorSpaceXform_XYZ<kCSM> 9399488833428e83c93a7e6002f4d056084fb57112fraftias::SkColorSpaceXform_XYZ(SkColorSpace_XYZ* srcSpace, const SkMatrix44& srcToDst, 940cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett SkColorSpace_XYZ* dstSpace, SkTransferFunctionBehavior premulBehavior) 941cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett : fPremulBehavior(premulBehavior) 9423418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett{ 94326a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 0] = srcToDst.get(0, 0); 94426a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 1] = srcToDst.get(1, 0); 94526a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 2] = srcToDst.get(2, 0); 94626a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 3] = srcToDst.get(0, 1); 94726a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 4] = srcToDst.get(1, 1); 94826a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 5] = srcToDst.get(2, 1); 94926a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 6] = srcToDst.get(0, 2); 95026a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 7] = srcToDst.get(1, 2); 95126a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 8] = srcToDst.get(2, 2); 95226a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 9] = srcToDst.get(0, 3); 95326a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[10] = srcToDst.get(1, 3); 95426a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[11] = srcToDst.get(2, 3); 95526a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[12] = 0.0f; 9567bbda991af353fbe6b34132132d211d23a3dba8cmsarett 9574be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett const int numSrcTables = num_tables(srcSpace); 958f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett const size_t srcEntries = numSrcTables * 256; 9597bbda991af353fbe6b34132132d211d23a3dba8cmsarett const bool srcGammasAreMatching = (1 >= numSrcTables); 960f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett fSrcStorage.reset(srcEntries); 961f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett build_gamma_tables(fSrcGammaTables, fSrcStorage.get(), 256, srcSpace, kToLinear, 962f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett srcGammasAreMatching); 963f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett 964f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett const int numDstTables = num_tables(dstSpace); 9659488833428e83c93a7e6002f4d056084fb57112fraftias dstSpace->toDstGammaTables(fDstGammaTables, &fDstStorage, numDstTables); 966379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett 967379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett if (srcSpace->gammaIsLinear()) { 968379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett fSrcGamma = kLinear_SrcGamma; 969379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett } else if (kSRGB_SkGammaNamed == srcSpace->gammaNamed()) { 970379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett fSrcGamma = kSRGB_SrcGamma; 971379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett } else { 972379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett fSrcGamma = kTable_SrcGamma; 973379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett } 974379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett 975379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett switch (dstSpace->gammaNamed()) { 976379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett case kSRGB_SkGammaNamed: 977379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett fDstGamma = kSRGB_DstGamma; 978379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 979379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett case k2Dot2Curve_SkGammaNamed: 980379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett fDstGamma = k2Dot2_DstGamma; 981379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 982379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett case kLinear_SkGammaNamed: 983379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett fDstGamma = kLinear_DstGamma; 984379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 985379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett default: 986379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett fDstGamma = kTable_DstGamma; 987379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 988379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett } 9893418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett} 990dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 9917bbda991af353fbe6b34132132d211d23a3dba8cmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 9927bbda991af353fbe6b34132132d211d23a3dba8cmsarett 993cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <SrcFormat kSrc, DstFormat kDst, ColorSpaceMatch kCSM> 994df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI bool apply_set_alpha(void* dst, const void* src, int len, SkAlphaType alphaType, 99526a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett const float* const srcTables[3], const float matrix[13], 996df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const dstTables[3]) { 9978bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (alphaType) { 9988bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kOpaque_SkAlphaType: 99931d097e865f266c8398f45114e4c75c0dfdef058msarett color_xform_RGBA<kSrc, kDst, kOpaque_SkAlphaType, kCSM> 10008bbcd5aab81dc0742c3367479c0c9d97363b1203msarett (dst, src, len, srcTables, matrix, dstTables); 100131d097e865f266c8398f45114e4c75c0dfdef058msarett return true; 10028bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kUnpremul_SkAlphaType: 100331d097e865f266c8398f45114e4c75c0dfdef058msarett color_xform_RGBA<kSrc, kDst, kUnpremul_SkAlphaType, kCSM> 10048bbcd5aab81dc0742c3367479c0c9d97363b1203msarett (dst, src, len, srcTables, matrix, dstTables); 100531d097e865f266c8398f45114e4c75c0dfdef058msarett return true; 10068bbcd5aab81dc0742c3367479c0c9d97363b1203msarett default: 100731d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 10088bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 10098bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 10108bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 1011379938e47bc9edb6edfd21aabefa01aed71dd135Matt Saretttemplate <DstFormat kDst, ColorSpaceMatch kCSM> 1012df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarettstatic AI bool apply_set_src(void* dst, const void* src, int len, SkAlphaType alphaType, 101326a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett const float* const srcTables[3], const float matrix[13], 1014df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett const uint8_t* const dstTables[3], 1015379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett SkColorSpaceXform::ColorFormat srcColorFormat, 1016379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett SrcGamma srcGamma) { 1017cf7b877d62537672b67449bc96858cc1262be5f8msarett switch (srcColorFormat) { 1018cf7b877d62537672b67449bc96858cc1262be5f8msarett case SkColorSpaceXform::kRGBA_8888_ColorFormat: 1019379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett switch (srcGamma) { 1020cf7b877d62537672b67449bc96858cc1262be5f8msarett case kLinear_SrcGamma: 1021cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kRGBA_8888_Linear_SrcFormat, kDst, kCSM> 1022cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, nullptr, matrix, dstTables); 1023379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett default: 1024cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kRGBA_8888_Table_SrcFormat, kDst, kCSM> 1025cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, srcTables, matrix, dstTables); 1026cf7b877d62537672b67449bc96858cc1262be5f8msarett } 1027cf7b877d62537672b67449bc96858cc1262be5f8msarett case SkColorSpaceXform::kBGRA_8888_ColorFormat: 1028379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett switch (srcGamma) { 1029cf7b877d62537672b67449bc96858cc1262be5f8msarett case kLinear_SrcGamma: 1030cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kBGRA_8888_Linear_SrcFormat, kDst, kCSM> 1031cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, nullptr, matrix, dstTables); 1032379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett default: 1033cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kBGRA_8888_Table_SrcFormat, kDst, kCSM> 1034cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, srcTables, matrix, dstTables); 1035cf7b877d62537672b67449bc96858cc1262be5f8msarett } 1036cf7b877d62537672b67449bc96858cc1262be5f8msarett default: 103731d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 10388bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 10398bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 10408bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 1041df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett#undef AI 1042df303a6f59a2121c133738d6304d2476689a4fd9Matt Sarett 1043379938e47bc9edb6edfd21aabefa01aed71dd135Matt Saretttemplate <ColorSpaceMatch kCSM> 1044379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarettbool SkColorSpaceXform_XYZ<kCSM> 104531d097e865f266c8398f45114e4c75c0dfdef058msarett::onApply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, const void* src, 104631d097e865f266c8398f45114e4c75c0dfdef058msarett int len, SkAlphaType alphaType) const 10473418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett{ 1048200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kFull_ColorSpaceMatch == kCSM) { 1049abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett if (kPremul_SkAlphaType != alphaType) { 1050abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett if ((kRGBA_8888_ColorFormat == dstColorFormat && 1051abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett kRGBA_8888_ColorFormat == srcColorFormat) || 1052abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett (kBGRA_8888_ColorFormat == dstColorFormat && 1053abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett kBGRA_8888_ColorFormat == srcColorFormat)) 1054abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett { 1055abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett memcpy(dst, src, len * sizeof(uint32_t)); 1056abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett return true; 1057abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett } 1058abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett if ((kRGBA_8888_ColorFormat == dstColorFormat && 1059abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett kBGRA_8888_ColorFormat == srcColorFormat) || 1060abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett (kBGRA_8888_ColorFormat == dstColorFormat && 1061abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett kRGBA_8888_ColorFormat == srcColorFormat)) 1062abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett { 1063abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett SkOpts::RGBA_to_BGRA((uint32_t*) dst, src, len); 1064abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett return true; 1065abf8ba34c8038b814e67fe7c4dcf6c9915d81698Matt Sarett } 1066200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1067200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1068200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 10695bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett if (kRGBA_F32_ColorFormat == dstColorFormat || 107068185be3389102cb8c979a26cbea72a39ac214caMatt Sarett kBGR_565_ColorFormat == dstColorFormat || 10714c55027dbf57d0701361b123e36b8fad46c341c3Matt Sarett kRGBA_F32_ColorFormat == srcColorFormat || 1072b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman kRGBA_F16_ColorFormat == srcColorFormat || 10735bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett kRGBA_U16_BE_ColorFormat == srcColorFormat || 1074e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett kRGB_U16_BE_ColorFormat == srcColorFormat || 1075e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett kPremul_SkAlphaType == alphaType) 10765bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett { 107726a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett return this->applyPipeline(dstColorFormat, dst, srcColorFormat, src, len, alphaType); 107826a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett } 107926a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett 1080c0444615ed76360f680619ad4d1f92cda6181a50msarett switch (dstColorFormat) { 1081c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_8888_ColorFormat: 1082379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett switch (fDstGamma) { 10838bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_DstGamma: 1084379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return apply_set_src<kRGBA_8888_Linear_DstFormat, kCSM> 1085cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1086379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett srcColorFormat, fSrcGamma); 10878bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kSRGB_DstGamma: 1088379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return apply_set_src<kRGBA_8888_SRGB_DstFormat, kCSM> 1089cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1090379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett srcColorFormat, fSrcGamma); 10918bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case k2Dot2_DstGamma: 1092379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return apply_set_src<kRGBA_8888_2Dot2_DstFormat, kCSM> 1093cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1094379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett srcColorFormat, fSrcGamma); 10958bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kTable_DstGamma: 1096379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return apply_set_src<kRGBA_8888_Table_DstFormat, kCSM> 1097cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, fDstGammaTables, 1098379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett srcColorFormat, fSrcGamma); 1099d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 1100c0444615ed76360f680619ad4d1f92cda6181a50msarett case kBGRA_8888_ColorFormat: 1101379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett switch (fDstGamma) { 11028bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_DstGamma: 1103379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return apply_set_src<kBGRA_8888_Linear_DstFormat, kCSM> 1104cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1105379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett srcColorFormat, fSrcGamma); 11068bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kSRGB_DstGamma: 1107379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return apply_set_src<kBGRA_8888_SRGB_DstFormat, kCSM> 1108cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1109379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett srcColorFormat, fSrcGamma); 11108bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case k2Dot2_DstGamma: 1111379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return apply_set_src<kBGRA_8888_2Dot2_DstFormat, kCSM> 1112cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1113379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett srcColorFormat, fSrcGamma); 11148bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kTable_DstGamma: 1115379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return apply_set_src<kBGRA_8888_Table_DstFormat, kCSM> 1116cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, fDstGammaTables, 1117379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett srcColorFormat, fSrcGamma); 1118d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 1119c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_F16_ColorFormat: 1120379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett switch (fDstGamma) { 11218bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_DstGamma: 1122379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return apply_set_src<kF16_Linear_DstFormat, kCSM> 1123cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1124379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett srcColorFormat, fSrcGamma); 1125d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett default: 112631d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 1127d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 1128d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett default: 112926a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett SkASSERT(false); 113031d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 1131d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 11329ce3a543c92a73e6daca420defc042886b3f2019msarett} 11339dc6cf6b8833d36c29a23d2519989b069745fcd5msarett 1134f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettbool SkColorSpaceXform::apply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, 1135f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett const void* src, int len, SkAlphaType alphaType) const { 1136f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return ((SkColorSpaceXform_Base*) this)->onApply(dstColorFormat, dst, srcColorFormat, src, len, 1137f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett alphaType); 1138f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett} 1139f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett 11407bbda991af353fbe6b34132132d211d23a3dba8cmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 11417bbda991af353fbe6b34132132d211d23a3dba8cmsarett 1142379938e47bc9edb6edfd21aabefa01aed71dd135Matt Saretttemplate <ColorSpaceMatch kCSM> 1143379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarettbool SkColorSpaceXform_XYZ<kCSM> 114426a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett::applyPipeline(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, 114526a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett const void* src, int len, SkAlphaType alphaType) const { 114626a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett SkRasterPipeline pipeline; 1147f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 114826a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett LoadTablesContext loadTables; 114926a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett switch (srcColorFormat) { 115026a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett case kRGBA_8888_ColorFormat: 1151379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett if (kLinear_SrcGamma == fSrcGamma) { 115226a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett pipeline.append(SkRasterPipeline::load_8888, &src); 115326a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett } else { 1154379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett loadTables.fSrc = src; 115526a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett loadTables.fR = fSrcGammaTables[0]; 115626a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett loadTables.fG = fSrcGammaTables[1]; 115726a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett loadTables.fB = fSrcGammaTables[2]; 115826a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett pipeline.append(SkRasterPipeline::load_tables, &loadTables); 1159f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1160f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 116126a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett break; 116226a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett case kBGRA_8888_ColorFormat: 1163379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett if (kLinear_SrcGamma == fSrcGamma) { 116426a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett pipeline.append(SkRasterPipeline::load_8888, &src); 116526a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett } else { 1166379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett loadTables.fSrc = src; 116726a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett loadTables.fR = fSrcGammaTables[2]; 116826a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett loadTables.fG = fSrcGammaTables[1]; 116926a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett loadTables.fB = fSrcGammaTables[0]; 117026a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett pipeline.append(SkRasterPipeline::load_tables, &loadTables); 1171f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1172f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1173f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::swap_rb); 117426a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett break; 1175b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman case kRGBA_F16_ColorFormat: 1176b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman if (kLinear_SrcGamma != fSrcGamma) { 1177b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman return false; 1178b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman } 1179b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman pipeline.append(SkRasterPipeline::load_f16, &src); 1180b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman break; 11814c55027dbf57d0701361b123e36b8fad46c341c3Matt Sarett case kRGBA_F32_ColorFormat: 11824c55027dbf57d0701361b123e36b8fad46c341c3Matt Sarett if (kLinear_SrcGamma != fSrcGamma) { 11834c55027dbf57d0701361b123e36b8fad46c341c3Matt Sarett return false; 11844c55027dbf57d0701361b123e36b8fad46c341c3Matt Sarett } 11854c55027dbf57d0701361b123e36b8fad46c341c3Matt Sarett pipeline.append(SkRasterPipeline::load_f32, &src); 11864c55027dbf57d0701361b123e36b8fad46c341c3Matt Sarett break; 1187379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett case kRGBA_U16_BE_ColorFormat: 1188379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett switch (fSrcGamma) { 1189379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett case kLinear_SrcGamma: 1190379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett pipeline.append(SkRasterPipeline::load_u16_be, &src); 1191379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 1192379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett case kSRGB_SrcGamma: 1193379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett pipeline.append(SkRasterPipeline::load_u16_be, &src); 1194379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett pipeline.append_from_srgb(kUnpremul_SkAlphaType); 1195379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 1196379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett case kTable_SrcGamma: 1197379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett loadTables.fSrc = src; 1198379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett loadTables.fR = fSrcGammaTables[0]; 1199379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett loadTables.fG = fSrcGammaTables[1]; 1200379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett loadTables.fB = fSrcGammaTables[2]; 1201379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett pipeline.append(SkRasterPipeline::load_tables_u16_be, &loadTables); 1202379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 1203379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett } 1204379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 12055bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett case kRGB_U16_BE_ColorFormat: 12065bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett switch (fSrcGamma) { 12075bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett case kLinear_SrcGamma: 12085bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett pipeline.append(SkRasterPipeline::load_rgb_u16_be, &src); 12095bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett break; 12105bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett case kSRGB_SrcGamma: 12115bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett pipeline.append(SkRasterPipeline::load_rgb_u16_be, &src); 12125bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett pipeline.append_from_srgb(kUnpremul_SkAlphaType); 12135bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett break; 12145bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett case kTable_SrcGamma: 12155bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett loadTables.fSrc = src; 12165bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett loadTables.fR = fSrcGammaTables[0]; 12175bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett loadTables.fG = fSrcGammaTables[1]; 12185bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett loadTables.fB = fSrcGammaTables[2]; 12195bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett pipeline.append(SkRasterPipeline::load_tables_rgb_u16_be, &loadTables); 12205bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett break; 12215bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett } 12225bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett break; 122368185be3389102cb8c979a26cbea72a39ac214caMatt Sarett default: 122468185be3389102cb8c979a26cbea72a39ac214caMatt Sarett return false; 1225f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1226f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 122726a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett if (kNone_ColorSpaceMatch == kCSM) { 1228f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::matrix_3x4, fSrcToDst); 1229f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 12307b2d1f683f59eb41c3d9c4011a1177489288a749Matt Sarett if (kRGBA_8888_ColorFormat == dstColorFormat || 12317b2d1f683f59eb41c3d9c4011a1177489288a749Matt Sarett kBGRA_8888_ColorFormat == dstColorFormat || 12327b2d1f683f59eb41c3d9c4011a1177489288a749Matt Sarett kBGR_565_ColorFormat == dstColorFormat) 12337b2d1f683f59eb41c3d9c4011a1177489288a749Matt Sarett { 12345e15961fa77281540a80ac0d036fefe071c11574Mike Klein bool need_clamp_0, need_clamp_1; 12355e15961fa77281540a80ac0d036fefe071c11574Mike Klein analyze_3x4_matrix(fSrcToDst, &need_clamp_0, &need_clamp_1); 12365e15961fa77281540a80ac0d036fefe071c11574Mike Klein 12375e15961fa77281540a80ac0d036fefe071c11574Mike Klein if (need_clamp_0) { pipeline.append(SkRasterPipeline::clamp_0); } 12385e15961fa77281540a80ac0d036fefe071c11574Mike Klein if (need_clamp_1) { pipeline.append(SkRasterPipeline::clamp_1); } 12395e15961fa77281540a80ac0d036fefe071c11574Mike Klein } 1240f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1241f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1242cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett if (kPremul_SkAlphaType == alphaType && SkTransferFunctionBehavior::kRespect == fPremulBehavior) 1243cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett { 1244f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::premul); 1245f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1246f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1247e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett TablesContext tables; 1248379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett switch (fDstGamma) { 1249f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kSRGB_DstGamma: 1250f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::to_srgb); 1251f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 1252f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case k2Dot2_DstGamma: 1253f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::to_2dot2); 1254f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 1255e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett case kTable_DstGamma: 1256e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett tables.fR = fDstGammaTables[0]; 1257e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett tables.fG = fDstGammaTables[1]; 1258e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett tables.fB = fDstGammaTables[2]; 1259e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett tables.fCount = SkColorSpaceXform_Base::kDstGammaTableSize; 1260e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett pipeline.append(SkRasterPipeline::byte_tables_rgb, &tables); 1261f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett default: 1262f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 1263f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1264f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1265cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett if (kPremul_SkAlphaType == alphaType && SkTransferFunctionBehavior::kIgnore == fPremulBehavior) 1266cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett { 1267e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett pipeline.append(SkRasterPipeline::premul); 1268e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett } 1269e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett 1270f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett switch (dstColorFormat) { 1271f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kRGBA_8888_ColorFormat: 1272e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett pipeline.append(SkRasterPipeline::store_8888, &dst); 1273f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 1274f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kBGRA_8888_ColorFormat: 1275e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett pipeline.append(SkRasterPipeline::swap_rb); 1276e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett pipeline.append(SkRasterPipeline::store_8888, &dst); 1277f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 1278f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kRGBA_F16_ColorFormat: 1279cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett if (kLinear_DstGamma != fDstGamma) { 1280f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett return false; 1281f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1282f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::store_f16, &dst); 1283f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 1284f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kRGBA_F32_ColorFormat: 1285cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett if (kLinear_DstGamma != fDstGamma) { 1286f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett return false; 1287f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1288f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::store_f32, &dst); 1289f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 129068185be3389102cb8c979a26cbea72a39ac214caMatt Sarett case kBGR_565_ColorFormat: 129168185be3389102cb8c979a26cbea72a39ac214caMatt Sarett if (kOpaque_SkAlphaType != alphaType) { 129268185be3389102cb8c979a26cbea72a39ac214caMatt Sarett return false; 129368185be3389102cb8c979a26cbea72a39ac214caMatt Sarett } 129468185be3389102cb8c979a26cbea72a39ac214caMatt Sarett pipeline.append(SkRasterPipeline::store_565, &dst); 129568185be3389102cb8c979a26cbea72a39ac214caMatt Sarett break; 1296379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett default: 1297379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return false; 1298f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 1299f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1300319ba3d3a177498095c31696e0aec8b3af25f663Mike Klein pipeline.run(0, len); 1301f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett return true; 1302f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett} 1303f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 1304f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett/////////////////////////////////////////////////////////////////////////////////////////////////// 1305f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 13069488833428e83c93a7e6002f4d056084fb57112fraftiasstd::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace_XYZ* space) { 1307cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ<kNone_ColorSpaceMatch> 1308cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett (space, SkMatrix::I(), space, SkTransferFunctionBehavior::kRespect)); 13099dc6cf6b8833d36c29a23d2519989b069745fcd5msarett} 1310