SkColorSpaceXform.cpp revision 200877eecaba782e56a1dd9e13a92f36d7b1ba12
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" 99876ac5b3016e5353c072378ac1545a0a2270757msarett#include "SkColorSpace_Base.h" 10200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett#include "SkColorSpacePriv.h" 119876ac5b3016e5353c072378ac1545a0a2270757msarett#include "SkColorSpaceXform.h" 12200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett#include "SkHalf.h" 13200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett#include "SkOpts.h" 14ac41bac40f5a80d2bc5ccec584c23478a6900179mtklein#include "SkSRGB.h" 159876ac5b3016e5353c072378ac1545a0a2270757msarett 166006f678e78af7b6f67a454cd4bc213048983f9dmsarettstatic constexpr float sk_linear_from_2dot2[256] = { 17b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000000000000000000f, 0.000005077051900662f, 0.000023328004666099f, 0.000056921765712193f, 18b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000107187362341244f, 0.000175123977503027f, 0.000261543754548491f, 0.000367136269815943f, 19b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000492503787191433f, 0.000638182842167022f, 0.000804658499513058f, 0.000992374304074325f, 20b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.001201739522438400f, 0.001433134589671860f, 0.001686915316789280f, 0.001963416213396470f, 21b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.002262953160706430f, 0.002585825596234170f, 0.002932318323938360f, 0.003302703032003640f, 22b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.003697239578900130f, 0.004116177093282750f, 0.004559754922526020f, 0.005028203456855540f, 23b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.005521744850239660f, 0.006040593654849810f, 0.006584957382581690f, 0.007155037004573030f, 24b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.007751027397660610f, 0.008373117745148580f, 0.009021491898012130f, 0.009696328701658230f, 25b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.010397802292555300f, 0.011126082368383200f, 0.011881334434813700f, 0.012663720031582100f, 26b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.013473396940142600f, 0.014310519374884100f, 0.015175238159625200f, 0.016067700890886900f, 27b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.016988052089250000f, 0.017936433339950200f, 0.018912983423721500f, 0.019917838438785700f, 28b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.020951131914781100f, 0.022012994919336500f, 0.023103556157921400f, 0.024222942067534200f, 29b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.025371276904734600f, 0.026548682828472900f, 0.027755279978126000f, 0.028991186547107800f, 30b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.030256518852388700f, 0.031551391400226400f, 0.032875916948383800f, 0.034230206565082000f, 31b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.035614369684918800f, 0.037028514161960200f, 0.038472746320194600f, 0.039947171001525600f, 32b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.041451891611462500f, 0.042987010162657100f, 0.044552627316421400f, 0.046148842422351000f, 33b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.047775753556170600f, 0.049433457555908000f, 0.051122050056493400f, 0.052841625522879000f, 34b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.054592277281760300f, 0.056374097551979800f, 0.058187177473685400f, 0.060031607136313200f, 35b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.061907475605455800f, 0.063814870948677200f, 0.065753880260330100f, 0.067724589685424300f, 36b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.069727084442598800f, 0.071761448846239100f, 0.073827766327784600f, 0.075926119456264800f, 37b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.078056589958101900f, 0.080219258736215100f, 0.082414205888459200f, 0.084641510725429500f, 38b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.086901251787660300f, 0.089193506862247800f, 0.091518352998919500f, 0.093875866525577800f, 39b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.096266123063339700f, 0.098689197541094500f, 0.101145164209600000f, 0.103634096655137000f, 40b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.106156067812744000f, 0.108711149979039000f, 0.111299414824660000f, 0.113920933406333000f, 41b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.116575776178572000f, 0.119264013005047000f, 0.121985713169619000f, 0.124740945387051000f, 42b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.127529777813422000f, 0.130352278056244000f, 0.133208513184300000f, 0.136098549737202000f, 43b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.139022453734703000f, 0.141980290685736000f, 0.144972125597231000f, 0.147998022982685000f, 44b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.151058046870511000f, 0.154152260812165000f, 0.157280727890073000f, 0.160443510725344000f, 45b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.163640671485290000f, 0.166872271890766000f, 0.170138373223312000f, 0.173439036332135000f, 46b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.176774321640903000f, 0.180144289154390000f, 0.183548998464951000f, 0.186988508758844000f, 47b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.190462878822409000f, 0.193972167048093000f, 0.197516431440340000f, 0.201095729621346000f, 48b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.204710118836677000f, 0.208359655960767000f, 0.212044397502288000f, 0.215764399609395000f, 49b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.219519718074868000f, 0.223310408341127000f, 0.227136525505149000f, 0.230998124323267000f, 50b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.234895259215880000f, 0.238827984272048000f, 0.242796353254002000f, 0.246800419601550000f, 51b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.250840236436400000f, 0.254915856566385000f, 0.259027332489606000f, 0.263174716398492000f, 52b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.267358060183772000f, 0.271577415438375000f, 0.275832833461245000f, 0.280124365261085000f, 53b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.284452061560024000f, 0.288815972797219000f, 0.293216149132375000f, 0.297652640449211000f, 54b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.302125496358853000f, 0.306634766203158000f, 0.311180499057984000f, 0.315762743736397000f, 55b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.320381548791810000f, 0.325036962521076000f, 0.329729032967515000f, 0.334457807923889000f, 56b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.339223334935327000f, 0.344025661302187000f, 0.348864834082879000f, 0.353740900096629000f, 57b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.358653905926199000f, 0.363603897920553000f, 0.368590922197487000f, 0.373615024646202000f, 58b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.378676250929840000f, 0.383774646487975000f, 0.388910256539059000f, 0.394083126082829000f, 59b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.399293299902674000f, 0.404540822567962000f, 0.409825738436323000f, 0.415148091655907000f, 60b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.420507926167587000f, 0.425905285707146000f, 0.431340213807410000f, 0.436812753800359000f, 61b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.442322948819202000f, 0.447870841800410000f, 0.453456475485731000f, 0.459079892424160000f, 62b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.464741134973889000f, 0.470440245304218000f, 0.476177265397440000f, 0.481952237050698000f, 63b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.487765201877811000f, 0.493616201311074000f, 0.499505276603030000f, 0.505432468828216000f, 64b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.511397818884880000f, 0.517401367496673000f, 0.523443155214325000f, 0.529523222417277000f, 65b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.535641609315311000f, 0.541798355950137000f, 0.547993502196972000f, 0.554227087766085000f, 66b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.560499152204328000f, 0.566809734896638000f, 0.573158875067523000f, 0.579546611782525000f, 67b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.585972983949661000f, 0.592438030320847000f, 0.598941789493296000f, 0.605484299910907000f, 68b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.612065599865624000f, 0.618685727498780000f, 0.625344720802427000f, 0.632042617620641000f, 69b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.638779455650817000f, 0.645555272444935000f, 0.652370105410821000f, 0.659223991813387000f, 70b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.666116968775851000f, 0.673049073280942000f, 0.680020342172095000f, 0.687030812154625000f, 71b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.694080519796882000f, 0.701169501531402000f, 0.708297793656032000f, 0.715465432335048000f, 72b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.722672453600255000f, 0.729918893352071000f, 0.737204787360605000f, 0.744530171266715000f, 73b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.751895080583051000f, 0.759299550695091000f, 0.766743616862161000f, 0.774227314218442000f, 74b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.781750677773962000f, 0.789313742415586000f, 0.796916542907978000f, 0.804559113894567000f, 75b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.812241489898490000f, 0.819963705323528000f, 0.827725794455034000f, 0.835527791460841000f, 76b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.843369730392169000f, 0.851251645184515000f, 0.859173569658532000f, 0.867135537520905000f, 77b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.875137582365205000f, 0.883179737672745000f, 0.891262036813419000f, 0.899384513046529000f, 78b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.907547199521614000f, 0.915750129279253000f, 0.923993335251873000f, 0.932276850264543000f, 79b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.940600707035753000f, 0.948964938178195000f, 0.957369576199527000f, 0.965814653503130000f, 80b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.974300202388861000f, 0.982826255053791000f, 0.991392843592940000f, 1.000000000000000000f, 81b39067696ad08a26bbe49b71a71f0546dc42a075msarett}; 82b39067696ad08a26bbe49b71a71f0546dc42a075msarett 836006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 846006f678e78af7b6f67a454cd4bc213048983f9dmsarett 85b39067696ad08a26bbe49b71a71f0546dc42a075msarettstatic constexpr uint8_t linear_to_srgb[1024] = { 86b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0, 3, 6, 10, 13, 15, 18, 20, 22, 23, 25, 27, 28, 30, 31, 32, 34, 35, 87b39067696ad08a26bbe49b71a71f0546dc42a075msarett 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 49, 50, 51, 52, 88b39067696ad08a26bbe49b71a71f0546dc42a075msarett 53, 53, 54, 55, 56, 56, 57, 58, 58, 59, 60, 61, 61, 62, 62, 63, 64, 64, 89b39067696ad08a26bbe49b71a71f0546dc42a075msarett 65, 66, 66, 67, 67, 68, 68, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 90b39067696ad08a26bbe49b71a71f0546dc42a075msarett 75, 76, 76, 77, 77, 78, 78, 79, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 91b39067696ad08a26bbe49b71a71f0546dc42a075msarett 84, 84, 85, 85, 85, 86, 86, 87, 87, 88, 88, 88, 89, 89, 90, 90, 91, 91, 92b39067696ad08a26bbe49b71a71f0546dc42a075msarett 91, 92, 92, 93, 93, 93, 94, 94, 95, 95, 95, 96, 96, 97, 97, 97, 98, 98, 93b39067696ad08a26bbe49b71a71f0546dc42a075msarett 98, 99, 99, 99, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 103, 104, 104, 104, 94b39067696ad08a26bbe49b71a71f0546dc42a075msarett 105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, 110, 110, 95b39067696ad08a26bbe49b71a71f0546dc42a075msarett 111, 111, 111, 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 115, 116, 116, 96b39067696ad08a26bbe49b71a71f0546dc42a075msarett 116, 117, 117, 117, 118, 118, 118, 118, 119, 119, 119, 120, 120, 120, 121, 121, 121, 121, 97b39067696ad08a26bbe49b71a71f0546dc42a075msarett 122, 122, 122, 123, 123, 123, 123, 124, 124, 124, 125, 125, 125, 125, 126, 126, 126, 126, 98b39067696ad08a26bbe49b71a71f0546dc42a075msarett 127, 127, 127, 128, 128, 128, 128, 129, 129, 129, 129, 130, 130, 130, 130, 131, 131, 131, 99b39067696ad08a26bbe49b71a71f0546dc42a075msarett 131, 132, 132, 132, 133, 133, 133, 133, 134, 134, 134, 134, 135, 135, 135, 135, 136, 136, 100b39067696ad08a26bbe49b71a71f0546dc42a075msarett 136, 136, 137, 137, 137, 137, 138, 138, 138, 138, 138, 139, 139, 139, 139, 140, 140, 140, 101b39067696ad08a26bbe49b71a71f0546dc42a075msarett 140, 141, 141, 141, 141, 142, 142, 142, 142, 143, 143, 143, 143, 143, 144, 144, 144, 144, 102b39067696ad08a26bbe49b71a71f0546dc42a075msarett 145, 145, 145, 145, 146, 146, 146, 146, 146, 147, 147, 147, 147, 148, 148, 148, 148, 148, 103b39067696ad08a26bbe49b71a71f0546dc42a075msarett 149, 149, 149, 149, 150, 150, 150, 150, 150, 151, 151, 151, 151, 152, 152, 152, 152, 152, 104b39067696ad08a26bbe49b71a71f0546dc42a075msarett 153, 153, 153, 153, 153, 154, 154, 154, 154, 155, 155, 155, 155, 155, 156, 156, 156, 156, 105b39067696ad08a26bbe49b71a71f0546dc42a075msarett 156, 157, 157, 157, 157, 157, 158, 158, 158, 158, 158, 159, 159, 159, 159, 159, 160, 160, 106b39067696ad08a26bbe49b71a71f0546dc42a075msarett 160, 160, 160, 161, 161, 161, 161, 161, 162, 162, 162, 162, 162, 163, 163, 163, 163, 163, 107b39067696ad08a26bbe49b71a71f0546dc42a075msarett 164, 164, 164, 164, 164, 165, 165, 165, 165, 165, 166, 166, 166, 166, 166, 167, 167, 167, 108b39067696ad08a26bbe49b71a71f0546dc42a075msarett 167, 167, 168, 168, 168, 168, 168, 168, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 109b39067696ad08a26bbe49b71a71f0546dc42a075msarett 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, 172, 173, 173, 173, 173, 173, 173, 174, 110b39067696ad08a26bbe49b71a71f0546dc42a075msarett 174, 174, 174, 174, 175, 175, 175, 175, 175, 175, 176, 176, 176, 176, 176, 177, 177, 177, 111b39067696ad08a26bbe49b71a71f0546dc42a075msarett 177, 177, 177, 178, 178, 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, 180, 180, 180, 112b39067696ad08a26bbe49b71a71f0546dc42a075msarett 180, 180, 181, 181, 181, 181, 181, 181, 182, 182, 182, 182, 182, 182, 183, 183, 183, 183, 113b39067696ad08a26bbe49b71a71f0546dc42a075msarett 183, 183, 184, 184, 184, 184, 184, 184, 185, 185, 185, 185, 185, 185, 186, 186, 186, 186, 114b39067696ad08a26bbe49b71a71f0546dc42a075msarett 186, 186, 187, 187, 187, 187, 187, 187, 188, 188, 188, 188, 188, 188, 189, 189, 189, 189, 115b39067696ad08a26bbe49b71a71f0546dc42a075msarett 189, 189, 190, 190, 190, 190, 190, 190, 191, 191, 191, 191, 191, 191, 191, 192, 192, 192, 116b39067696ad08a26bbe49b71a71f0546dc42a075msarett 192, 192, 192, 193, 193, 193, 193, 193, 193, 194, 194, 194, 194, 194, 194, 194, 195, 195, 117b39067696ad08a26bbe49b71a71f0546dc42a075msarett 195, 195, 195, 195, 196, 196, 196, 196, 196, 196, 197, 197, 197, 197, 197, 197, 197, 198, 118b39067696ad08a26bbe49b71a71f0546dc42a075msarett 198, 198, 198, 198, 198, 199, 199, 199, 199, 199, 199, 199, 200, 200, 200, 200, 200, 200, 119b39067696ad08a26bbe49b71a71f0546dc42a075msarett 200, 201, 201, 201, 201, 201, 201, 202, 202, 202, 202, 202, 202, 202, 203, 203, 203, 203, 120b39067696ad08a26bbe49b71a71f0546dc42a075msarett 203, 203, 203, 204, 204, 204, 204, 204, 204, 204, 205, 205, 205, 205, 205, 205, 206, 206, 121b39067696ad08a26bbe49b71a71f0546dc42a075msarett 206, 206, 206, 206, 206, 207, 207, 207, 207, 207, 207, 207, 208, 208, 208, 208, 208, 208, 122b39067696ad08a26bbe49b71a71f0546dc42a075msarett 208, 209, 209, 209, 209, 209, 209, 209, 210, 210, 210, 210, 210, 210, 210, 211, 211, 211, 123b39067696ad08a26bbe49b71a71f0546dc42a075msarett 211, 211, 211, 211, 212, 212, 212, 212, 212, 212, 212, 212, 213, 213, 213, 213, 213, 213, 124b39067696ad08a26bbe49b71a71f0546dc42a075msarett 213, 214, 214, 214, 214, 214, 214, 214, 215, 215, 215, 215, 215, 215, 215, 216, 216, 216, 125b39067696ad08a26bbe49b71a71f0546dc42a075msarett 216, 216, 216, 216, 216, 217, 217, 217, 217, 217, 217, 217, 218, 218, 218, 218, 218, 218, 126b39067696ad08a26bbe49b71a71f0546dc42a075msarett 218, 219, 219, 219, 219, 219, 219, 219, 219, 220, 220, 220, 220, 220, 220, 220, 221, 221, 127b39067696ad08a26bbe49b71a71f0546dc42a075msarett 221, 221, 221, 221, 221, 221, 222, 222, 222, 222, 222, 222, 222, 222, 223, 223, 223, 223, 128b39067696ad08a26bbe49b71a71f0546dc42a075msarett 223, 223, 223, 224, 224, 224, 224, 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 225, 129b39067696ad08a26bbe49b71a71f0546dc42a075msarett 225, 226, 226, 226, 226, 226, 226, 226, 227, 227, 227, 227, 227, 227, 227, 227, 228, 228, 130b39067696ad08a26bbe49b71a71f0546dc42a075msarett 228, 228, 228, 228, 228, 228, 229, 229, 229, 229, 229, 229, 229, 229, 230, 230, 230, 230, 131b39067696ad08a26bbe49b71a71f0546dc42a075msarett 230, 230, 230, 230, 231, 231, 231, 231, 231, 231, 231, 231, 232, 232, 232, 232, 232, 232, 132b39067696ad08a26bbe49b71a71f0546dc42a075msarett 232, 232, 233, 233, 233, 233, 233, 233, 233, 233, 234, 234, 234, 234, 234, 234, 234, 234, 133b39067696ad08a26bbe49b71a71f0546dc42a075msarett 235, 235, 235, 235, 235, 235, 235, 235, 236, 236, 236, 236, 236, 236, 236, 236, 236, 237, 134b39067696ad08a26bbe49b71a71f0546dc42a075msarett 237, 237, 237, 237, 237, 237, 237, 238, 238, 238, 238, 238, 238, 238, 238, 239, 239, 239, 135b39067696ad08a26bbe49b71a71f0546dc42a075msarett 239, 239, 239, 239, 239, 239, 240, 240, 240, 240, 240, 240, 240, 240, 241, 241, 241, 241, 136b39067696ad08a26bbe49b71a71f0546dc42a075msarett 241, 241, 241, 241, 241, 242, 242, 242, 242, 242, 242, 242, 242, 243, 243, 243, 243, 243, 137b39067696ad08a26bbe49b71a71f0546dc42a075msarett 243, 243, 243, 243, 244, 244, 244, 244, 244, 244, 244, 244, 245, 245, 245, 245, 245, 245, 138b39067696ad08a26bbe49b71a71f0546dc42a075msarett 245, 245, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 247, 247, 247, 247, 247, 139b39067696ad08a26bbe49b71a71f0546dc42a075msarett 247, 247, 248, 248, 248, 248, 248, 248, 248, 248, 248, 249, 249, 249, 249, 249, 249, 249, 140b39067696ad08a26bbe49b71a71f0546dc42a075msarett 249, 249, 250, 250, 250, 250, 250, 250, 250, 250, 250, 251, 251, 251, 251, 251, 251, 251, 141b39067696ad08a26bbe49b71a71f0546dc42a075msarett 251, 251, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 253, 142b39067696ad08a26bbe49b71a71f0546dc42a075msarett 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 255, 255, 255, 255, 255 143b39067696ad08a26bbe49b71a71f0546dc42a075msarett}; 144b39067696ad08a26bbe49b71a71f0546dc42a075msarett 14515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic constexpr uint8_t linear_to_2dot2_table[1024] = { 146b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0, 11, 15, 18, 21, 23, 25, 26, 28, 30, 31, 32, 34, 35, 36, 37, 39, 40, 147b39067696ad08a26bbe49b71a71f0546dc42a075msarett 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 50, 51, 52, 53, 54, 54, 55, 148b39067696ad08a26bbe49b71a71f0546dc42a075msarett 56, 56, 57, 58, 58, 59, 60, 60, 61, 62, 62, 63, 63, 64, 65, 65, 66, 66, 149b39067696ad08a26bbe49b71a71f0546dc42a075msarett 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 75, 76, 150b39067696ad08a26bbe49b71a71f0546dc42a075msarett 76, 77, 77, 78, 78, 79, 79, 80, 80, 81, 81, 81, 82, 82, 83, 83, 84, 84, 151b39067696ad08a26bbe49b71a71f0546dc42a075msarett 84, 85, 85, 86, 86, 87, 87, 87, 88, 88, 89, 89, 89, 90, 90, 91, 91, 91, 152b39067696ad08a26bbe49b71a71f0546dc42a075msarett 92, 92, 93, 93, 93, 94, 94, 94, 95, 95, 96, 96, 96, 97, 97, 97, 98, 98, 153b39067696ad08a26bbe49b71a71f0546dc42a075msarett 98, 99, 99, 99, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 103, 104, 104, 104, 154b39067696ad08a26bbe49b71a71f0546dc42a075msarett 105, 105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 108, 109, 109, 109, 110, 110, 155b39067696ad08a26bbe49b71a71f0546dc42a075msarett 110, 111, 111, 111, 112, 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 115, 156b39067696ad08a26bbe49b71a71f0546dc42a075msarett 116, 116, 116, 117, 117, 117, 117, 118, 118, 118, 119, 119, 119, 119, 120, 120, 120, 121, 157b39067696ad08a26bbe49b71a71f0546dc42a075msarett 121, 121, 121, 122, 122, 122, 123, 123, 123, 123, 124, 124, 124, 124, 125, 125, 125, 125, 158b39067696ad08a26bbe49b71a71f0546dc42a075msarett 126, 126, 126, 127, 127, 127, 127, 128, 128, 128, 128, 129, 129, 129, 129, 130, 130, 130, 159b39067696ad08a26bbe49b71a71f0546dc42a075msarett 130, 131, 131, 131, 131, 132, 132, 132, 132, 133, 133, 133, 133, 134, 134, 134, 134, 135, 160b39067696ad08a26bbe49b71a71f0546dc42a075msarett 135, 135, 135, 136, 136, 136, 136, 137, 137, 137, 137, 138, 138, 138, 138, 138, 139, 139, 161b39067696ad08a26bbe49b71a71f0546dc42a075msarett 139, 139, 140, 140, 140, 140, 141, 141, 141, 141, 142, 142, 142, 142, 142, 143, 143, 143, 162b39067696ad08a26bbe49b71a71f0546dc42a075msarett 143, 144, 144, 144, 144, 144, 145, 145, 145, 145, 146, 146, 146, 146, 146, 147, 147, 147, 163b39067696ad08a26bbe49b71a71f0546dc42a075msarett 147, 148, 148, 148, 148, 148, 149, 149, 149, 149, 149, 150, 150, 150, 150, 151, 151, 151, 164b39067696ad08a26bbe49b71a71f0546dc42a075msarett 151, 151, 152, 152, 152, 152, 152, 153, 153, 153, 153, 154, 154, 154, 154, 154, 155, 155, 165b39067696ad08a26bbe49b71a71f0546dc42a075msarett 155, 155, 155, 156, 156, 156, 156, 156, 157, 157, 157, 157, 157, 158, 158, 158, 158, 158, 166b39067696ad08a26bbe49b71a71f0546dc42a075msarett 159, 159, 159, 159, 159, 160, 160, 160, 160, 160, 161, 161, 161, 161, 161, 162, 162, 162, 167b39067696ad08a26bbe49b71a71f0546dc42a075msarett 162, 162, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 165, 165, 165, 165, 165, 165, 168b39067696ad08a26bbe49b71a71f0546dc42a075msarett 166, 166, 166, 166, 166, 167, 167, 167, 167, 167, 168, 168, 168, 168, 168, 168, 169, 169, 169b39067696ad08a26bbe49b71a71f0546dc42a075msarett 169, 169, 169, 170, 170, 170, 170, 170, 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, 170b39067696ad08a26bbe49b71a71f0546dc42a075msarett 172, 173, 173, 173, 173, 173, 173, 174, 174, 174, 174, 174, 174, 175, 175, 175, 175, 175, 171b39067696ad08a26bbe49b71a71f0546dc42a075msarett 176, 176, 176, 176, 176, 176, 177, 177, 177, 177, 177, 177, 178, 178, 178, 178, 178, 179, 172b39067696ad08a26bbe49b71a71f0546dc42a075msarett 179, 179, 179, 179, 179, 180, 180, 180, 180, 180, 180, 181, 181, 181, 181, 181, 181, 182, 173b39067696ad08a26bbe49b71a71f0546dc42a075msarett 182, 182, 182, 182, 182, 183, 183, 183, 183, 183, 183, 184, 184, 184, 184, 184, 185, 185, 174b39067696ad08a26bbe49b71a71f0546dc42a075msarett 185, 185, 185, 185, 186, 186, 186, 186, 186, 186, 186, 187, 187, 187, 187, 187, 187, 188, 175b39067696ad08a26bbe49b71a71f0546dc42a075msarett 188, 188, 188, 188, 188, 189, 189, 189, 189, 189, 189, 190, 190, 190, 190, 190, 190, 191, 176b39067696ad08a26bbe49b71a71f0546dc42a075msarett 191, 191, 191, 191, 191, 192, 192, 192, 192, 192, 192, 192, 193, 193, 193, 193, 193, 193, 177b39067696ad08a26bbe49b71a71f0546dc42a075msarett 194, 194, 194, 194, 194, 194, 195, 195, 195, 195, 195, 195, 195, 196, 196, 196, 196, 196, 178b39067696ad08a26bbe49b71a71f0546dc42a075msarett 196, 197, 197, 197, 197, 197, 197, 197, 198, 198, 198, 198, 198, 198, 199, 199, 199, 199, 179b39067696ad08a26bbe49b71a71f0546dc42a075msarett 199, 199, 199, 200, 200, 200, 200, 200, 200, 201, 201, 201, 201, 201, 201, 201, 202, 202, 180b39067696ad08a26bbe49b71a71f0546dc42a075msarett 202, 202, 202, 202, 202, 203, 203, 203, 203, 203, 203, 204, 204, 204, 204, 204, 204, 204, 181b39067696ad08a26bbe49b71a71f0546dc42a075msarett 205, 205, 205, 205, 205, 205, 205, 206, 206, 206, 206, 206, 206, 206, 207, 207, 207, 207, 182b39067696ad08a26bbe49b71a71f0546dc42a075msarett 207, 207, 207, 208, 208, 208, 208, 208, 208, 209, 209, 209, 209, 209, 209, 209, 210, 210, 183b39067696ad08a26bbe49b71a71f0546dc42a075msarett 210, 210, 210, 210, 210, 211, 211, 211, 211, 211, 211, 211, 212, 212, 212, 212, 212, 212, 184b39067696ad08a26bbe49b71a71f0546dc42a075msarett 212, 213, 213, 213, 213, 213, 213, 213, 213, 214, 214, 214, 214, 214, 214, 214, 215, 215, 185b39067696ad08a26bbe49b71a71f0546dc42a075msarett 215, 215, 215, 215, 215, 216, 216, 216, 216, 216, 216, 216, 217, 217, 217, 217, 217, 217, 186b39067696ad08a26bbe49b71a71f0546dc42a075msarett 217, 218, 218, 218, 218, 218, 218, 218, 218, 219, 219, 219, 219, 219, 219, 219, 220, 220, 187b39067696ad08a26bbe49b71a71f0546dc42a075msarett 220, 220, 220, 220, 220, 221, 221, 221, 221, 221, 221, 221, 221, 222, 222, 222, 222, 222, 188b39067696ad08a26bbe49b71a71f0546dc42a075msarett 222, 222, 223, 223, 223, 223, 223, 223, 223, 223, 224, 224, 224, 224, 224, 224, 224, 225, 189b39067696ad08a26bbe49b71a71f0546dc42a075msarett 225, 225, 225, 225, 225, 225, 225, 226, 226, 226, 226, 226, 226, 226, 226, 227, 227, 227, 190b39067696ad08a26bbe49b71a71f0546dc42a075msarett 227, 227, 227, 227, 228, 228, 228, 228, 228, 228, 228, 228, 229, 229, 229, 229, 229, 229, 191b39067696ad08a26bbe49b71a71f0546dc42a075msarett 229, 229, 230, 230, 230, 230, 230, 230, 230, 230, 231, 231, 231, 231, 231, 231, 231, 232, 192b39067696ad08a26bbe49b71a71f0546dc42a075msarett 232, 232, 232, 232, 232, 232, 232, 233, 233, 233, 233, 233, 233, 233, 233, 234, 234, 234, 193b39067696ad08a26bbe49b71a71f0546dc42a075msarett 234, 234, 234, 234, 234, 235, 235, 235, 235, 235, 235, 235, 235, 236, 236, 236, 236, 236, 194b39067696ad08a26bbe49b71a71f0546dc42a075msarett 236, 236, 236, 237, 237, 237, 237, 237, 237, 237, 237, 238, 238, 238, 238, 238, 238, 238, 195b39067696ad08a26bbe49b71a71f0546dc42a075msarett 238, 238, 239, 239, 239, 239, 239, 239, 239, 239, 240, 240, 240, 240, 240, 240, 240, 240, 196b39067696ad08a26bbe49b71a71f0546dc42a075msarett 241, 241, 241, 241, 241, 241, 241, 241, 242, 242, 242, 242, 242, 242, 242, 242, 243, 243, 197b39067696ad08a26bbe49b71a71f0546dc42a075msarett 243, 243, 243, 243, 243, 243, 243, 244, 244, 244, 244, 244, 244, 244, 244, 245, 245, 245, 198b39067696ad08a26bbe49b71a71f0546dc42a075msarett 245, 245, 245, 245, 245, 245, 246, 246, 246, 246, 246, 246, 246, 246, 247, 247, 247, 247, 199b39067696ad08a26bbe49b71a71f0546dc42a075msarett 247, 247, 247, 247, 248, 248, 248, 248, 248, 248, 248, 248, 248, 249, 249, 249, 249, 249, 200b39067696ad08a26bbe49b71a71f0546dc42a075msarett 249, 249, 249, 249, 250, 250, 250, 250, 250, 250, 250, 250, 251, 251, 251, 251, 251, 251, 201b39067696ad08a26bbe49b71a71f0546dc42a075msarett 251, 251, 251, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 202b39067696ad08a26bbe49b71a71f0546dc42a075msarett 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 203b39067696ad08a26bbe49b71a71f0546dc42a075msarett}; 204b39067696ad08a26bbe49b71a71f0546dc42a075msarett 20515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 20615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 20715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, float exponent) { 20815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 20915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = powf(x, exponent); 21015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 21115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 21215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 21315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett// Interpolating lookup in a variably sized table. 21415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic float interp_lut(float input, const float* table, int tableSize) { 21515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett float index = input * (tableSize - 1); 21615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett float diff = index - sk_float_floor2int(index); 21715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett return table[(int) sk_float_floor2int(index)] * (1.0f - diff) + 21815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett table[(int) sk_float_ceil2int(index)] * diff; 21915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 22015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 22115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett// outTable is always 256 entries, inTable may be larger or smaller. 22215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, const float* inTable, 22315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett int inTableSize) { 22415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett if (256 == inTableSize) { 22515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett memcpy(outTable, inTable, sizeof(float) * 256); 22615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett return; 22715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 22815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 22915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 23015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = interp_lut(x, inTable, inTableSize); 23115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 23215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 23315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 23415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, float g, float a, float b, float c, 23515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett float d, float e, float f) { 23615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett // Y = (aX + b)^g + c for X >= d 23715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett // Y = eX + f otherwise 23815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 23915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett if (x >= d) { 24015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = powf(a * x + b, g) + c; 24115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } else { 24215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = e * x + f; 24315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 24415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 24515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 24615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 24715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 24815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 249a9e878c836994bce695274b4c28890290139dcdfmsarett// Expand range from 0-1 to 0-255, then convert. 250b39067696ad08a26bbe49b71a71f0546dc42a075msarettstatic uint8_t clamp_normalized_float_to_byte(float v) { 251dea0340cadb759932e53416a657f5ea75fee8b5fmsarett // The ordering of the logic is a little strange here in order 252dea0340cadb759932e53416a657f5ea75fee8b5fmsarett // to make sure we convert NaNs to 0. 2539876ac5b3016e5353c072378ac1545a0a2270757msarett v = v * 255.0f; 254a9e878c836994bce695274b4c28890290139dcdfmsarett if (v >= 254.5f) { 2559876ac5b3016e5353c072378ac1545a0a2270757msarett return 255; 256dea0340cadb759932e53416a657f5ea75fee8b5fmsarett } else if (v >= 0.5f) { 2579876ac5b3016e5353c072378ac1545a0a2270757msarett return (uint8_t) (v + 0.5f); 258dea0340cadb759932e53416a657f5ea75fee8b5fmsarett } else { 259dea0340cadb759932e53416a657f5ea75fee8b5fmsarett return 0; 2609876ac5b3016e5353c072378ac1545a0a2270757msarett } 2619876ac5b3016e5353c072378ac1545a0a2270757msarett} 2629876ac5b3016e5353c072378ac1545a0a2270757msarett 2633418c0e797e2ee841d1c031ca9d7a5ba73205f51msarettstatic const int kDstGammaTableSize = 264200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkColorSpaceXform_Base<SkColorSpace::kNonStandard_GammaNamed, kNone_ColorSpaceMatch> 265200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett ::kDstGammaTableSize; 2663418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett 2671b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, float exponent) { 268b39067696ad08a26bbe49b71a71f0546dc42a075msarett float toGammaExp = 1.0f / exponent; 269b39067696ad08a26bbe49b71a71f0546dc42a075msarett 2703418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett for (int i = 0; i < kDstGammaTableSize; i++) { 2713418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1))); 272b39067696ad08a26bbe49b71a71f0546dc42a075msarett outTable[i] = clamp_normalized_float_to_byte(powf(x, toGammaExp)); 273b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 274dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett} 275dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 276dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett// Inverse table lookup. Ex: what index corresponds to the input value? This will 277dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett// have strange results when the table is non-increasing. But any sane gamma 278dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett// function will be increasing. 2791b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic float inverse_interp_lut(float input, const float* table, int tableSize) { 280dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett if (input <= table[0]) { 281dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett return table[0]; 282dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett } else if (input >= table[tableSize - 1]) { 283dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett return 1.0f; 284dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett } 285dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 286b39067696ad08a26bbe49b71a71f0546dc42a075msarett for (int i = 1; i < tableSize; i++) { 287dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett if (table[i] >= input) { 288dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett // We are guaranteed that input is greater than table[i - 1]. 289dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett float diff = input - table[i - 1]; 290dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett float distance = table[i] - table[i - 1]; 291dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett float index = (i - 1) + diff / distance; 292dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett return index / (tableSize - 1); 293dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett } 294dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett } 295dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 296dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett // Should be unreachable, since we'll return before the loop if input is 297dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett // larger than the last entry. 298dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett SkASSERT(false); 299dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett return 0.0f; 300dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett} 301dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 3021b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, const float* inTable, 303b39067696ad08a26bbe49b71a71f0546dc42a075msarett int inTableSize) { 3043418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett for (int i = 0; i < kDstGammaTableSize; i++) { 3053418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1))); 306b39067696ad08a26bbe49b71a71f0546dc42a075msarett float y = inverse_interp_lut(x, inTable, inTableSize); 307b39067696ad08a26bbe49b71a71f0546dc42a075msarett outTable[i] = clamp_normalized_float_to_byte(y); 308b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 309b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 310dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 311b39067696ad08a26bbe49b71a71f0546dc42a075msarettstatic float inverse_parametric(float x, float g, float a, float b, float c, float d, float e, 312b39067696ad08a26bbe49b71a71f0546dc42a075msarett float f) { 313b39067696ad08a26bbe49b71a71f0546dc42a075msarett // We need to take the inverse of the following piecewise function. 314b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Y = (aX + b)^g + c for X >= d 315b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Y = eX + f otherwise 316b39067696ad08a26bbe49b71a71f0546dc42a075msarett 317b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Assume that the gamma function is continuous, or this won't make much sense anyway. 318b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Plug in |d| to the first equation to calculate the new piecewise interval. 319b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Then simply use the inverse of the original functions. 320b39067696ad08a26bbe49b71a71f0546dc42a075msarett float interval = e * d + f; 321b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (x < interval) { 322b39067696ad08a26bbe49b71a71f0546dc42a075msarett // X = (Y - F) / E 323b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (0.0f == e) { 324b39067696ad08a26bbe49b71a71f0546dc42a075msarett // The gamma curve for this segment is constant, so the inverse is undefined. 325b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Since this is the lower segment, guess zero. 326b39067696ad08a26bbe49b71a71f0546dc42a075msarett return 0.0f; 327b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 328b39067696ad08a26bbe49b71a71f0546dc42a075msarett 329b39067696ad08a26bbe49b71a71f0546dc42a075msarett return (x - f) / e; 330b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 331b39067696ad08a26bbe49b71a71f0546dc42a075msarett 332b39067696ad08a26bbe49b71a71f0546dc42a075msarett // X = ((Y - C)^(1 / G) - B) / A 333b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (0.0f == a || 0.0f == g) { 334b39067696ad08a26bbe49b71a71f0546dc42a075msarett // The gamma curve for this segment is constant, so the inverse is undefined. 335b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Since this is the upper segment, guess one. 336b39067696ad08a26bbe49b71a71f0546dc42a075msarett return 1.0f; 337b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 338b39067696ad08a26bbe49b71a71f0546dc42a075msarett 339b39067696ad08a26bbe49b71a71f0546dc42a075msarett return (powf(x - c, 1.0f / g) - b) / a; 340b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 341b39067696ad08a26bbe49b71a71f0546dc42a075msarett 3421b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, float g, float a, 343b39067696ad08a26bbe49b71a71f0546dc42a075msarett float b, float c, float d, float e, float f) { 3443418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett for (int i = 0; i < kDstGammaTableSize; i++) { 3453418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1))); 346b39067696ad08a26bbe49b71a71f0546dc42a075msarett float y = inverse_parametric(x, g, a, b, c, d, e, f); 347b39067696ad08a26bbe49b71a71f0546dc42a075msarett outTable[i] = clamp_normalized_float_to_byte(y); 348b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 349b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 350b39067696ad08a26bbe49b71a71f0546dc42a075msarett 3516006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 3526006f678e78af7b6f67a454cd4bc213048983f9dmsarett 3531b93bd1e6eba3d14593490e4e24a34546638c8damsaretttemplate <typename T> 3541b93bd1e6eba3d14593490e4e24a34546638c8damsarettstruct GammaFns { 3551b93bd1e6eba3d14593490e4e24a34546638c8damsarett const T* fSRGBTable; 3561b93bd1e6eba3d14593490e4e24a34546638c8damsarett const T* f2Dot2Table; 3571b93bd1e6eba3d14593490e4e24a34546638c8damsarett 3581b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromValue)(T*, float); 3591b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromTable)(T*, const float*, int); 3601b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromParam)(T*, float, float, float, float, float, float, float); 3611b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 3621b93bd1e6eba3d14593490e4e24a34546638c8damsarett 3631b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic const GammaFns<float> kToLinear { 3641b93bd1e6eba3d14593490e4e24a34546638c8damsarett sk_linear_from_srgb, 3651b93bd1e6eba3d14593490e4e24a34546638c8damsarett sk_linear_from_2dot2, 3661b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 3671b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 3681b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 3691b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 3701b93bd1e6eba3d14593490e4e24a34546638c8damsarett 3711b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic const GammaFns<uint8_t> kFromLinear { 3721b93bd1e6eba3d14593490e4e24a34546638c8damsarett linear_to_srgb, 37315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett linear_to_2dot2_table, 3741b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 3751b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 3761b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 3771b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 3781b93bd1e6eba3d14593490e4e24a34546638c8damsarett 3791b93bd1e6eba3d14593490e4e24a34546638c8damsarett// Build tables to transform src gamma to linear. 3801b93bd1e6eba3d14593490e4e24a34546638c8damsaretttemplate <typename T> 3811b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_gamma_tables(const T* outGammaTables[3], T* gammaTableStorage, int gammaTableSize, 3821b93bd1e6eba3d14593490e4e24a34546638c8damsarett const sk_sp<SkColorSpace>& space, const GammaFns<T>& fns) { 3831b93bd1e6eba3d14593490e4e24a34546638c8damsarett switch (space->gammaNamed()) { 3841b93bd1e6eba3d14593490e4e24a34546638c8damsarett case SkColorSpace::kSRGB_GammaNamed: 3851b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.fSRGBTable; 3861b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 3871b93bd1e6eba3d14593490e4e24a34546638c8damsarett case SkColorSpace::k2Dot2Curve_GammaNamed: 3881b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.f2Dot2Table; 3891b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 3901b93bd1e6eba3d14593490e4e24a34546638c8damsarett case SkColorSpace::kLinear_GammaNamed: 3911b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromValue)(gammaTableStorage, 1.0f); 3921b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = gammaTableStorage; 3931b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 3941b93bd1e6eba3d14593490e4e24a34546638c8damsarett default: { 3951b93bd1e6eba3d14593490e4e24a34546638c8damsarett const SkGammas* gammas = as_CSB(space)->gammas(); 3961b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(gammas); 3971b93bd1e6eba3d14593490e4e24a34546638c8damsarett 3981b93bd1e6eba3d14593490e4e24a34546638c8damsarett for (int i = 0; i < 3; i++) { 3991b93bd1e6eba3d14593490e4e24a34546638c8damsarett if (i > 0) { 4001b93bd1e6eba3d14593490e4e24a34546638c8damsarett // Check if this curve matches the first curve. In this case, we can 4011b93bd1e6eba3d14593490e4e24a34546638c8damsarett // share the same table pointer. This should almost always be true. 4021b93bd1e6eba3d14593490e4e24a34546638c8damsarett // I've never seen a profile where all three gamma curves didn't match. 4031b93bd1e6eba3d14593490e4e24a34546638c8damsarett // But it is possible that they won't. 404a714bc39294f19500269c8ec536139f75c4b1f25msarett if (gammas->type(0) == gammas->type(i) && gammas->data(0) == gammas->data(i)) { 4051b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = outGammaTables[0]; 4061b93bd1e6eba3d14593490e4e24a34546638c8damsarett continue; 4071b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 4081b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 4091b93bd1e6eba3d14593490e4e24a34546638c8damsarett 4101b93bd1e6eba3d14593490e4e24a34546638c8damsarett if (gammas->isNamed(i)) { 4111b93bd1e6eba3d14593490e4e24a34546638c8damsarett switch (gammas->data(i).fNamed) { 4121b93bd1e6eba3d14593490e4e24a34546638c8damsarett case SkColorSpace::kSRGB_GammaNamed: 4131b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = fns.fSRGBTable; 4141b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 4151b93bd1e6eba3d14593490e4e24a34546638c8damsarett case SkColorSpace::k2Dot2Curve_GammaNamed: 4161b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = fns.f2Dot2Table; 4171b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 4181b93bd1e6eba3d14593490e4e24a34546638c8damsarett case SkColorSpace::kLinear_GammaNamed: 4191b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 1.0f); 4201b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 4211b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 4221b93bd1e6eba3d14593490e4e24a34546638c8damsarett default: 4231b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(false); 4241b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 4251b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 4261b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else if (gammas->isValue(i)) { 4271b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 4281b93bd1e6eba3d14593490e4e24a34546638c8damsarett gammas->data(i).fValue); 4291b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 4301b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else if (gammas->isTable(i)) { 4311b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromTable)(&gammaTableStorage[i * gammaTableSize], gammas->table(i), 4321b93bd1e6eba3d14593490e4e24a34546638c8damsarett gammas->data(i).fTable.fSize); 4331b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 4341b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else { 4351b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(gammas->isParametric(i)); 4361b93bd1e6eba3d14593490e4e24a34546638c8damsarett const SkGammas::Params& params = gammas->params(i); 4371b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromParam)(&gammaTableStorage[i * gammaTableSize], params.fG, 4381b93bd1e6eba3d14593490e4e24a34546638c8damsarett params.fA, params.fB, params.fC, params.fD, params.fE, 4391b93bd1e6eba3d14593490e4e24a34546638c8damsarett params.fF); 4401b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 4411b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 4421b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 4431b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 4441b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 4451b93bd1e6eba3d14593490e4e24a34546638c8damsarett} 4461b93bd1e6eba3d14593490e4e24a34546638c8damsarett 4471b93bd1e6eba3d14593490e4e24a34546638c8damsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 4481b93bd1e6eba3d14593490e4e24a34546638c8damsarett 44915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic inline bool compute_gamut_xform(SkMatrix44* srcToDst, const SkMatrix44& srcToXYZ, 45015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett const SkMatrix44& dstToXYZ) { 45115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett if (!dstToXYZ.invert(srcToDst)) { 45215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett return false; 45315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 45415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 45515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett srcToDst->postConcat(srcToXYZ); 45615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett return true; 45715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 45815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 459200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline bool is_almost_identity(const SkMatrix44& srcToDst) { 460200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett for (int i = 0; i < 4; i++) { 461200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett for (int j = 0; j < 4; j++) { 462200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett float expected = (i == j) ? 1.0f : 0.0f; 463200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (!color_space_almost_equal(srcToDst.getFloat(i,j), expected)) { 464200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return false; 465200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 466200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 467200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 468200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return true; 469200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 470200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 47115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 47215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 4736006f678e78af7b6f67a454cd4bc213048983f9dmsarettstd::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(const sk_sp<SkColorSpace>& srcSpace, 4746006f678e78af7b6f67a454cd4bc213048983f9dmsarett const sk_sp<SkColorSpace>& dstSpace) { 4756006f678e78af7b6f67a454cd4bc213048983f9dmsarett if (!srcSpace || !dstSpace) { 4766006f678e78af7b6f67a454cd4bc213048983f9dmsarett // Invalid input 4776006f678e78af7b6f67a454cd4bc213048983f9dmsarett return nullptr; 4786006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 4796006f678e78af7b6f67a454cd4bc213048983f9dmsarett 480200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett ColorSpaceMatch csm = kNone_ColorSpaceMatch; 4816006f678e78af7b6f67a454cd4bc213048983f9dmsarett SkMatrix44 srcToDst(SkMatrix44::kUninitialized_Constructor); 482200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (SkColorSpace::Equals(srcSpace.get(), dstSpace.get())) { 483200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcToDst.setIdentity(); 484200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett csm = kFull_ColorSpaceMatch; 485200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } else if (!compute_gamut_xform(&srcToDst, srcSpace->xyz(), dstSpace->xyz())) { 4866006f678e78af7b6f67a454cd4bc213048983f9dmsarett return nullptr; 487200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } else if (is_almost_identity(srcToDst)) { 488200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcToDst.setIdentity(); 489200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett csm = kGamut_ColorSpaceMatch; 4906006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 4916006f678e78af7b6f67a454cd4bc213048983f9dmsarett 492200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett switch (csm) { 493200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kNone_ColorSpaceMatch: 494200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett switch (dstSpace->gammaNamed()) { 495200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case SkColorSpace::kSRGB_GammaNamed: 496200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base 497200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett <SkColorSpace::kSRGB_GammaNamed, kNone_ColorSpaceMatch> 498200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett (srcSpace, srcToDst, dstSpace)); 499200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case SkColorSpace::k2Dot2Curve_GammaNamed: 500200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base 501200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett <SkColorSpace::k2Dot2Curve_GammaNamed, kNone_ColorSpaceMatch> 502200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett (srcSpace, srcToDst, dstSpace)); 503200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 504200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base 505200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett <SkColorSpace::kNonStandard_GammaNamed, kNone_ColorSpaceMatch> 506200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett (srcSpace, srcToDst, dstSpace)); 507200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 508200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kGamut_ColorSpaceMatch: 509200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett switch (dstSpace->gammaNamed()) { 510200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case SkColorSpace::kSRGB_GammaNamed: 511200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base 512200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett <SkColorSpace::kSRGB_GammaNamed, kGamut_ColorSpaceMatch> 513200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett (srcSpace, srcToDst, dstSpace)); 514200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case SkColorSpace::k2Dot2Curve_GammaNamed: 515200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base 516200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett <SkColorSpace::k2Dot2Curve_GammaNamed, kGamut_ColorSpaceMatch> 517200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett (srcSpace, srcToDst, dstSpace)); 518200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 519200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base 520200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett <SkColorSpace::kNonStandard_GammaNamed, kGamut_ColorSpaceMatch> 521200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett (srcSpace, srcToDst, dstSpace)); 522200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 523200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kFull_ColorSpaceMatch: 524200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett switch (dstSpace->gammaNamed()) { 525200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case SkColorSpace::kSRGB_GammaNamed: 526200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base 527200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett <SkColorSpace::kSRGB_GammaNamed, kFull_ColorSpaceMatch> 528200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett (srcSpace, srcToDst, dstSpace)); 529200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case SkColorSpace::k2Dot2Curve_GammaNamed: 530200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base 531200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett <SkColorSpace::k2Dot2Curve_GammaNamed, kFull_ColorSpaceMatch> 532200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett (srcSpace, srcToDst, dstSpace)); 533200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 534200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base 535200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett <SkColorSpace::kNonStandard_GammaNamed, kFull_ColorSpaceMatch> 536200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett (srcSpace, srcToDst, dstSpace)); 537200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 5383418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett default: 539200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkASSERT(false); 540200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return nullptr; 5416006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 5426006f678e78af7b6f67a454cd4bc213048983f9dmsarett} 5436006f678e78af7b6f67a454cd4bc213048983f9dmsarett 5446006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 5456006f678e78af7b6f67a454cd4bc213048983f9dmsarett 5460f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarettstatic float byte_to_float(uint8_t byte) { 5470f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett return ((float) byte) * (1.0f / 255.0f); 5480f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett} 5490f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 550b39067696ad08a26bbe49b71a71f0546dc42a075msarett// Clamp to the 0-1 range. 551b39067696ad08a26bbe49b71a71f0546dc42a075msarettstatic float clamp_normalized_float(float v) { 552b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (v > 1.0f) { 553b39067696ad08a26bbe49b71a71f0546dc42a075msarett return 1.0f; 554b39067696ad08a26bbe49b71a71f0546dc42a075msarett } else if ((v < 0.0f) || (v != v)) { 555b39067696ad08a26bbe49b71a71f0546dc42a075msarett return 0.0f; 556b39067696ad08a26bbe49b71a71f0546dc42a075msarett } else { 557b39067696ad08a26bbe49b71a71f0546dc42a075msarett return v; 558b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 559b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 560b39067696ad08a26bbe49b71a71f0546dc42a075msarett 5610f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarettstatic void interp_3d_clut(float dst[3], float src[3], const SkColorLookUpTable* colorLUT) { 5620f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // Call the src components x, y, and z. 5630f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett uint8_t maxX = colorLUT->fGridPoints[0] - 1; 5640f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett uint8_t maxY = colorLUT->fGridPoints[1] - 1; 5650f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett uint8_t maxZ = colorLUT->fGridPoints[2] - 1; 5660f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 5670f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // An approximate index into each of the three dimensions of the table. 5680f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett float x = src[0] * maxX; 5690f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett float y = src[1] * maxY; 5700f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett float z = src[2] * maxZ; 5710f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 5720f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // This gives us the low index for our interpolation. 5730f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett int ix = sk_float_floor2int(x); 5740f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett int iy = sk_float_floor2int(y); 5750f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett int iz = sk_float_floor2int(z); 5760f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 5770f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // Make sure the low index is not also the max index. 5780f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett ix = (maxX == ix) ? ix - 1 : ix; 5790f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett iy = (maxY == iy) ? iy - 1 : iy; 5800f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett iz = (maxZ == iz) ? iz - 1 : iz; 5810f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 5820f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // Weighting factors for the interpolation. 5830f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett float diffX = x - ix; 5840f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett float diffY = y - iy; 5850f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett float diffZ = z - iz; 5860f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 5870f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // Constants to help us navigate the 3D table. 5880f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // Ex: Assume x = a, y = b, z = c. 5890f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // table[a * n001 + b * n010 + c * n100] logically equals table[a][b][c]. 5900f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett const int n000 = 0; 5910f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett const int n001 = 3 * colorLUT->fGridPoints[1] * colorLUT->fGridPoints[2]; 5920f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett const int n010 = 3 * colorLUT->fGridPoints[2]; 5930f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett const int n011 = n001 + n010; 5940f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett const int n100 = 3; 5950f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett const int n101 = n100 + n001; 5960f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett const int n110 = n100 + n010; 5970f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett const int n111 = n110 + n001; 5980f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 5990f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // Base ptr into the table. 600959d45b43357a40854938586c303177c6aa53220msarett const float* ptr = &(colorLUT->table()[ix*n001 + iy*n010 + iz*n100]); 6010f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 6020f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // The code below performs a tetrahedral interpolation for each of the three 6030f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // dst components. Once the tetrahedron containing the interpolation point is 6040f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // identified, the interpolation is a weighted sum of grid values at the 6050f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // vertices of the tetrahedron. The claim is that tetrahedral interpolation 6060f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // provides a more accurate color conversion. 6070f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // blogs.mathworks.com/steve/2006/11/24/tetrahedral-interpolation-for-colorspace-conversion/ 6080f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // 6090f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // I have one test image, and visually I can't tell the difference between 6100f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // tetrahedral and trilinear interpolation. In terms of computation, the 6110f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // tetrahedral code requires more branches but less computation. The 6120f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // SampleICC library provides an option for the client to choose either 6130f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // tetrahedral or trilinear. 6140f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett for (int i = 0; i < 3; i++) { 6150f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett if (diffZ < diffY) { 6160f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett if (diffZ < diffX) { 6170f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett dst[i] = (ptr[n000] + diffZ * (ptr[n110] - ptr[n010]) + 6180f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett diffY * (ptr[n010] - ptr[n000]) + 6190f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett diffX * (ptr[n111] - ptr[n110])); 6200f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett } else if (diffY < diffX) { 6210f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett dst[i] = (ptr[n000] + diffZ * (ptr[n111] - ptr[n011]) + 6220f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett diffY * (ptr[n011] - ptr[n001]) + 6230f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett diffX * (ptr[n001] - ptr[n000])); 6240f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett } else { 6250f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett dst[i] = (ptr[n000] + diffZ * (ptr[n111] - ptr[n011]) + 6260f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett diffY * (ptr[n010] - ptr[n000]) + 6270f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett diffX * (ptr[n011] - ptr[n010])); 6280f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett } 6290f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett } else { 6300f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett if (diffZ < diffX) { 6310f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett dst[i] = (ptr[n000] + diffZ * (ptr[n101] - ptr[n001]) + 6320f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett diffY * (ptr[n111] - ptr[n101]) + 6330f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett diffX * (ptr[n001] - ptr[n000])); 6340f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett } else if (diffY < diffX) { 6350f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett dst[i] = (ptr[n000] + diffZ * (ptr[n100] - ptr[n000]) + 6360f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett diffY * (ptr[n111] - ptr[n101]) + 6370f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett diffX * (ptr[n101] - ptr[n100])); 6380f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett } else { 6390f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett dst[i] = (ptr[n000] + diffZ * (ptr[n100] - ptr[n000]) + 6400f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett diffY * (ptr[n110] - ptr[n100]) + 6410f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett diffX * (ptr[n111] - ptr[n110])); 6420f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett } 6430f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett } 6440f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 6450f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // Increment the table ptr in order to handle the next component. 6460f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // Note that this is the how table is designed: all of nXXX 6470f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // variables are multiples of 3 because there are 3 output 6480f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett // components. 6490f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett ptr++; 6500f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett } 6510f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett} 6520f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 6533418c0e797e2ee841d1c031ca9d7a5ba73205f51msarettstatic void handle_color_lut(uint32_t* dst, const uint32_t* src, int len, 6543418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett SkColorLookUpTable* colorLUT) { 655b39067696ad08a26bbe49b71a71f0546dc42a075msarett while (len-- > 0) { 6560f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett uint8_t r = (*src >> 0) & 0xFF, 6570f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett g = (*src >> 8) & 0xFF, 6580f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett b = (*src >> 16) & 0xFF; 6590f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 6603418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float in[3]; 6613418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float out[3]; 6623418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett in[0] = byte_to_float(r); 6633418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett in[1] = byte_to_float(g); 6643418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett in[2] = byte_to_float(b); 6653418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett interp_3d_clut(out, in, colorLUT); 6660f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 6673418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett r = sk_float_round2int(255.0f * clamp_normalized_float(out[0])); 6683418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett g = sk_float_round2int(255.0f * clamp_normalized_float(out[1])); 6693418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett b = sk_float_round2int(255.0f * clamp_normalized_float(out[2])); 6703418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett *dst = SkPackARGB_as_RGBA(0xFF, r, g, b); 6710f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 6723418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett src++; 6733418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett dst++; 6743418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett } 6753418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett} 6760f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 677200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettenum SwapRB { 678200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett kNo_SwapRB, 679200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett kYes_SwapRB, 680200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett}; 681200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 682200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void load_matrix(const float matrix[16], 683200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& rXgXbX, Sk4f& rYgYbY, Sk4f& rZgZbZ, Sk4f& rTgTbT) { 684200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rXgXbX = Sk4f::Load(matrix + 0); 685200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rYgYbY = Sk4f::Load(matrix + 4); 686200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rZgZbZ = Sk4f::Load(matrix + 8); 687200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rTgTbT = Sk4f::Load(matrix + 12); 688200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 689200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 690200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void load_rgb_from_tables(const uint32_t* src, 691200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 692200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const float* const srcTables[3]) { 693200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett r = { srcTables[0][(src[0] >> 0) & 0xFF], 694200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[0][(src[1] >> 0) & 0xFF], 695200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[0][(src[2] >> 0) & 0xFF], 696200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[0][(src[3] >> 0) & 0xFF], }; 697200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett g = { srcTables[1][(src[0] >> 8) & 0xFF], 698200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[1][(src[1] >> 8) & 0xFF], 699200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[1][(src[2] >> 8) & 0xFF], 700200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[1][(src[3] >> 8) & 0xFF], }; 701200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett b = { srcTables[2][(src[0] >> 16) & 0xFF], 702200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[2][(src[1] >> 16) & 0xFF], 703200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[2][(src[2] >> 16) & 0xFF], 704200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[2][(src[3] >> 16) & 0xFF], }; 705200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett a = 0.0f; // Don't let the compiler complain that |a| is uninitialized. 706200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 707200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 708200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void load_rgba_from_tables(const uint32_t* src, 709200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 710200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const float* const srcTables[3]) { 711200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett r = { srcTables[0][(src[0] >> 0) & 0xFF], 712200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[0][(src[1] >> 0) & 0xFF], 713200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[0][(src[2] >> 0) & 0xFF], 714200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[0][(src[3] >> 0) & 0xFF], }; 715200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett g = { srcTables[1][(src[0] >> 8) & 0xFF], 716200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[1][(src[1] >> 8) & 0xFF], 717200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[1][(src[2] >> 8) & 0xFF], 718200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[1][(src[3] >> 8) & 0xFF], }; 719200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett b = { srcTables[2][(src[0] >> 16) & 0xFF], 720200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[2][(src[1] >> 16) & 0xFF], 721200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[2][(src[2] >> 16) & 0xFF], 722200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcTables[2][(src[3] >> 16) & 0xFF], }; 723200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett a = (1.0f / 255.0f) * SkNx_cast<float>(Sk4u::Load(src) >> 24); 724200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 725200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 726200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void load_rgb_from_tables_1(const uint32_t* src, 727200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f&, 728200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const float* const srcTables[3]) { 729200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // Splat r,g,b across a register each. 730200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett r = Sk4f(srcTables[0][(*src >> 0) & 0xFF]); 731200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett g = Sk4f(srcTables[1][(*src >> 8) & 0xFF]); 732200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett b = Sk4f(srcTables[2][(*src >> 16) & 0xFF]); 733200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 734200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 735200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void load_rgba_from_tables_1(const uint32_t* src, 736200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& r, Sk4f& g, Sk4f& b, Sk4f& a, 737200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const float* const srcTables[3]) { 738200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // Splat r,g,b across a register each. 739200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett r = Sk4f(srcTables[0][(*src >> 0) & 0xFF]); 740200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett g = Sk4f(srcTables[1][(*src >> 8) & 0xFF]); 741200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett b = Sk4f(srcTables[2][(*src >> 16) & 0xFF]); 742200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett a = (1.0f / 255.0f) * Sk4f(*src >> 24); 743200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 744200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 745200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void transform_gamut(const Sk4f& r, const Sk4f& g, const Sk4f& b, const Sk4f& a, 746200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const Sk4f& rXgXbX, const Sk4f& rYgYbY, const Sk4f& rZgZbZ, 747200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da) { 748200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = rXgXbX[0]*r + rYgYbY[0]*g + rZgZbZ[0]*b; 749200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = rXgXbX[1]*r + rYgYbY[1]*g + rZgZbZ[1]*b; 750200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = rXgXbX[2]*r + rYgYbY[2]*g + rZgZbZ[2]*b; 751200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett da = a; 752200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 753200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 754200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void transform_gamut_1(const Sk4f& r, const Sk4f& g, const Sk4f& b, 755200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const Sk4f& rXgXbX, const Sk4f& rYgYbY, const Sk4f& rZgZbZ, 756200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& rgba) { 757200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = rXgXbX*r + rYgYbY*g + rZgZbZ*b; 758200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 759200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 760200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void translate_gamut(const Sk4f& rTgTbT, Sk4f& dr, Sk4f& dg, Sk4f& db) { 761200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = dr + rTgTbT[0]; 762200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = dg + rTgTbT[1]; 763200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = db + rTgTbT[2]; 764200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 765200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 766200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void translate_gamut_1(const Sk4f& rTgTbT, Sk4f& rgba) { 767200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = rgba + rTgTbT; 768200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 769200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 770200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void premultiply(Sk4f& dr, Sk4f& dg, Sk4f& db, const Sk4f& da) { 771200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = da * dr; 772200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = da * dg; 773200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = da * db; 774200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 775200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 776200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void premultiply_1(const Sk4f& a, Sk4f& rgba) { 777200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = a * rgba; 778200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 779200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 780200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_srgb(void* dst, const uint32_t* src, 781200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 782200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const uint8_t* const[3], SwapRB kSwapRB) { 783200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett int kRShift = 0; 784200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett int kGShift = 8; 785200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett int kBShift = 16; 786200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kYes_SwapRB == kSwapRB) { 787200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett kBShift = 0; 788200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett kRShift = 16; 789200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 790200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 791200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = sk_linear_to_srgb_needs_trunc(dr); 792200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = sk_linear_to_srgb_needs_trunc(dg); 793200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = sk_linear_to_srgb_needs_trunc(db); 794200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 795200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = sk_clamp_0_255(dr); 796200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = sk_clamp_0_255(dg); 797200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = sk_clamp_0_255(db); 798200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 799200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 800200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 801200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i rgba = (SkNx_cast<int>(dr) << kRShift) 802200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (SkNx_cast<int>(dg) << kGShift) 803200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (SkNx_cast<int>(db) << kBShift) 804200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (da ); 805200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba.store(dst); 806200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 807200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 808200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_srgb_1(void* dst, const uint32_t* src, 809200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& rgba, const Sk4f&, 810200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const uint8_t* const[3], SwapRB kSwapRB) { 811200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = sk_clamp_0_255(sk_linear_to_srgb_needs_trunc(rgba)); 812200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 813200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint32_t tmp; 814200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkNx_cast<uint8_t>(SkNx_cast<int32_t>(rgba)).store(&tmp); 815200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = (*src & 0xFF000000) | (tmp & 0x00FFFFFF); 816200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kYes_SwapRB == kSwapRB) { 817200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = SkSwizzle_RB(tmp); 818200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 819200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 820200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *(uint32_t*)dst = tmp; 821200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 822200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 823200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline Sk4f linear_to_2dot2(const Sk4f& x) { 824200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // x^(29/64) is a very good approximation of the true value, x^(1/2.2). 825200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett auto x2 = x.rsqrt(), // x^(-1/2) 826200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett x32 = x2.rsqrt().rsqrt().rsqrt().rsqrt(), // x^(-1/32) 827200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett x64 = x32.rsqrt(); // x^(+1/64) 828200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 829200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // 29 = 32 - 2 - 1 830200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return 255.0f * x2.invert() * x32 * x64.invert(); 831200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 832200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 833200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_2dot2(void* dst, const uint32_t* src, 834200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 835200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const uint8_t* const[3], SwapRB kSwapRB) { 836200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett int kRShift = 0; 837200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett int kGShift = 8; 838200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett int kBShift = 16; 839200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kYes_SwapRB == kSwapRB) { 840200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett kBShift = 0; 841200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett kRShift = 16; 842200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 843200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 844200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = linear_to_2dot2(dr); 845200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = linear_to_2dot2(dg); 846200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = linear_to_2dot2(db); 847200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 848200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = sk_clamp_0_255(dr); 849200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = sk_clamp_0_255(dg); 850200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = sk_clamp_0_255(db); 851200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 852200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 853200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 854200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i rgba = (Sk4f_round(dr) << kRShift) 855200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (Sk4f_round(dg) << kGShift) 856200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (Sk4f_round(db) << kBShift) 857200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (da ); 858200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba.store(dst); 859200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 860200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 861200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_2dot2_1(void* dst, const uint32_t* src, 862200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& rgba, const Sk4f&, 863200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const uint8_t* const[3], SwapRB kSwapRB) { 864200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = sk_clamp_0_255(linear_to_2dot2(rgba)); 865200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 866200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint32_t tmp; 867200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkNx_cast<uint8_t>(Sk4f_round(rgba)).store(&tmp); 868200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = (*src & 0xFF000000) | (tmp & 0x00FFFFFF); 869200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kYes_SwapRB == kSwapRB) { 870200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp = SkSwizzle_RB(tmp); 871200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 872200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 873200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *(uint32_t*)dst = tmp; 874200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 875200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 876200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_f16(void* dst, const uint32_t* src, 877200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da, 878200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const uint8_t* const[3], SwapRB) { 879200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4h_store4(dst, SkFloatToHalf_finite(dr), 880200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkFloatToHalf_finite(dg), 881200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkFloatToHalf_finite(db), 882200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkFloatToHalf_finite(da)); 883200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 884200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 885200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_f16_1(void* dst, const uint32_t* src, 886200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& rgba, const Sk4f& a, 887200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const uint8_t* const[3], SwapRB kSwapRB) { 888200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = Sk4f(rgba[0], rgba[1], rgba[2], a[3]); 889200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkFloatToHalf_finite(rgba).store((uint64_t*) dst); 890200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 891200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 892200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_f16_opaque(void* dst, const uint32_t* src, 893200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f& da, 894200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const uint8_t* const[3], SwapRB) { 895200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4h_store4(dst, SkFloatToHalf_finite(dr), 896200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkFloatToHalf_finite(dg), 897200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkFloatToHalf_finite(db), 898200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SK_Half1); 899200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 900200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 901200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_f16_1_opaque(void* dst, const uint32_t* src, 902200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& rgba, const Sk4f& a, 903200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const uint8_t* const[3], SwapRB kSwapRB) { 904200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint64_t tmp; 905200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkFloatToHalf_finite(rgba).store(&tmp); 906200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett tmp |= static_cast<uint64_t>(SK_Half1) << 48; 907200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *((uint64_t*) dst) = tmp; 908200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 909200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 910200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_generic(void* dst, const uint32_t* src, 911200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& dr, Sk4f& dg, Sk4f& db, Sk4f&, 912200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const uint8_t* const dstTables[3], SwapRB kSwapRB) { 913200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett int kRShift = 0; 914200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett int kGShift = 8; 915200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett int kBShift = 16; 916200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kYes_SwapRB == kSwapRB) { 917200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett kBShift = 0; 918200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett kRShift = 16; 919200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 920200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 921200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = Sk4f::Min(Sk4f::Max(1023.0f * dr, 0.0f), 1023.0f); 922200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = Sk4f::Min(Sk4f::Max(1023.0f * dg, 0.0f), 1023.0f); 923200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = Sk4f::Min(Sk4f::Max(1023.0f * db, 0.0f), 1023.0f); 924200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 925200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i ir = Sk4f_round(dr); 926200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i ig = Sk4f_round(dg); 927200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i ib = Sk4f_round(db); 928200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 929200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i da = Sk4i::Load(src) & 0xFF000000; 930200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 931200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett uint32_t* dst32 = (uint32_t*) dst; 932200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[0] = dstTables[0][ir[0]] << kRShift 933200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[0]] << kGShift 934200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[0]] << kBShift 935200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[0]; 936200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[1] = dstTables[0][ir[1]] << kRShift 937200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[1]] << kGShift 938200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[1]] << kBShift 939200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[1]; 940200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[2] = dstTables[0][ir[2]] << kRShift 941200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[2]] << kGShift 942200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[2]] << kBShift 943200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[2]; 944200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst32[3] = dstTables[0][ir[3]] << kRShift 945200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][ig[3]] << kGShift 946200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][ib[3]] << kBShift 947200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | da[3]; 948200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 949200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 950200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic inline void store_generic_1(void* dst, const uint32_t* src, 951200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f& rgba, const Sk4f&, 952200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const uint8_t* const dstTables[3], SwapRB kSwapRB) { 953200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = Sk4f::Min(Sk4f::Max(1023.0f * rgba, 0.0f), 1023.0f); 954200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 955200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4i indices = Sk4f_round(rgba); 956200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 957200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett *((uint32_t*) dst) = dstTables[0][indices[0]] << 0 958200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[1][indices[1]] << 8 959200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | dstTables[2][indices[2]] << 16 960200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett | (*src & 0xFF000000); 961200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 962200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 963200877eecaba782e56a1dd9e13a92f36d7b1ba12msaretttemplate <SkColorSpace::GammaNamed kDstGamma, 964200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett ColorSpaceMatch kCSM, 965200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkAlphaType kAlphaType, 966200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SwapRB kSwapRB> 967200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettstatic void color_xform_RGBA(void* dst, const uint32_t* src, int len, 968200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const float* const srcTables[3], const float matrix[16], 969200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const uint8_t* const dstTables[3]) { 970200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett decltype(store_srgb )* store; 971200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett decltype(store_srgb_1 )* store_1; 972200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett decltype(load_rgb_from_tables )* load; 973200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett decltype(load_rgb_from_tables_1)* load_1; 974200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett size_t sizeOfDstPixel; 975200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett switch (kDstGamma) { 976200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case SkColorSpace::kSRGB_GammaNamed: 977200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load = (kPremul_SkAlphaType == kAlphaType) ? load_rgba_from_tables : 978200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load_rgb_from_tables; 979200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load_1 = (kPremul_SkAlphaType == kAlphaType) ? load_rgba_from_tables_1 : 980200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load_rgb_from_tables_1; 981200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett store = store_srgb; 982200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett store_1 = store_srgb_1; 983200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett sizeOfDstPixel = 4; 984200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett break; 985200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case SkColorSpace::k2Dot2Curve_GammaNamed: 986200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load = (kPremul_SkAlphaType == kAlphaType) ? load_rgba_from_tables : 987200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load_rgb_from_tables; 988200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load_1 = (kPremul_SkAlphaType == kAlphaType) ? load_rgba_from_tables_1 : 989200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load_rgb_from_tables_1; 990200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett store = store_2dot2; 991200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett store_1 = store_2dot2_1; 992200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett sizeOfDstPixel = 4; 993200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett break; 994200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case SkColorSpace::kLinear_GammaNamed: 995200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load = load_rgba_from_tables; 996200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load_1 = load_rgba_from_tables_1; 997200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett store = (kOpaque_SkAlphaType == kAlphaType) ? store_f16_opaque : 998200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett store_f16; 999200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett store_1 = (kOpaque_SkAlphaType == kAlphaType) ? store_f16_1_opaque : 1000200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett store_f16_1; 1001200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett sizeOfDstPixel = 8; 1002200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett break; 1003200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case SkColorSpace::kNonStandard_GammaNamed: 1004200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load = (kPremul_SkAlphaType == kAlphaType) ? load_rgba_from_tables : 1005200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load_rgb_from_tables; 1006200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load_1 = (kPremul_SkAlphaType == kAlphaType) ? load_rgba_from_tables_1 : 1007200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load_rgb_from_tables_1; 1008200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett store = store_generic; 1009200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett store_1 = store_generic_1; 1010200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett sizeOfDstPixel = 4; 1011200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett break; 1012200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1013200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1014200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f rXgXbX, rYgYbY, rZgZbZ, rTgTbT; 1015200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load_matrix(matrix, rXgXbX, rYgYbY, rZgZbZ, rTgTbT); 1016200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1017200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (len >= 4) { 1018200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // Naively this would be a loop of load-transform-store, but we found it faster to 1019200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // move the N+1th load ahead of the Nth store. We don't bother doing this for N<4. 1020200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f r, g, b, a; 1021200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load(src, r, g, b, a, srcTables); 1022200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett src += 4; 1023200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett len -= 4; 1024200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1025200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f dr, dg, db, da; 1026200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett while (len >= 4) { 1027200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kNone_ColorSpaceMatch == kCSM) { 1028200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett transform_gamut(r, g, b, a, rXgXbX, rYgYbY, rZgZbZ, dr, dg, db, da); 1029200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett translate_gamut(rTgTbT, dr, dg, db); 1030200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } else { 1031200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = r; 1032200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = g; 1033200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = b; 1034200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett da = a; 1035200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1036200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1037200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kPremul_SkAlphaType == kAlphaType) { 1038200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett premultiply(dr, dg, db, da); 1039200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1040200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1041200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load(src, r, g, b, a, srcTables); 1042200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1043200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett store(dst, src - 4, dr, dg, db, da, dstTables, kSwapRB); 1044200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst = SkTAddOffset<void>(dst, 4 * sizeOfDstPixel); 1045200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett src += 4; 1046200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett len -= 4; 1047200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1048200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1049200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kNone_ColorSpaceMatch == kCSM) { 1050200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett transform_gamut(r, g, b, a, rXgXbX, rYgYbY, rZgZbZ, dr, dg, db, da); 1051200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett translate_gamut(rTgTbT, dr, dg, db); 1052200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } else { 1053200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dr = r; 1054200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dg = g; 1055200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett db = b; 1056200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett da = a; 1057200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1058200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1059200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kPremul_SkAlphaType == kAlphaType) { 1060200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett premultiply(dr, dg, db, da); 1061200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1062200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1063200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett store(dst, src - 4, dr, dg, db, da, dstTables, kSwapRB); 1064200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst = SkTAddOffset<void>(dst, 4 * sizeOfDstPixel); 1065200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1066200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1067200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett while (len > 0) { 1068200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f r, g, b, a; 1069200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett load_1(src, r, g, b, a, srcTables); 1070200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1071200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett Sk4f rgba; 1072200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kNone_ColorSpaceMatch == kCSM) { 1073200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett transform_gamut_1(r, g, b, rXgXbX, rYgYbY, rZgZbZ, rgba); 1074200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett translate_gamut_1(rTgTbT, rgba); 1075200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } else { 1076200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett rgba = Sk4f(r[0], g[0], b[0], a[0]); 1077200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1078200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1079200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kPremul_SkAlphaType == kAlphaType) { 1080200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett premultiply_1(a, rgba); 1081200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1082200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1083200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett store_1(dst, src, rgba, a, dstTables, kSwapRB); 1084200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 1085200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett src += 1; 1086200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett len -= 1; 1087200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett dst = SkTAddOffset<void>(dst, sizeOfDstPixel); 1088200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1089200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett} 1090200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 10913418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett/////////////////////////////////////////////////////////////////////////////////////////////////// 10920f83e0151f757ecd8d55d55ffefef58ecb11a97bmsarett 1093200877eecaba782e56a1dd9e13a92f36d7b1ba12msaretttemplate <SkColorSpace::GammaNamed kDst, ColorSpaceMatch kCSM> 1094200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettSkColorSpaceXform_Base<kDst, kCSM>::SkColorSpaceXform_Base(const sk_sp<SkColorSpace>& srcSpace, 1095200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const SkMatrix44& srcToDst, 1096200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett const sk_sp<SkColorSpace>& dstSpace) 10973418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett : fColorLUT(sk_ref_sp((SkColorLookUpTable*) as_CSB(srcSpace)->colorLUT())) 10983418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett{ 10993418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett srcToDst.asRowMajorf(fSrcToDst); 11003418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett build_gamma_tables(fSrcGammaTables, fSrcGammaTableStorage, 256, srcSpace, kToLinear); 1101200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett build_gamma_tables(fDstGammaTables, fDstGammaTableStorage, kDstGammaTableSize, dstSpace, 1102200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett kFromLinear); 11033418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett} 1104dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 1105200877eecaba782e56a1dd9e13a92f36d7b1ba12msaretttemplate <SkColorSpace::GammaNamed kDst, ColorSpaceMatch kCSM> 1106200877eecaba782e56a1dd9e13a92f36d7b1ba12msarettvoid SkColorSpaceXform_Base<kDst, kCSM> 1107d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett::apply(void* dst, const uint32_t* src, int len, SkColorType dstColorType, SkAlphaType dstAlphaType) 1108d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarettconst 11093418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett{ 1110200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett if (kFull_ColorSpaceMatch == kCSM) { 1111200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett switch (dstAlphaType) { 1112200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kPremul_SkAlphaType: 1113200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // We can't skip the xform since we need to perform a premultiply in the 1114200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // linear space. 1115200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett break; 1116200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 1117200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett switch (dstColorType) { 1118200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kRGBA_8888_SkColorType: 1119200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return (void) memcpy(dst, src, len * sizeof(uint32_t)); 1120200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kBGRA_8888_SkColorType: 1121200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return SkOpts::RGBA_to_BGRA((uint32_t*) dst, src, len); 1122200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kRGBA_F16_SkColorType: 1123200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett // There's still work to do to xform to linear F16. 1124200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett break; 1125200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett default: 1126200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkASSERT(false); 1127200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return; 1128200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1129200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1130200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett } 1131200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett 11323418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett if (fColorLUT) { 1133d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett size_t storageBytes = len * sizeof(uint32_t); 11343418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett#if defined(GOOGLE3) 11353418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett // Stack frame size is limited in GOOGLE3. 1136d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett SkAutoSMalloc<256 * sizeof(uint32_t)> storage(storageBytes); 11373418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett#else 1138d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett SkAutoSMalloc<1024 * sizeof(uint32_t)> storage(storageBytes); 11393418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett#endif 11403418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett 1141d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett handle_color_lut((uint32_t*) storage.get(), src, len, fColorLUT.get()); 1142d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett src = (const uint32_t*) storage.get(); 11433418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett } 11443418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett 1145d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett switch (dstAlphaType) { 1146d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett case kPremul_SkAlphaType: 1147d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett switch (dstColorType) { 1148d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett case kRGBA_8888_SkColorType: 1149200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return color_xform_RGBA<kDst, kCSM, kPremul_SkAlphaType, kNo_SwapRB> 1150d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett (dst, src, len, fSrcGammaTables, fSrcToDst, fDstGammaTables); 1151d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett case kBGRA_8888_SkColorType: 1152200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return color_xform_RGBA<kDst, kCSM, kPremul_SkAlphaType, kYes_SwapRB> 1153d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett (dst, src, len, fSrcGammaTables, fSrcToDst, fDstGammaTables); 1154d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett case kRGBA_F16_SkColorType: 1155200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return color_xform_RGBA<SkColorSpace::kLinear_GammaNamed, kCSM, 1156200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett kPremul_SkAlphaType, kNo_SwapRB> 1157d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett (dst, src, len, fSrcGammaTables, fSrcToDst, fDstGammaTables); 1158d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett default: 1159d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett SkASSERT(false); 1160d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett return; 1161d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 1162d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett break; 1163d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett case kUnpremul_SkAlphaType: 1164d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett switch (dstColorType) { 1165d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett case kRGBA_8888_SkColorType: 1166200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return color_xform_RGBA<kDst, kCSM, kUnpremul_SkAlphaType, kNo_SwapRB> 1167d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett (dst, src, len, fSrcGammaTables, fSrcToDst, fDstGammaTables); 1168d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett case kBGRA_8888_SkColorType: 1169200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return color_xform_RGBA<kDst, kCSM, kUnpremul_SkAlphaType, kYes_SwapRB> 1170d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett (dst, src, len, fSrcGammaTables, fSrcToDst, fDstGammaTables); 1171d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett case kRGBA_F16_SkColorType: 1172200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return color_xform_RGBA<SkColorSpace::kLinear_GammaNamed, kCSM, 1173200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett kUnpremul_SkAlphaType, kNo_SwapRB> 1174d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett (dst, src, len, fSrcGammaTables, fSrcToDst, fDstGammaTables); 1175d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett default: 1176d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett SkASSERT(false); 1177d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett return; 1178d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 1179d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett case kOpaque_SkAlphaType: 1180d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett switch (dstColorType) { 1181d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett case kRGBA_8888_SkColorType: 1182200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return color_xform_RGBA<kDst, kCSM, kOpaque_SkAlphaType, kNo_SwapRB> 1183d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett (dst, src, len, fSrcGammaTables, fSrcToDst, fDstGammaTables); 1184d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett case kBGRA_8888_SkColorType: 1185200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return color_xform_RGBA<kDst, kCSM, kOpaque_SkAlphaType, kYes_SwapRB> 1186d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett (dst, src, len, fSrcGammaTables, fSrcToDst, fDstGammaTables); 1187d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett case kRGBA_F16_SkColorType: 1188200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return color_xform_RGBA<SkColorSpace::kLinear_GammaNamed, kCSM, 1189200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett kOpaque_SkAlphaType, kNo_SwapRB> 1190d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett (dst, src, len, fSrcGammaTables, fSrcToDst, fDstGammaTables); 1191d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett default: 1192d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett SkASSERT(false); 1193d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett return; 1194d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 1195d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett default: 1196d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett SkASSERT(false); 1197d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett return; 1198d1ec89b1aca8f37a460a425259a23275f4d9a81dmsarett } 11999ce3a543c92a73e6daca420defc042886b3f2019msarett} 1200