SkColorSpaceXform.cpp revision a4083c97d48e8a4f88e2797d7363f141e3d42553
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 8a4083c97d48e8a4f88e2797d7363f141e3d42553Cary Clark#include "SkColorData.h" 99488833428e83c93a7e6002f4d056084fb57112fraftias#include "SkColorSpace_A2B.h" 109876ac5b3016e5353c072378ac1545a0a2270757msarett#include "SkColorSpace_Base.h" 119488833428e83c93a7e6002f4d056084fb57112fraftias#include "SkColorSpace_XYZ.h" 12200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett#include "SkColorSpacePriv.h" 132563601fc2b0505619f905f86bd249ae630197ccraftias#include "SkColorSpaceXform_A2B.h" 1431d097e865f266c8398f45114e4c75c0dfdef058msarett#include "SkColorSpaceXform_Base.h" 152563601fc2b0505619f905f86bd249ae630197ccraftias#include "SkColorSpaceXformPriv.h" 16200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett#include "SkHalf.h" 17200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett#include "SkOpts.h" 185e15961fa77281540a80ac0d036fefe071c11574Mike Klein#include "SkPM4fPriv.h" 19f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett#include "SkRasterPipeline.h" 20ac41bac40f5a80d2bc5ccec584c23478a6900179mtklein#include "SkSRGB.h" 2145c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein#include "../jumper/SkJumper.h" 229876ac5b3016e5353c072378ac1545a0a2270757msarett 236006f678e78af7b6f67a454cd4bc213048983f9dmsarettstatic constexpr float sk_linear_from_2dot2[256] = { 24b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000000000000000000f, 0.000005077051900662f, 0.000023328004666099f, 0.000056921765712193f, 25b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000107187362341244f, 0.000175123977503027f, 0.000261543754548491f, 0.000367136269815943f, 26b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.000492503787191433f, 0.000638182842167022f, 0.000804658499513058f, 0.000992374304074325f, 27b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.001201739522438400f, 0.001433134589671860f, 0.001686915316789280f, 0.001963416213396470f, 28b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.002262953160706430f, 0.002585825596234170f, 0.002932318323938360f, 0.003302703032003640f, 29b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.003697239578900130f, 0.004116177093282750f, 0.004559754922526020f, 0.005028203456855540f, 30b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.005521744850239660f, 0.006040593654849810f, 0.006584957382581690f, 0.007155037004573030f, 31b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.007751027397660610f, 0.008373117745148580f, 0.009021491898012130f, 0.009696328701658230f, 32b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.010397802292555300f, 0.011126082368383200f, 0.011881334434813700f, 0.012663720031582100f, 33b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.013473396940142600f, 0.014310519374884100f, 0.015175238159625200f, 0.016067700890886900f, 34b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.016988052089250000f, 0.017936433339950200f, 0.018912983423721500f, 0.019917838438785700f, 35b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.020951131914781100f, 0.022012994919336500f, 0.023103556157921400f, 0.024222942067534200f, 36b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.025371276904734600f, 0.026548682828472900f, 0.027755279978126000f, 0.028991186547107800f, 37b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.030256518852388700f, 0.031551391400226400f, 0.032875916948383800f, 0.034230206565082000f, 38b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.035614369684918800f, 0.037028514161960200f, 0.038472746320194600f, 0.039947171001525600f, 39b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.041451891611462500f, 0.042987010162657100f, 0.044552627316421400f, 0.046148842422351000f, 40b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.047775753556170600f, 0.049433457555908000f, 0.051122050056493400f, 0.052841625522879000f, 41b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.054592277281760300f, 0.056374097551979800f, 0.058187177473685400f, 0.060031607136313200f, 42b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.061907475605455800f, 0.063814870948677200f, 0.065753880260330100f, 0.067724589685424300f, 43b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.069727084442598800f, 0.071761448846239100f, 0.073827766327784600f, 0.075926119456264800f, 44b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.078056589958101900f, 0.080219258736215100f, 0.082414205888459200f, 0.084641510725429500f, 45b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.086901251787660300f, 0.089193506862247800f, 0.091518352998919500f, 0.093875866525577800f, 46b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.096266123063339700f, 0.098689197541094500f, 0.101145164209600000f, 0.103634096655137000f, 47b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.106156067812744000f, 0.108711149979039000f, 0.111299414824660000f, 0.113920933406333000f, 48b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.116575776178572000f, 0.119264013005047000f, 0.121985713169619000f, 0.124740945387051000f, 49b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.127529777813422000f, 0.130352278056244000f, 0.133208513184300000f, 0.136098549737202000f, 50b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.139022453734703000f, 0.141980290685736000f, 0.144972125597231000f, 0.147998022982685000f, 51b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.151058046870511000f, 0.154152260812165000f, 0.157280727890073000f, 0.160443510725344000f, 52b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.163640671485290000f, 0.166872271890766000f, 0.170138373223312000f, 0.173439036332135000f, 53b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.176774321640903000f, 0.180144289154390000f, 0.183548998464951000f, 0.186988508758844000f, 54b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.190462878822409000f, 0.193972167048093000f, 0.197516431440340000f, 0.201095729621346000f, 55b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.204710118836677000f, 0.208359655960767000f, 0.212044397502288000f, 0.215764399609395000f, 56b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.219519718074868000f, 0.223310408341127000f, 0.227136525505149000f, 0.230998124323267000f, 57b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.234895259215880000f, 0.238827984272048000f, 0.242796353254002000f, 0.246800419601550000f, 58b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.250840236436400000f, 0.254915856566385000f, 0.259027332489606000f, 0.263174716398492000f, 59b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.267358060183772000f, 0.271577415438375000f, 0.275832833461245000f, 0.280124365261085000f, 60b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.284452061560024000f, 0.288815972797219000f, 0.293216149132375000f, 0.297652640449211000f, 61b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.302125496358853000f, 0.306634766203158000f, 0.311180499057984000f, 0.315762743736397000f, 62b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.320381548791810000f, 0.325036962521076000f, 0.329729032967515000f, 0.334457807923889000f, 63b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.339223334935327000f, 0.344025661302187000f, 0.348864834082879000f, 0.353740900096629000f, 64b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.358653905926199000f, 0.363603897920553000f, 0.368590922197487000f, 0.373615024646202000f, 65b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.378676250929840000f, 0.383774646487975000f, 0.388910256539059000f, 0.394083126082829000f, 66b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.399293299902674000f, 0.404540822567962000f, 0.409825738436323000f, 0.415148091655907000f, 67b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.420507926167587000f, 0.425905285707146000f, 0.431340213807410000f, 0.436812753800359000f, 68b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.442322948819202000f, 0.447870841800410000f, 0.453456475485731000f, 0.459079892424160000f, 69b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.464741134973889000f, 0.470440245304218000f, 0.476177265397440000f, 0.481952237050698000f, 70b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.487765201877811000f, 0.493616201311074000f, 0.499505276603030000f, 0.505432468828216000f, 71b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.511397818884880000f, 0.517401367496673000f, 0.523443155214325000f, 0.529523222417277000f, 72b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.535641609315311000f, 0.541798355950137000f, 0.547993502196972000f, 0.554227087766085000f, 73b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.560499152204328000f, 0.566809734896638000f, 0.573158875067523000f, 0.579546611782525000f, 74b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.585972983949661000f, 0.592438030320847000f, 0.598941789493296000f, 0.605484299910907000f, 75b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.612065599865624000f, 0.618685727498780000f, 0.625344720802427000f, 0.632042617620641000f, 76b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.638779455650817000f, 0.645555272444935000f, 0.652370105410821000f, 0.659223991813387000f, 77b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.666116968775851000f, 0.673049073280942000f, 0.680020342172095000f, 0.687030812154625000f, 78b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.694080519796882000f, 0.701169501531402000f, 0.708297793656032000f, 0.715465432335048000f, 79b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.722672453600255000f, 0.729918893352071000f, 0.737204787360605000f, 0.744530171266715000f, 80b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.751895080583051000f, 0.759299550695091000f, 0.766743616862161000f, 0.774227314218442000f, 81b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.781750677773962000f, 0.789313742415586000f, 0.796916542907978000f, 0.804559113894567000f, 82b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.812241489898490000f, 0.819963705323528000f, 0.827725794455034000f, 0.835527791460841000f, 83b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.843369730392169000f, 0.851251645184515000f, 0.859173569658532000f, 0.867135537520905000f, 84b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.875137582365205000f, 0.883179737672745000f, 0.891262036813419000f, 0.899384513046529000f, 85b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.907547199521614000f, 0.915750129279253000f, 0.923993335251873000f, 0.932276850264543000f, 86b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.940600707035753000f, 0.948964938178195000f, 0.957369576199527000f, 0.965814653503130000f, 87b39067696ad08a26bbe49b71a71f0546dc42a075msarett 0.974300202388861000f, 0.982826255053791000f, 0.991392843592940000f, 1.000000000000000000f, 88b39067696ad08a26bbe49b71a71f0546dc42a075msarett}; 89b39067696ad08a26bbe49b71a71f0546dc42a075msarett 906006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 916006f678e78af7b6f67a454cd4bc213048983f9dmsarett 9215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, float exponent) { 9315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 9415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = powf(x, exponent); 9515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 9615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 9715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 9815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett// outTable is always 256 entries, inTable may be larger or smaller. 9915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, const float* inTable, 10015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett int inTableSize) { 10115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett if (256 == inTableSize) { 10215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett memcpy(outTable, inTable, sizeof(float) * 256); 10315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett return; 10415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 10515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 10615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 10715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett *outTable++ = interp_lut(x, inTable, inTableSize); 10815ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 10915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 11015ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 111aa34f7ea58330cb73ea17f01715cb6c7d439fae9Matt Sarett 11215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarettstatic void build_table_linear_from_gamma(float* outTable, float g, float a, float b, float c, 11315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett float d, float e, float f) { 1142410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett // Y = (aX + b)^g + e for X >= d 1152410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett // Y = cX + f otherwise 11615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett for (float x = 0.0f; x <= 1.0f; x += (1.0f/255.0f)) { 11715ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett if (x >= d) { 1182410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett *outTable++ = clamp_0_1(powf(a * x + b, g) + e); 11915ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } else { 1202410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett *outTable++ = clamp_0_1(c * x + f); 12115ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 12215ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett } 12315ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett} 12415ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 12515ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 12615ee3deee8aca2bf6e658449f25ee34a8153e6eemsarett 127f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettstatic const int kDstGammaTableSize = SkColorSpaceXform_Base::kDstGammaTableSize; 1283418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett 1291b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, float exponent) { 130b39067696ad08a26bbe49b71a71f0546dc42a075msarett float toGammaExp = 1.0f / exponent; 131b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1323418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett for (int i = 0; i < kDstGammaTableSize; i++) { 1333418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1))); 134b39067696ad08a26bbe49b71a71f0546dc42a075msarett outTable[i] = clamp_normalized_float_to_byte(powf(x, toGammaExp)); 135b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 136dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett} 137dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 1381b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, const float* inTable, 139b39067696ad08a26bbe49b71a71f0546dc42a075msarett int inTableSize) { 140197e311ac9d15696fae929d8f5fcf9d93ec55e18raftias invert_table_gamma(nullptr, outTable, kDstGammaTableSize, inTable, inTableSize); 141b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 142dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 143b39067696ad08a26bbe49b71a71f0546dc42a075msarettstatic float inverse_parametric(float x, float g, float a, float b, float c, float d, float e, 144b39067696ad08a26bbe49b71a71f0546dc42a075msarett float f) { 145b39067696ad08a26bbe49b71a71f0546dc42a075msarett // We need to take the inverse of the following piecewise function. 146b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Y = (aX + b)^g + c for X >= d 147b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Y = eX + f otherwise 148b39067696ad08a26bbe49b71a71f0546dc42a075msarett 149b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Assume that the gamma function is continuous, or this won't make much sense anyway. 150b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Plug in |d| to the first equation to calculate the new piecewise interval. 151b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Then simply use the inverse of the original functions. 1522410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett float interval = c * d + f; 153b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (x < interval) { 1542410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett // X = (Y - F) / C 1552410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett if (0.0f == c) { 156b39067696ad08a26bbe49b71a71f0546dc42a075msarett // The gamma curve for this segment is constant, so the inverse is undefined. 157b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Since this is the lower segment, guess zero. 158b39067696ad08a26bbe49b71a71f0546dc42a075msarett return 0.0f; 159b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 160b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1612410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett return (x - f) / c; 162b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 163b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1642410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett // X = ((Y - E)^(1 / G) - B) / A 165b39067696ad08a26bbe49b71a71f0546dc42a075msarett if (0.0f == a || 0.0f == g) { 166b39067696ad08a26bbe49b71a71f0546dc42a075msarett // The gamma curve for this segment is constant, so the inverse is undefined. 167b39067696ad08a26bbe49b71a71f0546dc42a075msarett // Since this is the upper segment, guess one. 168b39067696ad08a26bbe49b71a71f0546dc42a075msarett return 1.0f; 169b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 170b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1712410717f900c2691db880d84a2e03a6a24905ee2Matt Sarett return (powf(x - e, 1.0f / g) - b) / a; 172b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 173b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1741b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_table_linear_to_gamma(uint8_t* outTable, float g, float a, 175b39067696ad08a26bbe49b71a71f0546dc42a075msarett float b, float c, float d, float e, float f) { 1763418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett for (int i = 0; i < kDstGammaTableSize; i++) { 1773418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett float x = ((float) i) * (1.0f / ((float) (kDstGammaTableSize - 1))); 178b39067696ad08a26bbe49b71a71f0546dc42a075msarett float y = inverse_parametric(x, g, a, b, c, d, e, f); 179b39067696ad08a26bbe49b71a71f0546dc42a075msarett outTable[i] = clamp_normalized_float_to_byte(y); 180b39067696ad08a26bbe49b71a71f0546dc42a075msarett } 181b39067696ad08a26bbe49b71a71f0546dc42a075msarett} 182b39067696ad08a26bbe49b71a71f0546dc42a075msarett 1836006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 1846006f678e78af7b6f67a454cd4bc213048983f9dmsarett 1851b93bd1e6eba3d14593490e4e24a34546638c8damsaretttemplate <typename T> 1861b93bd1e6eba3d14593490e4e24a34546638c8damsarettstruct GammaFns { 1871b93bd1e6eba3d14593490e4e24a34546638c8damsarett const T* fSRGBTable; 1881b93bd1e6eba3d14593490e4e24a34546638c8damsarett const T* f2Dot2Table; 1891b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromValue)(T*, float); 1901b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromTable)(T*, const float*, int); 1911b93bd1e6eba3d14593490e4e24a34546638c8damsarett void (*fBuildFromParam)(T*, float, float, float, float, float, float, float); 1921b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 1931b93bd1e6eba3d14593490e4e24a34546638c8damsarett 1941b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic const GammaFns<float> kToLinear { 1951b93bd1e6eba3d14593490e4e24a34546638c8damsarett sk_linear_from_srgb, 1961b93bd1e6eba3d14593490e4e24a34546638c8damsarett sk_linear_from_2dot2, 1971b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 1981b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 1991b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_from_gamma, 2001b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 2011b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2021b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic const GammaFns<uint8_t> kFromLinear { 20355bcc8e0af3415601b3d62252a0d579fbe87c85amsarett nullptr, 20455bcc8e0af3415601b3d62252a0d579fbe87c85amsarett nullptr, 2051b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 2061b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 2071b93bd1e6eba3d14593490e4e24a34546638c8damsarett &build_table_linear_to_gamma, 2081b93bd1e6eba3d14593490e4e24a34546638c8damsarett}; 2091b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2101b93bd1e6eba3d14593490e4e24a34546638c8damsarett// Build tables to transform src gamma to linear. 2111b93bd1e6eba3d14593490e4e24a34546638c8damsaretttemplate <typename T> 2121b93bd1e6eba3d14593490e4e24a34546638c8damsarettstatic void build_gamma_tables(const T* outGammaTables[3], T* gammaTableStorage, int gammaTableSize, 2139488833428e83c93a7e6002f4d056084fb57112fraftias const SkColorSpace_XYZ* space, const GammaFns<T>& fns, 214f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett bool gammasAreMatching) 2154be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett{ 2169488833428e83c93a7e6002f4d056084fb57112fraftias switch (space->gammaNamed()) { 217600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 2181b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.fSRGBTable; 2191b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 220600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 2211b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = fns.f2Dot2Table; 2221b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 223600c737b64eae2c7379442ae2c852853cce3a278msarett case kLinear_SkGammaNamed: 2248bbcd5aab81dc0742c3367479c0c9d97363b1203msarett outGammaTables[0] = outGammaTables[1] = outGammaTables[2] = nullptr; 2251b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 2261b93bd1e6eba3d14593490e4e24a34546638c8damsarett default: { 2279488833428e83c93a7e6002f4d056084fb57112fraftias const SkGammas* gammas = space->gammas(); 2281b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(gammas); 2291b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2307bbda991af353fbe6b34132132d211d23a3dba8cmsarett auto build_table = [=](int i) { 2311b93bd1e6eba3d14593490e4e24a34546638c8damsarett if (gammas->isNamed(i)) { 2321b93bd1e6eba3d14593490e4e24a34546638c8damsarett switch (gammas->data(i).fNamed) { 233600c737b64eae2c7379442ae2c852853cce3a278msarett case kSRGB_SkGammaNamed: 234a8565e502db3e4c0bcdac04be03751bd8ca99cb1Hal Canary (*fns.fBuildFromParam)(&gammaTableStorage[i * gammaTableSize], 235a8565e502db3e4c0bcdac04be03751bd8ca99cb1Hal Canary gSRGB_TransferFn.fG, 236a8565e502db3e4c0bcdac04be03751bd8ca99cb1Hal Canary gSRGB_TransferFn.fA, 237a8565e502db3e4c0bcdac04be03751bd8ca99cb1Hal Canary gSRGB_TransferFn.fB, 238a8565e502db3e4c0bcdac04be03751bd8ca99cb1Hal Canary gSRGB_TransferFn.fC, 239a8565e502db3e4c0bcdac04be03751bd8ca99cb1Hal Canary gSRGB_TransferFn.fD, 240a8565e502db3e4c0bcdac04be03751bd8ca99cb1Hal Canary gSRGB_TransferFn.fE, 241a8565e502db3e4c0bcdac04be03751bd8ca99cb1Hal Canary gSRGB_TransferFn.fF); 24255bcc8e0af3415601b3d62252a0d579fbe87c85amsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2431b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 244600c737b64eae2c7379442ae2c852853cce3a278msarett case k2Dot2Curve_SkGammaNamed: 24555bcc8e0af3415601b3d62252a0d579fbe87c85amsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 2.2f); 24655bcc8e0af3415601b3d62252a0d579fbe87c85amsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2471b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 248600c737b64eae2c7379442ae2c852853cce3a278msarett case kLinear_SkGammaNamed: 2491b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 1.0f); 2501b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2511b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 2521b93bd1e6eba3d14593490e4e24a34546638c8damsarett default: 2531b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(false); 2541b93bd1e6eba3d14593490e4e24a34546638c8damsarett break; 2551b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2561b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else if (gammas->isValue(i)) { 2571b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromValue)(&gammaTableStorage[i * gammaTableSize], 2581b93bd1e6eba3d14593490e4e24a34546638c8damsarett gammas->data(i).fValue); 2591b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2601b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else if (gammas->isTable(i)) { 2611b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromTable)(&gammaTableStorage[i * gammaTableSize], gammas->table(i), 2621b93bd1e6eba3d14593490e4e24a34546638c8damsarett gammas->data(i).fTable.fSize); 2631b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2641b93bd1e6eba3d14593490e4e24a34546638c8damsarett } else { 2651b93bd1e6eba3d14593490e4e24a34546638c8damsarett SkASSERT(gammas->isParametric(i)); 266df44fc5f2bb282557df291e20dbd26c070533aa6Matt Sarett const SkColorSpaceTransferFn& params = gammas->params(i); 2671b93bd1e6eba3d14593490e4e24a34546638c8damsarett (*fns.fBuildFromParam)(&gammaTableStorage[i * gammaTableSize], params.fG, 2681b93bd1e6eba3d14593490e4e24a34546638c8damsarett params.fA, params.fB, params.fC, params.fD, params.fE, 2691b93bd1e6eba3d14593490e4e24a34546638c8damsarett params.fF); 2701b93bd1e6eba3d14593490e4e24a34546638c8damsarett outGammaTables[i] = &gammaTableStorage[i * gammaTableSize]; 2711b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2727bbda991af353fbe6b34132132d211d23a3dba8cmsarett }; 2737bbda991af353fbe6b34132132d211d23a3dba8cmsarett 2747bbda991af353fbe6b34132132d211d23a3dba8cmsarett if (gammasAreMatching) { 2757bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(0); 2767bbda991af353fbe6b34132132d211d23a3dba8cmsarett outGammaTables[1] = outGammaTables[0]; 2777bbda991af353fbe6b34132132d211d23a3dba8cmsarett outGammaTables[2] = outGammaTables[0]; 2787bbda991af353fbe6b34132132d211d23a3dba8cmsarett } else { 2797bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(0); 2807bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(1); 2817bbda991af353fbe6b34132132d211d23a3dba8cmsarett build_table(2); 2821b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2837bbda991af353fbe6b34132132d211d23a3dba8cmsarett 2847bbda991af353fbe6b34132132d211d23a3dba8cmsarett break; 2851b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2861b93bd1e6eba3d14593490e4e24a34546638c8damsarett } 2871b93bd1e6eba3d14593490e4e24a34546638c8damsarett} 2881b93bd1e6eba3d14593490e4e24a34546638c8damsarett 289f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettvoid SkColorSpaceXform_Base::BuildDstGammaTables(const uint8_t* dstGammaTables[3], 2909488833428e83c93a7e6002f4d056084fb57112fraftias uint8_t* dstStorage, 2919488833428e83c93a7e6002f4d056084fb57112fraftias const SkColorSpace_XYZ* space, 292f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett bool gammasAreMatching) { 293f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett build_gamma_tables(dstGammaTables, dstStorage, kDstGammaTableSize, space, kFromLinear, 294f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett gammasAreMatching); 295f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett} 296f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett 2971b93bd1e6eba3d14593490e4e24a34546638c8damsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 2981b93bd1e6eba3d14593490e4e24a34546638c8damsarett 2994be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarettstd::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(SkColorSpace* srcSpace, 3004be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett SkColorSpace* dstSpace) { 301cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett return SkColorSpaceXform_Base::New(srcSpace, dstSpace, SkTransferFunctionBehavior::kRespect); 302cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett} 303cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett 304cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarettstd::unique_ptr<SkColorSpaceXform> SkColorSpaceXform_Base::New(SkColorSpace* srcSpace, 305cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett SkColorSpace* dstSpace, SkTransferFunctionBehavior premulBehavior) { 306cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett 3076006f678e78af7b6f67a454cd4bc213048983f9dmsarett if (!srcSpace || !dstSpace) { 3086006f678e78af7b6f67a454cd4bc213048983f9dmsarett // Invalid input 3096006f678e78af7b6f67a454cd4bc213048983f9dmsarett return nullptr; 3106006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 3116006f678e78af7b6f67a454cd4bc213048983f9dmsarett 3129488833428e83c93a7e6002f4d056084fb57112fraftias if (SkColorSpace_Base::Type::kA2B == as_CSB(dstSpace)->type()) { 3132563601fc2b0505619f905f86bd249ae630197ccraftias SkCSXformPrintf("A2B destinations not supported\n"); 3149488833428e83c93a7e6002f4d056084fb57112fraftias return nullptr; 3159488833428e83c93a7e6002f4d056084fb57112fraftias } 3169488833428e83c93a7e6002f4d056084fb57112fraftias 3179488833428e83c93a7e6002f4d056084fb57112fraftias if (SkColorSpace_Base::Type::kA2B == as_CSB(srcSpace)->type()) { 3182563601fc2b0505619f905f86bd249ae630197ccraftias SkColorSpace_A2B* src = static_cast<SkColorSpace_A2B*>(srcSpace); 3192563601fc2b0505619f905f86bd249ae630197ccraftias SkColorSpace_XYZ* dst = static_cast<SkColorSpace_XYZ*>(dstSpace); 3202563601fc2b0505619f905f86bd249ae630197ccraftias return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_A2B(src, dst)); 3219488833428e83c93a7e6002f4d056084fb57112fraftias } 3229488833428e83c93a7e6002f4d056084fb57112fraftias SkColorSpace_XYZ* srcSpaceXYZ = static_cast<SkColorSpace_XYZ*>(srcSpace); 3239488833428e83c93a7e6002f4d056084fb57112fraftias SkColorSpace_XYZ* dstSpaceXYZ = static_cast<SkColorSpace_XYZ*>(dstSpace); 3249488833428e83c93a7e6002f4d056084fb57112fraftias 325200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett ColorSpaceMatch csm = kNone_ColorSpaceMatch; 3266006f678e78af7b6f67a454cd4bc213048983f9dmsarett SkMatrix44 srcToDst(SkMatrix44::kUninitialized_Constructor); 327f3880933092c3226cd7ffd1690fe72c9c0cc376cMatt Sarett if (SkColorSpace::Equals(srcSpace, dstSpace)) { 328200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett srcToDst.setIdentity(); 329200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett csm = kFull_ColorSpaceMatch; 330971cd496b9e25f87f3a75a0015c203322907136abrianosman } else { 331bbf251bf225489a0939fff6df938035a290f4d16Brian Osman if (srcSpaceXYZ->toXYZD50Hash() == dstSpaceXYZ->toXYZD50Hash()) { 332bbf251bf225489a0939fff6df938035a290f4d16Brian Osman SkASSERT(*srcSpaceXYZ->toXYZD50() == *dstSpaceXYZ->toXYZD50() && "Hash collision"); 333971cd496b9e25f87f3a75a0015c203322907136abrianosman srcToDst.setIdentity(); 334971cd496b9e25f87f3a75a0015c203322907136abrianosman csm = kGamut_ColorSpaceMatch; 335bbf251bf225489a0939fff6df938035a290f4d16Brian Osman } else { 336bbf251bf225489a0939fff6df938035a290f4d16Brian Osman srcToDst.setConcat(*dstSpaceXYZ->fromXYZD50(), *srcSpaceXYZ->toXYZD50()); 337971cd496b9e25f87f3a75a0015c203322907136abrianosman } 3386006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 3396006f678e78af7b6f67a454cd4bc213048983f9dmsarett 340200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett switch (csm) { 341200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kNone_ColorSpaceMatch: 342379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 343cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett <kNone_ColorSpaceMatch>(srcSpaceXYZ, srcToDst, dstSpaceXYZ, premulBehavior)); 344200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kGamut_ColorSpaceMatch: 345379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 346cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett <kGamut_ColorSpaceMatch>(srcSpaceXYZ, srcToDst, dstSpaceXYZ, premulBehavior)); 347200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett case kFull_ColorSpaceMatch: 348379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ 349cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett <kFull_ColorSpaceMatch>(srcSpaceXYZ, srcToDst, dstSpaceXYZ, premulBehavior)); 3503418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett default: 351200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett SkASSERT(false); 352200877eecaba782e56a1dd9e13a92f36d7b1ba12msarett return nullptr; 3536006f678e78af7b6f67a454cd4bc213048983f9dmsarett } 3546006f678e78af7b6f67a454cd4bc213048983f9dmsarett} 3556006f678e78af7b6f67a454cd4bc213048983f9dmsarett 3566006f678e78af7b6f67a454cd4bc213048983f9dmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 3576006f678e78af7b6f67a454cd4bc213048983f9dmsarett 358e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Kleinstatic inline int num_tables(SkColorSpace_XYZ* space) { 3599488833428e83c93a7e6002f4d056084fb57112fraftias switch (space->gammaNamed()) { 3607bbda991af353fbe6b34132132d211d23a3dba8cmsarett case kSRGB_SkGammaNamed: 3617bbda991af353fbe6b34132132d211d23a3dba8cmsarett case k2Dot2Curve_SkGammaNamed: 3627bbda991af353fbe6b34132132d211d23a3dba8cmsarett case kLinear_SkGammaNamed: 3637bbda991af353fbe6b34132132d211d23a3dba8cmsarett return 0; 3647bbda991af353fbe6b34132132d211d23a3dba8cmsarett default: { 3659488833428e83c93a7e6002f4d056084fb57112fraftias const SkGammas* gammas = space->gammas(); 3667bbda991af353fbe6b34132132d211d23a3dba8cmsarett SkASSERT(gammas); 3677bbda991af353fbe6b34132132d211d23a3dba8cmsarett 3687bbda991af353fbe6b34132132d211d23a3dba8cmsarett bool gammasAreMatching = (gammas->type(0) == gammas->type(1)) && 3697bbda991af353fbe6b34132132d211d23a3dba8cmsarett (gammas->data(0) == gammas->data(1)) && 3707bbda991af353fbe6b34132132d211d23a3dba8cmsarett (gammas->type(0) == gammas->type(2)) && 3717bbda991af353fbe6b34132132d211d23a3dba8cmsarett (gammas->data(0) == gammas->data(2)); 3727bbda991af353fbe6b34132132d211d23a3dba8cmsarett 3737bbda991af353fbe6b34132132d211d23a3dba8cmsarett // It's likely that each component will have the same gamma. In this case, 3747bbda991af353fbe6b34132132d211d23a3dba8cmsarett // we only need to build one table. 3757bbda991af353fbe6b34132132d211d23a3dba8cmsarett return gammasAreMatching ? 1 : 3; 3767bbda991af353fbe6b34132132d211d23a3dba8cmsarett } 3777bbda991af353fbe6b34132132d211d23a3dba8cmsarett } 3787bbda991af353fbe6b34132132d211d23a3dba8cmsarett} 3797bbda991af353fbe6b34132132d211d23a3dba8cmsarett 380379938e47bc9edb6edfd21aabefa01aed71dd135Matt Saretttemplate <ColorSpaceMatch kCSM> 381379938e47bc9edb6edfd21aabefa01aed71dd135Matt SarettSkColorSpaceXform_XYZ<kCSM> 3829488833428e83c93a7e6002f4d056084fb57112fraftias::SkColorSpaceXform_XYZ(SkColorSpace_XYZ* srcSpace, const SkMatrix44& srcToDst, 383cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett SkColorSpace_XYZ* dstSpace, SkTransferFunctionBehavior premulBehavior) 384cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett : fPremulBehavior(premulBehavior) 3853418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett{ 38626a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 0] = srcToDst.get(0, 0); 38726a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 1] = srcToDst.get(1, 0); 38826a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 2] = srcToDst.get(2, 0); 38926a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 3] = srcToDst.get(0, 1); 39026a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 4] = srcToDst.get(1, 1); 39126a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 5] = srcToDst.get(2, 1); 39226a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 6] = srcToDst.get(0, 2); 39326a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 7] = srcToDst.get(1, 2); 39426a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 8] = srcToDst.get(2, 2); 39526a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[ 9] = srcToDst.get(0, 3); 39626a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[10] = srcToDst.get(1, 3); 39726a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[11] = srcToDst.get(2, 3); 39826a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett fSrcToDst[12] = 0.0f; 3997bbda991af353fbe6b34132132d211d23a3dba8cmsarett 4004be0e7cfe0efceeaf4c7a4d598d77c27cfd3e69bmsarett const int numSrcTables = num_tables(srcSpace); 401f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett const size_t srcEntries = numSrcTables * 256; 4027bbda991af353fbe6b34132132d211d23a3dba8cmsarett const bool srcGammasAreMatching = (1 >= numSrcTables); 403f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett fSrcStorage.reset(srcEntries); 404f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett build_gamma_tables(fSrcGammaTables, fSrcStorage.get(), 256, srcSpace, kToLinear, 405f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett srcGammasAreMatching); 406f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett 407f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett const int numDstTables = num_tables(dstSpace); 4089488833428e83c93a7e6002f4d056084fb57112fraftias dstSpace->toDstGammaTables(fDstGammaTables, &fDstStorage, numDstTables); 409379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett 410379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett if (srcSpace->gammaIsLinear()) { 411379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett fSrcGamma = kLinear_SrcGamma; 412379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett } else if (kSRGB_SkGammaNamed == srcSpace->gammaNamed()) { 413379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett fSrcGamma = kSRGB_SrcGamma; 414379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett } else { 415379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett fSrcGamma = kTable_SrcGamma; 416379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett } 417379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett 418379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett switch (dstSpace->gammaNamed()) { 419379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett case kSRGB_SkGammaNamed: 420379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett fDstGamma = kSRGB_DstGamma; 421379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 422379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett case k2Dot2Curve_SkGammaNamed: 423379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett fDstGamma = k2Dot2_DstGamma; 424379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 425379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett case kLinear_SkGammaNamed: 426379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett fDstGamma = kLinear_DstGamma; 427379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 428379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett default: 429379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett fDstGamma = kTable_DstGamma; 430379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 431379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett } 4323418c0e797e2ee841d1c031ca9d7a5ba73205f51msarett} 433dc27a648d2ff23b2e96232c00c15976c46e1d48dmsarett 4347bbda991af353fbe6b34132132d211d23a3dba8cmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 4357bbda991af353fbe6b34132132d211d23a3dba8cmsarett 4361f8796dbde0dd2cd146e051e88def2c1c23f5d9cMike Kleintemplate <ColorSpaceMatch kCSM> 437e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Kleinbool SkColorSpaceXform_XYZ<kCSM>::onApply(ColorFormat dstColorFormat, void* dst, 438e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein ColorFormat srcColorFormat, const void* src, 439e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein int len, SkAlphaType alphaType) const { 440e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein if (kFull_ColorSpaceMatch == kCSM && kPremul_SkAlphaType != alphaType) { 441e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein if ((kRGBA_8888_ColorFormat == dstColorFormat && 442e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein kRGBA_8888_ColorFormat == srcColorFormat) || 443e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein (kBGRA_8888_ColorFormat == dstColorFormat && 444e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein kBGRA_8888_ColorFormat == srcColorFormat)) 445e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein { 446e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein memcpy(dst, src, len * sizeof(uint32_t)); 447e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein return true; 44858564425e5acb5911cc3719f9c1e39190cc829b8Mike Klein } 44926a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett 450e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein if ((kRGBA_8888_ColorFormat == dstColorFormat && 451e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein kBGRA_8888_ColorFormat == srcColorFormat) || 452e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein (kBGRA_8888_ColorFormat == dstColorFormat && 453e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein kRGBA_8888_ColorFormat == srcColorFormat)) 454e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein { 455e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein SkOpts::RGBA_to_BGRA((uint32_t*)dst, src, len); 456e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein return true; 457e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein } 4581f8796dbde0dd2cd146e051e88def2c1c23f5d9cMike Klein } 4591f8796dbde0dd2cd146e051e88def2c1c23f5d9cMike Klein 460e23e55ef33358b2f6f98fc9cb795c71397c01618Mike Klein return this->applyPipeline(dstColorFormat, dst, srcColorFormat, src, len, alphaType); 4619ce3a543c92a73e6daca420defc042886b3f2019msarett} 4629dc6cf6b8833d36c29a23d2519989b069745fcd5msarett 463f489886915034093278353d06c6f1973b2e8b7d2Matt Sarettbool SkColorSpaceXform::apply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, 464f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett const void* src, int len, SkAlphaType alphaType) const { 465f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett return ((SkColorSpaceXform_Base*) this)->onApply(dstColorFormat, dst, srcColorFormat, src, len, 466f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett alphaType); 467f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett} 468f489886915034093278353d06c6f1973b2e8b7d2Matt Sarett 469edf8a762190eccc6d2a7ab3a095d131e9fd101bcMike Reedbool SkColorSpaceXform::Apply(SkColorSpace* dstCS, ColorFormat dstFormat, void* dst, 470edf8a762190eccc6d2a7ab3a095d131e9fd101bcMike Reed SkColorSpace* srcCS, ColorFormat srcFormat, const void* src, 471edf8a762190eccc6d2a7ab3a095d131e9fd101bcMike Reed int count, AlphaOp op) { 472edf8a762190eccc6d2a7ab3a095d131e9fd101bcMike Reed SkAlphaType at; 473edf8a762190eccc6d2a7ab3a095d131e9fd101bcMike Reed switch (op) { 474edf8a762190eccc6d2a7ab3a095d131e9fd101bcMike Reed case kPreserve_AlphaOp: at = kUnpremul_SkAlphaType; break; 475edf8a762190eccc6d2a7ab3a095d131e9fd101bcMike Reed case kPremul_AlphaOp: at = kPremul_SkAlphaType; break; 476edf8a762190eccc6d2a7ab3a095d131e9fd101bcMike Reed case kSrcIsOpaque_AlphaOp: at = kOpaque_SkAlphaType; break; 477edf8a762190eccc6d2a7ab3a095d131e9fd101bcMike Reed } 478edf8a762190eccc6d2a7ab3a095d131e9fd101bcMike Reed return New(srcCS, dstCS)->apply(dstFormat, dst, srcFormat, src, count, at); 479edf8a762190eccc6d2a7ab3a095d131e9fd101bcMike Reed} 480edf8a762190eccc6d2a7ab3a095d131e9fd101bcMike Reed 4817bbda991af353fbe6b34132132d211d23a3dba8cmsarett/////////////////////////////////////////////////////////////////////////////////////////////////// 4827bbda991af353fbe6b34132132d211d23a3dba8cmsarett 483379938e47bc9edb6edfd21aabefa01aed71dd135Matt Saretttemplate <ColorSpaceMatch kCSM> 484379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarettbool SkColorSpaceXform_XYZ<kCSM> 48526a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett::applyPipeline(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, 48626a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett const void* src, int len, SkAlphaType alphaType) const { 487b24704d35f67f5b460be9c92794892e06adceb46Mike Klein SkRasterPipeline_<256> pipeline; 488f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 48945c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein SkJumper_MemoryCtx src_ctx = { (void*)src, 0 }, 49045c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein dst_ctx = { (void*)dst, 0 }; 49145c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein 49226a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett LoadTablesContext loadTables; 49326a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett switch (srcColorFormat) { 49426a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett case kRGBA_8888_ColorFormat: 495379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett if (kLinear_SrcGamma == fSrcGamma) { 49645c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein pipeline.append(SkRasterPipeline::load_8888, &src_ctx); 49726a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett } else { 498379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett loadTables.fSrc = src; 49926a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett loadTables.fR = fSrcGammaTables[0]; 50026a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett loadTables.fG = fSrcGammaTables[1]; 50126a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett loadTables.fB = fSrcGammaTables[2]; 50226a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett pipeline.append(SkRasterPipeline::load_tables, &loadTables); 503f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 504f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 50526a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett break; 50626a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett case kBGRA_8888_ColorFormat: 507379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett if (kLinear_SrcGamma == fSrcGamma) { 50845c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein pipeline.append(SkRasterPipeline::load_bgra, &src_ctx); 50926a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett } else { 510379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett loadTables.fSrc = src; 51126a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett loadTables.fR = fSrcGammaTables[2]; 51226a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett loadTables.fG = fSrcGammaTables[1]; 51326a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett loadTables.fB = fSrcGammaTables[0]; 51426a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett pipeline.append(SkRasterPipeline::load_tables, &loadTables); 515c2d207603edbbd3809d5144fe4a048a2ad774910Mike Klein pipeline.append(SkRasterPipeline::swap_rb); 516f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 517f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 51826a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett break; 519b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman case kRGBA_F16_ColorFormat: 520b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman if (kLinear_SrcGamma != fSrcGamma) { 521b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman return false; 522b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman } 52345c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein pipeline.append(SkRasterPipeline::load_f16, &src_ctx); 524b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman break; 5254c55027dbf57d0701361b123e36b8fad46c341c3Matt Sarett case kRGBA_F32_ColorFormat: 5264c55027dbf57d0701361b123e36b8fad46c341c3Matt Sarett if (kLinear_SrcGamma != fSrcGamma) { 5274c55027dbf57d0701361b123e36b8fad46c341c3Matt Sarett return false; 5284c55027dbf57d0701361b123e36b8fad46c341c3Matt Sarett } 52945c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein pipeline.append(SkRasterPipeline::load_f32, &src_ctx); 5304c55027dbf57d0701361b123e36b8fad46c341c3Matt Sarett break; 531379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett case kRGBA_U16_BE_ColorFormat: 532379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett switch (fSrcGamma) { 533379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett case kLinear_SrcGamma: 53445c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein pipeline.append(SkRasterPipeline::load_u16_be, &src_ctx); 535379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 536379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett case kSRGB_SrcGamma: 53745c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein pipeline.append(SkRasterPipeline::load_u16_be, &src_ctx); 538379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett pipeline.append_from_srgb(kUnpremul_SkAlphaType); 539379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 540379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett case kTable_SrcGamma: 541379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett loadTables.fSrc = src; 542379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett loadTables.fR = fSrcGammaTables[0]; 543379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett loadTables.fG = fSrcGammaTables[1]; 544379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett loadTables.fB = fSrcGammaTables[2]; 545379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett pipeline.append(SkRasterPipeline::load_tables_u16_be, &loadTables); 546379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 547379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett } 548379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett break; 5495bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett case kRGB_U16_BE_ColorFormat: 5505bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett switch (fSrcGamma) { 5515bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett case kLinear_SrcGamma: 55245c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein pipeline.append(SkRasterPipeline::load_rgb_u16_be, &src_ctx); 5535bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett break; 5545bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett case kSRGB_SrcGamma: 55545c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein pipeline.append(SkRasterPipeline::load_rgb_u16_be, &src_ctx); 5565bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett pipeline.append_from_srgb(kUnpremul_SkAlphaType); 5575bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett break; 5585bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett case kTable_SrcGamma: 5595bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett loadTables.fSrc = src; 5605bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett loadTables.fR = fSrcGammaTables[0]; 5615bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett loadTables.fG = fSrcGammaTables[1]; 5625bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett loadTables.fB = fSrcGammaTables[2]; 5635bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett pipeline.append(SkRasterPipeline::load_tables_rgb_u16_be, &loadTables); 5645bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett break; 5655bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett } 5665bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett break; 5673725f0a7dd2916c10bc6d0059821e19a5b4452c3Matt Sarett default: 5683725f0a7dd2916c10bc6d0059821e19a5b4452c3Matt Sarett return false; 569f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 570f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 57126a0543579cf7473de2099ce0d056ac8aba83811Matt Sarett if (kNone_ColorSpaceMatch == kCSM) { 572f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::matrix_3x4, fSrcToDst); 573f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 574eeb3cb1286c5ca8104da62fb36b07bb0fe04aee5Matt Sarett if (kRGBA_F16_ColorFormat != dstColorFormat && 575eeb3cb1286c5ca8104da62fb36b07bb0fe04aee5Matt Sarett kRGBA_F32_ColorFormat != dstColorFormat) 5768f7a9a9bfb51a00082bde7eb6b04515b935a588fMatt Sarett { 5775e15961fa77281540a80ac0d036fefe071c11574Mike Klein bool need_clamp_0, need_clamp_1; 5785e15961fa77281540a80ac0d036fefe071c11574Mike Klein analyze_3x4_matrix(fSrcToDst, &need_clamp_0, &need_clamp_1); 5795e15961fa77281540a80ac0d036fefe071c11574Mike Klein 5805e15961fa77281540a80ac0d036fefe071c11574Mike Klein if (need_clamp_0) { pipeline.append(SkRasterPipeline::clamp_0); } 5815e15961fa77281540a80ac0d036fefe071c11574Mike Klein if (need_clamp_1) { pipeline.append(SkRasterPipeline::clamp_1); } 5825e15961fa77281540a80ac0d036fefe071c11574Mike Klein } 583f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 584f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 585cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett if (kPremul_SkAlphaType == alphaType && SkTransferFunctionBehavior::kRespect == fPremulBehavior) 586cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett { 587f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::premul); 588f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 589f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 590e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett TablesContext tables; 591a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein float to_2dot2 = 1/2.2f; 592379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett switch (fDstGamma) { 593f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kSRGB_DstGamma: 594f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett pipeline.append(SkRasterPipeline::to_srgb); 595f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 596f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case k2Dot2_DstGamma: 597a07e4302cfefc282d8d235edfbc20a54c75afa88Mike Klein pipeline.append(SkRasterPipeline::gamma, &to_2dot2); 598f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 599e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett case kTable_DstGamma: 600e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett tables.fR = fDstGammaTables[0]; 601e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett tables.fG = fDstGammaTables[1]; 602e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett tables.fB = fDstGammaTables[2]; 603e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett tables.fCount = SkColorSpaceXform_Base::kDstGammaTableSize; 604e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett pipeline.append(SkRasterPipeline::byte_tables_rgb, &tables); 605f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett default: 606f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 607f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 608f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 609cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett if (kPremul_SkAlphaType == alphaType && SkTransferFunctionBehavior::kIgnore == fPremulBehavior) 610cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett { 611e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett pipeline.append(SkRasterPipeline::premul); 612e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett } 613e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett 614f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett switch (dstColorFormat) { 615f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kRGBA_8888_ColorFormat: 61645c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein pipeline.append(SkRasterPipeline::store_8888, &dst_ctx); 617f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 618f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kBGRA_8888_ColorFormat: 61945c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein pipeline.append(SkRasterPipeline::store_bgra, &dst_ctx); 620f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 621f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kRGBA_F16_ColorFormat: 622cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett if (kLinear_DstGamma != fDstGamma) { 623f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett return false; 624f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 62545c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein pipeline.append(SkRasterPipeline::store_f16, &dst_ctx); 626f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 627f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett case kRGBA_F32_ColorFormat: 628cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett if (kLinear_DstGamma != fDstGamma) { 629f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett return false; 630f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 63145c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein pipeline.append(SkRasterPipeline::store_f32, &dst_ctx); 632f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett break; 6333725f0a7dd2916c10bc6d0059821e19a5b4452c3Matt Sarett case kBGR_565_ColorFormat: 6343725f0a7dd2916c10bc6d0059821e19a5b4452c3Matt Sarett if (kOpaque_SkAlphaType != alphaType) { 6353725f0a7dd2916c10bc6d0059821e19a5b4452c3Matt Sarett return false; 6363725f0a7dd2916c10bc6d0059821e19a5b4452c3Matt Sarett } 63745c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein pipeline.append(SkRasterPipeline::store_565, &dst_ctx); 6383725f0a7dd2916c10bc6d0059821e19a5b4452c3Matt Sarett break; 639379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett default: 640379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett return false; 641f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett } 642f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 64345c16fa82cd2fec010d4cb7763b654a413cabd0cMike Klein pipeline.run(0,0, len,1); 644f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett return true; 645f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett} 646f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 647f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett/////////////////////////////////////////////////////////////////////////////////////////////////// 648f6878baba8c7cd347e185361bac2eabaef863bfaMatt Sarett 6499488833428e83c93a7e6002f4d056084fb57112fraftiasstd::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace_XYZ* space) { 650cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ<kNone_ColorSpaceMatch> 651cf3f2347c8933596aeba873d4ece597a9339392fMatt Sarett (space, SkMatrix::I(), space, SkTransferFunctionBehavior::kRespect)); 6529dc6cf6b8833d36c29a23d2519989b069745fcd5msarett} 653