SkColorSpaceXform.cpp revision 9488833428e83c93a7e6002f4d056084fb57112f
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" 1331d097e865f266c8398f45114e4c75c0dfdef058msarett#include "SkColorSpaceXform_Base.h" 14200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett#include "SkHalf.h" 15200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett#include "SkOpts.h" 16ac41bac40f5a80d2bc5ccec584c23478a6900179mtklein#include "SkSRGB.h" 179876ac5b3016e5353c072378ac1545a0a2270757msarett 186006f678e78af7b6f67a454cd4bc213048983f9dmsarettstatic constexpr float sk_linear_from_2dot2[256] = { 19b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000000000000000000f, 0.000005077051900662f, 0.000023328004666099f, 0.000056921765712193f, 20b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000107187362341244f, 0.000175123977503027f, 0.000261543754548491f, 0.000367136269815943f, 21b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000492503787191433f, 0.000638182842167022f, 0.000804658499513058f, 0.000992374304074325f, 22b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.001201739522438400f, 0.001433134589671860f, 0.001686915316789280f, 0.001963416213396470f, 23b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.002262953160706430f, 0.002585825596234170f, 0.002932318323938360f, 0.003302703032003640f, 24b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.003697239578900130f, 0.004116177093282750f, 0.004559754922526020f, 0.005028203456855540f, 25b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.005521744850239660f, 0.006040593654849810f, 0.006584957382581690f, 0.007155037004573030f, 26b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.007751027397660610f, 0.008373117745148580f, 0.009021491898012130f, 0.009696328701658230f, 27b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.010397802292555300f, 0.011126082368383200f, 0.011881334434813700f, 0.012663720031582100f, 28b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.013473396940142600f, 0.014310519374884100f, 0.015175238159625200f, 0.016067700890886900f, 29b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.016988052089250000f, 0.017936433339950200f, 0.018912983423721500f, 0.019917838438785700f, 30b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.020951131914781100f, 0.022012994919336500f, 0.023103556157921400f, 0.024222942067534200f, 31b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.025371276904734600f, 0.026548682828472900f, 0.027755279978126000f, 0.028991186547107800f, 32b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.030256518852388700f, 0.031551391400226400f, 0.032875916948383800f, 0.034230206565082000f, 33b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.035614369684918800f, 0.037028514161960200f, 0.038472746320194600f, 0.039947171001525600f, 34b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.041451891611462500f, 0.042987010162657100f, 0.044552627316421400f, 0.046148842422351000f, 35b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.047775753556170600f, 0.049433457555908000f, 0.051122050056493400f, 0.052841625522879000f, 36b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.054592277281760300f, 0.056374097551979800f, 0.058187177473685400f, 0.060031607136313200f, 37b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.061907475605455800f, 0.063814870948677200f, 0.065753880260330100f, 0.067724589685424300f, 38b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.069727084442598800f, 0.071761448846239100f, 0.073827766327784600f, 0.075926119456264800f, 39b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.078056589958101900f, 0.080219258736215100f, 0.082414205888459200f, 0.084641510725429500f, 40b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.086901251787660300f, 0.089193506862247800f, 0.091518352998919500f, 0.093875866525577800f, 41b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.096266123063339700f, 0.098689197541094500f, 0.101145164209600000f, 0.103634096655137000f, 42b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.106156067812744000f, 0.108711149979039000f, 0.111299414824660000f, 0.113920933406333000f, 43b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.116575776178572000f, 0.119264013005047000f, 0.121985713169619000f, 0.124740945387051000f, 44b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.127529777813422000f, 0.130352278056244000f, 0.133208513184300000f, 0.136098549737202000f, 45b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.139022453734703000f, 0.141980290685736000f, 0.144972125597231000f, 0.147998022982685000f, 46b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.151058046870511000f, 0.154152260812165000f, 0.157280727890073000f, 0.160443510725344000f, 47b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.163640671485290000f, 0.166872271890766000f, 0.170138373223312000f, 0.173439036332135000f, 48b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.176774321640903000f, 0.180144289154390000f, 0.183548998464951000f, 0.186988508758844000f, 49b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.190462878822409000f, 0.193972167048093000f, 0.197516431440340000f, 0.201095729621346000f, 50b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.204710118836677000f, 0.208359655960767000f, 0.212044397502288000f, 0.215764399609395000f, 51b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.219519718074868000f, 0.223310408341127000f, 0.227136525505149000f, 0.230998124323267000f, 52b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.234895259215880000f, 0.238827984272048000f, 0.242796353254002000f, 0.246800419601550000f, 53b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.250840236436400000f, 0.254915856566385000f, 0.259027332489606000f, 0.263174716398492000f, 54b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.267358060183772000f, 0.271577415438375000f, 0.275832833461245000f, 0.280124365261085000f, 55b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.284452061560024000f, 0.288815972797219000f, 0.293216149132375000f, 0.297652640449211000f, 56b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.302125496358853000f, 0.306634766203158000f, 0.311180499057984000f, 0.315762743736397000f, 57b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.320381548791810000f, 0.325036962521076000f, 0.329729032967515000f, 0.334457807923889000f, 58b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.339223334935327000f, 0.344025661302187000f, 0.348864834082879000f, 0.353740900096629000f, 59b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.358653905926199000f, 0.363603897920553000f, 0.368590922197487000f, 0.373615024646202000f, 60b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.378676250929840000f, 0.383774646487975000f, 0.388910256539059000f, 0.394083126082829000f, 61b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.399293299902674000f, 0.404540822567962000f, 0.409825738436323000f, 0.415148091655907000f, 62b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.420507926167587000f, 0.425905285707146000f, 0.431340213807410000f, 0.436812753800359000f, 63b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.442322948819202000f, 0.447870841800410000f, 0.453456475485731000f, 0.459079892424160000f, 64b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.464741134973889000f, 0.470440245304218000f, 0.476177265397440000f, 0.481952237050698000f, 65b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.487765201877811000f, 0.493616201311074000f, 0.499505276603030000f, 0.505432468828216000f, 66b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.511397818884880000f, 0.517401367496673000f, 0.523443155214325000f, 0.529523222417277000f, 67b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.535641609315311000f, 0.541798355950137000f, 0.547993502196972000f, 0.554227087766085000f, 68b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.560499152204328000f, 0.566809734896638000f, 0.573158875067523000f, 0.579546611782525000f, 69b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.585972983949661000f, 0.592438030320847000f, 0.598941789493296000f, 0.605484299910907000f, 70b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.612065599865624000f, 0.618685727498780000f, 0.625344720802427000f, 0.632042617620641000f, 71b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.638779455650817000f, 0.645555272444935000f, 0.652370105410821000f, 0.659223991813387000f, 72b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.666116968775851000f, 0.673049073280942000f, 0.680020342172095000f, 0.687030812154625000f, 73b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.694080519796882000f, 0.701169501531402000f, 0.708297793656032000f, 0.715465432335048000f, 74b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.722672453600255000f, 0.729918893352071000f, 0.737204787360605000f, 0.744530171266715000f, 75b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.751895080583051000f, 0.759299550695091000f, 0.766743616862161000f, 0.774227314218442000f, 76b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.781750677773962000f, 0.789313742415586000f, 0.796916542907978000f, 0.804559113894567000f, 77b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.812241489898490000f, 0.819963705323528000f, 0.827725794455034000f, 0.835527791460841000f, 78b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.843369730392169000f, 0.851251645184515000f, 0.859173569658532000f, 0.867135537520905000f, 79b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.875137582365205000f, 0.883179737672745000f, 0.891262036813419000f, 0.899384513046529000f, 80b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.907547199521614000f, 0.915750129279253000f, 0.923993335251873000f, 0.932276850264543000f, 81b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.940600707035753000f, 0.948964938178195000f, 0.957369576199527000f, 0.965814653503130000f, 82b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.974300202388861000f, 0.982826255053791000f, 0.991392843592940000f, 1.000000000000000000f, 83b39067696ad08a26bbe49b71a71f0546dc42a075msarett}; 84b39067696ad08a26bbe49b71a71f0546dc42a075msarett 856006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 866006f678e78af7b6f67a454cd4bc213048983f9dmsarett 8715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, float exponent) { 8815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 8915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = powf(x, exponent); 9015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 9115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 9215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 9315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett// Interpolating lookup in a variably sized table. 9415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic float interp_lut(float input, const float* table, int tableSize) { 9515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett float index = input * (tableSize - 1); 9615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett float diff = index - sk_float_floor2int(index); 9715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett return table[(int) sk_float_floor2int(index)] * (1.0f - diff) + 9815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett table[(int) sk_float_ceil2int(index)] * diff; 9915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 10015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 10115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett// outTable is always 256 entries, inTable may be larger or smaller. 10215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, const float* inTable, 10315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett int inTableSize) { 10415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett if (256 == inTableSize) { 10515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett memcpy(outTable, inTable, sizeof(float) * 256); 10615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett return; 10715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 10815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 10915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 11015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = interp_lut(x, inTable, inTableSize); 11115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 11215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 11315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 11415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, float g, float a, float b, float c, 11515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett float d, float e, float f) { 11615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett // Y = (aX + b)^g + c for X >= d 11715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett // Y = eX + f otherwise 11815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 11915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett if (x >= d) { 12015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = powf(a * x + b, g) + c; 12115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } else { 12215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = e * x + f; 12315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 12415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 12515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 12615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 12715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 12815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 129a9e878c836994bce695274b4c28890290139dcdfmsarett// Expand range from 0-1 to 0-255, then convert. 130b39067696ad08a26bbe49b71a71f0546dc42a075msarettstatic uint8_t clamp_normalized_float_to_byte(float v) { 131dea0340cadb759932e53416a657f5ea75fee8b5fmsarett // The ordering of the logic is a little strange here in order 132dea0340cadb759932e53416a657f5ea75fee8b5fmsarett // to make sure we convert NaNs to 0. 1339876ac5b3016e5353c072378ac1545a0a2270757msarett v = v * 255.0f; 134a9e878c836994bce695274b4c28890290139dcdfmsarett if (v >= 254.5f) { 1359876ac5b3016e5353c072378ac1545a0a2270757msarett return 255; 136dea0340cadb759932e53416a657f5ea75fee8b5fmsarett } else if (v >= 0.5f) { 1379876ac5b3016e5353c072378ac1545a0a2270757msarett return (uint8_t) (v + 0.5f); 138dea0340cadb759932e53416a657f5ea75fee8b5fmsarett } else { 139dea0340cadb759932e53416a657f5ea75fee8b5fmsarett return 0; 1409876ac5b3016e5353c072378ac1545a0a2270757msarett } 1419876ac5b3016e5353c072378ac1545a0a2270757msarett} 1429876ac5b3016e5353c072378ac1545a0a2270757msarett 143f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettstatic const int kDstGammaTableSize = SkColorSpaceXform_Base::kDstGammaTableSize; 1443418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett 1451b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, float exponent) { 146b39067696ad08a26bbe49b71a71f0546dc42a075msarett float toGammaExp = 1.0f / exponent; 147b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1483418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett for (int i = 0; i < kDstGammaTableSize; i++) { 1493418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1))); 150b39067696ad08a26bbe49b71a71f0546dc42a075msarett outTable[i] = clamp_normalized_float_to_byte(powf(x, toGammaExp)); 151b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 152dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett} 153dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 154dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett// Inverse table lookup. Ex: what index corresponds to the input value? This will 155dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett// have strange results when the table is non-increasing. But any sane gamma 156dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett// function will be increasing. 1571b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic float inverse_interp_lut(float input, const float* table, int tableSize) { 158dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett if (input <= table[0]) { 159dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett return table[0]; 160dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett } else if (input >= table[tableSize - 1]) { 161dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett return 1.0f; 162dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett } 163dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 164b39067696ad08a26bbe49b71a71f0546dc42a075msarett for (int i = 1; i < tableSize; i++) { 165dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett if (table[i] >= input) { 166dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett // We are guaranteed that input is greater than table[i - 1]. 167dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett float diff = input - table[i - 1]; 168dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett float distance = table[i] - table[i - 1]; 169dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett float index = (i - 1) + diff / distance; 170dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett return index / (tableSize - 1); 171dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett } 172dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett } 173dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 174dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett // Should be unreachable, since we'll return before the loop if input is 175dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett // larger than the last entry. 176dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett SkASSERT(false); 177dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett return 0.0f; 178dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett} 179dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 1801b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, const float* inTable, 181b39067696ad08a26bbe49b71a71f0546dc42a075msarett int inTableSize) { 1823418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett for (int i = 0; i < kDstGammaTableSize; i++) { 1833418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1))); 184b39067696ad08a26bbe49b71a71f0546dc42a075msarett float y = inverse_interp_lut(x, inTable, inTableSize); 185b39067696ad08a26bbe49b71a71f0546dc42a075msarett outTable[i] = clamp_normalized_float_to_byte(y); 186b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 187b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 188dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 189b39067696ad08a26bbe49b71a71f0546dc42a075msarettstatic float inverse_parametric(float x, float g, float a, float b, float c, float d, float e, 190b39067696ad08a26bbe49b71a71f0546dc42a075msarett float f) { 191b39067696ad08a26bbe49b71a71f0546dc42a075msarett // We need to take the inverse of the following piecewise function. 192b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Y = (aX + b)^g + c for X >= d 193b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Y = eX + f otherwise 194b39067696ad08a26bbe49b71a71f0546dc42a075msarett 195b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Assume that the gamma function is continuous, or this won't make much sense anyway. 196b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Plug in |d| to the first equation to calculate the new piecewise interval. 197b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Then simply use the inverse of the original functions. 198b39067696ad08a26bbe49b71a71f0546dc42a075msarett float interval = e * d + f; 199b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (x < interval) { 200b39067696ad08a26bbe49b71a71f0546dc42a075msarett // X = (Y - F) / E 201b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (0.0f == e) { 202b39067696ad08a26bbe49b71a71f0546dc42a075msarett // The gamma curve for this segment is constant, so the inverse is undefined. 203b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Since this is the lower segment, guess zero. 204b39067696ad08a26bbe49b71a71f0546dc42a075msarett return 0.0f; 205b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 206b39067696ad08a26bbe49b71a71f0546dc42a075msarett 207b39067696ad08a26bbe49b71a71f0546dc42a075msarett return (x - f) / e; 208b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 209b39067696ad08a26bbe49b71a71f0546dc42a075msarett 210b39067696ad08a26bbe49b71a71f0546dc42a075msarett // X = ((Y - C)^(1 / G) - B) / A 211b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (0.0f == a || 0.0f == g) { 212b39067696ad08a26bbe49b71a71f0546dc42a075msarett // The gamma curve for this segment is constant, so the inverse is undefined. 213b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Since this is the upper segment, guess one. 214b39067696ad08a26bbe49b71a71f0546dc42a075msarett return 1.0f; 215b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 216b39067696ad08a26bbe49b71a71f0546dc42a075msarett 217b39067696ad08a26bbe49b71a71f0546dc42a075msarett return (powf(x - c, 1.0f / g) - b) / a; 218b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 219b39067696ad08a26bbe49b71a71f0546dc42a075msarett 2201b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, float g, float a, 221b39067696ad08a26bbe49b71a71f0546dc42a075msarett float b, float c, float d, float e, float f) { 2223418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett for (int i = 0; i < kDstGammaTableSize; i++) { 2233418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1))); 224b39067696ad08a26bbe49b71a71f0546dc42a075msarett float y = inverse_parametric(x, g, a, b, c, d, e, f); 225b39067696ad08a26bbe49b71a71f0546dc42a075msarett outTable[i] = clamp_normalized_float_to_byte(y); 226b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 227b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 228b39067696ad08a26bbe49b71a71f0546dc42a075msarett 2296006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 2306006f678e78af7b6f67a454cd4bc213048983f9dmsarett 2311b93bd1e6eba3d14593490e4e24a34546638c8damsaretttemplate <typename T> 2321b93bd1e6eba3d14593490e4e24a34546638c8damsarettstruct GammaFns { 2331b93bd1e6eba3d14593490e4e24a34546638c8damsarett const T* fSRGBTable; 2341b93bd1e6eba3d14593490e4e24a34546638c8damsarett const T* f2Dot2Table; 2351b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromValue)(T*, float); 2361b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromTable)(T*, const float*, int); 2371b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromParam)(T*, float, float, float, float, float, float, float); 2381b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 2391b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2401b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic const GammaFns<float> kToLinear { 2411b93bd1e6eba3d14593490e4e24a34546638c8damsarett sk_linear_from_srgb, 2421b93bd1e6eba3d14593490e4e24a34546638c8damsarett sk_linear_from_2dot2, 2431b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 2441b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 2451b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 2461b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 2471b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2481b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic const GammaFns<uint8_t> kFromLinear { 24955bcc8e0af3415601b3d62252a0d579fbe87c85amsarett nullptr, 25055bcc8e0af3415601b3d62252a0d579fbe87c85amsarett nullptr, 2511b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 2521b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 2531b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 2541b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 2551b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2561b93bd1e6eba3d14593490e4e24a34546638c8damsarett// Build tables to transform src gamma to linear. 2571b93bd1e6eba3d14593490e4e24a34546638c8damsaretttemplate <typename T> 2581b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_gamma_tables(const T* outGammaTables[3], T* gammaTableStorage, int gammaTableSize, 2599488833428e83c93a7e6002f4d056084fb57112fraftias const SkColorSpace_XYZ* space, const GammaFns<T>& fns, 260f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett bool gammasAreMatching) 2614be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett{ 2629488833428e83c93a7e6002f4d056084fb57112fraftias switch (space->gammaNamed()) { 263600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 2641b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.fSRGBTable; 2651b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 266600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 2671b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.f2Dot2Table; 2681b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 269600c737b64eae2c7379442ae2c852853cce3a278msarett case kLinear_SkGammaNamed: 2708bbcd5aab81dc0742c3367479c0c9d97363b1203msarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = nullptr; 2711b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 2721b93bd1e6eba3d14593490e4e24a34546638c8damsarett default: { 2739488833428e83c93a7e6002f4d056084fb57112fraftias const SkGammas* gammas = space->gammas(); 2741b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(gammas); 2751b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2767bbda991af353fbe6b34132132d211d23a3dba8cmsarett auto build_table = [=](int i) { 2771b93bd1e6eba3d14593490e4e24a34546638c8damsarett if (gammas->isNamed(i)) { 2781b93bd1e6eba3d14593490e4e24a34546638c8damsarett switch (gammas->data(i).fNamed) { 279600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 28055bcc8e0af3415601b3d62252a0d579fbe87c85amsarett (*fns.fBuildFromParam)(&gammaTableStorage[i * gammaTableSize], 2.4f, 28155bcc8e0af3415601b3d62252a0d579fbe87c85amsarett (1.0f / 1.055f), (0.055f / 1.055f), 0.0f, 28255bcc8e0af3415601b3d62252a0d579fbe87c85amsarett 0.04045f, (1.0f / 12.92f), 0.0f); 28355bcc8e0af3415601b3d62252a0d579fbe87c85amsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2841b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 285600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 28655bcc8e0af3415601b3d62252a0d579fbe87c85amsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 2.2f); 28755bcc8e0af3415601b3d62252a0d579fbe87c85amsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2881b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 289600c737b64eae2c7379442ae2c852853cce3a278msarett case kLinear_SkGammaNamed: 2901b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 1.0f); 2911b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2921b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 2931b93bd1e6eba3d14593490e4e24a34546638c8damsarett default: 2941b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(false); 2951b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 2961b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2971b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else if (gammas->isValue(i)) { 2981b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 2991b93bd1e6eba3d14593490e4e24a34546638c8damsarett gammas->data(i).fValue); 3001b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 3011b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else if (gammas->isTable(i)) { 3021b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromTable)(&gammaTableStorage[i * gammaTableSize], gammas->table(i), 3031b93bd1e6eba3d14593490e4e24a34546638c8damsarett gammas->data(i).fTable.fSize); 3041b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 3051b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else { 3061b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(gammas->isParametric(i)); 307df44fc5f2bb282557df291e20dbd26c070533aa6Matt Sarett const SkColorSpaceTransferFn& params = gammas->params(i); 3081b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromParam)(&gammaTableStorage[i * gammaTableSize], params.fG, 3091b93bd1e6eba3d14593490e4e24a34546638c8damsarett params.fA, params.fB, params.fC, params.fD, params.fE, 3101b93bd1e6eba3d14593490e4e24a34546638c8damsarett params.fF); 3111b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 3121b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 3137bbda991af353fbe6b34132132d211d23a3dba8cmsarett }; 3147bbda991af353fbe6b34132132d211d23a3dba8cmsarett 3157bbda991af353fbe6b34132132d211d23a3dba8cmsarett if (gammasAreMatching) { 3167bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(0); 3177bbda991af353fbe6b34132132d211d23a3dba8cmsarett outGammaTables[1] = outGammaTables[0]; 3187bbda991af353fbe6b34132132d211d23a3dba8cmsarett outGammaTables[2] = outGammaTables[0]; 3197bbda991af353fbe6b34132132d211d23a3dba8cmsarett } else { 3207bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(0); 3217bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(1); 3227bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(2); 3231b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 3247bbda991af353fbe6b34132132d211d23a3dba8cmsarett 3257bbda991af353fbe6b34132132d211d23a3dba8cmsarett break; 3261b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 3271b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 3281b93bd1e6eba3d14593490e4e24a34546638c8damsarett} 3291b93bd1e6eba3d14593490e4e24a34546638c8damsarett 330f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettvoid SkColorSpaceXform_Base::BuildDstGammaTables(const uint8_t* dstGammaTables[3], 3319488833428e83c93a7e6002f4d056084fb57112fraftias uint8_t* dstStorage, 3329488833428e83c93a7e6002f4d056084fb57112fraftias const SkColorSpace_XYZ* space, 333f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett bool gammasAreMatching) { 334f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett build_gamma_tables(dstGammaTables, dstStorage, kDstGammaTableSize, space, kFromLinear, 335f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett gammasAreMatching); 336f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett} 337f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett 3381b93bd1e6eba3d14593490e4e24a34546638c8damsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 3391b93bd1e6eba3d14593490e4e24a34546638c8damsarett 340200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline bool is_almost_identity(const SkMatrix44& srcToDst) { 341200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett for (int i = 0; i < 4; i++) { 342200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett for (int j = 0; j < 4; j++) { 343200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett float expected = (i == j) ? 1.0f : 0.0f; 344200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (!color_space_almost_equal(srcToDst.getFloat(i,j), expected)) { 345200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return false; 346200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 347200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 348200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 349200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return true; 350200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 351200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 35215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 35315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 3544be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarettstd::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(SkColorSpace* srcSpace, 3554be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett SkColorSpace* dstSpace) { 3566006f678e78af7b6f67a454cd4bc213048983f9dmsarett if (!srcSpace || !dstSpace) { 3576006f678e78af7b6f67a454cd4bc213048983f9dmsarett // Invalid input 3586006f678e78af7b6f67a454cd4bc213048983f9dmsarett return nullptr; 3596006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 3606006f678e78af7b6f67a454cd4bc213048983f9dmsarett 3619488833428e83c93a7e6002f4d056084fb57112fraftias if (SkColorSpace_Base::Type::kA2B == as_CSB(dstSpace)->type()) { 3629488833428e83c93a7e6002f4d056084fb57112fraftias SkColorSpacePrintf("A2B destinations not supported\n"); 3639488833428e83c93a7e6002f4d056084fb57112fraftias return nullptr; 3649488833428e83c93a7e6002f4d056084fb57112fraftias } 3659488833428e83c93a7e6002f4d056084fb57112fraftias 3669488833428e83c93a7e6002f4d056084fb57112fraftias if (SkColorSpace_Base::Type::kA2B == as_CSB(srcSpace)->type()) { 3679488833428e83c93a7e6002f4d056084fb57112fraftias // TODO (raftias): return an A2B-supporting SkColorSpaceXform here once the xform. 3689488833428e83c93a7e6002f4d056084fb57112fraftias // is implemented. SkColorSpaceXform_Base only supports XYZ+TRC based SkColorSpaces 3699488833428e83c93a7e6002f4d056084fb57112fraftias //SkColorSpace_A2B* src = static_cast<SkColorSpace_A2B*>(srcSpace); 3709488833428e83c93a7e6002f4d056084fb57112fraftias //SkColorSpace_XYZ* dst = static_cast<SkColorSpace_XYZ*>(dstSpace); 3719488833428e83c93a7e6002f4d056084fb57112fraftias //return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_A2B(src, dst)); 3729488833428e83c93a7e6002f4d056084fb57112fraftias SkColorSpacePrintf("A2B sources not supported (yet)\n"); 3739488833428e83c93a7e6002f4d056084fb57112fraftias return nullptr; 3749488833428e83c93a7e6002f4d056084fb57112fraftias } 3759488833428e83c93a7e6002f4d056084fb57112fraftias SkColorSpace_XYZ* srcSpaceXYZ = static_cast<SkColorSpace_XYZ*>(srcSpace); 3769488833428e83c93a7e6002f4d056084fb57112fraftias SkColorSpace_XYZ* dstSpaceXYZ = static_cast<SkColorSpace_XYZ*>(dstSpace); 3779488833428e83c93a7e6002f4d056084fb57112fraftias 378200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett ColorSpaceMatch csm = kNone_ColorSpaceMatch; 3796006f678e78af7b6f67a454cd4bc213048983f9dmsarett SkMatrix44 srcToDst(SkMatrix44::kUninitialized_Constructor); 3804be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett if (SkColorSpace::Equals(srcSpace, dstSpace)) { 381200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcToDst.setIdentity(); 382200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett csm = kFull_ColorSpaceMatch; 383971cd496b9e25f87f3a75a0015c203322907136abrianosman } else { 3849488833428e83c93a7e6002f4d056084fb57112fraftias srcToDst.setConcat(*dstSpaceXYZ->fromXYZD50(), *srcSpaceXYZ->toXYZD50()); 385971cd496b9e25f87f3a75a0015c203322907136abrianosman 386971cd496b9e25f87f3a75a0015c203322907136abrianosman if (is_almost_identity(srcToDst)) { 387971cd496b9e25f87f3a75a0015c203322907136abrianosman srcToDst.setIdentity(); 388971cd496b9e25f87f3a75a0015c203322907136abrianosman csm = kGamut_ColorSpaceMatch; 389971cd496b9e25f87f3a75a0015c203322907136abrianosman } 3906006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 3916006f678e78af7b6f67a454cd4bc213048983f9dmsarett 392200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett switch (csm) { 393200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kNone_ColorSpaceMatch: 3949488833428e83c93a7e6002f4d056084fb57112fraftias switch (dstSpaceXYZ->gammaNamed()) { 395600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 3969488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 397f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 3988bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kSRGB_DstGamma, kNone_ColorSpaceMatch> 3999488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4008bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 401f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4028bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kSRGB_DstGamma, kNone_ColorSpaceMatch> 4039488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4048bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 405600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 4069488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 407f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4088bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, k2Dot2_DstGamma, kNone_ColorSpaceMatch> 4099488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4108bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 411f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4128bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, k2Dot2_DstGamma, kNone_ColorSpaceMatch> 4139488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4148bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 4158bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_SkGammaNamed: 4169488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 417f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4188bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kLinear_DstGamma, kNone_ColorSpaceMatch> 4199488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4208bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 421f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4228bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kLinear_DstGamma, kNone_ColorSpaceMatch> 4239488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4248bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 425200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 4269488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 427f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4288bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch> 4299488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4308bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 431f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4328bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch> 4339488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4348bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 435200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 436200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kGamut_ColorSpaceMatch: 4379488833428e83c93a7e6002f4d056084fb57112fraftias switch (dstSpaceXYZ->gammaNamed()) { 438600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 4399488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 440f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4418bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kSRGB_DstGamma, kGamut_ColorSpaceMatch> 4429488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4438bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 444f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4458bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kSRGB_DstGamma, kGamut_ColorSpaceMatch> 4469488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4478bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 448600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 4499488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 450f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4518bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, k2Dot2_DstGamma, kGamut_ColorSpaceMatch> 4529488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4538bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 454f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4558bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, k2Dot2_DstGamma, kGamut_ColorSpaceMatch> 4569488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4578bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 4588bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_SkGammaNamed: 4599488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 460f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4618bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kLinear_DstGamma, kGamut_ColorSpaceMatch> 4629488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4638bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 464f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4658bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kLinear_DstGamma, kGamut_ColorSpaceMatch> 4669488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4678bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 468200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 4699488833428e83c93a7e6002f4d056084fb57112fraftias if (srcSpaceXYZ->gammaIsLinear()) { 470f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4718bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kTable_DstGamma, kGamut_ColorSpaceMatch> 4729488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4738bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 474f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4758bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kTable_DstGamma, kGamut_ColorSpaceMatch> 4769488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4778bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 478200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 479200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kFull_ColorSpaceMatch: 4809488833428e83c93a7e6002f4d056084fb57112fraftias switch (dstSpaceXYZ->gammaNamed()) { 481600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 482f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4838bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kSRGB_DstGamma, kFull_ColorSpaceMatch> 4849488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 485600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 486f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4878bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, k2Dot2_DstGamma, kFull_ColorSpaceMatch> 4889488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 4898bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_SkGammaNamed: 490f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4918bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kLinear_SrcGamma, kLinear_DstGamma, kFull_ColorSpaceMatch> 4929488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 493200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 494f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 4958bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kTable_DstGamma, kFull_ColorSpaceMatch> 4969488833428e83c93a7e6002f4d056084fb57112fraftias (srcSpaceXYZ, srcToDst, dstSpaceXYZ)); 497200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 4983418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett default: 499200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkASSERT(false); 500200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return nullptr; 5016006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 5026006f678e78af7b6f67a454cd4bc213048983f9dmsarett} 5036006f678e78af7b6f67a454cd4bc213048983f9dmsarett 5046006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 5056006f678e78af7b6f67a454cd4bc213048983f9dmsarett 506200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void load_matrix(const float matrix[16], 507200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& rXgXbX, Sk4f& rYgYbY, Sk4f& rZgZbZ, Sk4f& rTgTbT) { 508200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rXgXbX = Sk4f::Load(matrix + 0); 509200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rYgYbY = Sk4f::Load(matrix + 4); 510200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rZgZbZ = Sk4f::Load(matrix + 8); 511200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rTgTbT = Sk4f::Load(matrix + 12); 512200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 513200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 514cf7b877d62537672b67449bc96858cc1262be5f8msarettenum Order { 515cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_Order, 516cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_Order, 517cf7b877d62537672b67449bc96858cc1262be5f8msarett}; 518cf7b877d62537672b67449bc96858cc1262be5f8msarett 519cf7b877d62537672b67449bc96858cc1262be5f8msarettstatic inline void set_rb_shifts(Order kOrder, int* kRShift, int* kBShift) { 520cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kRGBA_Order == kOrder) { 521cf7b877d62537672b67449bc96858cc1262be5f8msarett *kRShift = 0; 522cf7b877d62537672b67449bc96858cc1262be5f8msarett *kBShift = 16; 523cf7b877d62537672b67449bc96858cc1262be5f8msarett } else { 524cf7b877d62537672b67449bc96858cc1262be5f8msarett *kRShift = 16; 525cf7b877d62537672b67449bc96858cc1262be5f8msarett *kBShift = 0; 526cf7b877d62537672b67449bc96858cc1262be5f8msarett } 527cf7b877d62537672b67449bc96858cc1262be5f8msarett} 528cf7b877d62537672b67449bc96858cc1262be5f8msarett 529cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 530200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void load_rgb_from_tables(const uint32_t* src, 531200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 532200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const float* const srcTables[3]) { 533cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 534cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 535cf7b877d62537672b67449bc96858cc1262be5f8msarett r = { srcTables[0][(src[0] >> kRShift) & 0xFF], 536cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[1] >> kRShift) & 0xFF], 537cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[2] >> kRShift) & 0xFF], 538cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[3] >> kRShift) & 0xFF], }; 539cf7b877d62537672b67449bc96858cc1262be5f8msarett g = { srcTables[1][(src[0] >> kGShift) & 0xFF], 540cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[1] >> kGShift) & 0xFF], 541cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[2] >> kGShift) & 0xFF], 542cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[3] >> kGShift) & 0xFF], }; 543cf7b877d62537672b67449bc96858cc1262be5f8msarett b = { srcTables[2][(src[0] >> kBShift) & 0xFF], 544cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[1] >> kBShift) & 0xFF], 545cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[2] >> kBShift) & 0xFF], 546cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[3] >> kBShift) & 0xFF], }; 547200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett a = 0.0f; // Don't let the compiler complain that |a| is uninitialized. 548200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 549200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 550cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 551200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void load_rgba_from_tables(const uint32_t* src, 552200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 553200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const float* const srcTables[3]) { 554cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 555cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 556cf7b877d62537672b67449bc96858cc1262be5f8msarett r = { srcTables[0][(src[0] >> kRShift) & 0xFF], 557cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[1] >> kRShift) & 0xFF], 558cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[2] >> kRShift) & 0xFF], 559cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[0][(src[3] >> kRShift) & 0xFF], }; 5605414be06935ce0f990a2df5dccaf9ddec78ec553msarett g = { srcTables[1][(src[0] >> kGShift) & 0xFF], 561cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[1] >> kGShift) & 0xFF], 562cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[2] >> kGShift) & 0xFF], 563cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[1][(src[3] >> kGShift) & 0xFF], }; 564cf7b877d62537672b67449bc96858cc1262be5f8msarett b = { srcTables[2][(src[0] >> kBShift) & 0xFF], 565cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[1] >> kBShift) & 0xFF], 566cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[2] >> kBShift) & 0xFF], 567cf7b877d62537672b67449bc96858cc1262be5f8msarett srcTables[2][(src[3] >> kBShift) & 0xFF], }; 568200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett a = (1.0f / 255.0f) * SkNx_cast<float>(Sk4u::Load(src) >> 24); 569200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 570200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 571cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 5728bbcd5aab81dc0742c3367479c0c9d97363b1203msarettstatic inline void load_rgb_linear(const uint32_t* src, 573be362774f9b9e8964544a579281603ed995e6e5amsarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 5748bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const float* const[3]) { 575cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 576cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 577cf7b877d62537672b67449bc96858cc1262be5f8msarett r = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kRShift) & 0xFF); 578cf7b877d62537672b67449bc96858cc1262be5f8msarett g = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kGShift) & 0xFF); 579cf7b877d62537672b67449bc96858cc1262be5f8msarett b = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kBShift) & 0xFF); 580be362774f9b9e8964544a579281603ed995e6e5amsarett a = 0.0f; // Don't let the compiler complain that |a| is uninitialized. 5818bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 5828bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 583cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 5848bbcd5aab81dc0742c3367479c0c9d97363b1203msarettstatic inline void load_rgba_linear(const uint32_t* src, 5858bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 5868bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const float* const[3]) { 587cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 588cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 589cf7b877d62537672b67449bc96858cc1262be5f8msarett r = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kRShift) & 0xFF); 590cf7b877d62537672b67449bc96858cc1262be5f8msarett g = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kGShift) & 0xFF); 591cf7b877d62537672b67449bc96858cc1262be5f8msarett b = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> kBShift) & 0xFF); 592cf7b877d62537672b67449bc96858cc1262be5f8msarett a = (1.0f / 255.0f) * SkNx_cast<float>((Sk4u::Load(src) >> 24)); 5938bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 5948bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 595cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 596200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void load_rgb_from_tables_1(const uint32_t* src, 597200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f&, 598200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const float* const srcTables[3]) { 599cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 600cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 601cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f(srcTables[0][(*src >> kRShift) & 0xFF]); 602cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f(srcTables[1][(*src >> kGShift) & 0xFF]); 603cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f(srcTables[2][(*src >> kBShift) & 0xFF]); 604200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 605200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 606cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 607200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void load_rgba_from_tables_1(const uint32_t* src, 608200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 609200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const float* const srcTables[3]) { 610cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 611cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 612cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f(srcTables[0][(*src >> kRShift) & 0xFF]); 613cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f(srcTables[1][(*src >> kGShift) & 0xFF]); 614cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f(srcTables[2][(*src >> kBShift) & 0xFF]); 615200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett a = (1.0f / 255.0f) * Sk4f(*src >> 24); 616200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 617200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 618cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 6198bbcd5aab81dc0742c3367479c0c9d97363b1203msarettstatic inline void load_rgb_linear_1(const uint32_t* src, 6208bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f&, 6218bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const float* const srcTables[3]) { 622cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 623cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 624cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f((1.0f / 255.0f) * ((*src >> kRShift) & 0xFF)); 625cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f((1.0f / 255.0f) * ((*src >> kGShift) & 0xFF)); 626cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f((1.0f / 255.0f) * ((*src >> kBShift) & 0xFF)); 6278bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 6288bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 629cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 6308bbcd5aab81dc0742c3367479c0c9d97363b1203msarettstatic inline void load_rgba_linear_1(const uint32_t* src, 6318bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 6328bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const float* const srcTables[3]) { 633cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 634cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 635cf7b877d62537672b67449bc96858cc1262be5f8msarett r = Sk4f((1.0f / 255.0f) * ((*src >> kRShift) & 0xFF)); 636cf7b877d62537672b67449bc96858cc1262be5f8msarett g = Sk4f((1.0f / 255.0f) * ((*src >> kGShift) & 0xFF)); 637cf7b877d62537672b67449bc96858cc1262be5f8msarett b = Sk4f((1.0f / 255.0f) * ((*src >> kBShift) & 0xFF)); 638cf7b877d62537672b67449bc96858cc1262be5f8msarett a = Sk4f((1.0f / 255.0f) * ((*src >> 24))); 6398bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 6408bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 641200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void transform_gamut(const Sk4f& r, const Sk4f& g, const Sk4f& b, const Sk4f& a, 642200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const Sk4f& rXgXbX, const Sk4f& rYgYbY, const Sk4f& rZgZbZ, 643200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da) { 644200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = rXgXbX[0]*r + rYgYbY[0]*g + rZgZbZ[0]*b; 645200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = rXgXbX[1]*r + rYgYbY[1]*g + rZgZbZ[1]*b; 646200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = rXgXbX[2]*r + rYgYbY[2]*g + rZgZbZ[2]*b; 647200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett da = a; 648200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 649200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 650200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void transform_gamut_1(const Sk4f& r, const Sk4f& g, const Sk4f& b, 651200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const Sk4f& rXgXbX, const Sk4f& rYgYbY, const Sk4f& rZgZbZ, 652200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& rgba) { 653200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = rXgXbX*r + rYgYbY*g + rZgZbZ*b; 654200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 655200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 656200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void translate_gamut(const Sk4f& rTgTbT, Sk4f& dr, Sk4f& dg, Sk4f& db) { 657200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = dr + rTgTbT[0]; 658200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = dg + rTgTbT[1]; 659200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = db + rTgTbT[2]; 660200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 661200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 662200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void translate_gamut_1(const Sk4f& rTgTbT, Sk4f& rgba) { 663200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = rgba + rTgTbT; 664200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 665200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 666200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void premultiply(Sk4f& dr, Sk4f& dg, Sk4f& db, const Sk4f& da) { 667200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = da * dr; 668200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = da * dg; 669200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = da * db; 670200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 671200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 672200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void premultiply_1(const Sk4f& a, Sk4f& rgba) { 673200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = a * rgba; 674200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 675200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 676cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 677200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_srgb(void* dst, const uint32_t* src, 678200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 6798bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const uint8_t* const[3]) { 680cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 681cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 682200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = sk_linear_to_srgb_needs_trunc(dr); 683200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = sk_linear_to_srgb_needs_trunc(dg); 684200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = sk_linear_to_srgb_needs_trunc(db); 685200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 686200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = sk_clamp_0_255(dr); 687200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = sk_clamp_0_255(dg); 688200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = sk_clamp_0_255(db); 689200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 690200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 691200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 692200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i rgba = (SkNx_cast<int>(dr) << kRShift) 693200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (SkNx_cast<int>(dg) << kGShift) 694200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (SkNx_cast<int>(db) << kBShift) 695200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (da ); 696200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba.store(dst); 697200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 698200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 699cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 700200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_srgb_1(void* dst, const uint32_t* src, 701200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& rgba, const Sk4f&, 7028bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const uint8_t* const[3]) { 703200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = sk_clamp_0_255(sk_linear_to_srgb_needs_trunc(rgba)); 704200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 705200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint32_t tmp; 706200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkNx_cast<uint8_t>(SkNx_cast<int32_t>(rgba)).store(&tmp); 707200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = (*src & 0xFF000000) | (tmp & 0x00FFFFFF); 708cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kBGRA_Order == kOrder) { 709200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = SkSwizzle_RB(tmp); 710200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 711200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 712200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *(uint32_t*)dst = tmp; 713200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 714200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 715200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline Sk4f linear_to_2dot2(const Sk4f& x) { 716200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // x^(29/64) is a very good approximation of the true value, x^(1/2.2). 717200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett auto x2 = x.rsqrt(), // x^(-1/2) 718200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett x32 = x2.rsqrt().rsqrt().rsqrt().rsqrt(), // x^(-1/32) 719200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett x64 = x32.rsqrt(); // x^(+1/64) 720200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 721200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // 29 = 32 - 2 - 1 722200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return 255.0f * x2.invert() * x32 * x64.invert(); 723200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 724200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 725cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 726200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_2dot2(void* dst, const uint32_t* src, 727200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 7288bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const uint8_t* const[3]) { 729cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 730cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 731200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = linear_to_2dot2(dr); 732200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = linear_to_2dot2(dg); 733200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = linear_to_2dot2(db); 734200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 735200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = sk_clamp_0_255(dr); 736200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = sk_clamp_0_255(dg); 737200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = sk_clamp_0_255(db); 738200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 739200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 740200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 741200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i rgba = (Sk4f_round(dr) << kRShift) 742200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (Sk4f_round(dg) << kGShift) 743200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (Sk4f_round(db) << kBShift) 744200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (da ); 745200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba.store(dst); 746200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 747200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 748cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 749200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_2dot2_1(void* dst, const uint32_t* src, 750200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& rgba, const Sk4f&, 7518bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const uint8_t* const[3]) { 752200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = sk_clamp_0_255(linear_to_2dot2(rgba)); 753200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 754200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint32_t tmp; 755200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkNx_cast<uint8_t>(Sk4f_round(rgba)).store(&tmp); 756200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = (*src & 0xFF000000) | (tmp & 0x00FFFFFF); 757cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kBGRA_Order == kOrder) { 758200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = SkSwizzle_RB(tmp); 759200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 760200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 761200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *(uint32_t*)dst = tmp; 762200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 763200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 764cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 7658bbcd5aab81dc0742c3367479c0c9d97363b1203msarettstatic inline void store_linear(void* dst, const uint32_t* src, 7668bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 7678bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const uint8_t* const[3]) { 768cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 769cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 770591971d02a8e22dac0955c0f07b7cf500a89d5ccmsarett dr = sk_clamp_0_255(255.0f * dr); 771591971d02a8e22dac0955c0f07b7cf500a89d5ccmsarett dg = sk_clamp_0_255(255.0f * dg); 772591971d02a8e22dac0955c0f07b7cf500a89d5ccmsarett db = sk_clamp_0_255(255.0f * db); 7738bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7748bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 7758bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7768bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Sk4i rgba = (Sk4f_round(dr) << kRShift) 7778bbcd5aab81dc0742c3367479c0c9d97363b1203msarett | (Sk4f_round(dg) << kGShift) 7788bbcd5aab81dc0742c3367479c0c9d97363b1203msarett | (Sk4f_round(db) << kBShift) 7798bbcd5aab81dc0742c3367479c0c9d97363b1203msarett | (da ); 7808bbcd5aab81dc0742c3367479c0c9d97363b1203msarett rgba.store(dst); 7818bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 7828bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 783cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 7848bbcd5aab81dc0742c3367479c0c9d97363b1203msarettstatic inline void store_linear_1(void* dst, const uint32_t* src, 7858bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Sk4f& rgba, const Sk4f&, 7868bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const uint8_t* const[3]) { 787591971d02a8e22dac0955c0f07b7cf500a89d5ccmsarett rgba = sk_clamp_0_255(255.0f * rgba); 7888bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7898bbcd5aab81dc0742c3367479c0c9d97363b1203msarett uint32_t tmp; 7908bbcd5aab81dc0742c3367479c0c9d97363b1203msarett SkNx_cast<uint8_t>(Sk4f_round(rgba)).store(&tmp); 7918bbcd5aab81dc0742c3367479c0c9d97363b1203msarett tmp = (*src & 0xFF000000) | (tmp & 0x00FFFFFF); 792cf7b877d62537672b67449bc96858cc1262be5f8msarett if (kBGRA_Order == kOrder) { 7938bbcd5aab81dc0742c3367479c0c9d97363b1203msarett tmp = SkSwizzle_RB(tmp); 7948bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 7958bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 7968bbcd5aab81dc0742c3367479c0c9d97363b1203msarett *(uint32_t*)dst = tmp; 7978bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 7988bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 799cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 800200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_f16(void* dst, const uint32_t* src, 801200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da, 8028bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const uint8_t* const[3]) { 80333cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein Sk4h::Store4(dst, SkFloatToHalf_finite_ftz(dr), 80433cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(dg), 80533cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(db), 80633cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(da)); 807200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 808200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 809cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 810200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_f16_1(void* dst, const uint32_t* src, 811200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& rgba, const Sk4f& a, 8128bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const uint8_t* const[3]) { 813200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = Sk4f(rgba[0], rgba[1], rgba[2], a[3]); 8148ae991e433d2c0814ea5579613f00173805ff057mtklein SkFloatToHalf_finite_ftz(rgba).store((uint64_t*) dst); 815200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 816200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 817cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 818c0444615ed76360f680619ad4d1f92cda6181a50msarettstatic inline void store_f32(void* dst, const uint32_t* src, 819c0444615ed76360f680619ad4d1f92cda6181a50msarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da, 820c0444615ed76360f680619ad4d1f92cda6181a50msarett const uint8_t* const[3]) { 82133cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein Sk4f::Store4(dst, dr, dg, db, da); 822c0444615ed76360f680619ad4d1f92cda6181a50msarett} 823c0444615ed76360f680619ad4d1f92cda6181a50msarett 824cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 825c0444615ed76360f680619ad4d1f92cda6181a50msarettstatic inline void store_f32_1(void* dst, const uint32_t* src, 826c0444615ed76360f680619ad4d1f92cda6181a50msarett Sk4f& rgba, const Sk4f& a, 827c0444615ed76360f680619ad4d1f92cda6181a50msarett const uint8_t* const[3]) { 828c0444615ed76360f680619ad4d1f92cda6181a50msarett rgba = Sk4f(rgba[0], rgba[1], rgba[2], a[3]); 829c0444615ed76360f680619ad4d1f92cda6181a50msarett rgba.store((float*) dst); 830c0444615ed76360f680619ad4d1f92cda6181a50msarett} 831c0444615ed76360f680619ad4d1f92cda6181a50msarett 832cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 833200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_f16_opaque(void* dst, const uint32_t* src, 834c0444615ed76360f680619ad4d1f92cda6181a50msarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 8358bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const uint8_t* const[3]) { 83633cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein Sk4h::Store4(dst, SkFloatToHalf_finite_ftz(dr), 83733cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(dg), 83833cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SkFloatToHalf_finite_ftz(db), 83933cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein SK_Half1); 840200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 841200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 842cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 843200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_f16_1_opaque(void* dst, const uint32_t* src, 844c0444615ed76360f680619ad4d1f92cda6181a50msarett Sk4f& rgba, const Sk4f&, 8458bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const uint8_t* const[3]) { 846200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint64_t tmp; 8478ae991e433d2c0814ea5579613f00173805ff057mtklein SkFloatToHalf_finite_ftz(rgba).store(&tmp); 848200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp |= static_cast<uint64_t>(SK_Half1) << 48; 849200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *((uint64_t*) dst) = tmp; 850200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 851200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 852cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 853200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_generic(void* dst, const uint32_t* src, 854200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 8558bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const uint8_t* const dstTables[3]) { 856cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 857cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 858200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = Sk4f::Min(Sk4f::Max(1023.0f * dr, 0.0f), 1023.0f); 859200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = Sk4f::Min(Sk4f::Max(1023.0f * dg, 0.0f), 1023.0f); 860200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = Sk4f::Min(Sk4f::Max(1023.0f * db, 0.0f), 1023.0f); 861200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 862200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i ir = Sk4f_round(dr); 863200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i ig = Sk4f_round(dg); 864200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i ib = Sk4f_round(db); 865200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 866200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 867200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 868200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint32_t* dst32 = (uint32_t*) dst; 869200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[0] = dstTables[0][ir[0]] << kRShift 870200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[0]] << kGShift 871200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[0]] << kBShift 872200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[0]; 873200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[1] = dstTables[0][ir[1]] << kRShift 874200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[1]] << kGShift 875200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[1]] << kBShift 876200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[1]; 877200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[2] = dstTables[0][ir[2]] << kRShift 878200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[2]] << kGShift 879200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[2]] << kBShift 880200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[2]; 881200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[3] = dstTables[0][ir[3]] << kRShift 882200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[3]] << kGShift 883200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[3]] << kBShift 884200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[3]; 885200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 886200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 887cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <Order kOrder> 888200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_generic_1(void* dst, const uint32_t* src, 889200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& rgba, const Sk4f&, 8908bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const uint8_t* const dstTables[3]) { 891cf7b877d62537672b67449bc96858cc1262be5f8msarett int kRShift, kGShift = 8, kBShift; 892cf7b877d62537672b67449bc96858cc1262be5f8msarett set_rb_shifts(kOrder, &kRShift, &kBShift); 893200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = Sk4f::Min(Sk4f::Max(1023.0f * rgba, 0.0f), 1023.0f); 894200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 895200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i indices = Sk4f_round(rgba); 896200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 8979dc6cf6b8833d36c29a23d2519989b069745fcd5msarett *((uint32_t*) dst) = dstTables[0][indices[0]] << kRShift 8989dc6cf6b8833d36c29a23d2519989b069745fcd5msarett | dstTables[1][indices[1]] << kGShift 8999dc6cf6b8833d36c29a23d2519989b069745fcd5msarett | dstTables[2][indices[2]] << kBShift 900200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (*src & 0xFF000000); 901200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 902200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 903cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(load_rgb_from_tables<kRGBA_Order> )* LoadFn; 904cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(load_rgb_from_tables_1<kRGBA_Order>)* Load1Fn; 905cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(store_generic<kRGBA_Order> )* StoreFn; 906cf7b877d62537672b67449bc96858cc1262be5f8msaretttypedef decltype(store_generic_1<kRGBA_Order> )* Store1Fn; 9078bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 9088bbcd5aab81dc0742c3367479c0c9d97363b1203msarettenum SrcFormat { 9098bbcd5aab81dc0742c3367479c0c9d97363b1203msarett kRGBA_8888_Linear_SrcFormat, 9108bbcd5aab81dc0742c3367479c0c9d97363b1203msarett kRGBA_8888_Table_SrcFormat, 911cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Linear_SrcFormat, 912cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Table_SrcFormat, 9138bbcd5aab81dc0742c3367479c0c9d97363b1203msarett}; 9148bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 9158bbcd5aab81dc0742c3367479c0c9d97363b1203msarettenum DstFormat { 916cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_Linear_DstFormat, 917cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_SRGB_DstFormat, 918cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_2Dot2_DstFormat, 919cf7b877d62537672b67449bc96858cc1262be5f8msarett kRGBA_8888_Table_DstFormat, 920cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Linear_DstFormat, 921cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_SRGB_DstFormat, 922cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_2Dot2_DstFormat, 923cf7b877d62537672b67449bc96858cc1262be5f8msarett kBGRA_8888_Table_DstFormat, 9248bbcd5aab81dc0742c3367479c0c9d97363b1203msarett kF16_Linear_DstFormat, 925c0444615ed76360f680619ad4d1f92cda6181a50msarett kF32_Linear_DstFormat, 9268bbcd5aab81dc0742c3367479c0c9d97363b1203msarett}; 9278bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 9288bbcd5aab81dc0742c3367479c0c9d97363b1203msaretttemplate <SrcFormat kSrc, 9298bbcd5aab81dc0742c3367479c0c9d97363b1203msarett DstFormat kDst, 9308bbcd5aab81dc0742c3367479c0c9d97363b1203msarett SkAlphaType kAlphaType, 931cf7b877d62537672b67449bc96858cc1262be5f8msarett ColorSpaceMatch kCSM> 932d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarettstatic void color_xform_RGBA(void* dst, const void* vsrc, int len, 9338bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const float* const srcTables[3], const float matrix[16], 9348bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const uint8_t* const dstTables[3]) { 9358bbcd5aab81dc0742c3367479c0c9d97363b1203msarett LoadFn load; 9368bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Load1Fn load_1; 937c0444615ed76360f680619ad4d1f92cda6181a50msarett static constexpr bool loadAlpha = (kPremul_SkAlphaType == kAlphaType) || 938c0444615ed76360f680619ad4d1f92cda6181a50msarett (kF16_Linear_DstFormat == kDst) || 939c0444615ed76360f680619ad4d1f92cda6181a50msarett (kF32_Linear_DstFormat == kDst); 9408bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kSrc) { 9418bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kRGBA_8888_Linear_SrcFormat: 942c0444615ed76360f680619ad4d1f92cda6181a50msarett if (loadAlpha) { 943cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_linear<kRGBA_Order>; 944cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_linear_1<kRGBA_Order>; 9458bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 946cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_linear<kRGBA_Order>; 947cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_linear_1<kRGBA_Order>; 9488bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 9498bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 9508bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kRGBA_8888_Table_SrcFormat: 951c0444615ed76360f680619ad4d1f92cda6181a50msarett if (loadAlpha) { 952cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_from_tables<kRGBA_Order>; 953cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_from_tables_1<kRGBA_Order>; 9548bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } else { 955cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_from_tables<kRGBA_Order>; 956cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_from_tables_1<kRGBA_Order>; 957cf7b877d62537672b67449bc96858cc1262be5f8msarett } 958cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 959cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Linear_SrcFormat: 960cf7b877d62537672b67449bc96858cc1262be5f8msarett if (loadAlpha) { 961cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_linear<kBGRA_Order>; 962cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_linear_1<kBGRA_Order>; 963cf7b877d62537672b67449bc96858cc1262be5f8msarett } else { 964cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_linear<kBGRA_Order>; 965cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_linear_1<kBGRA_Order>; 966cf7b877d62537672b67449bc96858cc1262be5f8msarett } 967cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 968cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Table_SrcFormat: 969cf7b877d62537672b67449bc96858cc1262be5f8msarett if (loadAlpha) { 970cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgba_from_tables<kBGRA_Order>; 971cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgba_from_tables_1<kBGRA_Order>; 972cf7b877d62537672b67449bc96858cc1262be5f8msarett } else { 973cf7b877d62537672b67449bc96858cc1262be5f8msarett load = load_rgb_from_tables<kBGRA_Order>; 974cf7b877d62537672b67449bc96858cc1262be5f8msarett load_1 = load_rgb_from_tables_1<kBGRA_Order>; 9758bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 9768bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 9778bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 9788bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 9798bbcd5aab81dc0742c3367479c0c9d97363b1203msarett StoreFn store; 9808bbcd5aab81dc0742c3367479c0c9d97363b1203msarett Store1Fn store_1; 9818bbcd5aab81dc0742c3367479c0c9d97363b1203msarett size_t sizeOfDstPixel; 9828bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kDst) { 983cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_Linear_DstFormat: 984cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_linear<kRGBA_Order>; 985cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_linear_1<kRGBA_Order>; 986cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 987cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 988cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_SRGB_DstFormat: 989cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_srgb<kRGBA_Order>; 990cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_srgb_1<kRGBA_Order>; 991cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 992cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 993cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_2Dot2_DstFormat: 994cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_2dot2<kRGBA_Order>; 995cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_2dot2_1<kRGBA_Order>; 9968bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 9978bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 998cf7b877d62537672b67449bc96858cc1262be5f8msarett case kRGBA_8888_Table_DstFormat: 999cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_generic<kRGBA_Order>; 1000cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_generic_1<kRGBA_Order>; 10018bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 10028bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 1003cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Linear_DstFormat: 1004cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_linear<kBGRA_Order>; 1005cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_linear_1<kBGRA_Order>; 10068bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 10078bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 1008cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_SRGB_DstFormat: 1009cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_srgb<kBGRA_Order>; 1010cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_srgb_1<kBGRA_Order>; 1011cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 1012cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 1013cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_2Dot2_DstFormat: 1014cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_2dot2<kBGRA_Order>; 1015cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_2dot2_1<kBGRA_Order>; 1016cf7b877d62537672b67449bc96858cc1262be5f8msarett sizeOfDstPixel = 4; 1017cf7b877d62537672b67449bc96858cc1262be5f8msarett break; 1018cf7b877d62537672b67449bc96858cc1262be5f8msarett case kBGRA_8888_Table_DstFormat: 1019cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_generic<kBGRA_Order>; 1020cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_generic_1<kBGRA_Order>; 10218bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 4; 10228bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 10238bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kF16_Linear_DstFormat: 1024cf7b877d62537672b67449bc96858cc1262be5f8msarett store = (kOpaque_SkAlphaType == kAlphaType) ? store_f16_opaque<kRGBA_Order> : 1025cf7b877d62537672b67449bc96858cc1262be5f8msarett store_f16<kRGBA_Order>; 1026cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = (kOpaque_SkAlphaType == kAlphaType) ? store_f16_1_opaque<kRGBA_Order> : 1027cf7b877d62537672b67449bc96858cc1262be5f8msarett store_f16_1<kRGBA_Order>; 10288bbcd5aab81dc0742c3367479c0c9d97363b1203msarett sizeOfDstPixel = 8; 10298bbcd5aab81dc0742c3367479c0c9d97363b1203msarett break; 1030c0444615ed76360f680619ad4d1f92cda6181a50msarett case kF32_Linear_DstFormat: 1031cf7b877d62537672b67449bc96858cc1262be5f8msarett store = store_f32<kRGBA_Order>; 1032cf7b877d62537672b67449bc96858cc1262be5f8msarett store_1 = store_f32_1<kRGBA_Order>; 1033c0444615ed76360f680619ad4d1f92cda6181a50msarett sizeOfDstPixel = 16; 1034c0444615ed76360f680619ad4d1f92cda6181a50msarett break; 10358bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 10368bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 1037d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett const uint32_t* src = (const uint32_t*) vsrc; 1038d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f rXgXbX, rYgYbY, rZgZbZ, rTgTbT; 1039d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load_matrix(matrix, rXgXbX, rYgYbY, rZgZbZ, rTgTbT); 1040d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1041d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (len >= 4) { 1042d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett // Naively this would be a loop of load-transform-store, but we found it faster to 1043d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett // move the N+1th load ahead of the Nth store. We don't bother doing this for N<4. 1044d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f r, g, b, a; 1045d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load(src, r, g, b, a, srcTables); 1046d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett src += 4; 1047d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett len -= 4; 1048d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1049d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f dr, dg, db, da; 1050d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett while (len >= 4) { 1051d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kNone_ColorSpaceMatch == kCSM) { 1052d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett transform_gamut(r, g, b, a, rXgXbX, rYgYbY, rZgZbZ, dr, dg, db, da); 1053d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett translate_gamut(rTgTbT, dr, dg, db); 1054d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } else { 1055d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dr = r; 1056d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dg = g; 1057d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett db = b; 1058d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett da = a; 1059d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1060d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1061d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kPremul_SkAlphaType == kAlphaType) { 1062d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett premultiply(dr, dg, db, da); 1063d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1064d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1065d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load(src, r, g, b, a, srcTables); 1066d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1067d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett store(dst, src - 4, dr, dg, db, da, dstTables); 1068d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dst = SkTAddOffset<void>(dst, 4 * sizeOfDstPixel); 1069d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett src += 4; 1070d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett len -= 4; 1071d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1072d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1073d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kNone_ColorSpaceMatch == kCSM) { 1074d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett transform_gamut(r, g, b, a, rXgXbX, rYgYbY, rZgZbZ, dr, dg, db, da); 1075d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett translate_gamut(rTgTbT, dr, dg, db); 1076d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } else { 1077d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dr = r; 1078d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dg = g; 1079d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett db = b; 1080d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett da = a; 1081d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1082d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1083d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kPremul_SkAlphaType == kAlphaType) { 1084d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett premultiply(dr, dg, db, da); 1085d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1086d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1087d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett store(dst, src - 4, dr, dg, db, da, dstTables); 1088d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dst = SkTAddOffset<void>(dst, 4 * sizeOfDstPixel); 1089d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1090d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1091d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett while (len > 0) { 1092d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f r, g, b, a; 1093d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett load_1(src, r, g, b, a, srcTables); 1094d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1095d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett Sk4f rgba; 1096d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kNone_ColorSpaceMatch == kCSM) { 1097d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett transform_gamut_1(r, g, b, rXgXbX, rYgYbY, rZgZbZ, rgba); 1098d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett translate_gamut_1(rTgTbT, rgba); 1099d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } else { 1100d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett rgba = Sk4f(r[0], g[0], b[0], a[0]); 1101d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1102d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1103d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett if (kPremul_SkAlphaType == kAlphaType) { 1104d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett premultiply_1(a, rgba); 1105d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 1106d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1107d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett store_1(dst, src, rgba, a, dstTables); 1108d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett 1109d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett src += 1; 1110d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett len -= 1; 1111d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett dst = SkTAddOffset<void>(dst, sizeOfDstPixel); 1112d478a99f5c29f0e8fa64b50831f53232f5577f2dMatt Sarett } 11138bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 11148bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 11153418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett/////////////////////////////////////////////////////////////////////////////////////////////////// 11160f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 11179488833428e83c93a7e6002f4d056084fb57112fraftiasstatic inline int num_tables(SkColorSpace_XYZ* space) { 11189488833428e83c93a7e6002f4d056084fb57112fraftias switch (space->gammaNamed()) { 11197bbda991af353fbe6b34132132d211d23a3dba8cmsarett case kSRGB_SkGammaNamed: 11207bbda991af353fbe6b34132132d211d23a3dba8cmsarett case k2Dot2Curve_SkGammaNamed: 11217bbda991af353fbe6b34132132d211d23a3dba8cmsarett case kLinear_SkGammaNamed: 11227bbda991af353fbe6b34132132d211d23a3dba8cmsarett return 0; 11237bbda991af353fbe6b34132132d211d23a3dba8cmsarett default: { 11249488833428e83c93a7e6002f4d056084fb57112fraftias const SkGammas* gammas = space->gammas(); 11257bbda991af353fbe6b34132132d211d23a3dba8cmsarett SkASSERT(gammas); 11267bbda991af353fbe6b34132132d211d23a3dba8cmsarett 11277bbda991af353fbe6b34132132d211d23a3dba8cmsarett bool gammasAreMatching = (gammas->type(0) == gammas->type(1)) && 11287bbda991af353fbe6b34132132d211d23a3dba8cmsarett (gammas->data(0) == gammas->data(1)) && 11297bbda991af353fbe6b34132132d211d23a3dba8cmsarett (gammas->type(0) == gammas->type(2)) && 11307bbda991af353fbe6b34132132d211d23a3dba8cmsarett (gammas->data(0) == gammas->data(2)); 11317bbda991af353fbe6b34132132d211d23a3dba8cmsarett 11327bbda991af353fbe6b34132132d211d23a3dba8cmsarett // It's likely that each component will have the same gamma. In this case, 11337bbda991af353fbe6b34132132d211d23a3dba8cmsarett // we only need to build one table. 11347bbda991af353fbe6b34132132d211d23a3dba8cmsarett return gammasAreMatching ? 1 : 3; 11357bbda991af353fbe6b34132132d211d23a3dba8cmsarett } 11367bbda991af353fbe6b34132132d211d23a3dba8cmsarett } 11377bbda991af353fbe6b34132132d211d23a3dba8cmsarett} 11387bbda991af353fbe6b34132132d211d23a3dba8cmsarett 11398bbcd5aab81dc0742c3367479c0c9d97363b1203msaretttemplate <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM> 1140f489886915034093278353d06c6f1973b2e8b7d2Matt SarettSkColorSpaceXform_XYZ<kSrc, kDst, kCSM> 11419488833428e83c93a7e6002f4d056084fb57112fraftias::SkColorSpaceXform_XYZ(SkColorSpace_XYZ* srcSpace, const SkMatrix44& srcToDst, 11429488833428e83c93a7e6002f4d056084fb57112fraftias SkColorSpace_XYZ* dstSpace) 11433418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett{ 1144de68d6c4616d86621373d88100002ddfdb9c08e3brianosman srcToDst.asColMajorf(fSrcToDst); 11457bbda991af353fbe6b34132132d211d23a3dba8cmsarett 11464be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett const int numSrcTables = num_tables(srcSpace); 1147f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett const size_t srcEntries = numSrcTables * 256; 11487bbda991af353fbe6b34132132d211d23a3dba8cmsarett const bool srcGammasAreMatching = (1 >= numSrcTables); 1149f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett fSrcStorage.reset(srcEntries); 1150f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett build_gamma_tables(fSrcGammaTables, fSrcStorage.get(), 256, srcSpace, kToLinear, 1151f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett srcGammasAreMatching); 1152f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett 1153f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett const int numDstTables = num_tables(dstSpace); 11549488833428e83c93a7e6002f4d056084fb57112fraftias dstSpace->toDstGammaTables(fDstGammaTables, &fDstStorage, numDstTables); 11553418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett} 1156dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 11577bbda991af353fbe6b34132132d211d23a3dba8cmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 11587bbda991af353fbe6b34132132d211d23a3dba8cmsarett 1159cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <SrcFormat kSrc, DstFormat kDst, ColorSpaceMatch kCSM> 116031d097e865f266c8398f45114e4c75c0dfdef058msarettstatic inline bool apply_set_alpha(void* dst, const void* src, int len, SkAlphaType alphaType, 11618bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const float* const srcTables[3], const float matrix[16], 11628bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const uint8_t* const dstTables[3]) { 11638bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (alphaType) { 11648bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kOpaque_SkAlphaType: 116531d097e865f266c8398f45114e4c75c0dfdef058msarett color_xform_RGBA<kSrc, kDst, kOpaque_SkAlphaType, kCSM> 11668bbcd5aab81dc0742c3367479c0c9d97363b1203msarett (dst, src, len, srcTables, matrix, dstTables); 116731d097e865f266c8398f45114e4c75c0dfdef058msarett return true; 11688bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kPremul_SkAlphaType: 116931d097e865f266c8398f45114e4c75c0dfdef058msarett color_xform_RGBA<kSrc, kDst, kPremul_SkAlphaType, kCSM> 11708bbcd5aab81dc0742c3367479c0c9d97363b1203msarett (dst, src, len, srcTables, matrix, dstTables); 117131d097e865f266c8398f45114e4c75c0dfdef058msarett return true; 11728bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kUnpremul_SkAlphaType: 117331d097e865f266c8398f45114e4c75c0dfdef058msarett color_xform_RGBA<kSrc, kDst, kUnpremul_SkAlphaType, kCSM> 11748bbcd5aab81dc0742c3367479c0c9d97363b1203msarett (dst, src, len, srcTables, matrix, dstTables); 117531d097e865f266c8398f45114e4c75c0dfdef058msarett return true; 11768bbcd5aab81dc0742c3367479c0c9d97363b1203msarett default: 117731d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 11788bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 11798bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 11808bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 1181cf7b877d62537672b67449bc96858cc1262be5f8msaretttemplate <SrcGamma kSrc, DstFormat kDst, ColorSpaceMatch kCSM> 118231d097e865f266c8398f45114e4c75c0dfdef058msarettstatic inline bool apply_set_src(void* dst, const void* src, int len, SkAlphaType alphaType, 11838bbcd5aab81dc0742c3367479c0c9d97363b1203msarett const float* const srcTables[3], const float matrix[16], 1184cf7b877d62537672b67449bc96858cc1262be5f8msarett const uint8_t* const dstTables[3], 1185cf7b877d62537672b67449bc96858cc1262be5f8msarett SkColorSpaceXform::ColorFormat srcColorFormat) { 1186cf7b877d62537672b67449bc96858cc1262be5f8msarett switch (srcColorFormat) { 1187cf7b877d62537672b67449bc96858cc1262be5f8msarett case SkColorSpaceXform::kRGBA_8888_ColorFormat: 1188cf7b877d62537672b67449bc96858cc1262be5f8msarett switch (kSrc) { 1189cf7b877d62537672b67449bc96858cc1262be5f8msarett case kLinear_SrcGamma: 1190cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kRGBA_8888_Linear_SrcFormat, kDst, kCSM> 1191cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, nullptr, matrix, dstTables); 1192cf7b877d62537672b67449bc96858cc1262be5f8msarett case kTable_SrcGamma: 1193cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kRGBA_8888_Table_SrcFormat, kDst, kCSM> 1194cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, srcTables, matrix, dstTables); 1195cf7b877d62537672b67449bc96858cc1262be5f8msarett } 1196cf7b877d62537672b67449bc96858cc1262be5f8msarett case SkColorSpaceXform::kBGRA_8888_ColorFormat: 1197cf7b877d62537672b67449bc96858cc1262be5f8msarett switch (kSrc) { 1198cf7b877d62537672b67449bc96858cc1262be5f8msarett case kLinear_SrcGamma: 1199cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kBGRA_8888_Linear_SrcFormat, kDst, kCSM> 1200cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, nullptr, matrix, dstTables); 1201cf7b877d62537672b67449bc96858cc1262be5f8msarett case kTable_SrcGamma: 1202cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_alpha<kBGRA_8888_Table_SrcFormat, kDst, kCSM> 1203cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, srcTables, matrix, dstTables); 1204cf7b877d62537672b67449bc96858cc1262be5f8msarett } 1205cf7b877d62537672b67449bc96858cc1262be5f8msarett default: 120631d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 12078bbcd5aab81dc0742c3367479c0c9d97363b1203msarett } 12088bbcd5aab81dc0742c3367479c0c9d97363b1203msarett} 12098bbcd5aab81dc0742c3367479c0c9d97363b1203msarett 12108bbcd5aab81dc0742c3367479c0c9d97363b1203msaretttemplate <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM> 1211f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettbool SkColorSpaceXform_XYZ<kSrc, kDst, kCSM> 121231d097e865f266c8398f45114e4c75c0dfdef058msarett::onApply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, const void* src, 121331d097e865f266c8398f45114e4c75c0dfdef058msarett int len, SkAlphaType alphaType) const 12143418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett{ 1215200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kFull_ColorSpaceMatch == kCSM) { 12168bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (alphaType) { 1217200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kPremul_SkAlphaType: 1218200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // We can't skip the xform since we need to perform a premultiply in the 1219200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // linear space. 1220200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett break; 1221200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 1222c0444615ed76360f680619ad4d1f92cda6181a50msarett switch (dstColorFormat) { 1223c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_8888_ColorFormat: 122431d097e865f266c8398f45114e4c75c0dfdef058msarett memcpy(dst, src, len * sizeof(uint32_t)); 122531d097e865f266c8398f45114e4c75c0dfdef058msarett return true; 1226c0444615ed76360f680619ad4d1f92cda6181a50msarett case kBGRA_8888_ColorFormat: 122731d097e865f266c8398f45114e4c75c0dfdef058msarett SkOpts::RGBA_to_BGRA((uint32_t*) dst, src, len); 122831d097e865f266c8398f45114e4c75c0dfdef058msarett return true; 1229c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_F16_ColorFormat: 1230c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_F32_ColorFormat: 1231c0444615ed76360f680619ad4d1f92cda6181a50msarett // There's still work to do to xform to linear floats. 1232200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett break; 1233200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 123431d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 1235200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1236200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1237200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1238200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1239c0444615ed76360f680619ad4d1f92cda6181a50msarett switch (dstColorFormat) { 1240c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_8888_ColorFormat: 12418bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kDst) { 12428bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_DstGamma: 1243cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kRGBA_8888_Linear_DstFormat, kCSM> 1244cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1245cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12468bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kSRGB_DstGamma: 1247cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kRGBA_8888_SRGB_DstFormat, kCSM> 1248cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1249cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12508bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case k2Dot2_DstGamma: 1251cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kRGBA_8888_2Dot2_DstFormat, kCSM> 1252cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1253cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12548bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kTable_DstGamma: 1255cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kRGBA_8888_Table_DstFormat, kCSM> 1256cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, fDstGammaTables, 1257cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 1258d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 1259c0444615ed76360f680619ad4d1f92cda6181a50msarett case kBGRA_8888_ColorFormat: 12608bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kDst) { 12618bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_DstGamma: 1262cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kBGRA_8888_Linear_DstFormat, kCSM> 1263cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1264cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12658bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kSRGB_DstGamma: 1266cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kBGRA_8888_SRGB_DstFormat, kCSM> 1267cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1268cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12698bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case k2Dot2_DstGamma: 1270cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kBGRA_8888_2Dot2_DstFormat, kCSM> 1271cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1272cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 12738bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kTable_DstGamma: 1274cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kBGRA_8888_Table_DstFormat, kCSM> 1275cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, fDstGammaTables, 1276cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 1277d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 1278c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_F16_ColorFormat: 12798bbcd5aab81dc0742c3367479c0c9d97363b1203msarett switch (kDst) { 12808bbcd5aab81dc0742c3367479c0c9d97363b1203msarett case kLinear_DstGamma: 1281cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kF16_Linear_DstFormat, kCSM> 1282cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1283cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 1284d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett default: 128531d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 1286d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 1287c0444615ed76360f680619ad4d1f92cda6181a50msarett case kRGBA_F32_ColorFormat: 1288c0444615ed76360f680619ad4d1f92cda6181a50msarett switch (kDst) { 1289c0444615ed76360f680619ad4d1f92cda6181a50msarett case kLinear_DstGamma: 1290cf7b877d62537672b67449bc96858cc1262be5f8msarett return apply_set_src<kSrc, kF32_Linear_DstFormat, kCSM> 1291cf7b877d62537672b67449bc96858cc1262be5f8msarett (dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr, 1292cf7b877d62537672b67449bc96858cc1262be5f8msarett srcColorFormat); 1293c0444615ed76360f680619ad4d1f92cda6181a50msarett default: 129431d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 1295c0444615ed76360f680619ad4d1f92cda6181a50msarett } 1296d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett default: 129731d097e865f266c8398f45114e4c75c0dfdef058msarett return false; 1298d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 12999ce3a543c92a73e6daca420defc042886b3f2019msarett} 13009dc6cf6b8833d36c29a23d2519989b069745fcd5msarett 1301f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettbool SkColorSpaceXform::apply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, 1302f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett const void* src, int len, SkAlphaType alphaType) const { 1303f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return ((SkColorSpaceXform_Base*) this)->onApply(dstColorFormat, dst, srcColorFormat, src, len, 1304f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett alphaType); 1305f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett} 1306f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett 13077bbda991af353fbe6b34132132d211d23a3dba8cmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 13087bbda991af353fbe6b34132132d211d23a3dba8cmsarett 13099488833428e83c93a7e6002f4d056084fb57112fraftiasstd::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace_XYZ* space) { 1310f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 13118bbcd5aab81dc0742c3367479c0c9d97363b1203msarett <kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch> 13129dc6cf6b8833d36c29a23d2519989b069745fcd5msarett (space, SkMatrix::I(), space)); 13139dc6cf6b8833d36c29a23d2519989b069745fcd5msarett} 1314