basisu_transcoder.cpp 296 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436
  1. // basisu_transcoder.cpp
  2. // Copyright (C) 2019 Binomial LLC. All Rights Reserved.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. #include "basisu_transcoder.h"
  16. #include <limits.h>
  17. #include <vector>
  18. // The supported .basis file header version. Keep in sync with BASIS_FILE_VERSION.
  19. #define BASISD_SUPPORTED_BASIS_VERSION (0x13)
  20. // Set to 1 for fuzz testing. This will disable all CRC16 checks on headers and compressed data.
  21. #ifndef BASISU_NO_HEADER_OR_DATA_CRC16_CHECKS
  22. #define BASISU_NO_HEADER_OR_DATA_CRC16_CHECKS 0
  23. #endif
  24. #ifndef BASISD_SUPPORT_DXT1
  25. #define BASISD_SUPPORT_DXT1 1
  26. #endif
  27. #ifndef BASISD_SUPPORT_DXT5A
  28. #define BASISD_SUPPORT_DXT5A 1
  29. #endif
  30. // Disable all BC7 transcoders if necessary (useful when cross compiling to Javascript)
  31. #if defined(BASISD_SUPPORT_BC7) && !BASISD_SUPPORT_BC7
  32. #ifndef BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY
  33. #define BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY 0
  34. #endif
  35. #ifndef BASISD_SUPPORT_BC7_MODE5
  36. #define BASISD_SUPPORT_BC7_MODE5 0
  37. #endif
  38. #endif // !BASISD_SUPPORT_BC7
  39. // BC7 mode 6 opaque only is the highest quality (compared to ETC1), but the tables are massive.
  40. // For web/mobile use you probably should disable this.
  41. #ifndef BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY
  42. #define BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY 1
  43. #endif
  44. // BC7 mode 5 supports both opaque and opaque+alpha textures, and uses substantially less memory than BC7 mode 6 and even BC1.
  45. #ifndef BASISD_SUPPORT_BC7_MODE5
  46. #define BASISD_SUPPORT_BC7_MODE5 1
  47. #endif
  48. #ifndef BASISD_SUPPORT_PVRTC1
  49. #define BASISD_SUPPORT_PVRTC1 1
  50. #endif
  51. #ifndef BASISD_SUPPORT_ETC2_EAC_A8
  52. #define BASISD_SUPPORT_ETC2_EAC_A8 1
  53. #endif
  54. #ifndef BASISD_SUPPORT_ASTC
  55. #define BASISD_SUPPORT_ASTC 1
  56. #endif
  57. // Note that if BASISD_SUPPORT_ATC is enabled, BASISD_SUPPORT_DXT5A should also be enabled for alpha support.
  58. #ifndef BASISD_SUPPORT_ATC
  59. #define BASISD_SUPPORT_ATC 1
  60. #endif
  61. // If BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY is 1, opaque blocks will be transcoded to ASTC at slightly higher quality (higher than BC1), but the transcoder tables will be 2x as large.
  62. // This impacts grayscale and grayscale+alpha textures the most.
  63. #ifndef BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY
  64. #ifdef __EMSCRIPTEN__
  65. // Let's assume size matters more than quality when compiling with emscripten.
  66. #define BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY 0
  67. #else
  68. // Compiling native, so an extra 64K lookup table is probably acceptable.
  69. #define BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY 1
  70. #endif
  71. #endif
  72. #define BASISD_WRITE_NEW_BC7_TABLES 0
  73. #define BASISD_WRITE_NEW_BC7_MODE5_TABLES 0
  74. #define BASISD_WRITE_NEW_DXT1_TABLES 0
  75. #define BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES 0
  76. #define BASISD_WRITE_NEW_ASTC_TABLES 0
  77. #define BASISD_WRITE_NEW_ATC_TABLES 0
  78. #ifndef BASISD_ENABLE_DEBUG_FLAGS
  79. #define BASISD_ENABLE_DEBUG_FLAGS 0
  80. #endif
  81. namespace basisu
  82. {
  83. bool g_debug_printf;
  84. void enable_debug_printf(bool enabled)
  85. {
  86. g_debug_printf = enabled;
  87. }
  88. void debug_printf(const char* pFmt, ...)
  89. {
  90. #if BASISU_DEVEL_MESSAGES
  91. g_debug_printf = true;
  92. #endif
  93. if (g_debug_printf)
  94. {
  95. va_list args;
  96. va_start(args, pFmt);
  97. vprintf(pFmt, args);
  98. va_end(args);
  99. }
  100. }
  101. } // namespace basisu
  102. namespace basist
  103. {
  104. #include "basisu_transcoder_tables_bc7_m6.inc"
  105. #if BASISD_ENABLE_DEBUG_FLAGS
  106. static uint32_t g_debug_flags = 0;
  107. #endif
  108. uint32_t get_debug_flags()
  109. {
  110. #if BASISD_ENABLE_DEBUG_FLAGS
  111. return g_debug_flags;
  112. #else
  113. return 0;
  114. #endif
  115. }
  116. void set_debug_flags(uint32_t f)
  117. {
  118. (void)f;
  119. #if BASISD_ENABLE_DEBUG_FLAGS
  120. g_debug_flags = f;
  121. #endif
  122. }
  123. uint16_t crc16(const void* r, size_t size, uint16_t crc)
  124. {
  125. crc = ~crc;
  126. const uint8_t* p = reinterpret_cast<const uint8_t*>(r);
  127. for (; size; --size)
  128. {
  129. const uint16_t q = *p++ ^ (crc >> 8);
  130. uint16_t k = (q >> 4) ^ q;
  131. crc = (((crc << 8) ^ k) ^ (k << 5)) ^ (k << 12);
  132. }
  133. return static_cast<uint16_t>(~crc);
  134. }
  135. const uint32_t g_global_selector_cb[] =
  136. #include "basisu_global_selector_cb.h"
  137. ;
  138. const uint32_t g_global_selector_cb_size = sizeof(g_global_selector_cb) / sizeof(g_global_selector_cb[0]);
  139. void etc1_global_selector_codebook::init(uint32_t N, const uint32_t* pEntries)
  140. {
  141. m_palette.resize(N);
  142. for (uint32_t i = 0; i < N; i++)
  143. m_palette[i].set_uint32(pEntries[i]);
  144. }
  145. void etc1_global_selector_codebook::print_code(FILE* pFile)
  146. {
  147. fprintf(pFile, "{\n");
  148. for (uint32_t i = 0; i < m_palette.size(); i++)
  149. {
  150. fprintf(pFile, "0x%X,", m_palette[i].get_uint32());
  151. if ((i & 15) == 15)
  152. fprintf(pFile, "\n");
  153. }
  154. fprintf(pFile, "\n}\n");
  155. }
  156. enum etc_constants
  157. {
  158. cETC1BytesPerBlock = 8U,
  159. cETC1SelectorBits = 2U,
  160. cETC1SelectorValues = 1U << cETC1SelectorBits,
  161. cETC1SelectorMask = cETC1SelectorValues - 1U,
  162. cETC1BlockShift = 2U,
  163. cETC1BlockSize = 1U << cETC1BlockShift,
  164. cETC1LSBSelectorIndicesBitOffset = 0,
  165. cETC1MSBSelectorIndicesBitOffset = 16,
  166. cETC1FlipBitOffset = 32,
  167. cETC1DiffBitOffset = 33,
  168. cETC1IntenModifierNumBits = 3,
  169. cETC1IntenModifierValues = 1 << cETC1IntenModifierNumBits,
  170. cETC1RightIntenModifierTableBitOffset = 34,
  171. cETC1LeftIntenModifierTableBitOffset = 37,
  172. // Base+Delta encoding (5 bit bases, 3 bit delta)
  173. cETC1BaseColorCompNumBits = 5,
  174. cETC1BaseColorCompMax = 1 << cETC1BaseColorCompNumBits,
  175. cETC1DeltaColorCompNumBits = 3,
  176. cETC1DeltaColorComp = 1 << cETC1DeltaColorCompNumBits,
  177. cETC1DeltaColorCompMax = 1 << cETC1DeltaColorCompNumBits,
  178. cETC1BaseColor5RBitOffset = 59,
  179. cETC1BaseColor5GBitOffset = 51,
  180. cETC1BaseColor5BBitOffset = 43,
  181. cETC1DeltaColor3RBitOffset = 56,
  182. cETC1DeltaColor3GBitOffset = 48,
  183. cETC1DeltaColor3BBitOffset = 40,
  184. // Absolute (non-delta) encoding (two 4-bit per component bases)
  185. cETC1AbsColorCompNumBits = 4,
  186. cETC1AbsColorCompMax = 1 << cETC1AbsColorCompNumBits,
  187. cETC1AbsColor4R1BitOffset = 60,
  188. cETC1AbsColor4G1BitOffset = 52,
  189. cETC1AbsColor4B1BitOffset = 44,
  190. cETC1AbsColor4R2BitOffset = 56,
  191. cETC1AbsColor4G2BitOffset = 48,
  192. cETC1AbsColor4B2BitOffset = 40,
  193. cETC1ColorDeltaMin = -4,
  194. cETC1ColorDeltaMax = 3,
  195. // Delta3:
  196. // 0 1 2 3 4 5 6 7
  197. // 000 001 010 011 100 101 110 111
  198. // 0 1 2 3 -4 -3 -2 -1
  199. };
  200. #define DECLARE_ETC1_INTEN_TABLE(name, N) \
  201. static const int name[cETC1IntenModifierValues][cETC1SelectorValues] = \
  202. { \
  203. { N * -8, N * -2, N * 2, N * 8 },{ N * -17, N * -5, N * 5, N * 17 },{ N * -29, N * -9, N * 9, N * 29 },{ N * -42, N * -13, N * 13, N * 42 }, \
  204. { N * -60, N * -18, N * 18, N * 60 },{ N * -80, N * -24, N * 24, N * 80 },{ N * -106, N * -33, N * 33, N * 106 },{ N * -183, N * -47, N * 47, N * 183 } \
  205. };
  206. DECLARE_ETC1_INTEN_TABLE(g_etc1_inten_tables, 1);
  207. DECLARE_ETC1_INTEN_TABLE(g_etc1_inten_tables16, 16);
  208. DECLARE_ETC1_INTEN_TABLE(g_etc1_inten_tables48, 3 * 16);
  209. static const uint8_t g_etc_5_to_8[32] = { 0, 8, 16, 24, 33, 41, 49, 57, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140, 148, 156, 165, 173, 181, 189, 198, 206, 214, 222, 231, 239, 247, 255 };
  210. struct decoder_etc_block
  211. {
  212. // big endian uint64:
  213. // bit ofs: 56 48 40 32 24 16 8 0
  214. // byte ofs: b0, b1, b2, b3, b4, b5, b6, b7
  215. union
  216. {
  217. uint64_t m_uint64;
  218. uint32_t m_uint32[2];
  219. uint8_t m_bytes[8];
  220. struct
  221. {
  222. signed m_dred2 : 3;
  223. uint32_t m_red1 : 5;
  224. signed m_dgreen2 : 3;
  225. uint32_t m_green1 : 5;
  226. signed m_dblue2 : 3;
  227. uint32_t m_blue1 : 5;
  228. uint32_t m_flip : 1;
  229. uint32_t m_diff : 1;
  230. uint32_t m_cw2 : 3;
  231. uint32_t m_cw1 : 3;
  232. uint32_t m_selectors;
  233. } m_differential;
  234. };
  235. inline void clear()
  236. {
  237. assert(sizeof(*this) == 8);
  238. basisu::clear_obj(*this);
  239. }
  240. inline void set_byte_bits(uint32_t ofs, uint32_t num, uint32_t bits)
  241. {
  242. assert((ofs + num) <= 64U);
  243. assert(num && (num < 32U));
  244. assert((ofs >> 3) == ((ofs + num - 1) >> 3));
  245. assert(bits < (1U << num));
  246. const uint32_t byte_ofs = 7 - (ofs >> 3);
  247. const uint32_t byte_bit_ofs = ofs & 7;
  248. const uint32_t mask = (1 << num) - 1;
  249. m_bytes[byte_ofs] &= ~(mask << byte_bit_ofs);
  250. m_bytes[byte_ofs] |= (bits << byte_bit_ofs);
  251. }
  252. inline void set_flip_bit(bool flip)
  253. {
  254. m_bytes[3] &= ~1;
  255. m_bytes[3] |= static_cast<uint8_t>(flip);
  256. }
  257. inline void set_diff_bit(bool diff)
  258. {
  259. m_bytes[3] &= ~2;
  260. m_bytes[3] |= (static_cast<uint32_t>(diff) << 1);
  261. }
  262. // Sets intensity modifier table (0-7) used by subblock subblock_id (0 or 1)
  263. inline void set_inten_table(uint32_t subblock_id, uint32_t t)
  264. {
  265. assert(subblock_id < 2);
  266. assert(t < 8);
  267. const uint32_t ofs = subblock_id ? 2 : 5;
  268. m_bytes[3] &= ~(7 << ofs);
  269. m_bytes[3] |= (t << ofs);
  270. }
  271. // Selector "val" ranges from 0-3 and is a direct index into g_etc1_inten_tables.
  272. inline void set_selector(uint32_t x, uint32_t y, uint32_t val)
  273. {
  274. assert((x | y | val) < 4);
  275. const uint32_t bit_index = x * 4 + y;
  276. uint8_t* p = &m_bytes[7 - (bit_index >> 3)];
  277. const uint32_t byte_bit_ofs = bit_index & 7;
  278. const uint32_t mask = 1 << byte_bit_ofs;
  279. static const uint8_t s_selector_index_to_etc1[4] = { 3, 2, 0, 1 };
  280. const uint32_t etc1_val = s_selector_index_to_etc1[val];
  281. const uint32_t lsb = etc1_val & 1;
  282. const uint32_t msb = etc1_val >> 1;
  283. p[0] &= ~mask;
  284. p[0] |= (lsb << byte_bit_ofs);
  285. p[-2] &= ~mask;
  286. p[-2] |= (msb << byte_bit_ofs);
  287. }
  288. // Returned encoded selector value ranges from 0-3 (this is NOT a direct index into g_etc1_inten_tables, see get_selector())
  289. inline uint32_t get_raw_selector(uint32_t x, uint32_t y) const
  290. {
  291. assert((x | y) < 4);
  292. const uint32_t bit_index = x * 4 + y;
  293. const uint32_t byte_bit_ofs = bit_index & 7;
  294. const uint8_t* p = &m_bytes[7 - (bit_index >> 3)];
  295. const uint32_t lsb = (p[0] >> byte_bit_ofs) & 1;
  296. const uint32_t msb = (p[-2] >> byte_bit_ofs) & 1;
  297. const uint32_t val = lsb | (msb << 1);
  298. return val;
  299. }
  300. // Returned selector value ranges from 0-3 and is a direct index into g_etc1_inten_tables.
  301. inline uint32_t get_selector(uint32_t x, uint32_t y) const
  302. {
  303. static const uint8_t s_etc1_to_selector_index[cETC1SelectorValues] = { 2, 3, 1, 0 };
  304. return s_etc1_to_selector_index[get_raw_selector(x, y)];
  305. }
  306. inline void set_raw_selector_bits(uint32_t bits)
  307. {
  308. m_bytes[4] = static_cast<uint8_t>(bits);
  309. m_bytes[5] = static_cast<uint8_t>(bits >> 8);
  310. m_bytes[6] = static_cast<uint8_t>(bits >> 16);
  311. m_bytes[7] = static_cast<uint8_t>(bits >> 24);
  312. }
  313. inline bool are_all_selectors_the_same() const
  314. {
  315. uint32_t v = *reinterpret_cast<const uint32_t*>(&m_bytes[4]);
  316. if ((v == 0xFFFFFFFF) || (v == 0xFFFF) || (!v) || (v == 0xFFFF0000))
  317. return true;
  318. return false;
  319. }
  320. inline void set_raw_selector_bits(uint8_t byte0, uint8_t byte1, uint8_t byte2, uint8_t byte3)
  321. {
  322. m_bytes[4] = byte0;
  323. m_bytes[5] = byte1;
  324. m_bytes[6] = byte2;
  325. m_bytes[7] = byte3;
  326. }
  327. inline uint32_t get_raw_selector_bits() const
  328. {
  329. return m_bytes[4] | (m_bytes[5] << 8) | (m_bytes[6] << 16) | (m_bytes[7] << 24);
  330. }
  331. inline void set_base4_color(uint32_t idx, uint16_t c)
  332. {
  333. if (idx)
  334. {
  335. set_byte_bits(cETC1AbsColor4R2BitOffset, 4, (c >> 8) & 15);
  336. set_byte_bits(cETC1AbsColor4G2BitOffset, 4, (c >> 4) & 15);
  337. set_byte_bits(cETC1AbsColor4B2BitOffset, 4, c & 15);
  338. }
  339. else
  340. {
  341. set_byte_bits(cETC1AbsColor4R1BitOffset, 4, (c >> 8) & 15);
  342. set_byte_bits(cETC1AbsColor4G1BitOffset, 4, (c >> 4) & 15);
  343. set_byte_bits(cETC1AbsColor4B1BitOffset, 4, c & 15);
  344. }
  345. }
  346. inline void set_base5_color(uint16_t c)
  347. {
  348. set_byte_bits(cETC1BaseColor5RBitOffset, 5, (c >> 10) & 31);
  349. set_byte_bits(cETC1BaseColor5GBitOffset, 5, (c >> 5) & 31);
  350. set_byte_bits(cETC1BaseColor5BBitOffset, 5, c & 31);
  351. }
  352. void set_delta3_color(uint16_t c)
  353. {
  354. set_byte_bits(cETC1DeltaColor3RBitOffset, 3, (c >> 6) & 7);
  355. set_byte_bits(cETC1DeltaColor3GBitOffset, 3, (c >> 3) & 7);
  356. set_byte_bits(cETC1DeltaColor3BBitOffset, 3, c & 7);
  357. }
  358. void set_block_color4(const color32& c0_unscaled, const color32& c1_unscaled)
  359. {
  360. set_diff_bit(false);
  361. set_base4_color(0, pack_color4(c0_unscaled, false));
  362. set_base4_color(1, pack_color4(c1_unscaled, false));
  363. }
  364. void set_block_color5(const color32& c0_unscaled, const color32& c1_unscaled)
  365. {
  366. set_diff_bit(true);
  367. set_base5_color(pack_color5(c0_unscaled, false));
  368. int dr = c1_unscaled.r - c0_unscaled.r;
  369. int dg = c1_unscaled.g - c0_unscaled.g;
  370. int db = c1_unscaled.b - c0_unscaled.b;
  371. set_delta3_color(pack_delta3(dr, dg, db));
  372. }
  373. bool set_block_color5_check(const color32& c0_unscaled, const color32& c1_unscaled)
  374. {
  375. set_diff_bit(true);
  376. set_base5_color(pack_color5(c0_unscaled, false));
  377. int dr = c1_unscaled.r - c0_unscaled.r;
  378. int dg = c1_unscaled.g - c0_unscaled.g;
  379. int db = c1_unscaled.b - c0_unscaled.b;
  380. if (((dr < cETC1ColorDeltaMin) || (dr > cETC1ColorDeltaMax)) ||
  381. ((dg < cETC1ColorDeltaMin) || (dg > cETC1ColorDeltaMax)) ||
  382. ((db < cETC1ColorDeltaMin) || (db > cETC1ColorDeltaMax)))
  383. return false;
  384. set_delta3_color(pack_delta3(dr, dg, db));
  385. return true;
  386. }
  387. inline uint32_t get_byte_bits(uint32_t ofs, uint32_t num) const
  388. {
  389. assert((ofs + num) <= 64U);
  390. assert(num && (num <= 8U));
  391. assert((ofs >> 3) == ((ofs + num - 1) >> 3));
  392. const uint32_t byte_ofs = 7 - (ofs >> 3);
  393. const uint32_t byte_bit_ofs = ofs & 7;
  394. return (m_bytes[byte_ofs] >> byte_bit_ofs) & ((1 << num) - 1);
  395. }
  396. inline uint16_t get_base5_color() const
  397. {
  398. const uint32_t r = get_byte_bits(cETC1BaseColor5RBitOffset, 5);
  399. const uint32_t g = get_byte_bits(cETC1BaseColor5GBitOffset, 5);
  400. const uint32_t b = get_byte_bits(cETC1BaseColor5BBitOffset, 5);
  401. return static_cast<uint16_t>(b | (g << 5U) | (r << 10U));
  402. }
  403. inline color32 get_base5_color_unscaled() const
  404. {
  405. return color32(m_differential.m_red1, m_differential.m_green1, m_differential.m_blue1, 255);
  406. }
  407. inline uint32_t get_inten_table(uint32_t subblock_id) const
  408. {
  409. assert(subblock_id < 2);
  410. const uint32_t ofs = subblock_id ? 2 : 5;
  411. return (m_bytes[3] >> ofs) & 7;
  412. }
  413. static uint16_t pack_color4(const color32& color, bool scaled, uint32_t bias = 127U)
  414. {
  415. return pack_color4(color.r, color.g, color.b, scaled, bias);
  416. }
  417. static uint16_t pack_color4(uint32_t r, uint32_t g, uint32_t b, bool scaled, uint32_t bias = 127U)
  418. {
  419. if (scaled)
  420. {
  421. r = (r * 15U + bias) / 255U;
  422. g = (g * 15U + bias) / 255U;
  423. b = (b * 15U + bias) / 255U;
  424. }
  425. r = basisu::minimum(r, 15U);
  426. g = basisu::minimum(g, 15U);
  427. b = basisu::minimum(b, 15U);
  428. return static_cast<uint16_t>(b | (g << 4U) | (r << 8U));
  429. }
  430. static uint16_t pack_color5(const color32& color, bool scaled, uint32_t bias = 127U)
  431. {
  432. return pack_color5(color.r, color.g, color.b, scaled, bias);
  433. }
  434. static uint16_t pack_color5(uint32_t r, uint32_t g, uint32_t b, bool scaled, uint32_t bias = 127U)
  435. {
  436. if (scaled)
  437. {
  438. r = (r * 31U + bias) / 255U;
  439. g = (g * 31U + bias) / 255U;
  440. b = (b * 31U + bias) / 255U;
  441. }
  442. r = basisu::minimum(r, 31U);
  443. g = basisu::minimum(g, 31U);
  444. b = basisu::minimum(b, 31U);
  445. return static_cast<uint16_t>(b | (g << 5U) | (r << 10U));
  446. }
  447. uint16_t pack_delta3(const color32& color)
  448. {
  449. return pack_delta3(color.r, color.g, color.b);
  450. }
  451. uint16_t pack_delta3(int r, int g, int b)
  452. {
  453. assert((r >= cETC1ColorDeltaMin) && (r <= cETC1ColorDeltaMax));
  454. assert((g >= cETC1ColorDeltaMin) && (g <= cETC1ColorDeltaMax));
  455. assert((b >= cETC1ColorDeltaMin) && (b <= cETC1ColorDeltaMax));
  456. if (r < 0) r += 8;
  457. if (g < 0) g += 8;
  458. if (b < 0) b += 8;
  459. return static_cast<uint16_t>(b | (g << 3) | (r << 6));
  460. }
  461. static color32 unpack_color5(uint16_t packed_color5, bool scaled, uint32_t alpha = 255)
  462. {
  463. uint32_t b = packed_color5 & 31U;
  464. uint32_t g = (packed_color5 >> 5U) & 31U;
  465. uint32_t r = (packed_color5 >> 10U) & 31U;
  466. if (scaled)
  467. {
  468. b = (b << 3U) | (b >> 2U);
  469. g = (g << 3U) | (g >> 2U);
  470. r = (r << 3U) | (r >> 2U);
  471. }
  472. return color32(r, g, b, alpha);
  473. }
  474. static void unpack_color5(uint32_t& r, uint32_t& g, uint32_t& b, uint16_t packed_color5, bool scaled)
  475. {
  476. color32 c(unpack_color5(packed_color5, scaled, 0));
  477. r = c.r;
  478. g = c.g;
  479. b = c.b;
  480. }
  481. static void get_diff_subblock_colors(color32* pDst, uint16_t packed_color5, uint32_t table_idx)
  482. {
  483. assert(table_idx < cETC1IntenModifierValues);
  484. const int* pInten_modifer_table = &g_etc1_inten_tables[table_idx][0];
  485. uint32_t r, g, b;
  486. unpack_color5(r, g, b, packed_color5, true);
  487. const int ir = static_cast<int>(r), ig = static_cast<int>(g), ib = static_cast<int>(b);
  488. const int y0 = pInten_modifer_table[0];
  489. pDst[0].set(clamp255(ir + y0), clamp255(ig + y0), clamp255(ib + y0), 255);
  490. const int y1 = pInten_modifer_table[1];
  491. pDst[1].set(clamp255(ir + y1), clamp255(ig + y1), clamp255(ib + y1), 255);
  492. const int y2 = pInten_modifer_table[2];
  493. pDst[2].set(clamp255(ir + y2), clamp255(ig + y2), clamp255(ib + y2), 255);
  494. const int y3 = pInten_modifer_table[3];
  495. pDst[3].set(clamp255(ir + y3), clamp255(ig + y3), clamp255(ib + y3), 255);
  496. }
  497. static int clamp255(int x)
  498. {
  499. if (x & 0xFFFFFF00)
  500. {
  501. if (x < 0)
  502. x = 0;
  503. else if (x > 255)
  504. x = 255;
  505. }
  506. return x;
  507. }
  508. static void get_block_colors5(color32* pBlock_colors, const color32& base_color5, uint32_t inten_table)
  509. {
  510. color32 b(base_color5);
  511. b.r = (b.r << 3) | (b.r >> 2);
  512. b.g = (b.g << 3) | (b.g >> 2);
  513. b.b = (b.b << 3) | (b.b >> 2);
  514. const int* pInten_table = g_etc1_inten_tables[inten_table];
  515. pBlock_colors[0].set(clamp255(b.r + pInten_table[0]), clamp255(b.g + pInten_table[0]), clamp255(b.b + pInten_table[0]), 255);
  516. pBlock_colors[1].set(clamp255(b.r + pInten_table[1]), clamp255(b.g + pInten_table[1]), clamp255(b.b + pInten_table[1]), 255);
  517. pBlock_colors[2].set(clamp255(b.r + pInten_table[2]), clamp255(b.g + pInten_table[2]), clamp255(b.b + pInten_table[2]), 255);
  518. pBlock_colors[3].set(clamp255(b.r + pInten_table[3]), clamp255(b.g + pInten_table[3]), clamp255(b.b + pInten_table[3]), 255);
  519. }
  520. static void get_block_color5(const color32& base_color5, uint32_t inten_table, uint32_t index, uint32_t& r, uint32_t &g, uint32_t &b)
  521. {
  522. assert(index < 4);
  523. uint32_t br = (base_color5.r << 3) | (base_color5.r >> 2);
  524. uint32_t bg = (base_color5.g << 3) | (base_color5.g >> 2);
  525. uint32_t bb = (base_color5.b << 3) | (base_color5.b >> 2);
  526. const int* pInten_table = g_etc1_inten_tables[inten_table];
  527. r = clamp255(br + pInten_table[index]);
  528. g = clamp255(bg + pInten_table[index]);
  529. b = clamp255(bb + pInten_table[index]);
  530. }
  531. static void get_block_color5_r(const color32& base_color5, uint32_t inten_table, uint32_t index, uint32_t &r)
  532. {
  533. assert(index < 4);
  534. uint32_t br = (base_color5.r << 3) | (base_color5.r >> 2);
  535. const int* pInten_table = g_etc1_inten_tables[inten_table];
  536. r = clamp255(br + pInten_table[index]);
  537. }
  538. static void get_block_colors5_g(int* pBlock_colors, const color32& base_color5, uint32_t inten_table)
  539. {
  540. const int g = (base_color5.g << 3) | (base_color5.g >> 2);
  541. const int* pInten_table = g_etc1_inten_tables[inten_table];
  542. pBlock_colors[0] = clamp255(g + pInten_table[0]);
  543. pBlock_colors[1] = clamp255(g + pInten_table[1]);
  544. pBlock_colors[2] = clamp255(g + pInten_table[2]);
  545. pBlock_colors[3] = clamp255(g + pInten_table[3]);
  546. }
  547. static void get_block_colors5_bounds(color32* pBlock_colors, const color32& base_color5, uint32_t inten_table, uint32_t l = 0, uint32_t h = 3)
  548. {
  549. color32 b(base_color5);
  550. b.r = (b.r << 3) | (b.r >> 2);
  551. b.g = (b.g << 3) | (b.g >> 2);
  552. b.b = (b.b << 3) | (b.b >> 2);
  553. const int* pInten_table = g_etc1_inten_tables[inten_table];
  554. pBlock_colors[0].set(clamp255(b.r + pInten_table[l]), clamp255(b.g + pInten_table[l]), clamp255(b.b + pInten_table[l]), 255);
  555. pBlock_colors[1].set(clamp255(b.r + pInten_table[h]), clamp255(b.g + pInten_table[h]), clamp255(b.b + pInten_table[h]), 255);
  556. }
  557. static void get_block_colors5_bounds_g(uint32_t* pBlock_colors, const color32& base_color5, uint32_t inten_table, uint32_t l = 0, uint32_t h = 3)
  558. {
  559. color32 b(base_color5);
  560. b.g = (b.g << 3) | (b.g >> 2);
  561. const int* pInten_table = g_etc1_inten_tables[inten_table];
  562. pBlock_colors[0] = clamp255(b.g + pInten_table[l]);
  563. pBlock_colors[1] = clamp255(b.g + pInten_table[h]);
  564. }
  565. };
  566. enum dxt_constants
  567. {
  568. cDXT1SelectorBits = 2U, cDXT1SelectorValues = 1U << cDXT1SelectorBits, cDXT1SelectorMask = cDXT1SelectorValues - 1U,
  569. cDXT5SelectorBits = 3U, cDXT5SelectorValues = 1U << cDXT5SelectorBits, cDXT5SelectorMask = cDXT5SelectorValues - 1U,
  570. };
  571. static const uint8_t g_etc1_x_selector_unpack[4][256] =
  572. {
  573. {
  574. 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
  575. 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
  576. 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
  577. 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
  578. 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
  579. 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
  580. 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
  581. 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
  582. },
  583. {
  584. 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
  585. 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3,
  586. 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
  587. 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3,
  588. 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
  589. 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3,
  590. 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
  591. 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3,
  592. },
  593. {
  594. 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
  595. 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
  596. 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3,
  597. 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3,
  598. 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
  599. 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
  600. 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3,
  601. 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3,
  602. },
  603. {
  604. 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
  605. 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
  606. 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
  607. 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
  608. 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
  609. 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
  610. 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
  611. 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
  612. }
  613. };
  614. struct dxt1_block
  615. {
  616. enum { cTotalEndpointBytes = 2, cTotalSelectorBytes = 4 };
  617. uint8_t m_low_color[cTotalEndpointBytes];
  618. uint8_t m_high_color[cTotalEndpointBytes];
  619. uint8_t m_selectors[cTotalSelectorBytes];
  620. inline void clear() { basisu::clear_obj(*this); }
  621. inline uint32_t get_high_color() const { return m_high_color[0] | (m_high_color[1] << 8U); }
  622. inline uint32_t get_low_color() const { return m_low_color[0] | (m_low_color[1] << 8U); }
  623. inline void set_low_color(uint16_t c) { m_low_color[0] = static_cast<uint8_t>(c & 0xFF); m_low_color[1] = static_cast<uint8_t>((c >> 8) & 0xFF); }
  624. inline void set_high_color(uint16_t c) { m_high_color[0] = static_cast<uint8_t>(c & 0xFF); m_high_color[1] = static_cast<uint8_t>((c >> 8) & 0xFF); }
  625. inline uint32_t get_selector(uint32_t x, uint32_t y) const { assert((x < 4U) && (y < 4U)); return (m_selectors[y] >> (x * cDXT1SelectorBits)) & cDXT1SelectorMask; }
  626. inline void set_selector(uint32_t x, uint32_t y, uint32_t val) { assert((x < 4U) && (y < 4U) && (val < 4U)); m_selectors[y] &= (~(cDXT1SelectorMask << (x * cDXT1SelectorBits))); m_selectors[y] |= (val << (x * cDXT1SelectorBits)); }
  627. static uint16_t pack_color(const color32& color, bool scaled, uint32_t bias = 127U)
  628. {
  629. uint32_t r = color.r, g = color.g, b = color.b;
  630. if (scaled)
  631. {
  632. r = (r * 31U + bias) / 255U;
  633. g = (g * 63U + bias) / 255U;
  634. b = (b * 31U + bias) / 255U;
  635. }
  636. return static_cast<uint16_t>(basisu::minimum(b, 31U) | (basisu::minimum(g, 63U) << 5U) | (basisu::minimum(r, 31U) << 11U));
  637. }
  638. static uint16_t pack_unscaled_color(uint32_t r, uint32_t g, uint32_t b) { return static_cast<uint16_t>(b | (g << 5U) | (r << 11U)); }
  639. };
  640. struct dxt_selector_range
  641. {
  642. uint32_t m_low;
  643. uint32_t m_high;
  644. };
  645. #if BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY
  646. static dxt_selector_range g_etc1_to_bc7_selector_ranges[] =
  647. {
  648. { 0, 0 },
  649. { 1, 1 },
  650. { 2, 2 },
  651. { 3, 3 },
  652. { 0, 3 },
  653. { 1, 3 },
  654. { 0, 2 },
  655. { 1, 2 },
  656. { 2, 3 },
  657. { 0, 1 },
  658. };
  659. const uint32_t NUM_ETC1_TO_BC7_M6_SELECTOR_RANGES = sizeof(g_etc1_to_bc7_selector_ranges) / sizeof(g_etc1_to_bc7_selector_ranges[0]);
  660. static uint32_t g_etc1_to_bc7_m6_selector_range_index[4][4];
  661. static const uint8_t g_etc1_to_bc7_selector_mappings[][4] =
  662. {
  663. #if 1
  664. { 5 * 0, 5 * 0, 5 * 0, 5 * 0 },
  665. { 5 * 0, 5 * 0, 5 * 0, 5 * 1 },
  666. { 5 * 0, 5 * 0, 5 * 0, 5 * 2 },
  667. { 5 * 0, 5 * 0, 5 * 0, 5 * 3 },
  668. { 5 * 0, 5 * 0, 5 * 1, 5 * 1 },
  669. { 5 * 0, 5 * 0, 5 * 1, 5 * 2 },
  670. { 5 * 0, 5 * 0, 5 * 1, 5 * 3 },
  671. { 5 * 0, 5 * 0, 5 * 2, 5 * 2 },
  672. { 5 * 0, 5 * 0, 5 * 2, 5 * 3 },
  673. { 5 * 0, 5 * 0, 5 * 3, 5 * 3 },
  674. { 5 * 0, 5 * 1, 5 * 1, 5 * 1 },
  675. { 5 * 0, 5 * 1, 5 * 1, 5 * 2 },
  676. { 5 * 0, 5 * 1, 5 * 1, 5 * 3 },
  677. { 5 * 0, 5 * 1, 5 * 2, 5 * 2 },
  678. { 5 * 0, 5 * 1, 5 * 2, 5 * 3 },
  679. { 5 * 0, 5 * 1, 5 * 3, 5 * 3 },
  680. { 5 * 0, 5 * 2, 5 * 2, 5 * 2 },
  681. { 5 * 0, 5 * 2, 5 * 2, 5 * 3 },
  682. { 5 * 0, 5 * 2, 5 * 3, 5 * 3 },
  683. { 5 * 0, 5 * 3, 5 * 3, 5 * 3 },
  684. { 5 * 1, 5 * 1, 5 * 1, 5 * 1 },
  685. { 5 * 1, 5 * 1, 5 * 1, 5 * 2 },
  686. { 5 * 1, 5 * 1, 5 * 1, 5 * 3 },
  687. { 5 * 1, 5 * 1, 5 * 2, 5 * 2 },
  688. { 5 * 1, 5 * 1, 5 * 2, 5 * 3 },
  689. { 5 * 1, 5 * 1, 5 * 3, 5 * 3 },
  690. { 5 * 1, 5 * 2, 5 * 2, 5 * 2 },
  691. { 5 * 1, 5 * 2, 5 * 2, 5 * 3 },
  692. { 5 * 1, 5 * 2, 5 * 3, 5 * 3 },
  693. { 5 * 1, 5 * 3, 5 * 3, 5 * 3 },
  694. { 5 * 2, 5 * 2, 5 * 2, 5 * 2 },
  695. { 5 * 2, 5 * 2, 5 * 2, 5 * 3 },
  696. { 5 * 2, 5 * 2, 5 * 3, 5 * 3 },
  697. { 5 * 2, 5 * 3, 5 * 3, 5 * 3 },
  698. { 5 * 3, 5 * 3, 5 * 3, 5 * 3 },
  699. { 0, 1, 2, 3 },
  700. { 0, 0, 1, 1 },
  701. { 0, 0, 0, 1 },
  702. { 0, 2, 4, 6 },
  703. { 0, 3, 6, 9 },
  704. { 0, 4, 8, 12 },
  705. { 0, 4, 9, 15 },
  706. { 0, 6, 11, 15 },
  707. { 1, 2, 3, 4 },
  708. { 1, 3, 5, 7 },
  709. { 1, 8, 8, 14 },
  710. #else
  711. { 5 * 0, 5 * 0, 5 * 1, 5 * 1 },
  712. { 5 * 0, 5 * 0, 5 * 1, 5 * 2 },
  713. { 5 * 0, 5 * 0, 5 * 1, 5 * 3 },
  714. { 5 * 0, 5 * 0, 5 * 2, 5 * 3 },
  715. { 5 * 0, 5 * 1, 5 * 1, 5 * 1 },
  716. { 5 * 0, 5 * 1, 5 * 2, 5 * 2 },
  717. { 5 * 0, 5 * 1, 5 * 2, 5 * 3 },
  718. { 5 * 0, 5 * 2, 5 * 3, 5 * 3 },
  719. { 5 * 1, 5 * 2, 5 * 2, 5 * 2 },
  720. #endif
  721. { 5 * 1, 5 * 2, 5 * 3, 5 * 3 },
  722. { 8, 8, 8, 8 },
  723. };
  724. const uint32_t NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS = sizeof(g_etc1_to_bc7_selector_mappings) / sizeof(g_etc1_to_bc7_selector_mappings[0]);
  725. static uint8_t g_etc1_to_bc7_selector_mappings_inv[NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS][4];
  726. // encoding from LSB to MSB: low8, high8, error16, size is [32*8][NUM_ETC1_TO_BC7_M6_SELECTOR_RANGES][NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS]
  727. extern const uint32_t* g_etc1_to_bc7_m6_table[];
  728. const uint16_t s_bptc_table_aWeight4[16] = { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 };
  729. #if BASISD_WRITE_NEW_BC7_TABLES
  730. static void create_etc1_to_bc7_m6_conversion_table()
  731. {
  732. FILE* pFile = NULL;
  733. pFile = fopen("basisu_decoder_tables_bc7_m6.inc", "w");
  734. for (int inten = 0; inten < 8; inten++)
  735. {
  736. for (uint32_t g = 0; g < 32; g++)
  737. {
  738. color32 block_colors[4];
  739. decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
  740. fprintf(pFile, "static const uint32_t g_etc1_to_bc7_m6_table%u[] = {\n", g + inten * 32);
  741. uint32_t n = 0;
  742. for (uint32_t sr = 0; sr < NUM_ETC1_TO_BC7_M6_SELECTOR_RANGES; sr++)
  743. {
  744. const uint32_t low_selector = g_etc1_to_bc7_selector_ranges[sr].m_low;
  745. const uint32_t high_selector = g_etc1_to_bc7_selector_ranges[sr].m_high;
  746. for (uint32_t m = 0; m < NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS; m++)
  747. {
  748. uint32_t best_lo = 0;
  749. uint32_t best_hi = 0;
  750. uint64_t best_err = UINT64_MAX;
  751. for (uint32_t hi = 0; hi <= 127; hi++)
  752. {
  753. for (uint32_t lo = 0; lo <= 127; lo++)
  754. {
  755. uint32_t bc7_block_colors[16];
  756. bc7_block_colors[0] = lo << 1;
  757. bc7_block_colors[15] = (hi << 1) | 1;
  758. for (uint32_t i = 1; i < 15; i++)
  759. bc7_block_colors[i] = (bc7_block_colors[0] * (64 - s_bptc_table_aWeight4[i]) + bc7_block_colors[15] * s_bptc_table_aWeight4[i] + 32) >> 6;
  760. uint64_t total_err = 0;
  761. for (uint32_t s = low_selector; s <= high_selector; s++)
  762. {
  763. int err = (int)block_colors[s].g - (int)bc7_block_colors[g_etc1_to_bc7_selector_mappings[m][s]];
  764. total_err += err * err;
  765. }
  766. if (total_err < best_err)
  767. {
  768. best_err = total_err;
  769. best_lo = lo;
  770. best_hi = hi;
  771. }
  772. } // lo
  773. } // hi
  774. best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF);
  775. const uint32_t index = (g + inten * 32) * (NUM_ETC1_TO_BC7_M6_SELECTOR_RANGES * NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS) + (sr * NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS) + m;
  776. uint32_t v = best_err | (best_lo << 18) | (best_hi << 25);
  777. fprintf(pFile, "0x%X,", v);
  778. n++;
  779. if ((n & 31) == 31)
  780. fprintf(pFile, "\n");
  781. } // m
  782. } // sr
  783. fprintf(pFile, "};\n");
  784. } // g
  785. } // inten
  786. fprintf(pFile, "const uint32_t *g_etc1_to_bc7_m6_table[] = {\n");
  787. for (uint32_t i = 0; i < 32 * 8; i++)
  788. {
  789. fprintf(pFile, "g_etc1_to_bc7_m6_table%u, ", i);
  790. if ((i & 15) == 15)
  791. fprintf(pFile, "\n");
  792. }
  793. fprintf(pFile, "};\n");
  794. fclose(pFile);
  795. }
  796. #endif
  797. #endif
  798. struct etc1_to_dxt1_56_solution
  799. {
  800. uint8_t m_lo;
  801. uint8_t m_hi;
  802. uint16_t m_err;
  803. };
  804. #if BASISD_SUPPORT_DXT1
  805. static dxt_selector_range g_etc1_to_dxt1_selector_ranges[] =
  806. {
  807. { 0, 3 },
  808. { 1, 3 },
  809. { 0, 2 },
  810. { 1, 2 },
  811. { 2, 3 },
  812. { 0, 1 },
  813. };
  814. const uint32_t NUM_ETC1_TO_DXT1_SELECTOR_RANGES = sizeof(g_etc1_to_dxt1_selector_ranges) / sizeof(g_etc1_to_dxt1_selector_ranges[0]);
  815. static uint32_t g_etc1_to_dxt1_selector_range_index[4][4];
  816. const uint32_t NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS = 10;
  817. static const uint8_t g_etc1_to_dxt1_selector_mappings[NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS][4] =
  818. {
  819. { 0, 0, 1, 1 },
  820. { 0, 0, 1, 2 },
  821. { 0, 0, 1, 3 },
  822. { 0, 0, 2, 3 },
  823. { 0, 1, 1, 1 },
  824. { 0, 1, 2, 2 },
  825. { 0, 1, 2, 3 },
  826. { 0, 2, 3, 3 },
  827. { 1, 2, 2, 2 },
  828. { 1, 2, 3, 3 },
  829. };
  830. static uint8_t g_etc1_to_dxt1_selector_mappings_raw_dxt1_256[NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS][256];
  831. static uint8_t g_etc1_to_dxt1_selector_mappings_raw_dxt1_inv_256[NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS][256];
  832. static const etc1_to_dxt1_56_solution g_etc1_to_dxt_6[32 * 8 * NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS * NUM_ETC1_TO_DXT1_SELECTOR_RANGES] = {
  833. #include "basisu_transcoder_tables_dxt1_6.inc"
  834. };
  835. static const etc1_to_dxt1_56_solution g_etc1_to_dxt_5[32 * 8 * NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS * NUM_ETC1_TO_DXT1_SELECTOR_RANGES] = {
  836. #include "basisu_transcoder_tables_dxt1_5.inc"
  837. };
  838. // First saw the idea for optimal BC1 single-color block encoding using lookup tables in ryg_dxt.
  839. struct bc1_match_entry
  840. {
  841. uint8_t m_hi;
  842. uint8_t m_lo;
  843. };
  844. static bc1_match_entry g_bc1_match5_equals_1[256], g_bc1_match6_equals_1[256]; // selector 1, allow equals hi/lo
  845. static bc1_match_entry g_bc1_match5_equals_0[256], g_bc1_match6_equals_0[256]; // selector 0, allow equals hi/lo
  846. static void prepare_bc1_single_color_table(bc1_match_entry* pTable, const uint8_t* pExpand, int size0, int size1, int sel)
  847. {
  848. for (int i = 0; i < 256; i++)
  849. {
  850. int lowest_e = 256;
  851. for (int lo = 0; lo < size0; lo++)
  852. {
  853. for (int hi = 0; hi < size1; hi++)
  854. {
  855. const int lo_e = pExpand[lo], hi_e = pExpand[hi];
  856. int e;
  857. if (sel == 1)
  858. {
  859. // Selector 1
  860. e = abs(((hi_e * 2 + lo_e) / 3) - i) + ((abs(hi_e - lo_e) >> 5));
  861. }
  862. else
  863. {
  864. assert(sel == 0);
  865. // Selector 0
  866. e = abs(hi_e - i);
  867. }
  868. if (e < lowest_e)
  869. {
  870. pTable[i].m_hi = static_cast<uint8_t>(hi);
  871. pTable[i].m_lo = static_cast<uint8_t>(lo);
  872. lowest_e = e;
  873. }
  874. } // hi
  875. } // lo
  876. }
  877. }
  878. #endif // BASISD_SUPPORT_DXT1
  879. #if BASISD_WRITE_NEW_DXT1_TABLES
  880. static void create_etc1_to_dxt1_5_conversion_table()
  881. {
  882. FILE* pFile = nullptr;
  883. fopen_s(&pFile, "basisu_transcoder_tables_dxt1_5.inc", "w");
  884. uint32_t n = 0;
  885. for (int inten = 0; inten < 8; inten++)
  886. {
  887. for (uint32_t g = 0; g < 32; g++)
  888. {
  889. color32 block_colors[4];
  890. decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
  891. for (uint32_t sr = 0; sr < NUM_ETC1_TO_DXT1_SELECTOR_RANGES; sr++)
  892. {
  893. const uint32_t low_selector = g_etc1_to_dxt1_selector_ranges[sr].m_low;
  894. const uint32_t high_selector = g_etc1_to_dxt1_selector_ranges[sr].m_high;
  895. for (uint32_t m = 0; m < NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS; m++)
  896. {
  897. uint32_t best_lo = 0;
  898. uint32_t best_hi = 0;
  899. uint64_t best_err = UINT64_MAX;
  900. for (uint32_t hi = 0; hi <= 31; hi++)
  901. {
  902. for (uint32_t lo = 0; lo <= 31; lo++)
  903. {
  904. //if (lo == hi) continue;
  905. uint32_t colors[4];
  906. colors[0] = (lo << 3) | (lo >> 2);
  907. colors[3] = (hi << 3) | (hi >> 2);
  908. colors[1] = (colors[0] * 2 + colors[3]) / 3;
  909. colors[2] = (colors[3] * 2 + colors[0]) / 3;
  910. uint64_t total_err = 0;
  911. for (uint32_t s = low_selector; s <= high_selector; s++)
  912. {
  913. int err = block_colors[s].g - colors[g_etc1_to_dxt1_selector_mappings[m][s]];
  914. total_err += err * err;
  915. }
  916. if (total_err < best_err)
  917. {
  918. best_err = total_err;
  919. best_lo = lo;
  920. best_hi = hi;
  921. }
  922. }
  923. }
  924. assert(best_err <= 0xFFFF);
  925. //table[g + inten * 32].m_solutions[sr][m].m_lo = static_cast<uint8_t>(best_lo);
  926. //table[g + inten * 32].m_solutions[sr][m].m_hi = static_cast<uint8_t>(best_hi);
  927. //table[g + inten * 32].m_solutions[sr][m].m_err = static_cast<uint16_t>(best_err);
  928. //assert(best_lo != best_hi);
  929. fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err);
  930. n++;
  931. if ((n & 31) == 31)
  932. fprintf(pFile, "\n");
  933. } // m
  934. } // sr
  935. } // g
  936. } // inten
  937. fclose(pFile);
  938. }
  939. static void create_etc1_to_dxt1_6_conversion_table()
  940. {
  941. FILE* pFile = nullptr;
  942. fopen_s(&pFile, "basisu_transcoder_tables_dxt1_6.inc", "w");
  943. uint32_t n = 0;
  944. for (int inten = 0; inten < 8; inten++)
  945. {
  946. for (uint32_t g = 0; g < 32; g++)
  947. {
  948. color32 block_colors[4];
  949. decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
  950. for (uint32_t sr = 0; sr < NUM_ETC1_TO_DXT1_SELECTOR_RANGES; sr++)
  951. {
  952. const uint32_t low_selector = g_etc1_to_dxt1_selector_ranges[sr].m_low;
  953. const uint32_t high_selector = g_etc1_to_dxt1_selector_ranges[sr].m_high;
  954. for (uint32_t m = 0; m < NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS; m++)
  955. {
  956. uint32_t best_lo = 0;
  957. uint32_t best_hi = 0;
  958. uint64_t best_err = UINT64_MAX;
  959. for (uint32_t hi = 0; hi <= 63; hi++)
  960. {
  961. for (uint32_t lo = 0; lo <= 63; lo++)
  962. {
  963. //if (lo == hi) continue;
  964. uint32_t colors[4];
  965. colors[0] = (lo << 2) | (lo >> 4);
  966. colors[3] = (hi << 2) | (hi >> 4);
  967. colors[1] = (colors[0] * 2 + colors[3]) / 3;
  968. colors[2] = (colors[3] * 2 + colors[0]) / 3;
  969. uint64_t total_err = 0;
  970. for (uint32_t s = low_selector; s <= high_selector; s++)
  971. {
  972. int err = block_colors[s].g - colors[g_etc1_to_dxt1_selector_mappings[m][s]];
  973. total_err += err * err;
  974. }
  975. if (total_err < best_err)
  976. {
  977. best_err = total_err;
  978. best_lo = lo;
  979. best_hi = hi;
  980. }
  981. }
  982. }
  983. assert(best_err <= 0xFFFF);
  984. //table[g + inten * 32].m_solutions[sr][m].m_lo = static_cast<uint8_t>(best_lo);
  985. //table[g + inten * 32].m_solutions[sr][m].m_hi = static_cast<uint8_t>(best_hi);
  986. //table[g + inten * 32].m_solutions[sr][m].m_err = static_cast<uint16_t>(best_err);
  987. //assert(best_lo != best_hi);
  988. fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err);
  989. n++;
  990. if ((n & 31) == 31)
  991. fprintf(pFile, "\n");
  992. } // m
  993. } // sr
  994. } // g
  995. } // inten
  996. fclose(pFile);
  997. }
  998. #endif
  999. #if BASISD_SUPPORT_ETC2_EAC_A8
  1000. enum
  1001. {
  1002. cEAC_A8_BYTES_PER_BLOCK = 8,
  1003. cEAC_A8_SELECTOR_BYTES = 6,
  1004. cEAC_A8_SELECTOR_BITS = 3,
  1005. cEAC_RGBA8_BYTES_PER_BLOCK = 16,
  1006. cEAC_RGBA8_RGB_OFFSET = 8,
  1007. cEAC_RGBA8_A_OFFSET = 0,
  1008. cEAC_A8_MIN_VALUE_SELECTOR = 3,
  1009. cEAC_A8_MAX_VALUE_SELECTOR = 7
  1010. };
  1011. static const int8_t g_eac_a8_modifier_table[16][8] =
  1012. {
  1013. { -3, -6, -9, -15, 2, 5, 8, 14 },
  1014. { -3, -7, -10, -13, 2, 6, 9, 12 },
  1015. { -2, -5, -8, -13, 1, 4, 7, 12 },
  1016. { -2, -4, -6, -13, 1, 3, 5, 12 },
  1017. { -3, -6, -8, -12, 2, 5, 7, 11 },
  1018. { -3, -7, -9, -11, 2, 6, 8, 10 },
  1019. { -4, -7, -8, -11, 3, 6, 7, 10 },
  1020. { -3, -5, -8, -11, 2, 4, 7, 10 },
  1021. { -2, -6, -8, -10, 1, 5, 7, 9 },
  1022. { -2, -5, -8, -10, 1, 4, 7, 9 },
  1023. { -2, -4, -8, -10, 1, 3, 7, 9 },
  1024. { -2, -5, -7, -10, 1, 4, 6, 9 },
  1025. { -3, -4, -7, -10, 2, 3, 6, 9 },
  1026. { -1, -2, -3, -10, 0, 1, 2, 9 }, // entry 13
  1027. { -4, -6, -8, -9, 3, 5, 7, 8 },
  1028. { -3, -5, -7, -9, 2, 4, 6, 8 }
  1029. };
  1030. struct eac_a8_block
  1031. {
  1032. uint16_t m_base : 8;
  1033. uint16_t m_table : 4;
  1034. uint16_t m_multiplier : 4;
  1035. uint8_t m_selectors[6];
  1036. uint32_t get_selector(uint32_t x, uint32_t y) const
  1037. {
  1038. assert((x < 4) && (y < 4));
  1039. const uint32_t ofs = 45 - (y + x * 4) * 3;
  1040. const uint64_t pixels = get_selector_bits();
  1041. return (pixels >> ofs) & 7;
  1042. }
  1043. void set_selector(uint32_t x, uint32_t y, uint32_t s)
  1044. {
  1045. assert((x < 4) && (y < 4) && (s < 8));
  1046. const uint32_t ofs = 45 - (y + x * 4) * 3;
  1047. uint64_t pixels = get_selector_bits();
  1048. pixels &= ~(7ULL << ofs);
  1049. pixels |= (static_cast<uint64_t>(s) << ofs);
  1050. set_selector_bits(pixels);
  1051. }
  1052. uint64_t get_selector_bits() const
  1053. {
  1054. uint64_t pixels = ((uint64_t)m_selectors[0] << 40) | ((uint64_t)m_selectors[1] << 32) |
  1055. ((uint64_t)m_selectors[2] << 24) |
  1056. ((uint64_t)m_selectors[3] << 16) | ((uint64_t)m_selectors[4] << 8) | m_selectors[5];
  1057. return pixels;
  1058. }
  1059. void set_selector_bits(uint64_t pixels)
  1060. {
  1061. m_selectors[0] = (uint8_t)(pixels >> 40);
  1062. m_selectors[1] = (uint8_t)(pixels >> 32);
  1063. m_selectors[2] = (uint8_t)(pixels >> 24);
  1064. m_selectors[3] = (uint8_t)(pixels >> 16);
  1065. m_selectors[4] = (uint8_t)(pixels >> 8);
  1066. m_selectors[5] = (uint8_t)(pixels);
  1067. }
  1068. };
  1069. #if BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES
  1070. struct pack_eac_a8_results
  1071. {
  1072. uint32_t m_base;
  1073. uint32_t m_table;
  1074. uint32_t m_multiplier;
  1075. std::vector<uint8_t> m_selectors;
  1076. std::vector<uint8_t> m_selectors_temp;
  1077. };
  1078. static uint64_t pack_eac_a8_exhaustive(pack_eac_a8_results& results, const uint8_t* pPixels, uint32_t num_pixels)
  1079. {
  1080. results.m_selectors.resize(num_pixels);
  1081. results.m_selectors_temp.resize(num_pixels);
  1082. uint64_t best_err = UINT64_MAX;
  1083. for (uint32_t base_color = 0; base_color < 256; base_color++)
  1084. {
  1085. for (uint32_t multiplier = 1; multiplier < 16; multiplier++)
  1086. {
  1087. for (uint32_t table = 0; table < 16; table++)
  1088. {
  1089. uint64_t total_err = 0;
  1090. for (uint32_t i = 0; i < num_pixels; i++)
  1091. {
  1092. const int a = pPixels[i];
  1093. uint32_t best_s_err = UINT32_MAX;
  1094. uint32_t best_s = 0;
  1095. for (uint32_t s = 0; s < 8; s++)
  1096. {
  1097. int v = (int)multiplier * g_eac_a8_modifier_table[table][s] + (int)base_color;
  1098. if (v < 0)
  1099. v = 0;
  1100. else if (v > 255)
  1101. v = 255;
  1102. uint32_t err = abs(a - v);
  1103. if (err < best_s_err)
  1104. {
  1105. best_s_err = err;
  1106. best_s = s;
  1107. }
  1108. }
  1109. results.m_selectors_temp[i] = static_cast<uint8_t>(best_s);
  1110. total_err += best_s_err * best_s_err;
  1111. if (total_err >= best_err)
  1112. break;
  1113. }
  1114. if (total_err < best_err)
  1115. {
  1116. best_err = total_err;
  1117. results.m_base = base_color;
  1118. results.m_multiplier = multiplier;
  1119. results.m_table = table;
  1120. results.m_selectors.swap(results.m_selectors_temp);
  1121. }
  1122. } // table
  1123. } // multiplier
  1124. } // base_color
  1125. return best_err;
  1126. }
  1127. #endif
  1128. static const dxt_selector_range s_etc2_eac_a8_selector_ranges[] =
  1129. {
  1130. { 0, 3 },
  1131. { 1, 3 },
  1132. { 0, 2 },
  1133. { 1, 2 },
  1134. };
  1135. const uint32_t NUM_ETC2_EAC_A8_SELECTOR_RANGES = sizeof(s_etc2_eac_a8_selector_ranges) / sizeof(s_etc2_eac_a8_selector_ranges[0]);
  1136. struct etc1_g_to_etc2_a8_conversion
  1137. {
  1138. uint8_t m_base;
  1139. uint8_t m_table_mul; // mul*16+table
  1140. uint16_t m_trans; // translates ETC1 selectors to ETC2_EAC_A8
  1141. };
  1142. static
  1143. #if !BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES
  1144. const
  1145. #endif
  1146. etc1_g_to_etc2_a8_conversion s_etc1_g_to_etc2_a8[32 * 8][NUM_ETC2_EAC_A8_SELECTOR_RANGES] =
  1147. {
  1148. { { 0,1,3328 },{ 0,1,3328 },{ 0,1,256 },{ 0,1,256 } },
  1149. { { 0,226,3936 },{ 0,226,3936 },{ 0,81,488 },{ 0,81,488 } },
  1150. { { 6,178,4012 },{ 6,178,4008 },{ 0,146,501 },{ 0,130,496 } },
  1151. { { 14,178,4012 },{ 14,178,4008 },{ 8,146,501 },{ 6,82,496 } },
  1152. { { 23,178,4012 },{ 23,178,4008 },{ 17,146,501 },{ 3,228,496 } },
  1153. { { 31,178,4012 },{ 31,178,4008 },{ 25,146,501 },{ 11,228,496 } },
  1154. { { 39,178,4012 },{ 39,178,4008 },{ 33,146,501 },{ 19,228,496 } },
  1155. { { 47,178,4012 },{ 47,178,4008 },{ 41,146,501 },{ 27,228,496 } },
  1156. { { 56,178,4012 },{ 56,178,4008 },{ 50,146,501 },{ 36,228,496 } },
  1157. { { 64,178,4012 },{ 64,178,4008 },{ 58,146,501 },{ 44,228,496 } },
  1158. { { 72,178,4012 },{ 72,178,4008 },{ 66,146,501 },{ 52,228,496 } },
  1159. { { 80,178,4012 },{ 80,178,4008 },{ 74,146,501 },{ 60,228,496 } },
  1160. { { 89,178,4012 },{ 89,178,4008 },{ 83,146,501 },{ 69,228,496 } },
  1161. { { 97,178,4012 },{ 97,178,4008 },{ 91,146,501 },{ 77,228,496 } },
  1162. { { 105,178,4012 },{ 105,178,4008 },{ 99,146,501 },{ 85,228,496 } },
  1163. { { 113,178,4012 },{ 113,178,4008 },{ 107,146,501 },{ 93,228,496 } },
  1164. { { 122,178,4012 },{ 122,178,4008 },{ 116,146,501 },{ 102,228,496 } },
  1165. { { 130,178,4012 },{ 130,178,4008 },{ 124,146,501 },{ 110,228,496 } },
  1166. { { 138,178,4012 },{ 138,178,4008 },{ 132,146,501 },{ 118,228,496 } },
  1167. { { 146,178,4012 },{ 146,178,4008 },{ 140,146,501 },{ 126,228,496 } },
  1168. { { 155,178,4012 },{ 155,178,4008 },{ 149,146,501 },{ 135,228,496 } },
  1169. { { 163,178,4012 },{ 163,178,4008 },{ 157,146,501 },{ 143,228,496 } },
  1170. { { 171,178,4012 },{ 171,178,4008 },{ 165,146,501 },{ 151,228,496 } },
  1171. { { 179,178,4012 },{ 179,178,4008 },{ 173,146,501 },{ 159,228,496 } },
  1172. { { 188,178,4012 },{ 188,178,4008 },{ 182,146,501 },{ 168,228,496 } },
  1173. { { 196,178,4012 },{ 196,178,4008 },{ 190,146,501 },{ 176,228,496 } },
  1174. { { 204,178,4012 },{ 204,178,4008 },{ 198,146,501 },{ 184,228,496 } },
  1175. { { 212,178,4012 },{ 212,178,4008 },{ 206,146,501 },{ 192,228,496 } },
  1176. { { 221,178,4012 },{ 221,178,4008 },{ 215,146,501 },{ 201,228,496 } },
  1177. { { 229,178,4012 },{ 229,178,4008 },{ 223,146,501 },{ 209,228,496 } },
  1178. { { 235,66,4012 },{ 221,100,4008 },{ 231,146,501 },{ 217,228,496 } },
  1179. { { 211,102,4085 },{ 118,31,4080 },{ 211,102,501 },{ 118,31,496 } },
  1180. { { 1,2,3328 },{ 1,2,3328 },{ 0,1,320 },{ 0,1,320 } },
  1181. { { 7,162,3905 },{ 7,162,3904 },{ 1,17,480 },{ 1,17,480 } },
  1182. { { 15,162,3906 },{ 15,162,3904 },{ 1,117,352 },{ 1,117,352 } },
  1183. { { 23,162,3906 },{ 23,162,3904 },{ 5,34,500 },{ 4,53,424 } },
  1184. { { 32,162,3906 },{ 32,162,3904 },{ 14,34,500 },{ 3,69,424 } },
  1185. { { 40,162,3906 },{ 40,162,3904 },{ 22,34,500 },{ 1,133,496 } },
  1186. { { 48,162,3906 },{ 48,162,3904 },{ 30,34,500 },{ 4,85,496 } },
  1187. { { 56,162,3906 },{ 56,162,3904 },{ 38,34,500 },{ 12,85,496 } },
  1188. { { 65,162,3906 },{ 65,162,3904 },{ 47,34,500 },{ 1,106,424 } },
  1189. { { 73,162,3906 },{ 73,162,3904 },{ 55,34,500 },{ 9,106,424 } },
  1190. { { 81,162,3906 },{ 81,162,3904 },{ 63,34,500 },{ 7,234,496 } },
  1191. { { 89,162,3906 },{ 89,162,3904 },{ 71,34,500 },{ 15,234,496 } },
  1192. { { 98,162,3906 },{ 98,162,3904 },{ 80,34,500 },{ 24,234,496 } },
  1193. { { 106,162,3906 },{ 106,162,3904 },{ 88,34,500 },{ 32,234,496 } },
  1194. { { 114,162,3906 },{ 114,162,3904 },{ 96,34,500 },{ 40,234,496 } },
  1195. { { 122,162,3906 },{ 122,162,3904 },{ 104,34,500 },{ 48,234,496 } },
  1196. { { 131,162,3906 },{ 131,162,3904 },{ 113,34,500 },{ 57,234,496 } },
  1197. { { 139,162,3906 },{ 139,162,3904 },{ 121,34,500 },{ 65,234,496 } },
  1198. { { 147,162,3906 },{ 147,162,3904 },{ 129,34,500 },{ 73,234,496 } },
  1199. { { 155,162,3906 },{ 155,162,3904 },{ 137,34,500 },{ 81,234,496 } },
  1200. { { 164,162,3906 },{ 164,162,3904 },{ 146,34,500 },{ 90,234,496 } },
  1201. { { 172,162,3906 },{ 172,162,3904 },{ 154,34,500 },{ 98,234,496 } },
  1202. { { 180,162,3906 },{ 180,162,3904 },{ 162,34,500 },{ 106,234,496 } },
  1203. { { 188,162,3906 },{ 188,162,3904 },{ 170,34,500 },{ 114,234,496 } },
  1204. { { 197,162,3906 },{ 197,162,3904 },{ 179,34,500 },{ 123,234,496 } },
  1205. { { 205,162,3906 },{ 205,162,3904 },{ 187,34,500 },{ 131,234,496 } },
  1206. { { 213,162,3906 },{ 213,162,3904 },{ 195,34,500 },{ 139,234,496 } },
  1207. { { 221,162,3906 },{ 221,162,3904 },{ 203,34,500 },{ 147,234,496 } },
  1208. { { 230,162,3906 },{ 230,162,3904 },{ 212,34,500 },{ 156,234,496 } },
  1209. { { 238,162,3906 },{ 174,106,4008 },{ 220,34,500 },{ 164,234,496 } },
  1210. { { 240,178,4001 },{ 182,106,4008 },{ 228,34,500 },{ 172,234,496 } },
  1211. { { 166,108,4085 },{ 115,31,4080 },{ 166,108,501 },{ 115,31,496 } },
  1212. { { 1,68,3328 },{ 1,68,3328 },{ 0,17,384 },{ 0,17,384 } },
  1213. { { 1,148,3904 },{ 1,148,3904 },{ 1,2,384 },{ 1,2,384 } },
  1214. { { 21,18,3851 },{ 21,18,3848 },{ 1,50,488 },{ 1,50,488 } },
  1215. { { 27,195,3851 },{ 29,18,3848 },{ 0,67,488 },{ 0,67,488 } },
  1216. { { 34,195,3907 },{ 38,18,3848 },{ 20,66,482 },{ 0,3,496 } },
  1217. { { 42,195,3907 },{ 46,18,3848 },{ 28,66,482 },{ 2,6,424 } },
  1218. { { 50,195,3907 },{ 54,18,3848 },{ 36,66,482 },{ 4,22,424 } },
  1219. { { 58,195,3907 },{ 62,18,3848 },{ 44,66,482 },{ 3,73,424 } },
  1220. { { 67,195,3907 },{ 71,18,3848 },{ 53,66,482 },{ 3,22,496 } },
  1221. { { 75,195,3907 },{ 79,18,3848 },{ 61,66,482 },{ 2,137,496 } },
  1222. { { 83,195,3907 },{ 87,18,3848 },{ 69,66,482 },{ 1,89,496 } },
  1223. { { 91,195,3907 },{ 95,18,3848 },{ 77,66,482 },{ 9,89,496 } },
  1224. { { 100,195,3907 },{ 104,18,3848 },{ 86,66,482 },{ 18,89,496 } },
  1225. { { 108,195,3907 },{ 112,18,3848 },{ 94,66,482 },{ 26,89,496 } },
  1226. { { 116,195,3907 },{ 120,18,3848 },{ 102,66,482 },{ 34,89,496 } },
  1227. { { 124,195,3907 },{ 128,18,3848 },{ 110,66,482 },{ 42,89,496 } },
  1228. { { 133,195,3907 },{ 137,18,3848 },{ 119,66,482 },{ 51,89,496 } },
  1229. { { 141,195,3907 },{ 145,18,3848 },{ 127,66,482 },{ 59,89,496 } },
  1230. { { 149,195,3907 },{ 153,18,3848 },{ 135,66,482 },{ 67,89,496 } },
  1231. { { 157,195,3907 },{ 161,18,3848 },{ 143,66,482 },{ 75,89,496 } },
  1232. { { 166,195,3907 },{ 170,18,3848 },{ 152,66,482 },{ 84,89,496 } },
  1233. { { 174,195,3907 },{ 178,18,3848 },{ 160,66,482 },{ 92,89,496 } },
  1234. { { 182,195,3907 },{ 186,18,3848 },{ 168,66,482 },{ 100,89,496 } },
  1235. { { 190,195,3907 },{ 194,18,3848 },{ 176,66,482 },{ 108,89,496 } },
  1236. { { 199,195,3907 },{ 203,18,3848 },{ 185,66,482 },{ 117,89,496 } },
  1237. { { 207,195,3907 },{ 211,18,3848 },{ 193,66,482 },{ 125,89,496 } },
  1238. { { 215,195,3907 },{ 219,18,3848 },{ 201,66,482 },{ 133,89,496 } },
  1239. { { 223,195,3907 },{ 227,18,3848 },{ 209,66,482 },{ 141,89,496 } },
  1240. { { 231,195,3907 },{ 168,89,4008 },{ 218,66,482 },{ 150,89,496 } },
  1241. { { 236,18,3907 },{ 176,89,4008 },{ 226,66,482 },{ 158,89,496 } },
  1242. { { 158,90,4085 },{ 103,31,4080 },{ 158,90,501 },{ 103,31,496 } },
  1243. { { 166,90,4085 },{ 111,31,4080 },{ 166,90,501 },{ 111,31,496 } },
  1244. { { 0,70,3328 },{ 0,70,3328 },{ 0,45,256 },{ 0,45,256 } },
  1245. { { 0,117,3904 },{ 0,117,3904 },{ 0,35,384 },{ 0,35,384 } },
  1246. { { 13,165,3905 },{ 13,165,3904 },{ 3,221,416 },{ 3,221,416 } },
  1247. { { 21,165,3906 },{ 21,165,3904 },{ 11,221,416 },{ 11,221,416 } },
  1248. { { 30,165,3906 },{ 30,165,3904 },{ 7,61,352 },{ 7,61,352 } },
  1249. { { 38,165,3906 },{ 38,165,3904 },{ 2,125,352 },{ 2,125,352 } },
  1250. { { 46,165,3906 },{ 46,165,3904 },{ 2,37,500 },{ 10,125,352 } },
  1251. { { 54,165,3906 },{ 54,165,3904 },{ 10,37,500 },{ 5,61,424 } },
  1252. { { 63,165,3906 },{ 63,165,3904 },{ 19,37,500 },{ 1,189,424 } },
  1253. { { 4,254,4012 },{ 71,165,3904 },{ 27,37,500 },{ 9,189,424 } },
  1254. { { 12,254,4012 },{ 79,165,3904 },{ 35,37,500 },{ 4,77,424 } },
  1255. { { 20,254,4012 },{ 87,165,3904 },{ 43,37,500 },{ 12,77,424 } },
  1256. { { 29,254,4012 },{ 96,165,3904 },{ 52,37,500 },{ 8,93,424 } },
  1257. { { 37,254,4012 },{ 104,165,3904 },{ 60,37,500 },{ 3,141,496 } },
  1258. { { 45,254,4012 },{ 112,165,3904 },{ 68,37,500 },{ 11,141,496 } },
  1259. { { 53,254,4012 },{ 120,165,3904 },{ 76,37,500 },{ 6,93,496 } },
  1260. { { 62,254,4012 },{ 129,165,3904 },{ 85,37,500 },{ 15,93,496 } },
  1261. { { 70,254,4012 },{ 137,165,3904 },{ 93,37,500 },{ 23,93,496 } },
  1262. { { 78,254,4012 },{ 145,165,3904 },{ 101,37,500 },{ 31,93,496 } },
  1263. { { 86,254,4012 },{ 153,165,3904 },{ 109,37,500 },{ 39,93,496 } },
  1264. { { 95,254,4012 },{ 162,165,3904 },{ 118,37,500 },{ 48,93,496 } },
  1265. { { 103,254,4012 },{ 170,165,3904 },{ 126,37,500 },{ 56,93,496 } },
  1266. { { 111,254,4012 },{ 178,165,3904 },{ 134,37,500 },{ 64,93,496 } },
  1267. { { 119,254,4012 },{ 186,165,3904 },{ 142,37,500 },{ 72,93,496 } },
  1268. { { 128,254,4012 },{ 195,165,3904 },{ 151,37,500 },{ 81,93,496 } },
  1269. { { 136,254,4012 },{ 203,165,3904 },{ 159,37,500 },{ 89,93,496 } },
  1270. { { 212,165,3906 },{ 136,77,4008 },{ 167,37,500 },{ 97,93,496 } },
  1271. { { 220,165,3394 },{ 131,93,4008 },{ 175,37,500 },{ 105,93,496 } },
  1272. { { 214,181,4001 },{ 140,93,4008 },{ 184,37,500 },{ 114,93,496 } },
  1273. { { 222,181,4001 },{ 148,93,4008 },{ 192,37,500 },{ 122,93,496 } },
  1274. { { 114,95,4085 },{ 99,31,4080 },{ 114,95,501 },{ 99,31,496 } },
  1275. { { 122,95,4085 },{ 107,31,4080 },{ 122,95,501 },{ 107,31,496 } },
  1276. { { 0,102,3840 },{ 0,102,3840 },{ 0,18,384 },{ 0,18,384 } },
  1277. { { 5,167,3904 },{ 5,167,3904 },{ 0,13,256 },{ 0,13,256 } },
  1278. { { 4,54,3968 },{ 4,54,3968 },{ 1,67,448 },{ 1,67,448 } },
  1279. { { 30,198,3850 },{ 30,198,3848 },{ 0,3,480 },{ 0,3,480 } },
  1280. { { 39,198,3850 },{ 39,198,3848 },{ 3,52,488 },{ 3,52,488 } },
  1281. { { 47,198,3851 },{ 47,198,3848 },{ 3,4,488 },{ 3,4,488 } },
  1282. { { 55,198,3851 },{ 55,198,3848 },{ 1,70,488 },{ 1,70,488 } },
  1283. { { 54,167,3906 },{ 63,198,3848 },{ 3,22,488 },{ 3,22,488 } },
  1284. { { 62,167,3906 },{ 72,198,3848 },{ 24,118,488 },{ 0,6,496 } },
  1285. { { 70,167,3906 },{ 80,198,3848 },{ 32,118,488 },{ 2,89,488 } },
  1286. { { 78,167,3906 },{ 88,198,3848 },{ 40,118,488 },{ 1,73,496 } },
  1287. { { 86,167,3906 },{ 96,198,3848 },{ 48,118,488 },{ 0,28,424 } },
  1288. { { 95,167,3906 },{ 105,198,3848 },{ 57,118,488 },{ 9,28,424 } },
  1289. { { 103,167,3906 },{ 113,198,3848 },{ 65,118,488 },{ 5,108,496 } },
  1290. { { 111,167,3906 },{ 121,198,3848 },{ 73,118,488 },{ 13,108,496 } },
  1291. { { 119,167,3906 },{ 129,198,3848 },{ 81,118,488 },{ 21,108,496 } },
  1292. { { 128,167,3906 },{ 138,198,3848 },{ 90,118,488 },{ 6,28,496 } },
  1293. { { 136,167,3906 },{ 146,198,3848 },{ 98,118,488 },{ 14,28,496 } },
  1294. { { 144,167,3906 },{ 154,198,3848 },{ 106,118,488 },{ 22,28,496 } },
  1295. { { 152,167,3906 },{ 162,198,3848 },{ 114,118,488 },{ 30,28,496 } },
  1296. { { 161,167,3906 },{ 171,198,3848 },{ 123,118,488 },{ 39,28,496 } },
  1297. { { 169,167,3906 },{ 179,198,3848 },{ 131,118,488 },{ 47,28,496 } },
  1298. { { 177,167,3906 },{ 187,198,3848 },{ 139,118,488 },{ 55,28,496 } },
  1299. { { 185,167,3906 },{ 195,198,3848 },{ 147,118,488 },{ 63,28,496 } },
  1300. { { 194,167,3906 },{ 120,12,4008 },{ 156,118,488 },{ 72,28,496 } },
  1301. { { 206,198,3907 },{ 116,28,4008 },{ 164,118,488 },{ 80,28,496 } },
  1302. { { 214,198,3907 },{ 124,28,4008 },{ 172,118,488 },{ 88,28,496 } },
  1303. { { 222,198,3395 },{ 132,28,4008 },{ 180,118,488 },{ 96,28,496 } },
  1304. { { 207,134,4001 },{ 141,28,4008 },{ 189,118,488 },{ 105,28,496 } },
  1305. { { 95,30,4085 },{ 86,31,4080 },{ 95,30,501 },{ 86,31,496 } },
  1306. { { 103,30,4085 },{ 94,31,4080 },{ 103,30,501 },{ 94,31,496 } },
  1307. { { 111,30,4085 },{ 102,31,4080 },{ 111,30,501 },{ 102,31,496 } },
  1308. { { 0,104,3840 },{ 0,104,3840 },{ 0,18,448 },{ 0,18,448 } },
  1309. { { 4,39,3904 },{ 4,39,3904 },{ 0,4,384 },{ 0,4,384 } },
  1310. { { 0,56,3968 },{ 0,56,3968 },{ 0,84,448 },{ 0,84,448 } },
  1311. { { 6,110,3328 },{ 6,110,3328 },{ 0,20,448 },{ 0,20,448 } },
  1312. { { 41,200,3850 },{ 41,200,3848 },{ 1,4,480 },{ 1,4,480 } },
  1313. { { 49,200,3850 },{ 49,200,3848 },{ 1,8,416 },{ 1,8,416 } },
  1314. { { 57,200,3851 },{ 57,200,3848 },{ 1,38,488 },{ 1,38,488 } },
  1315. { { 65,200,3851 },{ 65,200,3848 },{ 1,120,488 },{ 1,120,488 } },
  1316. { { 74,200,3851 },{ 74,200,3848 },{ 2,72,488 },{ 2,72,488 } },
  1317. { { 69,6,3907 },{ 82,200,3848 },{ 2,24,488 },{ 2,24,488 } },
  1318. { { 77,6,3907 },{ 90,200,3848 },{ 26,120,488 },{ 10,24,488 } },
  1319. { { 97,63,3330 },{ 98,200,3848 },{ 34,120,488 },{ 2,8,496 } },
  1320. { { 106,63,3330 },{ 107,200,3848 },{ 43,120,488 },{ 3,92,488 } },
  1321. { { 114,63,3330 },{ 115,200,3848 },{ 51,120,488 },{ 11,92,488 } },
  1322. { { 122,63,3330 },{ 123,200,3848 },{ 59,120,488 },{ 7,76,496 } },
  1323. { { 130,63,3330 },{ 131,200,3848 },{ 67,120,488 },{ 15,76,496 } },
  1324. { { 139,63,3330 },{ 140,200,3848 },{ 76,120,488 },{ 24,76,496 } },
  1325. { { 147,63,3330 },{ 148,200,3848 },{ 84,120,488 },{ 32,76,496 } },
  1326. { { 155,63,3330 },{ 156,200,3848 },{ 92,120,488 },{ 40,76,496 } },
  1327. { { 163,63,3330 },{ 164,200,3848 },{ 100,120,488 },{ 48,76,496 } },
  1328. { { 172,63,3330 },{ 173,200,3848 },{ 109,120,488 },{ 57,76,496 } },
  1329. { { 184,6,3851 },{ 181,200,3848 },{ 117,120,488 },{ 65,76,496 } },
  1330. { { 192,6,3851 },{ 133,28,3936 },{ 125,120,488 },{ 73,76,496 } },
  1331. { { 189,200,3907 },{ 141,28,3936 },{ 133,120,488 },{ 81,76,496 } },
  1332. { { 198,200,3907 },{ 138,108,4000 },{ 142,120,488 },{ 90,76,496 } },
  1333. { { 206,200,3907 },{ 146,108,4000 },{ 150,120,488 },{ 98,76,496 } },
  1334. { { 214,200,3395 },{ 154,108,4000 },{ 158,120,488 },{ 106,76,496 } },
  1335. { { 190,136,4001 },{ 162,108,4000 },{ 166,120,488 },{ 114,76,496 } },
  1336. { { 123,30,4076 },{ 87,15,4080 },{ 123,30,492 },{ 87,15,496 } },
  1337. { { 117,110,4084 },{ 80,31,4080 },{ 117,110,500 },{ 80,31,496 } },
  1338. { { 125,110,4084 },{ 88,31,4080 },{ 125,110,500 },{ 88,31,496 } },
  1339. { { 133,110,4084 },{ 96,31,4080 },{ 133,110,500 },{ 96,31,496 } },
  1340. { { 9,56,3904 },{ 9,56,3904 },{ 0,67,448 },{ 0,67,448 } },
  1341. { { 1,8,3904 },{ 1,8,3904 },{ 1,84,448 },{ 1,84,448 } },
  1342. { { 1,124,3904 },{ 1,124,3904 },{ 0,39,384 },{ 0,39,384 } },
  1343. { { 9,124,3904 },{ 9,124,3904 },{ 1,4,448 },{ 1,4,448 } },
  1344. { { 6,76,3904 },{ 6,76,3904 },{ 0,70,448 },{ 0,70,448 } },
  1345. { { 62,6,3859 },{ 62,6,3856 },{ 2,38,480 },{ 2,38,480 } },
  1346. { { 70,6,3859 },{ 70,6,3856 },{ 5,43,416 },{ 5,43,416 } },
  1347. { { 78,6,3859 },{ 78,6,3856 },{ 2,11,416 },{ 2,11,416 } },
  1348. { { 87,6,3859 },{ 87,6,3856 },{ 0,171,488 },{ 0,171,488 } },
  1349. { { 67,8,3906 },{ 95,6,3856 },{ 8,171,488 },{ 8,171,488 } },
  1350. { { 75,8,3907 },{ 103,6,3856 },{ 5,123,488 },{ 5,123,488 } },
  1351. { { 83,8,3907 },{ 111,6,3856 },{ 2,75,488 },{ 2,75,488 } },
  1352. { { 92,8,3907 },{ 120,6,3856 },{ 0,27,488 },{ 0,27,488 } },
  1353. { { 100,8,3907 },{ 128,6,3856 },{ 8,27,488 },{ 8,27,488 } },
  1354. { { 120,106,3843 },{ 136,6,3856 },{ 100,6,387 },{ 16,27,488 } },
  1355. { { 128,106,3843 },{ 144,6,3856 },{ 108,6,387 },{ 2,11,496 } },
  1356. { { 137,106,3843 },{ 153,6,3856 },{ 117,6,387 },{ 11,11,496 } },
  1357. { { 145,106,3843 },{ 161,6,3856 },{ 125,6,387 },{ 19,11,496 } },
  1358. { { 163,8,3851 },{ 137,43,3904 },{ 133,6,387 },{ 27,11,496 } },
  1359. { { 171,8,3851 },{ 101,11,4000 },{ 141,6,387 },{ 35,11,496 } },
  1360. { { 180,8,3851 },{ 110,11,4000 },{ 150,6,387 },{ 44,11,496 } },
  1361. { { 188,8,3851 },{ 118,11,4000 },{ 158,6,387 },{ 52,11,496 } },
  1362. { { 172,72,3907 },{ 126,11,4000 },{ 166,6,387 },{ 60,11,496 } },
  1363. { { 174,6,3971 },{ 134,11,4000 },{ 174,6,387 },{ 68,11,496 } },
  1364. { { 183,6,3971 },{ 143,11,4000 },{ 183,6,387 },{ 77,11,496 } },
  1365. { { 191,6,3971 },{ 151,11,4000 },{ 191,6,387 },{ 85,11,496 } },
  1366. { { 199,6,3971 },{ 159,11,4000 },{ 199,6,387 },{ 93,11,496 } },
  1367. { { 92,12,4084 },{ 69,15,4080 },{ 92,12,500 },{ 69,15,496 } },
  1368. { { 101,12,4084 },{ 78,15,4080 },{ 101,12,500 },{ 78,15,496 } },
  1369. { { 109,12,4084 },{ 86,15,4080 },{ 109,12,500 },{ 86,15,496 } },
  1370. { { 117,12,4084 },{ 79,31,4080 },{ 117,12,500 },{ 79,31,496 } },
  1371. { { 125,12,4084 },{ 87,31,4080 },{ 125,12,500 },{ 87,31,496 } },
  1372. { { 71,8,3602 },{ 71,8,3600 },{ 2,21,384 },{ 2,21,384 } },
  1373. { { 79,8,3611 },{ 79,8,3608 },{ 0,69,448 },{ 0,69,448 } },
  1374. { { 87,8,3611 },{ 87,8,3608 },{ 0,23,384 },{ 0,23,384 } },
  1375. { { 95,8,3611 },{ 95,8,3608 },{ 1,5,448 },{ 1,5,448 } },
  1376. { { 104,8,3611 },{ 104,8,3608 },{ 0,88,448 },{ 0,88,448 } },
  1377. { { 112,8,3611 },{ 112,8,3608 },{ 0,72,448 },{ 0,72,448 } },
  1378. { { 120,8,3611 },{ 121,8,3608 },{ 36,21,458 },{ 36,21,456 } },
  1379. { { 133,47,3091 },{ 129,8,3608 },{ 44,21,458 },{ 44,21,456 } },
  1380. { { 142,47,3091 },{ 138,8,3608 },{ 53,21,459 },{ 53,21,456 } },
  1381. { { 98,12,3850 },{ 98,12,3848 },{ 61,21,459 },{ 61,21,456 } },
  1382. { { 106,12,3850 },{ 106,12,3848 },{ 10,92,480 },{ 69,21,456 } },
  1383. { { 114,12,3851 },{ 114,12,3848 },{ 18,92,480 },{ 77,21,456 } },
  1384. { { 87,12,3906 },{ 87,12,3904 },{ 3,44,488 },{ 86,21,456 } },
  1385. { { 95,12,3906 },{ 95,12,3904 },{ 11,44,488 },{ 94,21,456 } },
  1386. { { 103,12,3906 },{ 103,12,3904 },{ 19,44,488 },{ 102,21,456 } },
  1387. { { 111,12,3907 },{ 111,12,3904 },{ 27,44,489 },{ 110,21,456 } },
  1388. { { 120,12,3907 },{ 120,12,3904 },{ 36,44,489 },{ 119,21,456 } },
  1389. { { 128,12,3907 },{ 128,12,3904 },{ 44,44,489 },{ 127,21,456 } },
  1390. { { 136,12,3907 },{ 136,12,3904 },{ 52,44,489 },{ 135,21,456 } },
  1391. { { 144,12,3907 },{ 144,12,3904 },{ 60,44,489 },{ 143,21,456 } },
  1392. { { 153,12,3907 },{ 153,12,3904 },{ 69,44,490 },{ 152,21,456 } },
  1393. { { 161,12,3395 },{ 149,188,3968 },{ 77,44,490 },{ 160,21,456 } },
  1394. { { 169,12,3395 },{ 198,21,3928 },{ 85,44,490 },{ 168,21,456 } },
  1395. { { 113,95,4001 },{ 201,69,3992 },{ 125,8,483 },{ 176,21,456 } },
  1396. { { 122,95,4001 },{ 200,21,3984 },{ 134,8,483 },{ 185,21,456 } },
  1397. { { 142,8,4067 },{ 208,21,3984 },{ 142,8,483 },{ 193,21,456 } },
  1398. { { 151,8,4067 },{ 47,15,4080 },{ 151,8,483 },{ 47,15,496 } },
  1399. { { 159,8,4067 },{ 55,15,4080 },{ 159,8,483 },{ 55,15,496 } },
  1400. { { 168,8,4067 },{ 64,15,4080 },{ 168,8,483 },{ 64,15,496 } },
  1401. { { 160,40,4075 },{ 72,15,4080 },{ 160,40,491 },{ 72,15,496 } },
  1402. { { 168,40,4075 },{ 80,15,4080 },{ 168,40,491 },{ 80,15,496 } },
  1403. { { 144,8,4082 },{ 88,15,4080 },{ 144,8,498 },{ 88,15,496 } }
  1404. };
  1405. #endif
  1406. #if BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES
  1407. static void create_etc2_eac_a8_conversion_table()
  1408. {
  1409. FILE* pFile = fopen("basisu_decoder_tables_etc2_eac_a8.inc", "w");
  1410. for (uint32_t inten = 0; inten < 8; inten++)
  1411. {
  1412. for (uint32_t base = 0; base < 32; base++)
  1413. {
  1414. color32 block_colors[4];
  1415. decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(base, base, base, 255), false), inten);
  1416. fprintf(pFile, "{");
  1417. for (uint32_t sel_range = 0; sel_range < NUM_ETC2_EAC_A8_SELECTOR_RANGES; sel_range++)
  1418. {
  1419. const uint32_t low_selector = s_etc2_eac_a8_selector_ranges[sel_range].m_low;
  1420. const uint32_t high_selector = s_etc2_eac_a8_selector_ranges[sel_range].m_high;
  1421. // We have a ETC1 base color and intensity, and a used selector range from low_selector-high_selector.
  1422. // Now find the best ETC2 EAC A8 base/table/multiplier that fits these colors.
  1423. uint8_t pixels[4];
  1424. uint32_t num_pixels = 0;
  1425. for (uint32_t s = low_selector; s <= high_selector; s++)
  1426. pixels[num_pixels++] = block_colors[s].g;
  1427. pack_eac_a8_results pack_results;
  1428. pack_eac_a8_exhaustive(pack_results, pixels, num_pixels);
  1429. etc1_g_to_etc2_a8_conversion& c = s_etc1_g_to_etc2_a8[base + inten * 32][sel_range];
  1430. c.m_base = pack_results.m_base;
  1431. c.m_table_mul = pack_results.m_table * 16 + pack_results.m_multiplier;
  1432. c.m_trans = 0;
  1433. for (uint32_t s = 0; s < 4; s++)
  1434. {
  1435. if ((s < low_selector) || (s > high_selector))
  1436. continue;
  1437. uint32_t etc2_selector = pack_results.m_selectors[s - low_selector];
  1438. c.m_trans |= (etc2_selector << (s * 3));
  1439. }
  1440. fprintf(pFile, "{%u,%u,%u}", c.m_base, c.m_table_mul, c.m_trans);
  1441. if (sel_range < (NUM_ETC2_EAC_A8_SELECTOR_RANGES - 1))
  1442. fprintf(pFile, ",");
  1443. }
  1444. fprintf(pFile, "},\n");
  1445. }
  1446. }
  1447. fclose(pFile);
  1448. }
  1449. #endif
  1450. #if BASISD_WRITE_NEW_ASTC_TABLES
  1451. static void create_etc1_to_astc_conversion_table_0_47();
  1452. static void create_etc1_to_astc_conversion_table_0_255();
  1453. #endif
  1454. #if BASISD_SUPPORT_ASTC
  1455. static void transcoder_init_astc();
  1456. #endif
  1457. #if BASISD_WRITE_NEW_BC7_MODE5_TABLES
  1458. static void create_etc1_to_bc7_m5_color_conversion_table();
  1459. static void create_etc1_to_bc7_m5_alpha_conversion_table();
  1460. #endif
  1461. #if BASISD_SUPPORT_BC7_MODE5
  1462. static void transcoder_init_bc7_mode5();
  1463. #endif
  1464. #if BASISD_WRITE_NEW_ATC_TABLES
  1465. static void create_etc1s_to_atc_conversion_tables();
  1466. #endif
  1467. #if BASISD_SUPPORT_ATC
  1468. static void transcoder_init_atc();
  1469. #endif
  1470. // Library global initialization. Requires ~9 milliseconds when compiled and executed natively on a Core i7 2.2 GHz.
  1471. // If this is too slow, these computed tables can easilky be moved to be compiled in.
  1472. void basisu_transcoder_init()
  1473. {
  1474. static bool s_initialized;
  1475. if (s_initialized)
  1476. return;
  1477. #if BASISD_SUPPORT_ASTC
  1478. transcoder_init_astc();
  1479. #endif
  1480. #if BASISD_WRITE_NEW_ASTC_TABLES
  1481. create_etc1_to_astc_conversion_table_0_47();
  1482. create_etc1_to_astc_conversion_table_0_255();
  1483. exit(0);
  1484. #endif
  1485. #if BASISD_WRITE_NEW_BC7_TABLES
  1486. create_etc1_to_bc7_m6_conversion_table();
  1487. exit(0);
  1488. #endif
  1489. #if BASISD_WRITE_NEW_BC7_MODE5_TABLES
  1490. create_etc1_to_bc7_m5_color_conversion_table();
  1491. create_etc1_to_bc7_m5_alpha_conversion_table();
  1492. exit(0);
  1493. #endif
  1494. #if BASISD_WRITE_NEW_DXT1_TABLES
  1495. create_etc1_to_dxt1_5_conversion_table();
  1496. create_etc1_to_dxt1_6_conversion_table();
  1497. exit(0);
  1498. #endif
  1499. #if BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES
  1500. create_etc2_eac_a8_conversion_table();
  1501. exit(0);
  1502. #endif
  1503. #if BASISD_WRITE_NEW_ATC_TABLES
  1504. create_etc1s_to_atc_conversion_tables();
  1505. exit(0);
  1506. #endif
  1507. #if BASISD_SUPPORT_DXT1
  1508. uint8_t bc1_expand5[32];
  1509. for (int i = 0; i < 32; i++)
  1510. bc1_expand5[i] = static_cast<uint8_t>((i << 3) | (i >> 2));
  1511. prepare_bc1_single_color_table(g_bc1_match5_equals_1, bc1_expand5, 32, 32, 1);
  1512. prepare_bc1_single_color_table(g_bc1_match5_equals_0, bc1_expand5, 1, 32, 0);
  1513. uint8_t bc1_expand6[64];
  1514. for (int i = 0; i < 64; i++)
  1515. bc1_expand6[i] = static_cast<uint8_t>((i << 2) | (i >> 4));
  1516. prepare_bc1_single_color_table(g_bc1_match6_equals_1, bc1_expand6, 64, 64, 1);
  1517. prepare_bc1_single_color_table(g_bc1_match6_equals_0, bc1_expand6, 1, 64, 0);
  1518. for (uint32_t i = 0; i < NUM_ETC1_TO_DXT1_SELECTOR_RANGES; i++)
  1519. {
  1520. uint32_t l = g_etc1_to_dxt1_selector_ranges[i].m_low;
  1521. uint32_t h = g_etc1_to_dxt1_selector_ranges[i].m_high;
  1522. g_etc1_to_dxt1_selector_range_index[l][h] = i;
  1523. }
  1524. for (uint32_t sm = 0; sm < NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS; sm++)
  1525. {
  1526. uint8_t etc1_to_dxt1_selector_mappings_raw_dxt1[4];
  1527. uint8_t etc1_to_dxt1_selector_mappings_raw_dxt1_inv[4];
  1528. for (uint32_t j = 0; j < 4; j++)
  1529. {
  1530. static const uint8_t s_linear_dxt1_to_dxt1[4] = { 0, 2, 3, 1 };
  1531. static const uint8_t s_dxt1_inverted_xlat[4] = { 1, 0, 3, 2 };
  1532. etc1_to_dxt1_selector_mappings_raw_dxt1[j] = (uint8_t)s_linear_dxt1_to_dxt1[g_etc1_to_dxt1_selector_mappings[sm][j]];
  1533. etc1_to_dxt1_selector_mappings_raw_dxt1_inv[j] = (uint8_t)s_dxt1_inverted_xlat[etc1_to_dxt1_selector_mappings_raw_dxt1[j]];
  1534. }
  1535. for (uint32_t i = 0; i < 256; i++)
  1536. {
  1537. uint32_t k = 0, k_inv = 0;
  1538. for (uint32_t s = 0; s < 4; s++)
  1539. {
  1540. k |= (etc1_to_dxt1_selector_mappings_raw_dxt1[(i >> (s * 2)) & 3] << (s * 2));
  1541. k_inv |= (etc1_to_dxt1_selector_mappings_raw_dxt1_inv[(i >> (s * 2)) & 3] << (s * 2));
  1542. }
  1543. g_etc1_to_dxt1_selector_mappings_raw_dxt1_256[sm][i] = (uint8_t)k;
  1544. g_etc1_to_dxt1_selector_mappings_raw_dxt1_inv_256[sm][i] = (uint8_t)k_inv;
  1545. }
  1546. }
  1547. #endif
  1548. #if BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY
  1549. for (uint32_t i = 0; i < NUM_ETC1_TO_BC7_M6_SELECTOR_RANGES; i++)
  1550. {
  1551. uint32_t l = g_etc1_to_bc7_selector_ranges[i].m_low;
  1552. uint32_t h = g_etc1_to_bc7_selector_ranges[i].m_high;
  1553. g_etc1_to_bc7_m6_selector_range_index[l][h] = i;
  1554. }
  1555. for (uint32_t sm = 0; sm < NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS; sm++)
  1556. for (uint32_t j = 0; j < 4; j++)
  1557. g_etc1_to_bc7_selector_mappings_inv[sm][j] = 15 - g_etc1_to_bc7_selector_mappings[sm][j];
  1558. #endif
  1559. #if BASISD_SUPPORT_BC7_MODE5
  1560. transcoder_init_bc7_mode5();
  1561. #endif
  1562. #if BASISD_SUPPORT_ATC
  1563. transcoder_init_atc();
  1564. #endif
  1565. s_initialized = true;
  1566. }
  1567. #if BASISD_SUPPORT_DXT1
  1568. static void convert_etc1s_to_dxt1(dxt1_block* pDst_block, const endpoint *pEndpoints, const selector* pSelector, bool use_threecolor_blocks)
  1569. {
  1570. #if !BASISD_WRITE_NEW_DXT1_TABLES
  1571. const uint32_t low_selector = pSelector->m_lo_selector;
  1572. const uint32_t high_selector = pSelector->m_hi_selector;
  1573. const color32& base_color = pEndpoints->m_color5;
  1574. const uint32_t inten_table = pEndpoints->m_inten5;
  1575. if (low_selector == high_selector)
  1576. {
  1577. uint32_t r, g, b;
  1578. decoder_etc_block::get_block_color5(base_color, inten_table, low_selector, r, g, b);
  1579. uint32_t mask = 0xAA;
  1580. uint32_t max16 = (g_bc1_match5_equals_1[r].m_hi << 11) | (g_bc1_match6_equals_1[g].m_hi << 5) | g_bc1_match5_equals_1[b].m_hi;
  1581. uint32_t min16 = (g_bc1_match5_equals_1[r].m_lo << 11) | (g_bc1_match6_equals_1[g].m_lo << 5) | g_bc1_match5_equals_1[b].m_lo;
  1582. if ((!use_threecolor_blocks) && (min16 == max16))
  1583. {
  1584. // This is an annoying edge case that impacts BC3.
  1585. // This is to guarantee that BC3 blocks never use punchthrough alpha (3 color) mode, which isn't supported on some (all?) GPU's.
  1586. mask = 0;
  1587. // Make l > h
  1588. if (min16 > 0)
  1589. min16--;
  1590. else
  1591. {
  1592. // l = h = 0
  1593. assert(min16 == max16 && max16 == 0);
  1594. max16 = 1;
  1595. min16 = 0;
  1596. mask = 0x55;
  1597. }
  1598. assert(max16 > min16);
  1599. }
  1600. if (max16 < min16)
  1601. {
  1602. std::swap(max16, min16);
  1603. mask ^= 0x55;
  1604. }
  1605. pDst_block->set_low_color(static_cast<uint16_t>(max16));
  1606. pDst_block->set_high_color(static_cast<uint16_t>(min16));
  1607. pDst_block->m_selectors[0] = static_cast<uint8_t>(mask);
  1608. pDst_block->m_selectors[1] = static_cast<uint8_t>(mask);
  1609. pDst_block->m_selectors[2] = static_cast<uint8_t>(mask);
  1610. pDst_block->m_selectors[3] = static_cast<uint8_t>(mask);
  1611. return;
  1612. }
  1613. else if ((inten_table >= 7) && (pSelector->m_num_unique_selectors == 2) && (pSelector->m_lo_selector == 0) && (pSelector->m_hi_selector == 3))
  1614. {
  1615. color32 block_colors[4];
  1616. decoder_etc_block::get_block_colors5(block_colors, base_color, inten_table);
  1617. const uint32_t r0 = block_colors[0].r;
  1618. const uint32_t g0 = block_colors[0].g;
  1619. const uint32_t b0 = block_colors[0].b;
  1620. const uint32_t r1 = block_colors[3].r;
  1621. const uint32_t g1 = block_colors[3].g;
  1622. const uint32_t b1 = block_colors[3].b;
  1623. uint32_t max16 = (g_bc1_match5_equals_0[r0].m_hi << 11) | (g_bc1_match6_equals_0[g0].m_hi << 5) | g_bc1_match5_equals_0[b0].m_hi;
  1624. uint32_t min16 = (g_bc1_match5_equals_0[r1].m_hi << 11) | (g_bc1_match6_equals_0[g1].m_hi << 5) | g_bc1_match5_equals_0[b1].m_hi;
  1625. uint32_t l = 0, h = 1;
  1626. if (min16 == max16)
  1627. {
  1628. // Make l > h
  1629. if (min16 > 0)
  1630. {
  1631. min16--;
  1632. l = 0;
  1633. h = 0;
  1634. }
  1635. else
  1636. {
  1637. // l = h = 0
  1638. assert(min16 == max16 && max16 == 0);
  1639. max16 = 1;
  1640. min16 = 0;
  1641. l = 1;
  1642. h = 1;
  1643. }
  1644. assert(max16 > min16);
  1645. }
  1646. if (max16 < min16)
  1647. {
  1648. std::swap(max16, min16);
  1649. l = 1;
  1650. h = 0;
  1651. }
  1652. pDst_block->set_low_color((uint16_t)max16);
  1653. pDst_block->set_high_color((uint16_t)min16);
  1654. for (uint32_t y = 0; y < 4; y++)
  1655. {
  1656. for (uint32_t x = 0; x < 4; x++)
  1657. {
  1658. uint32_t s = pSelector->get_selector(x, y);
  1659. pDst_block->set_selector(x, y, (s == 3) ? h : l);
  1660. }
  1661. }
  1662. return;
  1663. }
  1664. const uint32_t selector_range_table = g_etc1_to_dxt1_selector_range_index[low_selector][high_selector];
  1665. //[32][8][RANGES][MAPPING]
  1666. const etc1_to_dxt1_56_solution* pTable_r = &g_etc1_to_dxt_5[(inten_table * 32 + base_color.r) * (NUM_ETC1_TO_DXT1_SELECTOR_RANGES * NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS];
  1667. const etc1_to_dxt1_56_solution* pTable_g = &g_etc1_to_dxt_6[(inten_table * 32 + base_color.g) * (NUM_ETC1_TO_DXT1_SELECTOR_RANGES * NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS];
  1668. const etc1_to_dxt1_56_solution* pTable_b = &g_etc1_to_dxt_5[(inten_table * 32 + base_color.b) * (NUM_ETC1_TO_DXT1_SELECTOR_RANGES * NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS];
  1669. uint32_t best_err = UINT_MAX;
  1670. uint32_t best_mapping = 0;
  1671. assert(NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS == 10);
  1672. #define DO_ITER(m) { uint32_t total_err = pTable_r[m].m_err + pTable_g[m].m_err + pTable_b[m].m_err; if (total_err < best_err) { best_err = total_err; best_mapping = m; } }
  1673. DO_ITER(0); DO_ITER(1); DO_ITER(2); DO_ITER(3); DO_ITER(4);
  1674. DO_ITER(5); DO_ITER(6); DO_ITER(7); DO_ITER(8); DO_ITER(9);
  1675. #undef DO_ITER
  1676. uint32_t l = dxt1_block::pack_unscaled_color(pTable_r[best_mapping].m_lo, pTable_g[best_mapping].m_lo, pTable_b[best_mapping].m_lo);
  1677. uint32_t h = dxt1_block::pack_unscaled_color(pTable_r[best_mapping].m_hi, pTable_g[best_mapping].m_hi, pTable_b[best_mapping].m_hi);
  1678. const uint8_t* pSelectors_xlat_256 = &g_etc1_to_dxt1_selector_mappings_raw_dxt1_256[best_mapping][0];
  1679. if (l < h)
  1680. {
  1681. std::swap(l, h);
  1682. pSelectors_xlat_256 = &g_etc1_to_dxt1_selector_mappings_raw_dxt1_inv_256[best_mapping][0];
  1683. }
  1684. pDst_block->set_low_color(static_cast<uint16_t>(l));
  1685. pDst_block->set_high_color(static_cast<uint16_t>(h));
  1686. if (l == h)
  1687. {
  1688. uint8_t mask = 0;
  1689. if (!use_threecolor_blocks)
  1690. {
  1691. // This is an annoying edge case that impacts BC3.
  1692. // Make l > h
  1693. if (h > 0)
  1694. h--;
  1695. else
  1696. {
  1697. // l = h = 0
  1698. assert(l == h && h == 0);
  1699. h = 0;
  1700. l = 1;
  1701. mask = 0x55;
  1702. }
  1703. assert(l > h);
  1704. pDst_block->set_low_color(static_cast<uint16_t>(l));
  1705. pDst_block->set_high_color(static_cast<uint16_t>(h));
  1706. }
  1707. pDst_block->m_selectors[0] = mask;
  1708. pDst_block->m_selectors[1] = mask;
  1709. pDst_block->m_selectors[2] = mask;
  1710. pDst_block->m_selectors[3] = mask;
  1711. return;
  1712. }
  1713. pDst_block->m_selectors[0] = pSelectors_xlat_256[pSelector->m_selectors[0]];
  1714. pDst_block->m_selectors[1] = pSelectors_xlat_256[pSelector->m_selectors[1]];
  1715. pDst_block->m_selectors[2] = pSelectors_xlat_256[pSelector->m_selectors[2]];
  1716. pDst_block->m_selectors[3] = pSelectors_xlat_256[pSelector->m_selectors[3]];
  1717. #endif
  1718. }
  1719. #if BASISD_ENABLE_DEBUG_FLAGS
  1720. static void convert_etc1s_to_dxt1_vis(dxt1_block* pDst_block, const endpoint* pEndpoints, const selector* pSelector, bool use_threecolor_blocks)
  1721. {
  1722. convert_etc1s_to_dxt1(pDst_block, pEndpoints, pSelector, use_threecolor_blocks);
  1723. if (g_debug_flags & cDebugFlagVisBC1Sels)
  1724. {
  1725. uint32_t l = dxt1_block::pack_unscaled_color(31, 63, 31);
  1726. uint32_t h = dxt1_block::pack_unscaled_color(0, 0, 0);
  1727. pDst_block->set_low_color(static_cast<uint16_t>(l));
  1728. pDst_block->set_high_color(static_cast<uint16_t>(h));
  1729. }
  1730. else if (g_debug_flags & cDebugFlagVisBC1Endpoints)
  1731. {
  1732. for (uint32_t y = 0; y < 4; y++)
  1733. for (uint32_t x = 0; x < 4; x++)
  1734. pDst_block->set_selector(x, y, (y < 2) ? 0 : 1);
  1735. }
  1736. }
  1737. #endif
  1738. #endif
  1739. #if BASISD_SUPPORT_DXT5A
  1740. static dxt_selector_range s_dxt5a_selector_ranges[] =
  1741. {
  1742. { 0, 3 },
  1743. { 1, 3 },
  1744. { 0, 2 },
  1745. { 1, 2 },
  1746. };
  1747. const uint32_t NUM_DXT5A_SELECTOR_RANGES = sizeof(s_dxt5a_selector_ranges) / sizeof(s_dxt5a_selector_ranges[0]);
  1748. struct etc1_g_to_dxt5a_conversion
  1749. {
  1750. uint8_t m_lo, m_hi;
  1751. uint16_t m_trans;
  1752. };
  1753. static etc1_g_to_dxt5a_conversion g_etc1_g_to_dxt5a[32 * 8][NUM_DXT5A_SELECTOR_RANGES] =
  1754. {
  1755. { { 8, 0, 393 },{ 8, 0, 392 },{ 2, 0, 9 },{ 2, 0, 8 }, }, { { 6, 16, 710 },{ 16, 6, 328 },{ 0, 10, 96 },{ 10, 6, 8 }, },
  1756. { { 28, 5, 1327 },{ 24, 14, 328 },{ 8, 18, 96 },{ 18, 14, 8 }, }, { { 36, 13, 1327 },{ 32, 22, 328 },{ 16, 26, 96 },{ 26, 22, 8 }, },
  1757. { { 45, 22, 1327 },{ 41, 31, 328 },{ 25, 35, 96 },{ 35, 31, 8 }, }, { { 53, 30, 1327 },{ 49, 39, 328 },{ 33, 43, 96 },{ 43, 39, 8 }, },
  1758. { { 61, 38, 1327 },{ 57, 47, 328 },{ 41, 51, 96 },{ 51, 47, 8 }, }, { { 69, 46, 1327 },{ 65, 55, 328 },{ 49, 59, 96 },{ 59, 55, 8 }, },
  1759. { { 78, 55, 1327 },{ 74, 64, 328 },{ 58, 68, 96 },{ 68, 64, 8 }, }, { { 86, 63, 1327 },{ 82, 72, 328 },{ 66, 76, 96 },{ 76, 72, 8 }, },
  1760. { { 94, 71, 1327 },{ 90, 80, 328 },{ 74, 84, 96 },{ 84, 80, 8 }, }, { { 102, 79, 1327 },{ 98, 88, 328 },{ 82, 92, 96 },{ 92, 88, 8 }, },
  1761. { { 111, 88, 1327 },{ 107, 97, 328 },{ 91, 101, 96 },{ 101, 97, 8 }, }, { { 119, 96, 1327 },{ 115, 105, 328 },{ 99, 109, 96 },{ 109, 105, 8 }, },
  1762. { { 127, 104, 1327 },{ 123, 113, 328 },{ 107, 117, 96 },{ 117, 113, 8 }, }, { { 135, 112, 1327 },{ 131, 121, 328 },{ 115, 125, 96 },{ 125, 121, 8 }, },
  1763. { { 144, 121, 1327 },{ 140, 130, 328 },{ 124, 134, 96 },{ 134, 130, 8 }, }, { { 152, 129, 1327 },{ 148, 138, 328 },{ 132, 142, 96 },{ 142, 138, 8 }, },
  1764. { { 160, 137, 1327 },{ 156, 146, 328 },{ 140, 150, 96 },{ 150, 146, 8 }, }, { { 168, 145, 1327 },{ 164, 154, 328 },{ 148, 158, 96 },{ 158, 154, 8 }, },
  1765. { { 177, 154, 1327 },{ 173, 163, 328 },{ 157, 167, 96 },{ 167, 163, 8 }, }, { { 185, 162, 1327 },{ 181, 171, 328 },{ 165, 175, 96 },{ 175, 171, 8 }, },
  1766. { { 193, 170, 1327 },{ 189, 179, 328 },{ 173, 183, 96 },{ 183, 179, 8 }, }, { { 201, 178, 1327 },{ 197, 187, 328 },{ 181, 191, 96 },{ 191, 187, 8 }, },
  1767. { { 210, 187, 1327 },{ 206, 196, 328 },{ 190, 200, 96 },{ 200, 196, 8 }, }, { { 218, 195, 1327 },{ 214, 204, 328 },{ 198, 208, 96 },{ 208, 204, 8 }, },
  1768. { { 226, 203, 1327 },{ 222, 212, 328 },{ 206, 216, 96 },{ 216, 212, 8 }, }, { { 234, 211, 1327 },{ 230, 220, 328 },{ 214, 224, 96 },{ 224, 220, 8 }, },
  1769. { { 243, 220, 1327 },{ 239, 229, 328 },{ 223, 233, 96 },{ 233, 229, 8 }, }, { { 251, 228, 1327 },{ 247, 237, 328 },{ 231, 241, 96 },{ 241, 237, 8 }, },
  1770. { { 239, 249, 3680 },{ 245, 249, 3648 },{ 239, 249, 96 },{ 249, 245, 8 }, }, { { 247, 253, 4040 },{ 255, 253, 8 },{ 247, 253, 456 },{ 255, 253, 8 }, },
  1771. { { 5, 17, 566 },{ 5, 17, 560 },{ 5, 0, 9 },{ 5, 0, 8 }, }, { { 25, 0, 313 },{ 25, 3, 328 },{ 13, 0, 49 },{ 13, 3, 8 }, },
  1772. { { 39, 0, 1329 },{ 33, 11, 328 },{ 11, 21, 70 },{ 21, 11, 8 }, }, { { 47, 7, 1329 },{ 41, 19, 328 },{ 29, 7, 33 },{ 29, 19, 8 }, },
  1773. { { 50, 11, 239 },{ 50, 28, 328 },{ 38, 16, 33 },{ 38, 28, 8 }, }, { { 92, 13, 2423 },{ 58, 36, 328 },{ 46, 24, 33 },{ 46, 36, 8 }, },
  1774. { { 100, 21, 2423 },{ 66, 44, 328 },{ 54, 32, 33 },{ 54, 44, 8 }, }, { { 86, 7, 1253 },{ 74, 52, 328 },{ 62, 40, 33 },{ 62, 52, 8 }, },
  1775. { { 95, 16, 1253 },{ 83, 61, 328 },{ 71, 49, 33 },{ 71, 61, 8 }, }, { { 103, 24, 1253 },{ 91, 69, 328 },{ 79, 57, 33 },{ 79, 69, 8 }, },
  1776. { { 111, 32, 1253 },{ 99, 77, 328 },{ 87, 65, 33 },{ 87, 77, 8 }, }, { { 119, 40, 1253 },{ 107, 85, 328 },{ 95, 73, 33 },{ 95, 85, 8 }, },
  1777. { { 128, 49, 1253 },{ 116, 94, 328 },{ 104, 82, 33 },{ 104, 94, 8 }, }, { { 136, 57, 1253 },{ 124, 102, 328 },{ 112, 90, 33 },{ 112, 102, 8 }, },
  1778. { { 144, 65, 1253 },{ 132, 110, 328 },{ 120, 98, 33 },{ 120, 110, 8 }, }, { { 152, 73, 1253 },{ 140, 118, 328 },{ 128, 106, 33 },{ 128, 118, 8 }, },
  1779. { { 161, 82, 1253 },{ 149, 127, 328 },{ 137, 115, 33 },{ 137, 127, 8 }, }, { { 169, 90, 1253 },{ 157, 135, 328 },{ 145, 123, 33 },{ 145, 135, 8 }, },
  1780. { { 177, 98, 1253 },{ 165, 143, 328 },{ 153, 131, 33 },{ 153, 143, 8 }, }, { { 185, 106, 1253 },{ 173, 151, 328 },{ 161, 139, 33 },{ 161, 151, 8 }, },
  1781. { { 194, 115, 1253 },{ 182, 160, 328 },{ 170, 148, 33 },{ 170, 160, 8 }, }, { { 202, 123, 1253 },{ 190, 168, 328 },{ 178, 156, 33 },{ 178, 168, 8 }, },
  1782. { { 210, 131, 1253 },{ 198, 176, 328 },{ 186, 164, 33 },{ 186, 176, 8 }, }, { { 218, 139, 1253 },{ 206, 184, 328 },{ 194, 172, 33 },{ 194, 184, 8 }, },
  1783. { { 227, 148, 1253 },{ 215, 193, 328 },{ 203, 181, 33 },{ 203, 193, 8 }, }, { { 235, 156, 1253 },{ 223, 201, 328 },{ 211, 189, 33 },{ 211, 201, 8 }, },
  1784. { { 243, 164, 1253 },{ 231, 209, 328 },{ 219, 197, 33 },{ 219, 209, 8 }, }, { { 183, 239, 867 },{ 239, 217, 328 },{ 227, 205, 33 },{ 227, 217, 8 }, },
  1785. { { 254, 214, 1329 },{ 248, 226, 328 },{ 236, 214, 33 },{ 236, 226, 8 }, }, { { 222, 244, 3680 },{ 234, 244, 3648 },{ 244, 222, 33 },{ 244, 234, 8 }, },
  1786. { { 230, 252, 3680 },{ 242, 252, 3648 },{ 252, 230, 33 },{ 252, 242, 8 }, }, { { 238, 250, 4040 },{ 255, 250, 8 },{ 238, 250, 456 },{ 255, 250, 8 }, },
  1787. { { 9, 29, 566 },{ 9, 29, 560 },{ 9, 0, 9 },{ 9, 0, 8 }, }, { { 17, 37, 566 },{ 17, 37, 560 },{ 17, 0, 9 },{ 17, 0, 8 }, },
  1788. { { 45, 0, 313 },{ 45, 0, 312 },{ 25, 0, 49 },{ 25, 7, 8 }, }, { { 14, 63, 2758 },{ 5, 53, 784 },{ 15, 33, 70 },{ 33, 15, 8 }, },
  1789. { { 71, 6, 1329 },{ 72, 4, 1328 },{ 42, 4, 33 },{ 42, 24, 8 }, }, { { 70, 3, 239 },{ 70, 2, 232 },{ 50, 12, 33 },{ 50, 32, 8 }, },
  1790. { { 0, 98, 2842 },{ 78, 10, 232 },{ 58, 20, 33 },{ 58, 40, 8 }, }, { { 97, 27, 1329 },{ 86, 18, 232 },{ 66, 28, 33 },{ 66, 48, 8 }, },
  1791. { { 0, 94, 867 },{ 95, 27, 232 },{ 75, 37, 33 },{ 75, 57, 8 }, }, { { 8, 102, 867 },{ 103, 35, 232 },{ 83, 45, 33 },{ 83, 65, 8 }, },
  1792. { { 12, 112, 867 },{ 111, 43, 232 },{ 91, 53, 33 },{ 91, 73, 8 }, }, { { 139, 2, 1253 },{ 119, 51, 232 },{ 99, 61, 33 },{ 99, 81, 8 }, },
  1793. { { 148, 13, 1253 },{ 128, 60, 232 },{ 108, 70, 33 },{ 108, 90, 8 }, }, { { 156, 21, 1253 },{ 136, 68, 232 },{ 116, 78, 33 },{ 116, 98, 8 }, },
  1794. { { 164, 29, 1253 },{ 144, 76, 232 },{ 124, 86, 33 },{ 124, 106, 8 }, }, { { 172, 37, 1253 },{ 152, 84, 232 },{ 132, 94, 33 },{ 132, 114, 8 }, },
  1795. { { 181, 46, 1253 },{ 161, 93, 232 },{ 141, 103, 33 },{ 141, 123, 8 }, }, { { 189, 54, 1253 },{ 169, 101, 232 },{ 149, 111, 33 },{ 149, 131, 8 }, },
  1796. { { 197, 62, 1253 },{ 177, 109, 232 },{ 157, 119, 33 },{ 157, 139, 8 }, }, { { 205, 70, 1253 },{ 185, 117, 232 },{ 165, 127, 33 },{ 165, 147, 8 }, },
  1797. { { 214, 79, 1253 },{ 194, 126, 232 },{ 174, 136, 33 },{ 174, 156, 8 }, }, { { 222, 87, 1253 },{ 202, 134, 232 },{ 182, 144, 33 },{ 182, 164, 8 }, },
  1798. { { 230, 95, 1253 },{ 210, 142, 232 },{ 190, 152, 33 },{ 190, 172, 8 }, }, { { 238, 103, 1253 },{ 218, 150, 232 },{ 198, 160, 33 },{ 198, 180, 8 }, },
  1799. { { 247, 112, 1253 },{ 227, 159, 232 },{ 207, 169, 33 },{ 207, 189, 8 }, }, { { 255, 120, 1253 },{ 235, 167, 232 },{ 215, 177, 33 },{ 215, 197, 8 }, },
  1800. { { 146, 243, 867 },{ 243, 175, 232 },{ 223, 185, 33 },{ 223, 205, 8 }, }, { { 184, 231, 3682 },{ 203, 251, 784 },{ 231, 193, 33 },{ 231, 213, 8 }, },
  1801. { { 193, 240, 3682 },{ 222, 240, 3648 },{ 240, 202, 33 },{ 240, 222, 8 }, }, { { 255, 210, 169 },{ 230, 248, 3648 },{ 248, 210, 33 },{ 248, 230, 8 }, },
  1802. { { 218, 238, 4040 },{ 255, 238, 8 },{ 218, 238, 456 },{ 255, 238, 8 }, }, { { 226, 246, 4040 },{ 255, 246, 8 },{ 226, 246, 456 },{ 255, 246, 8 }, },
  1803. { { 13, 42, 566 },{ 13, 42, 560 },{ 13, 0, 9 },{ 13, 0, 8 }, }, { { 50, 0, 329 },{ 50, 0, 328 },{ 21, 0, 9 },{ 21, 0, 8 }, },
  1804. { { 29, 58, 566 },{ 67, 2, 1352 },{ 3, 29, 70 },{ 29, 3, 8 }, }, { { 10, 79, 2758 },{ 76, 11, 1352 },{ 11, 37, 70 },{ 37, 11, 8 }, },
  1805. { { 7, 75, 790 },{ 7, 75, 784 },{ 20, 46, 70 },{ 46, 20, 8 }, }, { { 15, 83, 790 },{ 97, 1, 1328 },{ 28, 54, 70 },{ 54, 28, 8 }, },
  1806. { { 101, 7, 1329 },{ 105, 9, 1328 },{ 62, 0, 39 },{ 62, 36, 8 }, }, { { 99, 1, 239 },{ 99, 3, 232 },{ 1, 71, 98 },{ 70, 44, 8 }, },
  1807. { { 107, 11, 239 },{ 108, 12, 232 },{ 10, 80, 98 },{ 79, 53, 8 }, }, { { 115, 19, 239 },{ 116, 20, 232 },{ 18, 88, 98 },{ 87, 61, 8 }, },
  1808. { { 123, 27, 239 },{ 124, 28, 232 },{ 26, 96, 98 },{ 95, 69, 8 }, }, { { 131, 35, 239 },{ 132, 36, 232 },{ 34, 104, 98 },{ 103, 77, 8 }, },
  1809. { { 140, 44, 239 },{ 141, 45, 232 },{ 43, 113, 98 },{ 112, 86, 8 }, }, { { 148, 52, 239 },{ 149, 53, 232 },{ 51, 121, 98 },{ 120, 94, 8 }, },
  1810. { { 156, 60, 239 },{ 157, 61, 232 },{ 59, 129, 98 },{ 128, 102, 8 }, }, { { 164, 68, 239 },{ 165, 69, 232 },{ 67, 137, 98 },{ 136, 110, 8 }, },
  1811. { { 173, 77, 239 },{ 174, 78, 232 },{ 76, 146, 98 },{ 145, 119, 8 }, }, { { 181, 85, 239 },{ 182, 86, 232 },{ 84, 154, 98 },{ 153, 127, 8 }, },
  1812. { { 189, 93, 239 },{ 190, 94, 232 },{ 92, 162, 98 },{ 161, 135, 8 }, }, { { 197, 101, 239 },{ 198, 102, 232 },{ 100, 170, 98 },{ 169, 143, 8 }, },
  1813. { { 206, 110, 239 },{ 207, 111, 232 },{ 109, 179, 98 },{ 178, 152, 8 }, }, { { 214, 118, 239 },{ 215, 119, 232 },{ 117, 187, 98 },{ 186, 160, 8 }, },
  1814. { { 222, 126, 239 },{ 223, 127, 232 },{ 125, 195, 98 },{ 194, 168, 8 }, }, { { 230, 134, 239 },{ 231, 135, 232 },{ 133, 203, 98 },{ 202, 176, 8 }, },
  1815. { { 239, 143, 239 },{ 240, 144, 232 },{ 142, 212, 98 },{ 211, 185, 8 }, }, { { 247, 151, 239 },{ 180, 248, 784 },{ 150, 220, 98 },{ 219, 193, 8 }, },
  1816. { { 159, 228, 3682 },{ 201, 227, 3648 },{ 158, 228, 98 },{ 227, 201, 8 }, }, { { 181, 249, 3928 },{ 209, 235, 3648 },{ 166, 236, 98 },{ 235, 209, 8 }, },
  1817. { { 255, 189, 169 },{ 218, 244, 3648 },{ 175, 245, 98 },{ 244, 218, 8 }, }, { { 197, 226, 4040 },{ 226, 252, 3648 },{ 183, 253, 98 },{ 252, 226, 8 }, },
  1818. { { 205, 234, 4040 },{ 255, 234, 8 },{ 205, 234, 456 },{ 255, 234, 8 }, }, { { 213, 242, 4040 },{ 255, 242, 8 },{ 213, 242, 456 },{ 255, 242, 8 }, },
  1819. { { 18, 60, 566 },{ 18, 60, 560 },{ 18, 0, 9 },{ 18, 0, 8 }, }, { { 26, 68, 566 },{ 26, 68, 560 },{ 26, 0, 9 },{ 26, 0, 8 }, },
  1820. { { 34, 76, 566 },{ 34, 76, 560 },{ 34, 0, 9 },{ 34, 0, 8 }, }, { { 5, 104, 2758 },{ 98, 5, 1352 },{ 42, 0, 57 },{ 42, 6, 8 }, },
  1821. { { 92, 0, 313 },{ 93, 1, 312 },{ 15, 51, 70 },{ 51, 15, 8 }, }, { { 3, 101, 790 },{ 3, 101, 784 },{ 0, 59, 88 },{ 59, 23, 8 }, },
  1822. { { 14, 107, 790 },{ 11, 109, 784 },{ 31, 67, 70 },{ 67, 31, 8 }, }, { { 19, 117, 790 },{ 19, 117, 784 },{ 39, 75, 70 },{ 75, 39, 8 }, },
  1823. { { 28, 126, 790 },{ 28, 126, 784 },{ 83, 5, 33 },{ 84, 48, 8 }, }, { { 132, 0, 239 },{ 36, 134, 784 },{ 91, 13, 33 },{ 92, 56, 8 }, },
  1824. { { 142, 4, 239 },{ 44, 142, 784 },{ 99, 21, 33 },{ 100, 64, 8 }, }, { { 150, 12, 239 },{ 52, 150, 784 },{ 107, 29, 33 },{ 108, 72, 8 }, },
  1825. { { 159, 21, 239 },{ 61, 159, 784 },{ 116, 38, 33 },{ 117, 81, 8 }, }, { { 167, 29, 239 },{ 69, 167, 784 },{ 124, 46, 33 },{ 125, 89, 8 }, },
  1826. { { 175, 37, 239 },{ 77, 175, 784 },{ 132, 54, 33 },{ 133, 97, 8 }, }, { { 183, 45, 239 },{ 85, 183, 784 },{ 140, 62, 33 },{ 141, 105, 8 }, },
  1827. { { 192, 54, 239 },{ 94, 192, 784 },{ 149, 71, 33 },{ 150, 114, 8 }, }, { { 200, 62, 239 },{ 102, 200, 784 },{ 157, 79, 33 },{ 158, 122, 8 }, },
  1828. { { 208, 70, 239 },{ 110, 208, 784 },{ 165, 87, 33 },{ 166, 130, 8 }, }, { { 216, 78, 239 },{ 118, 216, 784 },{ 173, 95, 33 },{ 174, 138, 8 }, },
  1829. { { 225, 87, 239 },{ 127, 225, 784 },{ 182, 104, 33 },{ 183, 147, 8 }, }, { { 233, 95, 239 },{ 135, 233, 784 },{ 190, 112, 33 },{ 191, 155, 8 }, },
  1830. { { 241, 103, 239 },{ 143, 241, 784 },{ 198, 120, 33 },{ 199, 163, 8 }, }, { { 111, 208, 3682 },{ 151, 249, 784 },{ 206, 128, 33 },{ 207, 171, 8 }, },
  1831. { { 120, 217, 3682 },{ 180, 216, 3648 },{ 215, 137, 33 },{ 216, 180, 8 }, }, { { 128, 225, 3682 },{ 188, 224, 3648 },{ 223, 145, 33 },{ 224, 188, 8 }, },
  1832. { { 155, 253, 3928 },{ 196, 232, 3648 },{ 231, 153, 33 },{ 232, 196, 8 }, }, { { 144, 241, 3682 },{ 204, 240, 3648 },{ 239, 161, 33 },{ 240, 204, 8 }, },
  1833. { { 153, 250, 3682 },{ 213, 249, 3648 },{ 248, 170, 33 },{ 249, 213, 8 }, }, { { 179, 221, 4040 },{ 255, 221, 8 },{ 179, 221, 456 },{ 255, 221, 8 }, },
  1834. { { 187, 229, 4040 },{ 255, 229, 8 },{ 187, 229, 456 },{ 255, 229, 8 }, }, { { 195, 237, 4040 },{ 255, 237, 8 },{ 195, 237, 456 },{ 255, 237, 8 }, },
  1835. { { 24, 80, 566 },{ 24, 80, 560 },{ 24, 0, 9 },{ 24, 0, 8 }, }, { { 32, 88, 566 },{ 32, 88, 560 },{ 32, 0, 9 },{ 32, 0, 8 }, },
  1836. { { 40, 96, 566 },{ 40, 96, 560 },{ 40, 0, 9 },{ 40, 0, 8 }, }, { { 48, 104, 566 },{ 48, 104, 560 },{ 48, 0, 9 },{ 48, 0, 8 }, },
  1837. { { 9, 138, 2758 },{ 130, 7, 1352 },{ 9, 57, 70 },{ 57, 9, 8 }, }, { { 119, 0, 313 },{ 120, 0, 312 },{ 17, 65, 70 },{ 65, 17, 8 }, },
  1838. { { 0, 128, 784 },{ 128, 6, 312 },{ 25, 73, 70 },{ 73, 25, 8 }, }, { { 6, 137, 790 },{ 5, 136, 784 },{ 33, 81, 70 },{ 81, 33, 8 }, },
  1839. { { 42, 171, 2758 },{ 14, 145, 784 },{ 42, 90, 70 },{ 90, 42, 8 }, }, { { 50, 179, 2758 },{ 22, 153, 784 },{ 50, 98, 70 },{ 98, 50, 8 }, },
  1840. { { 58, 187, 2758 },{ 30, 161, 784 },{ 58, 106, 70 },{ 106, 58, 8 }, }, { { 191, 18, 1329 },{ 38, 169, 784 },{ 112, 9, 33 },{ 114, 66, 8 }, },
  1841. { { 176, 0, 239 },{ 47, 178, 784 },{ 121, 18, 33 },{ 123, 75, 8 }, }, { { 187, 1, 239 },{ 55, 186, 784 },{ 129, 26, 33 },{ 131, 83, 8 }, },
  1842. { { 195, 10, 239 },{ 63, 194, 784 },{ 137, 34, 33 },{ 139, 91, 8 }, }, { { 203, 18, 239 },{ 71, 202, 784 },{ 145, 42, 33 },{ 147, 99, 8 }, },
  1843. { { 212, 27, 239 },{ 80, 211, 784 },{ 154, 51, 33 },{ 156, 108, 8 }, }, { { 220, 35, 239 },{ 88, 219, 784 },{ 162, 59, 33 },{ 164, 116, 8 }, },
  1844. { { 228, 43, 239 },{ 96, 227, 784 },{ 170, 67, 33 },{ 172, 124, 8 }, }, { { 236, 51, 239 },{ 104, 235, 784 },{ 178, 75, 33 },{ 180, 132, 8 }, },
  1845. { { 245, 60, 239 },{ 113, 244, 784 },{ 187, 84, 33 },{ 189, 141, 8 }, }, { { 91, 194, 3680 },{ 149, 197, 3648 },{ 195, 92, 33 },{ 197, 149, 8 }, },
  1846. { { 99, 202, 3680 },{ 157, 205, 3648 },{ 203, 100, 33 },{ 205, 157, 8 }, }, { { 107, 210, 3680 },{ 165, 213, 3648 },{ 211, 108, 33 },{ 213, 165, 8 }, },
  1847. { { 119, 249, 3928 },{ 174, 222, 3648 },{ 220, 117, 33 },{ 222, 174, 8 }, }, { { 127, 255, 856 },{ 182, 230, 3648 },{ 228, 125, 33 },{ 230, 182, 8 }, },
  1848. { { 255, 135, 169 },{ 190, 238, 3648 },{ 236, 133, 33 },{ 238, 190, 8 }, }, { { 140, 243, 3680 },{ 198, 246, 3648 },{ 244, 141, 33 },{ 246, 198, 8 }, },
  1849. { { 151, 207, 4040 },{ 255, 207, 8 },{ 151, 207, 456 },{ 255, 207, 8 }, }, { { 159, 215, 4040 },{ 255, 215, 8 },{ 159, 215, 456 },{ 255, 215, 8 }, },
  1850. { { 167, 223, 4040 },{ 255, 223, 8 },{ 167, 223, 456 },{ 255, 223, 8 }, }, { { 175, 231, 4040 },{ 255, 231, 8 },{ 175, 231, 456 },{ 255, 231, 8 }, },
  1851. { { 33, 106, 566 },{ 33, 106, 560 },{ 33, 0, 9 },{ 33, 0, 8 }, }, { { 41, 114, 566 },{ 41, 114, 560 },{ 41, 0, 9 },{ 41, 0, 8 }, },
  1852. { { 49, 122, 566 },{ 49, 122, 560 },{ 49, 0, 9 },{ 49, 0, 8 }, }, { { 57, 130, 566 },{ 57, 130, 560 },{ 57, 0, 9 },{ 57, 0, 8 }, },
  1853. { { 66, 139, 566 },{ 66, 139, 560 },{ 66, 0, 9 },{ 66, 0, 8 }, }, { { 74, 147, 566 },{ 170, 7, 1352 },{ 8, 74, 70 },{ 74, 8, 8 }, },
  1854. { { 152, 0, 313 },{ 178, 15, 1352 },{ 0, 82, 80 },{ 82, 16, 8 }, }, { { 162, 0, 313 },{ 186, 23, 1352 },{ 24, 90, 70 },{ 90, 24, 8 }, },
  1855. { { 0, 171, 784 },{ 195, 32, 1352 },{ 33, 99, 70 },{ 99, 33, 8 }, }, { { 6, 179, 790 },{ 203, 40, 1352 },{ 41, 107, 70 },{ 107, 41, 8 }, },
  1856. { { 15, 187, 790 },{ 211, 48, 1352 },{ 115, 0, 41 },{ 115, 49, 8 }, }, { { 61, 199, 710 },{ 219, 56, 1352 },{ 57, 123, 70 },{ 123, 57, 8 }, },
  1857. { { 70, 208, 710 },{ 228, 65, 1352 },{ 66, 132, 70 },{ 132, 66, 8 }, }, { { 78, 216, 710 },{ 236, 73, 1352 },{ 74, 140, 70 },{ 140, 74, 8 }, },
  1858. { { 86, 224, 710 },{ 244, 81, 1352 },{ 145, 7, 33 },{ 148, 82, 8 }, }, { { 222, 8, 233 },{ 252, 89, 1352 },{ 153, 15, 33 },{ 156, 90, 8 }, },
  1859. { { 235, 0, 239 },{ 241, 101, 328 },{ 166, 6, 39 },{ 165, 99, 8 }, }, { { 32, 170, 3680 },{ 249, 109, 328 },{ 0, 175, 98 },{ 173, 107, 8 }, },
  1860. { { 40, 178, 3680 },{ 115, 181, 3648 },{ 8, 183, 98 },{ 181, 115, 8 }, }, { { 48, 186, 3680 },{ 123, 189, 3648 },{ 16, 191, 98 },{ 189, 123, 8 }, },
  1861. { { 57, 195, 3680 },{ 132, 198, 3648 },{ 25, 200, 98 },{ 198, 132, 8 }, }, { { 67, 243, 3928 },{ 140, 206, 3648 },{ 33, 208, 98 },{ 206, 140, 8 }, },
  1862. { { 76, 251, 3928 },{ 148, 214, 3648 },{ 41, 216, 98 },{ 214, 148, 8 }, }, { { 86, 255, 856 },{ 156, 222, 3648 },{ 49, 224, 98 },{ 222, 156, 8 }, },
  1863. { { 255, 93, 169 },{ 165, 231, 3648 },{ 58, 233, 98 },{ 231, 165, 8 }, }, { { 98, 236, 3680 },{ 173, 239, 3648 },{ 66, 241, 98 },{ 239, 173, 8 }, },
  1864. { { 108, 181, 4040 },{ 181, 247, 3648 },{ 74, 249, 98 },{ 247, 181, 8 }, }, { { 116, 189, 4040 },{ 255, 189, 8 },{ 116, 189, 456 },{ 255, 189, 8 }, },
  1865. { { 125, 198, 4040 },{ 255, 198, 8 },{ 125, 198, 456 },{ 255, 198, 8 }, }, { { 133, 206, 4040 },{ 255, 206, 8 },{ 133, 206, 456 },{ 255, 206, 8 }, },
  1866. { { 141, 214, 4040 },{ 255, 214, 8 },{ 141, 214, 456 },{ 255, 214, 8 }, }, { { 149, 222, 4040 },{ 255, 222, 8 },{ 149, 222, 456 },{ 255, 222, 8 }, },
  1867. { { 47, 183, 566 },{ 47, 183, 560 },{ 47, 0, 9 },{ 47, 0, 8 }, }, { { 55, 191, 566 },{ 55, 191, 560 },{ 55, 0, 9 },{ 55, 0, 8 }, },
  1868. { { 63, 199, 566 },{ 63, 199, 560 },{ 63, 0, 9 },{ 63, 0, 8 }, }, { { 71, 207, 566 },{ 71, 207, 560 },{ 71, 0, 9 },{ 71, 0, 8 }, },
  1869. { { 80, 216, 566 },{ 80, 216, 560 },{ 80, 0, 9 },{ 80, 0, 8 }, }, { { 88, 224, 566 },{ 88, 224, 560 },{ 88, 0, 9 },{ 88, 0, 8 }, },
  1870. { { 3, 233, 710 },{ 3, 233, 704 },{ 2, 96, 70 },{ 96, 2, 8 }, }, { { 11, 241, 710 },{ 11, 241, 704 },{ 10, 104, 70 },{ 104, 10, 8 }, },
  1871. { { 20, 250, 710 },{ 20, 250, 704 },{ 19, 113, 70 },{ 113, 19, 8 }, }, { { 27, 121, 3654 },{ 27, 121, 3648 },{ 27, 121, 70 },{ 121, 27, 8 }, },
  1872. { { 35, 129, 3654 },{ 35, 129, 3648 },{ 35, 129, 70 },{ 129, 35, 8 }, }, { { 43, 137, 3654 },{ 43, 137, 3648 },{ 43, 137, 70 },{ 137, 43, 8 }, },
  1873. { { 52, 146, 3654 },{ 52, 146, 3648 },{ 52, 146, 70 },{ 146, 52, 8 }, }, { { 60, 154, 3654 },{ 60, 154, 3648 },{ 60, 154, 70 },{ 154, 60, 8 }, },
  1874. { { 68, 162, 3654 },{ 68, 162, 3648 },{ 68, 162, 70 },{ 162, 68, 8 }, }, { { 76, 170, 3654 },{ 76, 170, 3648 },{ 76, 170, 70 },{ 170, 76, 8 }, },
  1875. { { 85, 179, 3654 },{ 85, 179, 3648 },{ 85, 179, 70 },{ 179, 85, 8 }, }, { { 93, 187, 3654 },{ 93, 187, 3648 },{ 93, 187, 70 },{ 187, 93, 8 }, },
  1876. { { 101, 195, 3654 },{ 101, 195, 3648 },{ 101, 195, 70 },{ 195, 101, 8 }, }, { { 109, 203, 3654 },{ 109, 203, 3648 },{ 109, 203, 70 },{ 203, 109, 8 }, },
  1877. { { 118, 212, 3654 },{ 118, 212, 3648 },{ 118, 212, 70 },{ 212, 118, 8 }, }, { { 126, 220, 3654 },{ 126, 220, 3648 },{ 126, 220, 70 },{ 220, 126, 8 }, },
  1878. { { 134, 228, 3654 },{ 134, 228, 3648 },{ 134, 228, 70 },{ 228, 134, 8 }, }, { { 5, 236, 3680 },{ 142, 236, 3648 },{ 5, 236, 96 },{ 236, 142, 8 }, },
  1879. { { 14, 245, 3680 },{ 151, 245, 3648 },{ 14, 245, 96 },{ 245, 151, 8 }, }, { { 23, 159, 4040 },{ 159, 253, 3648 },{ 23, 159, 456 },{ 253, 159, 8 }, },
  1880. { { 31, 167, 4040 },{ 255, 167, 8 },{ 31, 167, 456 },{ 255, 167, 8 }, }, { { 39, 175, 4040 },{ 255, 175, 8 },{ 39, 175, 456 },{ 255, 175, 8 }, },
  1881. { { 48, 184, 4040 },{ 255, 184, 8 },{ 48, 184, 456 },{ 255, 184, 8 }, }, { { 56, 192, 4040 },{ 255, 192, 8 },{ 56, 192, 456 },{ 255, 192, 8 }, },
  1882. { { 64, 200, 4040 },{ 255, 200, 8 },{ 64, 200, 456 },{ 255, 200, 8 }, },{ { 72, 208, 4040 },{ 255, 208, 8 },{ 72, 208, 456 },{ 255, 208, 8 }, },
  1883. };
  1884. struct dxt5a_block
  1885. {
  1886. uint8_t m_endpoints[2];
  1887. enum { cTotalSelectorBytes = 6 };
  1888. uint8_t m_selectors[cTotalSelectorBytes];
  1889. inline void clear()
  1890. {
  1891. basisu::clear_obj(*this);
  1892. }
  1893. inline uint32_t get_low_alpha() const
  1894. {
  1895. return m_endpoints[0];
  1896. }
  1897. inline uint32_t get_high_alpha() const
  1898. {
  1899. return m_endpoints[1];
  1900. }
  1901. inline void set_low_alpha(uint32_t i)
  1902. {
  1903. assert(i <= UINT8_MAX);
  1904. m_endpoints[0] = static_cast<uint8_t>(i);
  1905. }
  1906. inline void set_high_alpha(uint32_t i)
  1907. {
  1908. assert(i <= UINT8_MAX);
  1909. m_endpoints[1] = static_cast<uint8_t>(i);
  1910. }
  1911. inline bool is_alpha6_block() const { return get_low_alpha() <= get_high_alpha(); }
  1912. uint32_t get_endpoints_as_word() const { return m_endpoints[0] | (m_endpoints[1] << 8); }
  1913. uint32_t get_selectors_as_word(uint32_t index) { assert(index < 3); return m_selectors[index * 2] | (m_selectors[index * 2 + 1] << 8); }
  1914. inline uint32_t get_selector(uint32_t x, uint32_t y) const
  1915. {
  1916. assert((x < 4U) && (y < 4U));
  1917. uint32_t selector_index = (y * 4) + x;
  1918. uint32_t bit_index = selector_index * cDXT5SelectorBits;
  1919. uint32_t byte_index = bit_index >> 3;
  1920. uint32_t bit_ofs = bit_index & 7;
  1921. uint32_t v = m_selectors[byte_index];
  1922. if (byte_index < (cTotalSelectorBytes - 1))
  1923. v |= (m_selectors[byte_index + 1] << 8);
  1924. return (v >> bit_ofs) & 7;
  1925. }
  1926. inline void set_selector(uint32_t x, uint32_t y, uint32_t val)
  1927. {
  1928. assert((x < 4U) && (y < 4U) && (val < 8U));
  1929. uint32_t selector_index = (y * 4) + x;
  1930. uint32_t bit_index = selector_index * cDXT5SelectorBits;
  1931. uint32_t byte_index = bit_index >> 3;
  1932. uint32_t bit_ofs = bit_index & 7;
  1933. uint32_t v = m_selectors[byte_index];
  1934. if (byte_index < (cTotalSelectorBytes - 1))
  1935. v |= (m_selectors[byte_index + 1] << 8);
  1936. v &= (~(7 << bit_ofs));
  1937. v |= (val << bit_ofs);
  1938. m_selectors[byte_index] = static_cast<uint8_t>(v);
  1939. if (byte_index < (cTotalSelectorBytes - 1))
  1940. m_selectors[byte_index + 1] = static_cast<uint8_t>(v >> 8);
  1941. }
  1942. enum { cMaxSelectorValues = 8 };
  1943. static uint32_t get_block_values6(color32* pDst, uint32_t l, uint32_t h)
  1944. {
  1945. pDst[0].a = static_cast<uint8_t>(l);
  1946. pDst[1].a = static_cast<uint8_t>(h);
  1947. pDst[2].a = static_cast<uint8_t>((l * 4 + h) / 5);
  1948. pDst[3].a = static_cast<uint8_t>((l * 3 + h * 2) / 5);
  1949. pDst[4].a = static_cast<uint8_t>((l * 2 + h * 3) / 5);
  1950. pDst[5].a = static_cast<uint8_t>((l + h * 4) / 5);
  1951. pDst[6].a = 0;
  1952. pDst[7].a = 255;
  1953. return 6;
  1954. }
  1955. static uint32_t get_block_values8(color32* pDst, uint32_t l, uint32_t h)
  1956. {
  1957. pDst[0].a = static_cast<uint8_t>(l);
  1958. pDst[1].a = static_cast<uint8_t>(h);
  1959. pDst[2].a = static_cast<uint8_t>((l * 6 + h) / 7);
  1960. pDst[3].a = static_cast<uint8_t>((l * 5 + h * 2) / 7);
  1961. pDst[4].a = static_cast<uint8_t>((l * 4 + h * 3) / 7);
  1962. pDst[5].a = static_cast<uint8_t>((l * 3 + h * 4) / 7);
  1963. pDst[6].a = static_cast<uint8_t>((l * 2 + h * 5) / 7);
  1964. pDst[7].a = static_cast<uint8_t>((l + h * 6) / 7);
  1965. return 8;
  1966. }
  1967. static uint32_t get_block_values(color32* pDst, uint32_t l, uint32_t h)
  1968. {
  1969. if (l > h)
  1970. return get_block_values8(pDst, l, h);
  1971. else
  1972. return get_block_values6(pDst, l, h);
  1973. }
  1974. };
  1975. static void convert_etc1s_to_dxt5a(dxt5a_block* pDst_block, const endpoint* pEndpoints, const selector* pSelector)
  1976. {
  1977. const uint32_t low_selector = pSelector->m_lo_selector;
  1978. const uint32_t high_selector = pSelector->m_hi_selector;
  1979. const color32& base_color = pEndpoints->m_color5;
  1980. const uint32_t inten_table = pEndpoints->m_inten5;
  1981. if (low_selector == high_selector)
  1982. {
  1983. uint32_t r;
  1984. decoder_etc_block::get_block_color5_r(base_color, inten_table, low_selector, r);
  1985. pDst_block->set_low_alpha(r);
  1986. pDst_block->set_high_alpha(r);
  1987. pDst_block->m_selectors[0] = 0;
  1988. pDst_block->m_selectors[1] = 0;
  1989. pDst_block->m_selectors[2] = 0;
  1990. pDst_block->m_selectors[3] = 0;
  1991. pDst_block->m_selectors[4] = 0;
  1992. pDst_block->m_selectors[5] = 0;
  1993. return;
  1994. }
  1995. else if (pSelector->m_num_unique_selectors == 2)
  1996. {
  1997. color32 block_colors[4];
  1998. decoder_etc_block::get_block_colors5(block_colors, base_color, inten_table);
  1999. const uint32_t r0 = block_colors[low_selector].r;
  2000. const uint32_t r1 = block_colors[high_selector].r;
  2001. pDst_block->set_low_alpha(r0);
  2002. pDst_block->set_high_alpha(r1);
  2003. // TODO: Optimize this
  2004. for (uint32_t y = 0; y < 4; y++)
  2005. {
  2006. for (uint32_t x = 0; x < 4; x++)
  2007. {
  2008. uint32_t s = pSelector->get_selector(x, y);
  2009. pDst_block->set_selector(x, y, (s == high_selector) ? 1 : 0);
  2010. }
  2011. }
  2012. return;
  2013. }
  2014. uint32_t selector_range_table = 0;
  2015. for (selector_range_table = 0; selector_range_table < NUM_DXT5A_SELECTOR_RANGES; selector_range_table++)
  2016. if ((low_selector == s_dxt5a_selector_ranges[selector_range_table].m_low) && (high_selector == s_dxt5a_selector_ranges[selector_range_table].m_high))
  2017. break;
  2018. if (selector_range_table >= NUM_DXT5A_SELECTOR_RANGES)
  2019. selector_range_table = 0;
  2020. const etc1_g_to_dxt5a_conversion* pTable_entry = &g_etc1_g_to_dxt5a[base_color.r + inten_table * 32][selector_range_table];
  2021. pDst_block->set_low_alpha(pTable_entry->m_lo);
  2022. pDst_block->set_high_alpha(pTable_entry->m_hi);
  2023. // TODO: Optimize this (like ETC1->BC1)
  2024. for (uint32_t y = 0; y < 4; y++)
  2025. {
  2026. for (uint32_t x = 0; x < 4; x++)
  2027. {
  2028. uint32_t s = pSelector->get_selector(x, y);
  2029. uint32_t ds = (pTable_entry->m_trans >> (s * 3)) & 7;
  2030. pDst_block->set_selector(x, y, ds);
  2031. }
  2032. }
  2033. }
  2034. #endif //BASISD_SUPPORT_DXT5A
  2035. // PVRTC
  2036. #if BASISD_SUPPORT_PVRTC1
  2037. static const uint16_t g_pvrtc_swizzle_table[256] =
  2038. {
  2039. 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155,
  2040. 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555,
  2041. 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155,
  2042. 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555,
  2043. 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155,
  2044. 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555,
  2045. 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155,
  2046. 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555
  2047. };
  2048. // Note we can't use simple calculations to convert PVRTC1 encoded endpoint components to/from 8-bits, due to hardware approximations.
  2049. static const uint8_t g_pvrtc_5[32] = { 0,8,16,24,33,41,49,57,66,74,82,90,99,107,115,123,132,140,148,156,165,173,181,189,198,206,214,222,231,239,247,255 };
  2050. static const uint8_t g_pvrtc_4[16] = { 0,16,33,49,66,82,99,115,140,156,173,189,206,222,239,255 };
  2051. static const uint8_t g_pvrtc_3[8] = { 0,33,74,107,148,181,222,255 };
  2052. static const uint8_t g_pvrtc_alpha[9] = { 0,34,68,102,136,170,204,238,255 };
  2053. static const uint8_t g_pvrtc_5_floor[256] =
  2054. {
  2055. 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,
  2056. 3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,
  2057. 7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,
  2058. 11,11,11,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,15,15,15,15,15,
  2059. 15,15,15,15,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,
  2060. 19,19,19,19,19,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23,
  2061. 23,23,23,23,23,23,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,27,27,
  2062. 27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,31
  2063. };
  2064. static const uint8_t g_pvrtc_5_ceil[256] =
  2065. {
  2066. 0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,
  2067. 4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8,
  2068. 8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,12,12,12,12,12,
  2069. 12,12,12,12,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,16,16,16,16,
  2070. 16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20,
  2071. 20,20,20,20,20,20,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24,
  2072. 24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,28,
  2073. 28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31
  2074. };
  2075. static const uint8_t g_pvrtc_4_floor[256] =
  2076. {
  2077. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  2078. 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
  2079. 3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  2080. 5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,
  2081. 7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,
  2082. 9,9,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,
  2083. 11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,
  2084. 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15
  2085. };
  2086. static const uint8_t g_pvrtc_4_ceil[256] =
  2087. {
  2088. 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
  2089. 2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  2090. 4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,
  2091. 6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,
  2092. 8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,10,10,10,
  2093. 10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,
  2094. 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,
  2095. 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15
  2096. };
  2097. static const uint8_t g_pvrtc_3_floor[256] =
  2098. {
  2099. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  2100. 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  2101. 1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
  2102. 2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
  2103. 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,
  2104. 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,
  2105. 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,
  2106. 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7
  2107. };
  2108. static const uint8_t g_pvrtc_3_ceil[256] =
  2109. {
  2110. 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  2111. 1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
  2112. 2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
  2113. 3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  2114. 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,
  2115. 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,
  2116. 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,
  2117. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
  2118. };
  2119. static const uint8_t g_pvrtc_alpha_floor[256] =
  2120. {
  2121. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  2122. 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  2123. 1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
  2124. 2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
  2125. 3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  2126. 4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  2127. 5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  2128. 6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8
  2129. };
  2130. static const uint8_t g_pvrtc_alpha_ceil[256] =
  2131. {
  2132. 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  2133. 1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
  2134. 2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
  2135. 3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  2136. 4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  2137. 5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  2138. 6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  2139. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
  2140. };
  2141. struct pvrtc4_block
  2142. {
  2143. uint32_t m_modulation;
  2144. uint32_t m_endpoints;
  2145. pvrtc4_block() : m_modulation(0), m_endpoints(0) { }
  2146. inline bool operator== (const pvrtc4_block& rhs) const
  2147. {
  2148. return (m_modulation == rhs.m_modulation) && (m_endpoints == rhs.m_endpoints);
  2149. }
  2150. inline void clear()
  2151. {
  2152. m_modulation = 0;
  2153. m_endpoints = 0;
  2154. }
  2155. inline bool get_block_uses_transparent_modulation() const
  2156. {
  2157. return (m_endpoints & 1) != 0;
  2158. }
  2159. inline void set_block_uses_transparent_modulation(bool m)
  2160. {
  2161. m_endpoints = (m_endpoints & ~1U) | static_cast<uint32_t>(m);
  2162. }
  2163. inline bool is_endpoint_opaque(uint32_t endpoint_index) const
  2164. {
  2165. static const uint32_t s_bitmasks[2] = { 0x8000U, 0x80000000U };
  2166. return (m_endpoints & s_bitmasks[basisu::open_range_check(endpoint_index, 2U)]) != 0;
  2167. }
  2168. inline void set_endpoint_opaque(uint32_t endpoint_index, bool opaque)
  2169. {
  2170. assert(endpoint_index < 2);
  2171. static const uint32_t s_bitmasks[2] = { 0x8000U, 0x80000000U };
  2172. if (opaque)
  2173. m_endpoints |= s_bitmasks[endpoint_index];
  2174. else
  2175. m_endpoints &= ~s_bitmasks[endpoint_index];
  2176. }
  2177. inline color32 get_endpoint_5554(uint32_t endpoint_index) const
  2178. {
  2179. assert(endpoint_index < 2);
  2180. static const uint32_t s_endpoint_mask[2] = { 0xFFFE, 0xFFFF };
  2181. uint32_t packed = (m_endpoints >> (basisu::open_range_check(endpoint_index, 2U) ? 16 : 0)) & s_endpoint_mask[endpoint_index];
  2182. uint32_t r, g, b, a;
  2183. if (packed & 0x8000)
  2184. {
  2185. // opaque 554 or 555
  2186. r = (packed >> 10) & 31;
  2187. g = (packed >> 5) & 31;
  2188. b = packed & 31;
  2189. if (!endpoint_index)
  2190. b |= (b >> 4);
  2191. a = 0xF;
  2192. }
  2193. else
  2194. {
  2195. // translucent 4433 or 4443
  2196. r = (packed >> 7) & 0x1E;
  2197. g = (packed >> 3) & 0x1E;
  2198. b = (packed & 0xF) << 1;
  2199. r |= (r >> 4);
  2200. g |= (g >> 4);
  2201. if (!endpoint_index)
  2202. b |= (b >> 3);
  2203. else
  2204. b |= (b >> 4);
  2205. a = (packed >> 11) & 0xE;
  2206. }
  2207. assert((r < 32) && (g < 32) && (b < 32) && (a < 16));
  2208. return color32(r, g, b, a);
  2209. }
  2210. inline color32 get_endpoint_8888(uint32_t endpoint_index) const
  2211. {
  2212. assert(endpoint_index < 2);
  2213. static const uint32_t s_endpoint_mask[2] = { 0xFFFE, 0xFFFF };
  2214. uint32_t packed = (m_endpoints >> (basisu::open_range_check(endpoint_index, 2U) ? 16 : 0)) & s_endpoint_mask[endpoint_index];
  2215. uint32_t r, g, b, a;
  2216. if (packed & 0x8000)
  2217. {
  2218. // opaque 554 or 555
  2219. // 1RRRRRGGGGGBBBBM
  2220. // 1RRRRRGGGGGBBBBB
  2221. r = (packed >> 10) & 31;
  2222. g = (packed >> 5) & 31;
  2223. b = packed & 31;
  2224. r = g_pvrtc_5[r];
  2225. g = g_pvrtc_5[g];
  2226. if (!endpoint_index)
  2227. b = g_pvrtc_4[b >> 1];
  2228. else
  2229. b = g_pvrtc_5[b];
  2230. a = 255;
  2231. }
  2232. else
  2233. {
  2234. // translucent 4433 or 4443
  2235. // 0AAA RRRR GGGG BBBM
  2236. // 0AAA RRRR GGGG BBBB
  2237. r = (packed >> 8) & 0xF;
  2238. g = (packed >> 4) & 0xF;
  2239. b = packed & 0xF;
  2240. a = (packed >> 12) & 7;
  2241. r = g_pvrtc_4[r];
  2242. g = g_pvrtc_4[g];
  2243. if (!endpoint_index)
  2244. b = g_pvrtc_3[b >> 1];
  2245. else
  2246. b = g_pvrtc_4[b];
  2247. a = g_pvrtc_alpha[a];
  2248. }
  2249. return color32(r, g, b, a);
  2250. }
  2251. inline uint32_t get_endpoint_l8(uint32_t endpoint_index) const
  2252. {
  2253. color32 c(get_endpoint_8888(endpoint_index));
  2254. return c.r + c.g + c.b + c.a;
  2255. }
  2256. inline uint32_t get_opaque_endpoint_l0() const
  2257. {
  2258. uint32_t packed = m_endpoints & 0xFFFE;
  2259. uint32_t r, g, b;
  2260. assert(packed & 0x8000);
  2261. // opaque 554 or 555
  2262. r = (packed >> 10) & 31;
  2263. g = (packed >> 5) & 31;
  2264. b = packed & 31;
  2265. b |= (b >> 4);
  2266. return r + g + b;
  2267. }
  2268. inline uint32_t get_opaque_endpoint_l1() const
  2269. {
  2270. uint32_t packed = m_endpoints >> 16;
  2271. uint32_t r, g, b;
  2272. assert(packed & 0x8000);
  2273. // opaque 554 or 555
  2274. r = (packed >> 10) & 31;
  2275. g = (packed >> 5) & 31;
  2276. b = packed & 31;
  2277. return r + g + b;
  2278. }
  2279. static uint32_t get_component_precision_in_bits(uint32_t c, uint32_t endpoint_index, bool opaque_endpoint)
  2280. {
  2281. static const uint32_t s_comp_prec[4][4] =
  2282. {
  2283. // R0 G0 B0 A0 R1 G1 B1 A1
  2284. { 4, 4, 3, 3 },{ 4, 4, 4, 3 }, // transparent endpoint
  2285. { 5, 5, 4, 0 },{ 5, 5, 5, 0 } // opaque endpoint
  2286. };
  2287. return s_comp_prec[basisu::open_range_check(endpoint_index, 2U) + (opaque_endpoint * 2)][basisu::open_range_check(c, 4U)];
  2288. }
  2289. static color32 get_color_precision_in_bits(uint32_t endpoint_index, bool opaque_endpoint)
  2290. {
  2291. static const color32 s_color_prec[4] =
  2292. {
  2293. color32(4, 4, 3, 3), color32(4, 4, 4, 3), // transparent endpoint
  2294. color32(5, 5, 4, 0), color32(5, 5, 5, 0) // opaque endpoint
  2295. };
  2296. return s_color_prec[basisu::open_range_check(endpoint_index, 2U) + (opaque_endpoint * 2)];
  2297. }
  2298. inline void set_opaque_endpoint_floor(uint32_t endpoint_index, const color32& c)
  2299. {
  2300. assert(endpoint_index < 2);
  2301. const uint32_t m = m_endpoints & 1;
  2302. uint32_t r = g_pvrtc_5_floor[c[0]], g = g_pvrtc_5_floor[c[1]], b = c[2];
  2303. if (!endpoint_index)
  2304. b = g_pvrtc_4_floor[b] << 1;
  2305. else
  2306. b = g_pvrtc_5_floor[b];
  2307. // rgba=555 here
  2308. assert((r < 32) && (g < 32) && (b < 32));
  2309. // 1RRRRRGGGGGBBBBM
  2310. // 1RRRRRGGGGGBBBBB
  2311. // opaque 554 or 555
  2312. uint32_t packed = 0x8000 | (r << 10) | (g << 5) | b;
  2313. if (!endpoint_index)
  2314. packed = (packed & ~1) | m;
  2315. assert(packed <= 0xFFFF);
  2316. if (endpoint_index)
  2317. m_endpoints = (m_endpoints & 0xFFFFU) | (packed << 16);
  2318. else
  2319. m_endpoints = (m_endpoints & 0xFFFF0000U) | packed;
  2320. }
  2321. inline void set_opaque_endpoint_ceil(uint32_t endpoint_index, const color32& c)
  2322. {
  2323. assert(endpoint_index < 2);
  2324. const uint32_t m = m_endpoints & 1;
  2325. uint32_t r = g_pvrtc_5_ceil[c[0]], g = g_pvrtc_5_ceil[c[1]], b = c[2];
  2326. if (!endpoint_index)
  2327. b = g_pvrtc_4_ceil[b] << 1;
  2328. else
  2329. b = g_pvrtc_5_ceil[b];
  2330. // rgba=555 here
  2331. assert((r < 32) && (g < 32) && (b < 32));
  2332. // 1RRRRRGGGGGBBBBM
  2333. // 1RRRRRGGGGGBBBBB
  2334. // opaque 554 or 555
  2335. uint32_t packed = 0x8000 | (r << 10) | (g << 5) | b;
  2336. if (!endpoint_index)
  2337. packed |= m;
  2338. assert(packed <= 0xFFFF);
  2339. if (endpoint_index)
  2340. m_endpoints = (m_endpoints & 0xFFFFU) | (packed << 16);
  2341. else
  2342. m_endpoints = (m_endpoints & 0xFFFF0000U) | packed;
  2343. }
  2344. // opaque endpoints: 554 or 555
  2345. // transparent endpoints: 3443 or 3444
  2346. inline void set_endpoint_raw(uint32_t endpoint_index, const color32& c, bool opaque_endpoint)
  2347. {
  2348. assert(endpoint_index < 2);
  2349. const uint32_t m = m_endpoints & 1;
  2350. uint32_t r = c[0], g = c[1], b = c[2], a = c[3];
  2351. uint32_t packed;
  2352. if (opaque_endpoint)
  2353. {
  2354. if (!endpoint_index)
  2355. {
  2356. // 554
  2357. // 1RRRRRGGGGGBBBBM
  2358. assert((r < 32) && (g < 32) && (b < 16));
  2359. packed = 0x8000 | (r << 10) | (g << 5) | (b << 1) | m;
  2360. }
  2361. else
  2362. {
  2363. // 555
  2364. // 1RRRRRGGGGGBBBBB
  2365. assert((r < 32) && (g < 32) && (b < 32));
  2366. packed = 0x8000 | (r << 10) | (g << 5) | b;
  2367. }
  2368. }
  2369. else
  2370. {
  2371. if (!endpoint_index)
  2372. {
  2373. // 3443
  2374. // 0AAA RRRR GGGG BBBM
  2375. assert((r < 16) && (g < 16) && (b < 8) && (a < 8));
  2376. packed = (a << 12) | (r << 8) | (g << 4) | (b << 1) | m;
  2377. }
  2378. else
  2379. {
  2380. // 3444
  2381. // 0AAA RRRR GGGG BBBB
  2382. assert((r < 16) && (g < 16) && (b < 16) && (a < 8));
  2383. packed = (a << 12) | (r << 8) | (g << 4) | b;
  2384. }
  2385. }
  2386. assert(packed <= 0xFFFF);
  2387. if (endpoint_index)
  2388. m_endpoints = (m_endpoints & 0xFFFFU) | (packed << 16);
  2389. else
  2390. m_endpoints = (m_endpoints & 0xFFFF0000U) | packed;
  2391. }
  2392. inline void set_endpoint_floor(uint32_t endpoint_index, const color32& c)
  2393. {
  2394. assert(endpoint_index < 2);
  2395. int a = g_pvrtc_alpha_floor[c.a];
  2396. if (a == 8)
  2397. {
  2398. // 554 or 555
  2399. uint32_t r = g_pvrtc_5_floor[c[0]], g = g_pvrtc_5_floor[c[1]], b = c[2];
  2400. if (!endpoint_index)
  2401. b = g_pvrtc_4_floor[b];
  2402. else
  2403. b = g_pvrtc_5_floor[b];
  2404. set_endpoint_raw(endpoint_index, color32(r, g, b, a), true);
  2405. }
  2406. else
  2407. {
  2408. // 4433 or 4443
  2409. uint32_t r = g_pvrtc_4_floor[c[0]], g = g_pvrtc_4_floor[c[1]], b = c[2];
  2410. if (!endpoint_index)
  2411. b = g_pvrtc_3_floor[b];
  2412. else
  2413. b = g_pvrtc_4_floor[b];
  2414. set_endpoint_raw(endpoint_index, color32(r, g, b, a), false);
  2415. }
  2416. }
  2417. inline void set_endpoint_ceil(uint32_t endpoint_index, const color32& c)
  2418. {
  2419. assert(endpoint_index < 2);
  2420. int a = g_pvrtc_alpha_ceil[c.a];
  2421. if (a == 8)
  2422. {
  2423. // 554 or 555
  2424. uint32_t r = g_pvrtc_5_ceil[c[0]], g = g_pvrtc_5_ceil[c[1]], b = c[2];
  2425. if (!endpoint_index)
  2426. b = g_pvrtc_4_ceil[b];
  2427. else
  2428. b = g_pvrtc_5_ceil[b];
  2429. set_endpoint_raw(endpoint_index, color32(r, g, b, a), true);
  2430. }
  2431. else
  2432. {
  2433. // 4433 or 4443
  2434. uint32_t r = g_pvrtc_4_ceil[c[0]], g = g_pvrtc_4_ceil[c[1]], b = c[2];
  2435. if (!endpoint_index)
  2436. b = g_pvrtc_3_ceil[b];
  2437. else
  2438. b = g_pvrtc_4_ceil[b];
  2439. set_endpoint_raw(endpoint_index, color32(r, g, b, a), false);
  2440. }
  2441. }
  2442. inline uint32_t get_modulation(uint32_t x, uint32_t y) const
  2443. {
  2444. assert((x < 4) && (y < 4));
  2445. return (m_modulation >> ((y * 4 + x) * 2)) & 3;
  2446. }
  2447. // Scaled by 8
  2448. inline const uint32_t* get_scaled_modulation_values(bool block_uses_transparent_modulation) const
  2449. {
  2450. static const uint32_t s_block_scales[2][4] = { { 0, 3, 5, 8 },{ 0, 4, 4, 8 } };
  2451. return s_block_scales[block_uses_transparent_modulation];
  2452. }
  2453. // Scaled by 8
  2454. inline uint32_t get_scaled_modulation(uint32_t x, uint32_t y) const
  2455. {
  2456. return get_scaled_modulation_values(get_block_uses_transparent_modulation())[get_modulation(x, y)];
  2457. }
  2458. inline void set_modulation(uint32_t x, uint32_t y, uint32_t s)
  2459. {
  2460. assert((x < 4) && (y < 4) && (s < 4));
  2461. uint32_t n = (y * 4 + x) * 2;
  2462. m_modulation = (m_modulation & (~(3 << n))) | (s << n);
  2463. assert(get_modulation(x, y) == s);
  2464. }
  2465. // Assumes modulation was initialized to 0
  2466. inline void set_modulation_fast(uint32_t x, uint32_t y, uint32_t s)
  2467. {
  2468. assert((x < 4) && (y < 4) && (s < 4));
  2469. uint32_t n = (y * 4 + x) * 2;
  2470. m_modulation |= (s << n);
  2471. assert(get_modulation(x, y) == s);
  2472. }
  2473. };
  2474. static const uint8_t g_pvrtc_bilinear_weights[16][4] =
  2475. {
  2476. { 4, 4, 4, 4 }, { 2, 6, 2, 6 }, { 8, 0, 8, 0 }, { 6, 2, 6, 2 },
  2477. { 2, 2, 6, 6 }, { 1, 3, 3, 9 }, { 4, 0, 12, 0 }, { 3, 1, 9, 3 },
  2478. { 8, 8, 0, 0 }, { 4, 12, 0, 0 }, { 16, 0, 0, 0 }, { 12, 4, 0, 0 },
  2479. { 6, 6, 2, 2 }, { 3, 9, 1, 3 }, { 12, 0, 4, 0 }, { 9, 3, 3, 1 },
  2480. };
  2481. struct pvrtc1_temp_block
  2482. {
  2483. decoder_etc_block m_etc1_block;
  2484. uint32_t m_pvrtc_endpoints;
  2485. };
  2486. static inline uint32_t get_opaque_endpoint_l0(uint32_t endpoints)
  2487. {
  2488. uint32_t packed = endpoints;
  2489. uint32_t r, g, b;
  2490. assert(packed & 0x8000);
  2491. r = (packed >> 10) & 31;
  2492. g = (packed >> 5) & 31;
  2493. b = packed & 30;
  2494. b |= (b >> 4);
  2495. return r + g + b;
  2496. }
  2497. static inline uint32_t get_opaque_endpoint_l1(uint32_t endpoints)
  2498. {
  2499. uint32_t packed = endpoints >> 16;
  2500. uint32_t r, g, b;
  2501. assert(packed & 0x8000);
  2502. r = (packed >> 10) & 31;
  2503. g = (packed >> 5) & 31;
  2504. b = packed & 31;
  2505. return r + g + b;
  2506. }
  2507. static color32 get_endpoint_8888(uint32_t endpoints, uint32_t endpoint_index)
  2508. {
  2509. assert(endpoint_index < 2);
  2510. static const uint32_t s_endpoint_mask[2] = { 0xFFFE, 0xFFFF };
  2511. uint32_t packed = (endpoints >> (basisu::open_range_check(endpoint_index, 2U) ? 16 : 0)) & s_endpoint_mask[endpoint_index];
  2512. uint32_t r, g, b, a;
  2513. if (packed & 0x8000)
  2514. {
  2515. // opaque 554 or 555
  2516. // 1RRRRRGGGGGBBBBM
  2517. // 1RRRRRGGGGGBBBBB
  2518. r = (packed >> 10) & 31;
  2519. g = (packed >> 5) & 31;
  2520. b = packed & 31;
  2521. r = g_pvrtc_5[r];
  2522. g = g_pvrtc_5[g];
  2523. if (!endpoint_index)
  2524. b = g_pvrtc_4[b >> 1];
  2525. else
  2526. b = g_pvrtc_5[b];
  2527. a = 255;
  2528. }
  2529. else
  2530. {
  2531. // translucent 4433 or 4443
  2532. // 0AAA RRRR GGGG BBBM
  2533. // 0AAA RRRR GGGG BBBB
  2534. r = (packed >> 8) & 0xF;
  2535. g = (packed >> 4) & 0xF;
  2536. b = packed & 0xF;
  2537. a = (packed >> 12) & 7;
  2538. r = g_pvrtc_4[r];
  2539. g = g_pvrtc_4[g];
  2540. if (!endpoint_index)
  2541. b = g_pvrtc_3[b >> 1];
  2542. else
  2543. b = g_pvrtc_4[b];
  2544. a = g_pvrtc_alpha[a];
  2545. }
  2546. return color32(r, g, b, a);
  2547. }
  2548. static uint32_t get_endpoint_l8(uint32_t endpoints, uint32_t endpoint_index)
  2549. {
  2550. color32 c(get_endpoint_8888(endpoints, endpoint_index));
  2551. return c.r + c.g + c.b + c.a;
  2552. }
  2553. // TODO: Support decoding a non-pow2 ETC1S texture into the next larger pow2 PVRTC texture.
  2554. static void fixup_pvrtc1_4_modulation_rgb(const decoder_etc_block* pETC_Blocks, const uint32_t* pPVRTC_endpoints, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool pvrtc_wrap_addressing)
  2555. {
  2556. const uint32_t x_mask = num_blocks_x - 1;
  2557. const uint32_t y_mask = num_blocks_y - 1;
  2558. const uint32_t x_bits = basisu::total_bits(x_mask);
  2559. const uint32_t y_bits = basisu::total_bits(y_mask);
  2560. const uint32_t min_bits = basisu::minimum(x_bits, y_bits);
  2561. const uint32_t max_bits = basisu::maximum(x_bits, y_bits);
  2562. const uint32_t swizzle_mask = (1 << (min_bits * 2)) - 1;
  2563. uint32_t block_index = 0;
  2564. // really 3x3
  2565. int e0[4][4], e1[4][4];
  2566. for (int y = 0; y < static_cast<int>(num_blocks_y); y++)
  2567. {
  2568. const uint32_t* pE_rows[3];
  2569. for (int ey = 0; ey < 3; ey++)
  2570. {
  2571. int by = y + ey - 1; if (!pvrtc_wrap_addressing) by = basisu::clamp<int>(by, 0, y_mask);
  2572. const uint32_t* pE = &pPVRTC_endpoints[(by & y_mask) * num_blocks_x];
  2573. pE_rows[ey] = pE;
  2574. for (int ex = 0; ex < 3; ex++)
  2575. {
  2576. int bx = 0 + ex - 1; if (!pvrtc_wrap_addressing) bx = basisu::clamp<int>(bx, 0, x_mask);
  2577. const uint32_t e = pE[bx & x_mask];
  2578. e0[ex][ey] = (get_opaque_endpoint_l0(e) * 255) / 31;
  2579. e1[ex][ey] = (get_opaque_endpoint_l1(e) * 255) / 31;
  2580. }
  2581. }
  2582. const uint32_t y_swizzle = (g_pvrtc_swizzle_table[y >> 8] << 16) | g_pvrtc_swizzle_table[y & 0xFF];
  2583. for (int x = 0; x < static_cast<int>(num_blocks_x); x++, block_index++)
  2584. {
  2585. const decoder_etc_block& src_block = pETC_Blocks[block_index];
  2586. const uint32_t x_swizzle = (g_pvrtc_swizzle_table[x >> 8] << 17) | (g_pvrtc_swizzle_table[x & 0xFF] << 1);
  2587. uint32_t swizzled = x_swizzle | y_swizzle;
  2588. if (num_blocks_x != num_blocks_y)
  2589. {
  2590. swizzled &= swizzle_mask;
  2591. if (num_blocks_x > num_blocks_y)
  2592. swizzled |= ((x >> min_bits) << (min_bits * 2));
  2593. else
  2594. swizzled |= ((y >> min_bits) << (min_bits * 2));
  2595. }
  2596. pvrtc4_block* pDst_block = static_cast<pvrtc4_block*>(pDst_blocks) + swizzled;
  2597. pDst_block->m_endpoints = pPVRTC_endpoints[block_index];
  2598. uint32_t base_r = g_etc_5_to_8[src_block.m_differential.m_red1];
  2599. uint32_t base_g = g_etc_5_to_8[src_block.m_differential.m_green1];
  2600. uint32_t base_b = g_etc_5_to_8[src_block.m_differential.m_blue1];
  2601. const int* pInten_table48 = g_etc1_inten_tables48[src_block.m_differential.m_cw1];
  2602. int by = (base_r + base_g + base_b) * 16;
  2603. int block_colors_y_x16[4];
  2604. block_colors_y_x16[0] = by + pInten_table48[2];
  2605. block_colors_y_x16[1] = by + pInten_table48[3];
  2606. block_colors_y_x16[2] = by + pInten_table48[1];
  2607. block_colors_y_x16[3] = by + pInten_table48[0];
  2608. {
  2609. const uint32_t ex = 2;
  2610. int bx = x + ex - 1;
  2611. if (!pvrtc_wrap_addressing)
  2612. bx = basisu::clamp<int>(bx, 0, x_mask);
  2613. bx &= x_mask;
  2614. #define DO_ROW(ey) \
  2615. { \
  2616. const uint32_t e = pE_rows[ey][bx]; \
  2617. e0[ex][ey] = (get_opaque_endpoint_l0(e) * 255) / 31; \
  2618. e1[ex][ey] = (get_opaque_endpoint_l1(e) * 255) / 31; \
  2619. }
  2620. DO_ROW(0);
  2621. DO_ROW(1);
  2622. DO_ROW(2);
  2623. #undef DO_ROW
  2624. }
  2625. uint32_t mod = 0;
  2626. uint32_t lookup_x[4];
  2627. #define DO_LOOKUP(lx) { \
  2628. const uint32_t byte_ofs = 7 - (((lx) * 4) >> 3); \
  2629. const uint32_t lsb_bits = src_block.m_bytes[byte_ofs] >> (((lx) & 1) * 4); \
  2630. const uint32_t msb_bits = src_block.m_bytes[byte_ofs - 2] >> (((lx) & 1) * 4); \
  2631. lookup_x[lx] = (lsb_bits & 0xF) | ((msb_bits & 0xF) << 4); }
  2632. DO_LOOKUP(0);
  2633. DO_LOOKUP(1);
  2634. DO_LOOKUP(2);
  2635. DO_LOOKUP(3);
  2636. #undef DO_LOOKUP
  2637. #define DO_PIX(lx, ly, w0, w1, w2, w3) \
  2638. { \
  2639. int ca_l = a0 * w0 + a1 * w1 + a2 * w2 + a3 * w3; \
  2640. int cb_l = b0 * w0 + b1 * w1 + b2 * w2 + b3 * w3; \
  2641. int cl = block_colors_y_x16[g_etc1_x_selector_unpack[ly][lookup_x[lx]]]; \
  2642. int dl = cb_l - ca_l; \
  2643. int vl = cl - ca_l; \
  2644. int p = vl * 16; \
  2645. if (ca_l > cb_l) { p = -p; dl = -dl; } \
  2646. uint32_t m = 0; \
  2647. if (p > 3 * dl) m = (uint32_t)(1 << ((ly) * 8 + (lx) * 2)); \
  2648. if (p > 8 * dl) m = (uint32_t)(2 << ((ly) * 8 + (lx) * 2)); \
  2649. if (p > 13 * dl) m = (uint32_t)(3 << ((ly) * 8 + (lx) * 2)); \
  2650. mod |= m; \
  2651. }
  2652. {
  2653. const uint32_t ex = 0, ey = 0;
  2654. const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1];
  2655. const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1];
  2656. DO_PIX(0, 0, 4, 4, 4, 4);
  2657. DO_PIX(1, 0, 2, 6, 2, 6);
  2658. DO_PIX(0, 1, 2, 2, 6, 6);
  2659. DO_PIX(1, 1, 1, 3, 3, 9);
  2660. }
  2661. {
  2662. const uint32_t ex = 1, ey = 0;
  2663. const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1];
  2664. const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1];
  2665. DO_PIX(2, 0, 8, 0, 8, 0);
  2666. DO_PIX(3, 0, 6, 2, 6, 2);
  2667. DO_PIX(2, 1, 4, 0, 12, 0);
  2668. DO_PIX(3, 1, 3, 1, 9, 3);
  2669. }
  2670. {
  2671. const uint32_t ex = 0, ey = 1;
  2672. const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1];
  2673. const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1];
  2674. DO_PIX(0, 2, 8, 8, 0, 0);
  2675. DO_PIX(1, 2, 4, 12, 0, 0);
  2676. DO_PIX(0, 3, 6, 6, 2, 2);
  2677. DO_PIX(1, 3, 3, 9, 1, 3);
  2678. }
  2679. {
  2680. const uint32_t ex = 1, ey = 1;
  2681. const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1];
  2682. const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1];
  2683. DO_PIX(2, 2, 16, 0, 0, 0);
  2684. DO_PIX(3, 2, 12, 4, 0, 0);
  2685. DO_PIX(2, 3, 12, 0, 4, 0);
  2686. DO_PIX(3, 3, 9, 3, 3, 1);
  2687. }
  2688. #undef DO_PIX
  2689. pDst_block->m_modulation = mod;
  2690. e0[0][0] = e0[1][0]; e0[1][0] = e0[2][0];
  2691. e0[0][1] = e0[1][1]; e0[1][1] = e0[2][1];
  2692. e0[0][2] = e0[1][2]; e0[1][2] = e0[2][2];
  2693. e1[0][0] = e1[1][0]; e1[1][0] = e1[2][0];
  2694. e1[0][1] = e1[1][1]; e1[1][1] = e1[2][1];
  2695. e1[0][2] = e1[1][2]; e1[1][2] = e1[2][2];
  2696. } // x
  2697. } // y
  2698. }
  2699. static void fixup_pvrtc1_4_modulation_rgba(
  2700. const decoder_etc_block* pETC_Blocks,
  2701. const uint32_t* pPVRTC_endpoints,
  2702. void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool pvrtc_wrap_addressing, void *pAlpha_blocks,
  2703. const endpoint* pEndpoints, const selector* pSelectors)
  2704. {
  2705. const uint32_t x_mask = num_blocks_x - 1;
  2706. const uint32_t y_mask = num_blocks_y - 1;
  2707. const uint32_t x_bits = basisu::total_bits(x_mask);
  2708. const uint32_t y_bits = basisu::total_bits(y_mask);
  2709. const uint32_t min_bits = basisu::minimum(x_bits, y_bits);
  2710. const uint32_t max_bits = basisu::maximum(x_bits, y_bits);
  2711. const uint32_t swizzle_mask = (1 << (min_bits * 2)) - 1;
  2712. uint32_t block_index = 0;
  2713. // really 3x3
  2714. int e0[4][4], e1[4][4];
  2715. for (int y = 0; y < static_cast<int>(num_blocks_y); y++)
  2716. {
  2717. const uint32_t* pE_rows[3];
  2718. for (int ey = 0; ey < 3; ey++)
  2719. {
  2720. int by = y + ey - 1; if (!pvrtc_wrap_addressing) by = basisu::clamp<int>(by, 0, y_mask);
  2721. const uint32_t* pE = &pPVRTC_endpoints[(by & y_mask) * num_blocks_x];
  2722. pE_rows[ey] = pE;
  2723. for (int ex = 0; ex < 3; ex++)
  2724. {
  2725. int bx = 0 + ex - 1; if (!pvrtc_wrap_addressing) bx = basisu::clamp<int>(bx, 0, x_mask);
  2726. const uint32_t e = pE[bx & x_mask];
  2727. e0[ex][ey] = get_endpoint_l8(e, 0);
  2728. e1[ex][ey] = get_endpoint_l8(e, 1);
  2729. }
  2730. }
  2731. const uint32_t y_swizzle = (g_pvrtc_swizzle_table[y >> 8] << 16) | g_pvrtc_swizzle_table[y & 0xFF];
  2732. for (int x = 0; x < static_cast<int>(num_blocks_x); x++, block_index++)
  2733. {
  2734. const decoder_etc_block& src_block = pETC_Blocks[block_index];
  2735. const uint16_t* pSrc_alpha_block = reinterpret_cast<const uint16_t*>(static_cast<const uint32_t*>(pAlpha_blocks) + x + (y * num_blocks_x));
  2736. const endpoint* pAlpha_endpoints = &pEndpoints[pSrc_alpha_block[0]];
  2737. const selector* pAlpha_selectors = &pSelectors[pSrc_alpha_block[1]];
  2738. const uint32_t x_swizzle = (g_pvrtc_swizzle_table[x >> 8] << 17) | (g_pvrtc_swizzle_table[x & 0xFF] << 1);
  2739. uint32_t swizzled = x_swizzle | y_swizzle;
  2740. if (num_blocks_x != num_blocks_y)
  2741. {
  2742. swizzled &= swizzle_mask;
  2743. if (num_blocks_x > num_blocks_y)
  2744. swizzled |= ((x >> min_bits) << (min_bits * 2));
  2745. else
  2746. swizzled |= ((y >> min_bits) << (min_bits * 2));
  2747. }
  2748. pvrtc4_block* pDst_block = static_cast<pvrtc4_block*>(pDst_blocks) + swizzled;
  2749. pDst_block->m_endpoints = pPVRTC_endpoints[block_index];
  2750. uint32_t base_r = g_etc_5_to_8[src_block.m_differential.m_red1];
  2751. uint32_t base_g = g_etc_5_to_8[src_block.m_differential.m_green1];
  2752. uint32_t base_b = g_etc_5_to_8[src_block.m_differential.m_blue1];
  2753. const int* pInten_table48 = g_etc1_inten_tables48[src_block.m_differential.m_cw1];
  2754. int by = (base_r + base_g + base_b) * 16;
  2755. int block_colors_y_x16[4];
  2756. block_colors_y_x16[0] = basisu::clamp<int>(by + pInten_table48[0], 0, 48 * 255);
  2757. block_colors_y_x16[1] = basisu::clamp<int>(by + pInten_table48[1], 0, 48 * 255);
  2758. block_colors_y_x16[2] = basisu::clamp<int>(by + pInten_table48[2], 0, 48 * 255);
  2759. block_colors_y_x16[3] = basisu::clamp<int>(by + pInten_table48[3], 0, 48 * 255);
  2760. uint32_t alpha_base_g = g_etc_5_to_8[pAlpha_endpoints->m_color5.g] * 16;
  2761. const int* pInten_table16 = g_etc1_inten_tables16[pAlpha_endpoints->m_inten5];
  2762. int alpha_block_colors_x16[4];
  2763. alpha_block_colors_x16[0] = basisu::clamp<int>(alpha_base_g + pInten_table16[0], 0, 16 * 255);
  2764. alpha_block_colors_x16[1] = basisu::clamp<int>(alpha_base_g + pInten_table16[1], 0, 16 * 255);
  2765. alpha_block_colors_x16[2] = basisu::clamp<int>(alpha_base_g + pInten_table16[2], 0, 16 * 255);
  2766. alpha_block_colors_x16[3] = basisu::clamp<int>(alpha_base_g + pInten_table16[3], 0, 16 * 255);
  2767. // clamp((base_r + base_g + base_b) * 16 + color_inten[s] * 48) + clamp(alpha_base_g * 16 + alpha_inten[as] * 16)
  2768. {
  2769. const uint32_t ex = 2;
  2770. int bx = x + ex - 1;
  2771. if (!pvrtc_wrap_addressing)
  2772. bx = basisu::clamp<int>(bx, 0, x_mask);
  2773. bx &= x_mask;
  2774. #define DO_ROW(ey) \
  2775. { \
  2776. const uint32_t e = pE_rows[ey][bx]; \
  2777. e0[ex][ey] = get_endpoint_l8(e, 0); \
  2778. e1[ex][ey] = get_endpoint_l8(e, 1); \
  2779. }
  2780. DO_ROW(0);
  2781. DO_ROW(1);
  2782. DO_ROW(2);
  2783. #undef DO_ROW
  2784. }
  2785. uint32_t mod = 0;
  2786. #define DO_PIX(lx, ly, w0, w1, w2, w3) \
  2787. { \
  2788. int ca_l = a0 * w0 + a1 * w1 + a2 * w2 + a3 * w3; \
  2789. int cb_l = b0 * w0 + b1 * w1 + b2 * w2 + b3 * w3; \
  2790. int cl = block_colors_y_x16[(src_block.m_bytes[4 + ly] >> (lx * 2)) & 3] + alpha_block_colors_x16[(pAlpha_selectors->m_selectors[ly] >> (lx * 2)) & 3]; \
  2791. int dl = cb_l - ca_l; \
  2792. int vl = cl - ca_l; \
  2793. int p = vl * 16; \
  2794. if (ca_l > cb_l) { p = -p; dl = -dl; } \
  2795. uint32_t m = 0; \
  2796. if (p > 3 * dl) m = (uint32_t)(1 << ((ly) * 8 + (lx) * 2)); \
  2797. if (p > 8 * dl) m = (uint32_t)(2 << ((ly) * 8 + (lx) * 2)); \
  2798. if (p > 13 * dl) m = (uint32_t)(3 << ((ly) * 8 + (lx) * 2)); \
  2799. mod |= m; \
  2800. }
  2801. {
  2802. const uint32_t ex = 0, ey = 0;
  2803. const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1];
  2804. const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1];
  2805. DO_PIX(0, 0, 4, 4, 4, 4);
  2806. DO_PIX(1, 0, 2, 6, 2, 6);
  2807. DO_PIX(0, 1, 2, 2, 6, 6);
  2808. DO_PIX(1, 1, 1, 3, 3, 9);
  2809. }
  2810. {
  2811. const uint32_t ex = 1, ey = 0;
  2812. const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1];
  2813. const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1];
  2814. DO_PIX(2, 0, 8, 0, 8, 0);
  2815. DO_PIX(3, 0, 6, 2, 6, 2);
  2816. DO_PIX(2, 1, 4, 0, 12, 0);
  2817. DO_PIX(3, 1, 3, 1, 9, 3);
  2818. }
  2819. {
  2820. const uint32_t ex = 0, ey = 1;
  2821. const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1];
  2822. const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1];
  2823. DO_PIX(0, 2, 8, 8, 0, 0);
  2824. DO_PIX(1, 2, 4, 12, 0, 0);
  2825. DO_PIX(0, 3, 6, 6, 2, 2);
  2826. DO_PIX(1, 3, 3, 9, 1, 3);
  2827. }
  2828. {
  2829. const uint32_t ex = 1, ey = 1;
  2830. const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1];
  2831. const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1];
  2832. DO_PIX(2, 2, 16, 0, 0, 0);
  2833. DO_PIX(3, 2, 12, 4, 0, 0);
  2834. DO_PIX(2, 3, 12, 0, 4, 0);
  2835. DO_PIX(3, 3, 9, 3, 3, 1);
  2836. }
  2837. #undef DO_PIX
  2838. pDst_block->m_modulation = mod;
  2839. e0[0][0] = e0[1][0]; e0[1][0] = e0[2][0];
  2840. e0[0][1] = e0[1][1]; e0[1][1] = e0[2][1];
  2841. e0[0][2] = e0[1][2]; e0[1][2] = e0[2][2];
  2842. e1[0][0] = e1[1][0]; e1[1][0] = e1[2][0];
  2843. e1[0][1] = e1[1][1]; e1[1][1] = e1[2][1];
  2844. e1[0][2] = e1[1][2]; e1[1][2] = e1[2][2];
  2845. } // x
  2846. } // y
  2847. }
  2848. #endif // BASISD_SUPPORT_PVRTC1
  2849. #if BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY
  2850. struct bc7_mode_6
  2851. {
  2852. struct
  2853. {
  2854. uint64_t m_mode : 7;
  2855. uint64_t m_r0 : 7;
  2856. uint64_t m_r1 : 7;
  2857. uint64_t m_g0 : 7;
  2858. uint64_t m_g1 : 7;
  2859. uint64_t m_b0 : 7;
  2860. uint64_t m_b1 : 7;
  2861. uint64_t m_a0 : 7;
  2862. uint64_t m_a1 : 7;
  2863. uint64_t m_p0 : 1;
  2864. } m_lo;
  2865. union
  2866. {
  2867. struct
  2868. {
  2869. uint64_t m_p1 : 1;
  2870. uint64_t m_s00 : 3;
  2871. uint64_t m_s10 : 4;
  2872. uint64_t m_s20 : 4;
  2873. uint64_t m_s30 : 4;
  2874. uint64_t m_s01 : 4;
  2875. uint64_t m_s11 : 4;
  2876. uint64_t m_s21 : 4;
  2877. uint64_t m_s31 : 4;
  2878. uint64_t m_s02 : 4;
  2879. uint64_t m_s12 : 4;
  2880. uint64_t m_s22 : 4;
  2881. uint64_t m_s32 : 4;
  2882. uint64_t m_s03 : 4;
  2883. uint64_t m_s13 : 4;
  2884. uint64_t m_s23 : 4;
  2885. uint64_t m_s33 : 4;
  2886. } m_hi;
  2887. uint64_t m_hi_bits;
  2888. };
  2889. };
  2890. static void convert_etc1s_to_bc7_m6(bc7_mode_6* pDst_block, const endpoint *pEndpoint, const selector* pSelector)
  2891. {
  2892. #if !BASISD_WRITE_NEW_BC7_TABLES
  2893. const uint32_t low_selector = pSelector->m_lo_selector;
  2894. const uint32_t high_selector = pSelector->m_hi_selector;
  2895. const uint32_t base_color_r = pEndpoint->m_color5.r;
  2896. const uint32_t base_color_g = pEndpoint->m_color5.g;
  2897. const uint32_t base_color_b = pEndpoint->m_color5.b;
  2898. const uint32_t inten_table = pEndpoint->m_inten5;
  2899. if (pSelector->m_num_unique_selectors <= 2)
  2900. {
  2901. // Only two unique selectors so just switch to block truncation coding (BTC) to avoid quality issues on extreme blocks.
  2902. pDst_block->m_lo.m_mode = 64;
  2903. pDst_block->m_lo.m_a0 = 127;
  2904. pDst_block->m_lo.m_a1 = 127;
  2905. color32 block_colors[4];
  2906. decoder_etc_block::get_block_colors5(block_colors, color32(base_color_r, base_color_g, base_color_b, 255), inten_table);
  2907. const uint32_t r0 = block_colors[low_selector].r;
  2908. const uint32_t g0 = block_colors[low_selector].g;
  2909. const uint32_t b0 = block_colors[low_selector].b;
  2910. const uint32_t low_bits0 = (r0 & 1) + (g0 & 1) + (b0 & 1);
  2911. uint32_t p0 = low_bits0 >= 2;
  2912. const uint32_t r1 = block_colors[high_selector].r;
  2913. const uint32_t g1 = block_colors[high_selector].g;
  2914. const uint32_t b1 = block_colors[high_selector].b;
  2915. const uint32_t low_bits1 = (r1 & 1) + (g1 & 1) + (b1 & 1);
  2916. uint32_t p1 = low_bits1 >= 2;
  2917. pDst_block->m_lo.m_r0 = r0 >> 1;
  2918. pDst_block->m_lo.m_g0 = g0 >> 1;
  2919. pDst_block->m_lo.m_b0 = b0 >> 1;
  2920. pDst_block->m_lo.m_p0 = p0;
  2921. pDst_block->m_lo.m_r1 = r1 >> 1;
  2922. pDst_block->m_lo.m_g1 = g1 >> 1;
  2923. pDst_block->m_lo.m_b1 = b1 >> 1;
  2924. uint32_t output_low_selector = 0;
  2925. uint32_t output_bit_offset = 1;
  2926. uint64_t output_hi_bits = p1;
  2927. for (uint32_t y = 0; y < 4; y++)
  2928. {
  2929. for (uint32_t x = 0; x < 4; x++)
  2930. {
  2931. uint32_t s = pSelector->get_selector(x, y);
  2932. uint32_t os = (s == low_selector) ? output_low_selector : (15 ^ output_low_selector);
  2933. uint32_t num_bits = 4;
  2934. if ((x | y) == 0)
  2935. {
  2936. if (os & 8)
  2937. {
  2938. pDst_block->m_lo.m_r0 = r1 >> 1;
  2939. pDst_block->m_lo.m_g0 = g1 >> 1;
  2940. pDst_block->m_lo.m_b0 = b1 >> 1;
  2941. pDst_block->m_lo.m_p0 = p1;
  2942. pDst_block->m_lo.m_r1 = r0 >> 1;
  2943. pDst_block->m_lo.m_g1 = g0 >> 1;
  2944. pDst_block->m_lo.m_b1 = b0 >> 1;
  2945. output_hi_bits &= ~1ULL;
  2946. output_hi_bits |= p0;
  2947. std::swap(p0, p1);
  2948. output_low_selector = 15;
  2949. os = 0;
  2950. }
  2951. num_bits = 3;
  2952. }
  2953. output_hi_bits |= (static_cast<uint64_t>(os) << output_bit_offset);
  2954. output_bit_offset += num_bits;
  2955. }
  2956. }
  2957. pDst_block->m_hi_bits = output_hi_bits;
  2958. assert(pDst_block->m_hi.m_p1 == p1);
  2959. return;
  2960. }
  2961. uint32_t selector_range_table = g_etc1_to_bc7_m6_selector_range_index[low_selector][high_selector];
  2962. const uint32_t* pTable_r = g_etc1_to_bc7_m6_table[base_color_r + inten_table * 32] + (selector_range_table * NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS);
  2963. const uint32_t* pTable_g = g_etc1_to_bc7_m6_table[base_color_g + inten_table * 32] + (selector_range_table * NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS);
  2964. const uint32_t* pTable_b = g_etc1_to_bc7_m6_table[base_color_b + inten_table * 32] + (selector_range_table * NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS);
  2965. #if 1
  2966. assert(NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS == 48);
  2967. uint32_t best_err0 = UINT_MAX, best_err1 = UINT_MAX;
  2968. #define DO_ITER2(idx) \
  2969. { \
  2970. uint32_t v0 = ((pTable_r[(idx)+0] + pTable_g[(idx)+0] + pTable_b[(idx)+0]) << 14) | ((idx) + 0); if (v0 < best_err0) best_err0 = v0; \
  2971. uint32_t v1 = ((pTable_r[(idx)+1] + pTable_g[(idx)+1] + pTable_b[(idx)+1]) << 14) | ((idx) + 1); if (v1 < best_err1) best_err1 = v1; \
  2972. }
  2973. #define DO_ITER4(idx) DO_ITER2(idx); DO_ITER2((idx) + 2);
  2974. #define DO_ITER8(idx) DO_ITER4(idx); DO_ITER4((idx) + 4);
  2975. #define DO_ITER16(idx) DO_ITER8(idx); DO_ITER8((idx) + 8);
  2976. DO_ITER16(0);
  2977. DO_ITER16(16);
  2978. DO_ITER16(32);
  2979. #undef DO_ITER2
  2980. #undef DO_ITER4
  2981. #undef DO_ITER8
  2982. #undef DO_ITER16
  2983. uint32_t best_err = basisu::minimum(best_err0, best_err1);
  2984. uint32_t best_mapping = best_err & 0xFF;
  2985. //best_err >>= 14;
  2986. #else
  2987. uint32_t best_err = UINT_MAX;
  2988. uint32_t best_mapping = 0;
  2989. assert((NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS % 2) == 0);
  2990. for (uint32_t m = 0; m < NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS; m += 2)
  2991. {
  2992. #define DO_ITER(idx) { uint32_t total_err = (pTable_r[idx] + pTable_g[idx] + pTable_b[idx]) & 0x3FFFF; if (total_err < best_err) { best_err = total_err; best_mapping = idx; } }
  2993. DO_ITER(m);
  2994. DO_ITER(m + 1);
  2995. #undef DO_ITER
  2996. }
  2997. #endif
  2998. pDst_block->m_lo.m_mode = 64;
  2999. pDst_block->m_lo.m_a0 = 127;
  3000. pDst_block->m_lo.m_a1 = 127;
  3001. uint64_t v = 0;
  3002. const uint8_t* pSelectors_xlat;
  3003. if (g_etc1_to_bc7_selector_mappings[best_mapping][pSelector->get_selector(0, 0)] & 8)
  3004. {
  3005. pDst_block->m_lo.m_r1 = (pTable_r[best_mapping] >> 18) & 0x7F;
  3006. pDst_block->m_lo.m_g1 = (pTable_g[best_mapping] >> 18) & 0x7F;
  3007. pDst_block->m_lo.m_b1 = (pTable_b[best_mapping] >> 18) & 0x7F;
  3008. pDst_block->m_lo.m_r0 = (pTable_r[best_mapping] >> 25) & 0x7F;
  3009. pDst_block->m_lo.m_g0 = (pTable_g[best_mapping] >> 25) & 0x7F;
  3010. pDst_block->m_lo.m_b0 = (pTable_b[best_mapping] >> 25) & 0x7F;
  3011. pDst_block->m_lo.m_p0 = 1;
  3012. pDst_block->m_hi.m_p1 = 0;
  3013. v = 0;
  3014. pSelectors_xlat = &g_etc1_to_bc7_selector_mappings_inv[best_mapping][0];
  3015. }
  3016. else
  3017. {
  3018. pDst_block->m_lo.m_r0 = (pTable_r[best_mapping] >> 18) & 0x7F;
  3019. pDst_block->m_lo.m_g0 = (pTable_g[best_mapping] >> 18) & 0x7F;
  3020. pDst_block->m_lo.m_b0 = (pTable_b[best_mapping] >> 18) & 0x7F;
  3021. pDst_block->m_lo.m_r1 = (pTable_r[best_mapping] >> 25) & 0x7F;
  3022. pDst_block->m_lo.m_g1 = (pTable_g[best_mapping] >> 25) & 0x7F;
  3023. pDst_block->m_lo.m_b1 = (pTable_b[best_mapping] >> 25) & 0x7F;
  3024. pDst_block->m_lo.m_p0 = 0;
  3025. pDst_block->m_hi.m_p1 = 1;
  3026. v = 1;
  3027. pSelectors_xlat = &g_etc1_to_bc7_selector_mappings[best_mapping][0];
  3028. }
  3029. uint64_t v1 = 0, v2 = 0, v3 = 0;
  3030. #define DO_X(x, s0, s1, s2, s3) { \
  3031. v |= ((uint64_t)pSelectors_xlat[(pSelector->m_selectors[0] >> ((x) * 2)) & 3] << (s0)); \
  3032. v1 |= ((uint64_t)pSelectors_xlat[(pSelector->m_selectors[1] >> ((x) * 2)) & 3] << (s1)); \
  3033. v2 |= ((uint64_t)pSelectors_xlat[(pSelector->m_selectors[2] >> ((x) * 2)) & 3] << (s2)); \
  3034. v3 |= ((uint64_t)pSelectors_xlat[(pSelector->m_selectors[3] >> ((x) * 2)) & 3] << (s3)); }
  3035. // 1 4 8 12
  3036. // 16 20 24 28
  3037. // 32 36 40 44
  3038. // 48 52 56 60
  3039. DO_X(0, 1, 16, 32, 48);
  3040. DO_X(1, 4, 20, 36, 52);
  3041. DO_X(2, 8, 24, 40, 56);
  3042. DO_X(3, 12, 28, 44, 60);
  3043. #undef DO_X
  3044. pDst_block->m_hi_bits = v | v1 | v2 | v3;
  3045. #endif
  3046. }
  3047. #endif // BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY
  3048. #if BASISD_SUPPORT_BC7_MODE5
  3049. static dxt_selector_range g_etc1_to_bc7_m5_selector_ranges[] =
  3050. {
  3051. { 0, 3 },
  3052. { 1, 3 },
  3053. { 0, 2 },
  3054. { 1, 2 },
  3055. { 2, 3 },
  3056. { 0, 1 },
  3057. };
  3058. const uint32_t NUM_ETC1_TO_BC7_M5_SELECTOR_RANGES = sizeof(g_etc1_to_bc7_m5_selector_ranges) / sizeof(g_etc1_to_bc7_m5_selector_ranges[0]);
  3059. static uint32_t g_etc1_to_bc7_m5_selector_range_index[4][4];
  3060. const uint32_t NUM_ETC1_TO_BC7_M5_SELECTOR_MAPPINGS = 10;
  3061. static const uint8_t g_etc1_to_bc7_m5_selector_mappings[NUM_ETC1_TO_BC7_M5_SELECTOR_MAPPINGS][4] =
  3062. {
  3063. { 0, 0, 1, 1 },
  3064. { 0, 0, 1, 2 },
  3065. { 0, 0, 1, 3 },
  3066. { 0, 0, 2, 3 },
  3067. { 0, 1, 1, 1 },
  3068. { 0, 1, 2, 2 },
  3069. { 0, 1, 2, 3 },
  3070. { 0, 2, 3, 3 },
  3071. { 1, 2, 2, 2 },
  3072. { 1, 2, 3, 3 },
  3073. };
  3074. struct etc1_to_bc7_m5_solution
  3075. {
  3076. uint8_t m_lo;
  3077. uint8_t m_hi;
  3078. uint16_t m_err;
  3079. };
  3080. static const etc1_to_bc7_m5_solution g_etc1_to_bc7_m5_color[32 * 8 * NUM_ETC1_TO_BC7_M5_SELECTOR_MAPPINGS * NUM_ETC1_TO_BC7_M5_SELECTOR_RANGES] = {
  3081. #include "basisu_transcoder_tables_bc7_m5_color.inc"
  3082. };
  3083. static dxt_selector_range g_etc1_to_bc7_m5a_selector_ranges[] =
  3084. {
  3085. { 0, 3 },
  3086. { 1, 3 },
  3087. { 0, 2 },
  3088. { 1, 2 },
  3089. { 2, 3 },
  3090. { 0, 1 }
  3091. };
  3092. const uint32_t NUM_ETC1_TO_BC7_M5A_SELECTOR_RANGES = sizeof(g_etc1_to_bc7_m5a_selector_ranges) / sizeof(g_etc1_to_bc7_m5a_selector_ranges[0]);
  3093. static uint32_t g_etc1_to_bc7_m5a_selector_range_index[4][4];
  3094. struct etc1_g_to_bc7_m5a_conversion
  3095. {
  3096. uint8_t m_lo, m_hi;
  3097. uint8_t m_trans;
  3098. };
  3099. static etc1_g_to_bc7_m5a_conversion g_etc1_g_to_bc7_m5a[8 * 32 * NUM_ETC1_TO_BC7_M5A_SELECTOR_RANGES] =
  3100. {
  3101. #include "basisu_transcoder_tables_bc7_m5_alpha.inc"
  3102. };
  3103. static inline uint32_t set_block_bits(uint8_t* pBytes, uint32_t val, uint32_t num_bits, uint32_t cur_ofs)
  3104. {
  3105. assert(num_bits < 32);
  3106. assert(val < (1ULL << num_bits));
  3107. uint32_t mask = (1 << num_bits) - 1;
  3108. while (num_bits)
  3109. {
  3110. const uint32_t n = basisu::minimum<uint32_t>(8 - (cur_ofs & 7), num_bits);
  3111. pBytes[cur_ofs >> 3] &= ~static_cast<uint8_t>(mask << (cur_ofs & 7));
  3112. pBytes[cur_ofs >> 3] |= static_cast<uint8_t>(val << (cur_ofs & 7));
  3113. val >>= n;
  3114. mask >>= n;
  3115. num_bits -= n;
  3116. cur_ofs += n;
  3117. }
  3118. return cur_ofs;
  3119. }
  3120. struct bc7_mode_5
  3121. {
  3122. union
  3123. {
  3124. struct
  3125. {
  3126. uint64_t m_mode : 6;
  3127. uint64_t m_rot : 2;
  3128. uint64_t m_r0 : 7;
  3129. uint64_t m_r1 : 7;
  3130. uint64_t m_g0 : 7;
  3131. uint64_t m_g1 : 7;
  3132. uint64_t m_b0 : 7;
  3133. uint64_t m_b1 : 7;
  3134. uint64_t m_a0 : 8;
  3135. uint64_t m_a1_0 : 6;
  3136. } m_lo;
  3137. uint64_t m_lo_bits;
  3138. };
  3139. union
  3140. {
  3141. struct
  3142. {
  3143. uint64_t m_a1_1 : 2;
  3144. // bit 2
  3145. uint64_t m_c00 : 1;
  3146. uint64_t m_c10 : 2;
  3147. uint64_t m_c20 : 2;
  3148. uint64_t m_c30 : 2;
  3149. uint64_t m_c01 : 2;
  3150. uint64_t m_c11 : 2;
  3151. uint64_t m_c21 : 2;
  3152. uint64_t m_c31 : 2;
  3153. uint64_t m_c02 : 2;
  3154. uint64_t m_c12 : 2;
  3155. uint64_t m_c22 : 2;
  3156. uint64_t m_c32 : 2;
  3157. uint64_t m_c03 : 2;
  3158. uint64_t m_c13 : 2;
  3159. uint64_t m_c23 : 2;
  3160. uint64_t m_c33 : 2;
  3161. // bit 33
  3162. uint64_t m_a00 : 1;
  3163. uint64_t m_a10 : 2;
  3164. uint64_t m_a20 : 2;
  3165. uint64_t m_a30 : 2;
  3166. uint64_t m_a01 : 2;
  3167. uint64_t m_a11 : 2;
  3168. uint64_t m_a21 : 2;
  3169. uint64_t m_a31 : 2;
  3170. uint64_t m_a02 : 2;
  3171. uint64_t m_a12 : 2;
  3172. uint64_t m_a22 : 2;
  3173. uint64_t m_a32 : 2;
  3174. uint64_t m_a03 : 2;
  3175. uint64_t m_a13 : 2;
  3176. uint64_t m_a23 : 2;
  3177. uint64_t m_a33 : 2;
  3178. } m_hi;
  3179. uint64_t m_hi_bits;
  3180. };
  3181. };
  3182. #if BASISD_WRITE_NEW_BC7_MODE5_TABLES
  3183. static void create_etc1_to_bc7_m5_color_conversion_table()
  3184. {
  3185. FILE* pFile = nullptr;
  3186. fopen_s(&pFile, "basisu_transcoder_tables_bc7_m5_color.inc", "w");
  3187. uint32_t n = 0;
  3188. for (int inten = 0; inten < 8; inten++)
  3189. {
  3190. for (uint32_t g = 0; g < 32; g++)
  3191. {
  3192. color32 block_colors[4];
  3193. decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
  3194. for (uint32_t sr = 0; sr < NUM_ETC1_TO_BC7_M5_SELECTOR_RANGES; sr++)
  3195. {
  3196. const uint32_t low_selector = g_etc1_to_bc7_m5_selector_ranges[sr].m_low;
  3197. const uint32_t high_selector = g_etc1_to_bc7_m5_selector_ranges[sr].m_high;
  3198. for (uint32_t m = 0; m < NUM_ETC1_TO_BC7_M5_SELECTOR_MAPPINGS; m++)
  3199. {
  3200. uint32_t best_lo = 0;
  3201. uint32_t best_hi = 0;
  3202. uint64_t best_err = UINT64_MAX;
  3203. for (uint32_t hi = 0; hi <= 127; hi++)
  3204. {
  3205. for (uint32_t lo = 0; lo <= 127; lo++)
  3206. {
  3207. uint32_t colors[4];
  3208. colors[0] = (lo << 1) | (lo >> 6);
  3209. colors[3] = (hi << 1) | (hi >> 6);
  3210. colors[1] = (colors[0] * (64 - 21) + colors[3] * 21 + 32) / 64;
  3211. colors[2] = (colors[0] * (64 - 43) + colors[3] * 43 + 32) / 64;
  3212. uint64_t total_err = 0;
  3213. for (uint32_t s = low_selector; s <= high_selector; s++)
  3214. {
  3215. int err = block_colors[s].g - colors[g_etc1_to_bc7_m5_selector_mappings[m][s]];
  3216. int err_scale = 1;
  3217. // Special case when the intensity table is 7, low_selector is 0, and high_selector is 3. In this extreme case, it's likely the encoder is trying to strongly favor
  3218. // the low/high selectors which are clamping to either 0 or 255.
  3219. if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
  3220. err_scale = 5;
  3221. total_err += (err * err) * err_scale;
  3222. }
  3223. if (total_err < best_err)
  3224. {
  3225. best_err = total_err;
  3226. best_lo = lo;
  3227. best_hi = hi;
  3228. }
  3229. }
  3230. }
  3231. best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF);
  3232. fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err);
  3233. n++;
  3234. if ((n & 31) == 31)
  3235. fprintf(pFile, "\n");
  3236. } // m
  3237. } // sr
  3238. } // g
  3239. } // inten
  3240. fclose(pFile);
  3241. }
  3242. static void create_etc1_to_bc7_m5_alpha_conversion_table()
  3243. {
  3244. FILE* pFile = nullptr;
  3245. fopen_s(&pFile, "basisu_transcoder_tables_bc7_m5_alpha.inc", "w");
  3246. uint32_t n = 0;
  3247. for (int inten = 0; inten < 8; inten++)
  3248. {
  3249. for (uint32_t g = 0; g < 32; g++)
  3250. {
  3251. color32 block_colors[4];
  3252. decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
  3253. for (uint32_t sr = 0; sr < NUM_ETC1_TO_BC7_M5A_SELECTOR_RANGES; sr++)
  3254. {
  3255. const uint32_t low_selector = g_etc1_to_bc7_m5a_selector_ranges[sr].m_low;
  3256. const uint32_t high_selector = g_etc1_to_bc7_m5a_selector_ranges[sr].m_high;
  3257. uint32_t best_lo = 0;
  3258. uint32_t best_hi = 0;
  3259. uint64_t best_err = UINT64_MAX;
  3260. uint32_t best_output_selectors = 0;
  3261. for (uint32_t hi = 0; hi <= 255; hi++)
  3262. {
  3263. for (uint32_t lo = 0; lo <= 255; lo++)
  3264. {
  3265. uint32_t colors[4];
  3266. colors[0] = lo;
  3267. colors[3] = hi;
  3268. colors[1] = (colors[0] * (64 - 21) + colors[3] * 21 + 32) / 64;
  3269. colors[2] = (colors[0] * (64 - 43) + colors[3] * 43 + 32) / 64;
  3270. uint64_t total_err = 0;
  3271. uint32_t output_selectors = 0;
  3272. for (uint32_t s = low_selector; s <= high_selector; s++)
  3273. {
  3274. int best_mapping_err = INT_MAX;
  3275. int best_k = 0;
  3276. for (int k = 0; k < 4; k++)
  3277. {
  3278. int mapping_err = block_colors[s].g - colors[k];
  3279. mapping_err *= mapping_err;
  3280. // Special case when the intensity table is 7, low_selector is 0, and high_selector is 3. In this extreme case, it's likely the encoder is trying to strongly favor
  3281. // the low/high selectors which are clamping to either 0 or 255.
  3282. if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
  3283. mapping_err *= 5;
  3284. if (mapping_err < best_mapping_err)
  3285. {
  3286. best_mapping_err = mapping_err;
  3287. best_k = k;
  3288. }
  3289. } // k
  3290. total_err += best_mapping_err;
  3291. output_selectors |= (best_k << (s * 2));
  3292. } // s
  3293. if (total_err < best_err)
  3294. {
  3295. best_err = total_err;
  3296. best_lo = lo;
  3297. best_hi = hi;
  3298. best_output_selectors = output_selectors;
  3299. }
  3300. } // lo
  3301. } // hi
  3302. fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, best_output_selectors);
  3303. n++;
  3304. if ((n & 31) == 31)
  3305. fprintf(pFile, "\n");
  3306. } // sr
  3307. } // g
  3308. } // inten
  3309. fclose(pFile);
  3310. }
  3311. #endif // BASISD_WRITE_NEW_BC7_MODE5_TABLES
  3312. struct bc7_m5_match_entry
  3313. {
  3314. uint8_t m_hi;
  3315. uint8_t m_lo;
  3316. };
  3317. static bc7_m5_match_entry g_bc7_m5_equals_1[256] =
  3318. {
  3319. {0,0},{1,0},{3,0},{4,0},{6,0},{7,0},{9,0},{10,0},{12,0},{13,0},{15,0},{16,0},{18,0},{20,0},{21,0},{23,0},
  3320. {24,0},{26,0},{27,0},{29,0},{30,0},{32,0},{33,0},{35,0},{36,0},{38,0},{39,0},{41,0},{42,0},{44,0},{45,0},{47,0},
  3321. {48,0},{50,0},{52,0},{53,0},{55,0},{56,0},{58,0},{59,0},{61,0},{62,0},{64,0},{65,0},{66,0},{68,0},{69,0},{71,0},
  3322. {72,0},{74,0},{75,0},{77,0},{78,0},{80,0},{82,0},{83,0},{85,0},{86,0},{88,0},{89,0},{91,0},{92,0},{94,0},{95,0},
  3323. {97,0},{98,0},{100,0},{101,0},{103,0},{104,0},{106,0},{107,0},{109,0},{110,0},{112,0},{114,0},{115,0},{117,0},{118,0},{120,0},
  3324. {121,0},{123,0},{124,0},{126,0},{127,0},{127,1},{126,2},{126,3},{127,3},{127,4},{126,5},{126,6},{127,6},{127,7},{126,8},{126,9},
  3325. {127,9},{127,10},{126,11},{126,12},{127,12},{127,13},{126,14},{125,15},{127,15},{126,16},{126,17},{127,17},{127,18},{126,19},{126,20},{127,20},
  3326. {127,21},{126,22},{126,23},{127,23},{127,24},{126,25},{126,26},{127,26},{127,27},{126,28},{126,29},{127,29},{127,30},{126,31},{126,32},{127,32},
  3327. {127,33},{126,34},{126,35},{127,35},{127,36},{126,37},{126,38},{127,38},{127,39},{126,40},{126,41},{127,41},{127,42},{126,43},{126,44},{127,44},
  3328. {127,45},{126,46},{125,47},{127,47},{126,48},{126,49},{127,49},{127,50},{126,51},{126,52},{127,52},{127,53},{126,54},{126,55},{127,55},{127,56},
  3329. {126,57},{126,58},{127,58},{127,59},{126,60},{126,61},{127,61},{127,62},{126,63},{125,64},{126,64},{126,65},{127,65},{127,66},{126,67},{126,68},
  3330. {127,68},{127,69},{126,70},{126,71},{127,71},{127,72},{126,73},{126,74},{127,74},{127,75},{126,76},{125,77},{127,77},{126,78},{126,79},{127,79},
  3331. {127,80},{126,81},{126,82},{127,82},{127,83},{126,84},{126,85},{127,85},{127,86},{126,87},{126,88},{127,88},{127,89},{126,90},{126,91},{127,91},
  3332. {127,92},{126,93},{126,94},{127,94},{127,95},{126,96},{126,97},{127,97},{127,98},{126,99},{126,100},{127,100},{127,101},{126,102},{126,103},{127,103},
  3333. {127,104},{126,105},{126,106},{127,106},{127,107},{126,108},{125,109},{127,109},{126,110},{126,111},{127,111},{127,112},{126,113},{126,114},{127,114},{127,115},
  3334. {126,116},{126,117},{127,117},{127,118},{126,119},{126,120},{127,120},{127,121},{126,122},{126,123},{127,123},{127,124},{126,125},{126,126},{127,126},{127,127}
  3335. };
  3336. static void transcoder_init_bc7_mode5()
  3337. {
  3338. #if 0
  3339. // This is a little too much work to do at init time, so precompute it.
  3340. for (int i = 0; i < 256; i++)
  3341. {
  3342. int lowest_e = 256;
  3343. for (int lo = 0; lo < 128; lo++)
  3344. {
  3345. for (int hi = 0; hi < 128; hi++)
  3346. {
  3347. const int lo_e = (lo << 1) | (lo >> 6);
  3348. const int hi_e = (hi << 1) | (hi >> 6);
  3349. // Selector 1
  3350. int v = (lo_e * (64 - 21) + hi_e * 21 + 32) >> 6;
  3351. int e = abs(v - i);
  3352. if (e < lowest_e)
  3353. {
  3354. g_bc7_m5_equals_1[i].m_hi = static_cast<uint8_t>(hi);
  3355. g_bc7_m5_equals_1[i].m_lo = static_cast<uint8_t>(lo);
  3356. lowest_e = e;
  3357. }
  3358. } // hi
  3359. } // lo
  3360. printf("{%u,%u},", g_bc7_m5_equals_1[i].m_hi, g_bc7_m5_equals_1[i].m_lo);
  3361. if ((i & 15) == 15) printf("\n");
  3362. }
  3363. #endif
  3364. for (uint32_t i = 0; i < NUM_ETC1_TO_BC7_M5_SELECTOR_RANGES; i++)
  3365. {
  3366. uint32_t l = g_etc1_to_bc7_m5_selector_ranges[i].m_low;
  3367. uint32_t h = g_etc1_to_bc7_m5_selector_ranges[i].m_high;
  3368. g_etc1_to_bc7_m5_selector_range_index[l][h] = i;
  3369. }
  3370. for (uint32_t i = 0; i < NUM_ETC1_TO_BC7_M5A_SELECTOR_RANGES; i++)
  3371. {
  3372. uint32_t l = g_etc1_to_bc7_m5a_selector_ranges[i].m_low;
  3373. uint32_t h = g_etc1_to_bc7_m5a_selector_ranges[i].m_high;
  3374. g_etc1_to_bc7_m5a_selector_range_index[l][h] = i;
  3375. }
  3376. }
  3377. static void convert_etc1s_to_bc7_m5_color(void* pDst, const endpoint* pEndpoints, const selector* pSelector)
  3378. {
  3379. bc7_mode_5* pDst_block = static_cast<bc7_mode_5*>(pDst);
  3380. static_cast<uint64_t*>(pDst)[0] = 0;
  3381. static_cast<uint64_t*>(pDst)[1] = 0;
  3382. pDst_block->m_lo.m_mode = 1 << 5;
  3383. pDst_block->m_lo.m_a0 = 255;
  3384. pDst_block->m_lo.m_a1_0 = 63;
  3385. pDst_block->m_hi.m_a1_1 = 3;
  3386. const uint32_t low_selector = pSelector->m_lo_selector;
  3387. const uint32_t high_selector = pSelector->m_hi_selector;
  3388. const uint32_t base_color_r = pEndpoints->m_color5.r;
  3389. const uint32_t base_color_g = pEndpoints->m_color5.g;
  3390. const uint32_t base_color_b = pEndpoints->m_color5.b;
  3391. const uint32_t inten_table = pEndpoints->m_inten5;
  3392. if (pSelector->m_num_unique_selectors == 1)
  3393. {
  3394. // Solid color block - use precomputed tables and set selectors to 1.
  3395. uint32_t r, g, b;
  3396. decoder_etc_block::get_block_color5(pEndpoints->m_color5, inten_table, low_selector, r, g, b);
  3397. pDst_block->m_lo.m_r0 = g_bc7_m5_equals_1[r].m_lo;
  3398. pDst_block->m_lo.m_g0 = g_bc7_m5_equals_1[g].m_lo;
  3399. pDst_block->m_lo.m_b0 = g_bc7_m5_equals_1[b].m_lo;
  3400. pDst_block->m_lo.m_r1 = g_bc7_m5_equals_1[r].m_hi;
  3401. pDst_block->m_lo.m_g1 = g_bc7_m5_equals_1[g].m_hi;
  3402. pDst_block->m_lo.m_b1 = g_bc7_m5_equals_1[b].m_hi;
  3403. set_block_bits((uint8_t*)pDst, 0x2aaaaaab, 31, 66);
  3404. return;
  3405. }
  3406. else if (pSelector->m_num_unique_selectors == 2)
  3407. {
  3408. // Only one or two unique selectors, so just switch to block truncation coding (BTC) to avoid quality issues on extreme blocks.
  3409. color32 block_colors[4];
  3410. decoder_etc_block::get_block_colors5(block_colors, color32(base_color_r, base_color_g, base_color_b, 255), inten_table);
  3411. const uint32_t r0 = block_colors[low_selector].r;
  3412. const uint32_t g0 = block_colors[low_selector].g;
  3413. const uint32_t b0 = block_colors[low_selector].b;
  3414. const uint32_t r1 = block_colors[high_selector].r;
  3415. const uint32_t g1 = block_colors[high_selector].g;
  3416. const uint32_t b1 = block_colors[high_selector].b;
  3417. pDst_block->m_lo.m_r0 = r0 >> 1;
  3418. pDst_block->m_lo.m_g0 = g0 >> 1;
  3419. pDst_block->m_lo.m_b0 = b0 >> 1;
  3420. pDst_block->m_lo.m_r1 = r1 >> 1;
  3421. pDst_block->m_lo.m_g1 = g1 >> 1;
  3422. pDst_block->m_lo.m_b1 = b1 >> 1;
  3423. uint32_t output_low_selector = 0, output_bit_offset = 0, output_bits = 0;
  3424. for (uint32_t y = 0; y < 4; y++)
  3425. {
  3426. for (uint32_t x = 0; x < 4; x++)
  3427. {
  3428. uint32_t s = pSelector->get_selector(x, y);
  3429. uint32_t os = (s == low_selector) ? output_low_selector : (3 ^ output_low_selector);
  3430. uint32_t num_bits = 2;
  3431. if ((x | y) == 0)
  3432. {
  3433. if (os & 2)
  3434. {
  3435. pDst_block->m_lo.m_r0 = r1 >> 1;
  3436. pDst_block->m_lo.m_g0 = g1 >> 1;
  3437. pDst_block->m_lo.m_b0 = b1 >> 1;
  3438. pDst_block->m_lo.m_r1 = r0 >> 1;
  3439. pDst_block->m_lo.m_g1 = g0 >> 1;
  3440. pDst_block->m_lo.m_b1 = b0 >> 1;
  3441. output_low_selector = 3;
  3442. os = 0;
  3443. }
  3444. num_bits = 1;
  3445. }
  3446. output_bits |= (os << output_bit_offset);
  3447. output_bit_offset += num_bits;
  3448. }
  3449. }
  3450. set_block_bits((uint8_t*)pDst, output_bits, 31, 66);
  3451. return;
  3452. }
  3453. const uint32_t selector_range_table = g_etc1_to_bc7_m5_selector_range_index[low_selector][high_selector];
  3454. //[32][8][RANGES][MAPPING]
  3455. const etc1_to_bc7_m5_solution* pTable_r = &g_etc1_to_bc7_m5_color[(inten_table * 32 + base_color_r) * (NUM_ETC1_TO_BC7_M5_SELECTOR_RANGES * NUM_ETC1_TO_BC7_M5_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1_TO_BC7_M5_SELECTOR_MAPPINGS];
  3456. const etc1_to_bc7_m5_solution* pTable_g = &g_etc1_to_bc7_m5_color[(inten_table * 32 + base_color_g) * (NUM_ETC1_TO_BC7_M5_SELECTOR_RANGES * NUM_ETC1_TO_BC7_M5_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1_TO_BC7_M5_SELECTOR_MAPPINGS];
  3457. const etc1_to_bc7_m5_solution* pTable_b = &g_etc1_to_bc7_m5_color[(inten_table * 32 + base_color_b) * (NUM_ETC1_TO_BC7_M5_SELECTOR_RANGES * NUM_ETC1_TO_BC7_M5_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1_TO_BC7_M5_SELECTOR_MAPPINGS];
  3458. uint32_t best_err = UINT_MAX;
  3459. uint32_t best_mapping = 0;
  3460. assert(NUM_ETC1_TO_BC7_M5_SELECTOR_MAPPINGS == 10);
  3461. #define DO_ITER(m) { uint32_t total_err = pTable_r[m].m_err + pTable_g[m].m_err + pTable_b[m].m_err; if (total_err < best_err) { best_err = total_err; best_mapping = m; } }
  3462. DO_ITER(0); DO_ITER(1); DO_ITER(2); DO_ITER(3); DO_ITER(4);
  3463. DO_ITER(5); DO_ITER(6); DO_ITER(7); DO_ITER(8); DO_ITER(9);
  3464. #undef DO_ITER
  3465. const uint8_t* pSelectors_xlat = &g_etc1_to_bc7_m5_selector_mappings[best_mapping][0];
  3466. uint32_t s_inv = 0;
  3467. if (pSelectors_xlat[pSelector->get_selector(0, 0)] & 2)
  3468. {
  3469. pDst_block->m_lo.m_r0 = pTable_r[best_mapping].m_hi;
  3470. pDst_block->m_lo.m_g0 = pTable_g[best_mapping].m_hi;
  3471. pDst_block->m_lo.m_b0 = pTable_b[best_mapping].m_hi;
  3472. pDst_block->m_lo.m_r1 = pTable_r[best_mapping].m_lo;
  3473. pDst_block->m_lo.m_g1 = pTable_g[best_mapping].m_lo;
  3474. pDst_block->m_lo.m_b1 = pTable_b[best_mapping].m_lo;
  3475. s_inv = 3;
  3476. }
  3477. else
  3478. {
  3479. pDst_block->m_lo.m_r0 = pTable_r[best_mapping].m_lo;
  3480. pDst_block->m_lo.m_g0 = pTable_g[best_mapping].m_lo;
  3481. pDst_block->m_lo.m_b0 = pTable_b[best_mapping].m_lo;
  3482. pDst_block->m_lo.m_r1 = pTable_r[best_mapping].m_hi;
  3483. pDst_block->m_lo.m_g1 = pTable_g[best_mapping].m_hi;
  3484. pDst_block->m_lo.m_b1 = pTable_b[best_mapping].m_hi;
  3485. }
  3486. uint32_t output_bits = 0, output_bit_ofs = 0;
  3487. for (uint32_t y = 0; y < 4; y++)
  3488. {
  3489. for (uint32_t x = 0; x < 4; x++)
  3490. {
  3491. const uint32_t s = pSelector->get_selector(x, y);
  3492. const uint32_t os = pSelectors_xlat[s] ^ s_inv;
  3493. output_bits |= (os << output_bit_ofs);
  3494. output_bit_ofs += (((x | y) == 0) ? 1 : 2);
  3495. }
  3496. }
  3497. set_block_bits((uint8_t*)pDst, output_bits, 31, 66);
  3498. }
  3499. static void convert_etc1s_to_bc7_m5_alpha(void* pDst, const endpoint* pEndpoints, const selector* pSelector)
  3500. {
  3501. bc7_mode_5* pDst_block = static_cast<bc7_mode_5*>(pDst);
  3502. const uint32_t low_selector = pSelector->m_lo_selector;
  3503. const uint32_t high_selector = pSelector->m_hi_selector;
  3504. const uint32_t base_color_r = pEndpoints->m_color5.r;
  3505. const uint32_t inten_table = pEndpoints->m_inten5;
  3506. if (pSelector->m_num_unique_selectors == 1)
  3507. {
  3508. uint32_t r;
  3509. decoder_etc_block::get_block_color5_r(pEndpoints->m_color5, inten_table, low_selector, r);
  3510. pDst_block->m_lo.m_a0 = r;
  3511. pDst_block->m_lo.m_a1_0 = r & 63;
  3512. pDst_block->m_hi.m_a1_1 = r >> 6;
  3513. return;
  3514. }
  3515. else if (pSelector->m_num_unique_selectors == 2)
  3516. {
  3517. // Only one or two unique selectors, so just switch to block truncation coding (BTC) to avoid quality issues on extreme blocks.
  3518. int block_colors[4];
  3519. decoder_etc_block::get_block_colors5_g(block_colors, pEndpoints->m_color5, inten_table);
  3520. pDst_block->m_lo.m_a0 = block_colors[low_selector];
  3521. pDst_block->m_lo.m_a1_0 = block_colors[high_selector] & 63;
  3522. pDst_block->m_hi.m_a1_1 = block_colors[high_selector] >> 6;
  3523. uint32_t output_low_selector = 0, output_bit_offset = 0, output_bits = 0;
  3524. for (uint32_t y = 0; y < 4; y++)
  3525. {
  3526. for (uint32_t x = 0; x < 4; x++)
  3527. {
  3528. const uint32_t s = pSelector->get_selector(x, y);
  3529. uint32_t os = (s == low_selector) ? output_low_selector : (3 ^ output_low_selector);
  3530. uint32_t num_bits = 2;
  3531. if ((x | y) == 0)
  3532. {
  3533. if (os & 2)
  3534. {
  3535. pDst_block->m_lo.m_a0 = block_colors[high_selector];
  3536. pDst_block->m_lo.m_a1_0 = block_colors[low_selector] & 63;
  3537. pDst_block->m_hi.m_a1_1 = block_colors[low_selector] >> 6;
  3538. output_low_selector = 3;
  3539. os = 0;
  3540. }
  3541. num_bits = 1;
  3542. }
  3543. output_bits |= (os << output_bit_offset);
  3544. output_bit_offset += num_bits;
  3545. }
  3546. }
  3547. set_block_bits((uint8_t*)pDst, output_bits, 31, 97);
  3548. return;
  3549. }
  3550. const uint32_t selector_range_table = g_etc1_to_bc7_m5a_selector_range_index[low_selector][high_selector];
  3551. const etc1_g_to_bc7_m5a_conversion* pTable = &g_etc1_g_to_bc7_m5a[inten_table * (32 * NUM_ETC1_TO_BC7_M5A_SELECTOR_RANGES) + base_color_r * NUM_ETC1_TO_BC7_M5A_SELECTOR_RANGES + selector_range_table];
  3552. pDst_block->m_lo.m_a0 = pTable->m_lo;
  3553. pDst_block->m_lo.m_a1_0 = pTable->m_hi & 63;
  3554. pDst_block->m_hi.m_a1_1 = pTable->m_hi >> 6;
  3555. uint32_t output_bit_offset = 0, output_bits = 0, selector_trans = pTable->m_trans;
  3556. for (uint32_t y = 0; y < 4; y++)
  3557. {
  3558. for (uint32_t x = 0; x < 4; x++)
  3559. {
  3560. const uint32_t s = pSelector->get_selector(x, y);
  3561. uint32_t os = (selector_trans >> (s * 2)) & 3;
  3562. uint32_t num_bits = 2;
  3563. if ((x | y) == 0)
  3564. {
  3565. if (os & 2)
  3566. {
  3567. pDst_block->m_lo.m_a0 = pTable->m_hi;
  3568. pDst_block->m_lo.m_a1_0 = pTable->m_lo & 63;
  3569. pDst_block->m_hi.m_a1_1 = pTable->m_lo >> 6;
  3570. selector_trans ^= 0xFF;
  3571. os ^= 3;
  3572. }
  3573. num_bits = 1;
  3574. }
  3575. output_bits |= (os << output_bit_offset);
  3576. output_bit_offset += num_bits;
  3577. }
  3578. }
  3579. set_block_bits((uint8_t*)pDst, output_bits, 31, 97);
  3580. }
  3581. #endif // BASISD_SUPPORT_BC7_MODE5
  3582. #if BASISD_SUPPORT_ETC2_EAC_A8
  3583. static void convert_etc1s_to_etc2_eac_a8(eac_a8_block* pDst_block, const endpoint* pEndpoints, const selector* pSelector)
  3584. {
  3585. const uint32_t low_selector = pSelector->m_lo_selector;
  3586. const uint32_t high_selector = pSelector->m_hi_selector;
  3587. const color32& base_color = pEndpoints->m_color5;
  3588. const uint32_t inten_table = pEndpoints->m_inten5;
  3589. if (low_selector == high_selector)
  3590. {
  3591. uint32_t r;
  3592. decoder_etc_block::get_block_color5_r(base_color, inten_table, low_selector, r);
  3593. // Constant alpha block
  3594. // Select table 13, use selector 4 (0), set multiplier to 1 and base color g
  3595. pDst_block->m_base = r;
  3596. pDst_block->m_table = 13;
  3597. pDst_block->m_multiplier = 1;
  3598. // selectors are all 4's
  3599. static const uint8_t s_etc2_eac_a8_sel4[6] = { 0x92, 0x49, 0x24, 0x92, 0x49, 0x24 };
  3600. memcpy(pDst_block->m_selectors, s_etc2_eac_a8_sel4, sizeof(s_etc2_eac_a8_sel4));
  3601. return;
  3602. }
  3603. uint32_t selector_range_table = 0;
  3604. for (selector_range_table = 0; selector_range_table < NUM_ETC2_EAC_A8_SELECTOR_RANGES; selector_range_table++)
  3605. if ((low_selector == s_etc2_eac_a8_selector_ranges[selector_range_table].m_low) && (high_selector == s_etc2_eac_a8_selector_ranges[selector_range_table].m_high))
  3606. break;
  3607. if (selector_range_table >= NUM_ETC2_EAC_A8_SELECTOR_RANGES)
  3608. selector_range_table = 0;
  3609. const etc1_g_to_etc2_a8_conversion* pTable_entry = &s_etc1_g_to_etc2_a8[base_color.r + inten_table * 32][selector_range_table];
  3610. pDst_block->m_base = pTable_entry->m_base;
  3611. pDst_block->m_table = pTable_entry->m_table_mul >> 4;
  3612. pDst_block->m_multiplier = pTable_entry->m_table_mul & 15;
  3613. uint64_t selector_bits = 0;
  3614. for (uint32_t y = 0; y < 4; y++)
  3615. {
  3616. for (uint32_t x = 0; x < 4; x++)
  3617. {
  3618. uint32_t s = pSelector->get_selector(x, y);
  3619. uint32_t ds = (pTable_entry->m_trans >> (s * 3)) & 7;
  3620. const uint32_t dst_ofs = 45 - (y + x * 4) * 3;
  3621. selector_bits |= (static_cast<uint64_t>(ds) << dst_ofs);
  3622. }
  3623. }
  3624. pDst_block->set_selector_bits(selector_bits);
  3625. }
  3626. #endif // BASISD_SUPPORT_ETC2_EAC_A8
  3627. // ASTC
  3628. struct etc1_to_astc_solution
  3629. {
  3630. uint8_t m_lo;
  3631. uint8_t m_hi;
  3632. uint16_t m_err;
  3633. };
  3634. #if BASISD_SUPPORT_ASTC
  3635. static dxt_selector_range g_etc1_to_astc_selector_ranges[] =
  3636. {
  3637. { 0, 3 },
  3638. { 1, 3 },
  3639. { 0, 2 },
  3640. { 1, 2 },
  3641. { 2, 3 },
  3642. { 0, 1 },
  3643. };
  3644. const uint32_t NUM_ETC1_TO_ASTC_SELECTOR_RANGES = sizeof(g_etc1_to_astc_selector_ranges) / sizeof(g_etc1_to_astc_selector_ranges[0]);
  3645. static uint32_t g_etc1_to_astc_selector_range_index[4][4];
  3646. const uint32_t NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS = 10;
  3647. static const uint8_t g_etc1_to_astc_selector_mappings[NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS][4] =
  3648. {
  3649. { 0, 0, 1, 1 },
  3650. { 0, 0, 1, 2 },
  3651. { 0, 0, 1, 3 },
  3652. { 0, 0, 2, 3 },
  3653. { 0, 1, 1, 1 },
  3654. { 0, 1, 2, 2 },
  3655. { 0, 1, 2, 3 },
  3656. { 0, 2, 3, 3 },
  3657. { 1, 2, 2, 2 },
  3658. { 1, 2, 3, 3 },
  3659. };
  3660. static const etc1_to_astc_solution g_etc1_to_astc[32 * 8 * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS * NUM_ETC1_TO_ASTC_SELECTOR_RANGES] = {
  3661. #include "basisu_transcoder_tables_astc.inc"
  3662. };
  3663. // The best selector mapping to use given a base base+inten table and used selector range for converting grayscale data.
  3664. static uint8_t g_etc1_to_astc_best_grayscale_mapping[32][8][NUM_ETC1_TO_ASTC_SELECTOR_RANGES];
  3665. #if BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY
  3666. static const etc1_to_astc_solution g_etc1_to_astc_0_255[32 * 8 * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS * NUM_ETC1_TO_ASTC_SELECTOR_RANGES] = {
  3667. #include "basisu_transcoder_tables_astc_0_255.inc"
  3668. };
  3669. static uint8_t g_etc1_to_astc_best_grayscale_mapping_0_255[32][8][NUM_ETC1_TO_ASTC_SELECTOR_RANGES];
  3670. #endif
  3671. static uint32_t g_ise_to_unquant[48];
  3672. #if BASISD_WRITE_NEW_ASTC_TABLES
  3673. static void create_etc1_to_astc_conversion_table_0_47()
  3674. {
  3675. FILE* pFile = nullptr;
  3676. fopen_s(&pFile, "basisu_transcoder_tables_astc.inc", "w");
  3677. uint32_t n = 0;
  3678. for (int inten = 0; inten < 8; inten++)
  3679. {
  3680. for (uint32_t g = 0; g < 32; g++)
  3681. {
  3682. color32 block_colors[4];
  3683. decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
  3684. for (uint32_t sr = 0; sr < NUM_ETC1_TO_ASTC_SELECTOR_RANGES; sr++)
  3685. {
  3686. const uint32_t low_selector = g_etc1_to_astc_selector_ranges[sr].m_low;
  3687. const uint32_t high_selector = g_etc1_to_astc_selector_ranges[sr].m_high;
  3688. uint32_t mapping_best_low[NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  3689. uint32_t mapping_best_high[NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  3690. uint64_t mapping_best_err[NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  3691. uint64_t highest_best_err = 0;
  3692. for (uint32_t m = 0; m < NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS; m++)
  3693. {
  3694. uint32_t best_lo = 0;
  3695. uint32_t best_hi = 0;
  3696. uint64_t best_err = UINT64_MAX;
  3697. for (uint32_t hi = 0; hi <= 47; hi++)
  3698. {
  3699. for (uint32_t lo = 0; lo <= 47; lo++)
  3700. {
  3701. uint32_t colors[4];
  3702. for (uint32_t s = 0; s < 4; s++)
  3703. {
  3704. uint32_t s_scaled = s | (s << 2) | (s << 4);
  3705. if (s_scaled > 32)
  3706. s_scaled++;
  3707. uint32_t c0 = g_ise_to_unquant[lo] | (g_ise_to_unquant[lo] << 8);
  3708. uint32_t c1 = g_ise_to_unquant[hi] | (g_ise_to_unquant[hi] << 8);
  3709. colors[s] = ((c0 * (64 - s_scaled) + c1 * s_scaled + 32) / 64) >> 8;
  3710. }
  3711. uint64_t total_err = 0;
  3712. for (uint32_t s = low_selector; s <= high_selector; s++)
  3713. {
  3714. int err = block_colors[s].g - colors[g_etc1_to_astc_selector_mappings[m][s]];
  3715. int err_scale = 1;
  3716. // Special case when the intensity table is 7, low_selector is 0, and high_selector is 3. In this extreme case, it's likely the encoder is trying to strongly favor
  3717. // the low/high selectors which are clamping to either 0 or 255.
  3718. if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
  3719. err_scale = 8;
  3720. total_err += (err * err) * err_scale;
  3721. }
  3722. if (total_err < best_err)
  3723. {
  3724. best_err = total_err;
  3725. best_lo = lo;
  3726. best_hi = hi;
  3727. }
  3728. }
  3729. }
  3730. mapping_best_low[m] = best_lo;
  3731. mapping_best_high[m] = best_hi;
  3732. mapping_best_err[m] = best_err;
  3733. highest_best_err = basisu::maximum(highest_best_err, best_err);
  3734. } // m
  3735. for (uint32_t m = 0; m < NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS; m++)
  3736. {
  3737. uint64_t err = mapping_best_err[m];
  3738. err = basisu::minimum<uint64_t>(err, 0xFFFF);
  3739. fprintf(pFile, "{%u,%u,%u},", mapping_best_low[m], mapping_best_high[m], (uint32_t)err);
  3740. n++;
  3741. if ((n & 31) == 31)
  3742. fprintf(pFile, "\n");
  3743. } // m
  3744. } // sr
  3745. } // g
  3746. } // inten
  3747. fclose(pFile);
  3748. }
  3749. static void create_etc1_to_astc_conversion_table_0_255()
  3750. {
  3751. FILE* pFile = nullptr;
  3752. fopen_s(&pFile, "basisu_transcoder_tables_astc_0_255.inc", "w");
  3753. uint32_t n = 0;
  3754. for (int inten = 0; inten < 8; inten++)
  3755. {
  3756. for (uint32_t g = 0; g < 32; g++)
  3757. {
  3758. color32 block_colors[4];
  3759. decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
  3760. for (uint32_t sr = 0; sr < NUM_ETC1_TO_ASTC_SELECTOR_RANGES; sr++)
  3761. {
  3762. const uint32_t low_selector = g_etc1_to_astc_selector_ranges[sr].m_low;
  3763. const uint32_t high_selector = g_etc1_to_astc_selector_ranges[sr].m_high;
  3764. uint32_t mapping_best_low[NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  3765. uint32_t mapping_best_high[NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  3766. uint64_t mapping_best_err[NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  3767. uint64_t highest_best_err = 0;
  3768. for (uint32_t m = 0; m < NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS; m++)
  3769. {
  3770. uint32_t best_lo = 0;
  3771. uint32_t best_hi = 0;
  3772. uint64_t best_err = UINT64_MAX;
  3773. for (uint32_t hi = 0; hi <= 255; hi++)
  3774. {
  3775. for (uint32_t lo = 0; lo <= 255; lo++)
  3776. {
  3777. uint32_t colors[4];
  3778. for (uint32_t s = 0; s < 4; s++)
  3779. {
  3780. uint32_t s_scaled = s | (s << 2) | (s << 4);
  3781. if (s_scaled > 32)
  3782. s_scaled++;
  3783. uint32_t c0 = lo | (lo << 8);
  3784. uint32_t c1 = hi | (hi << 8);
  3785. colors[s] = ((c0 * (64 - s_scaled) + c1 * s_scaled + 32) / 64) >> 8;
  3786. }
  3787. uint64_t total_err = 0;
  3788. for (uint32_t s = low_selector; s <= high_selector; s++)
  3789. {
  3790. int err = block_colors[s].g - colors[g_etc1_to_astc_selector_mappings[m][s]];
  3791. // Special case when the intensity table is 7, low_selector is 0, and high_selector is 3. In this extreme case, it's likely the encoder is trying to strongly favor
  3792. // the low/high selectors which are clamping to either 0 or 255.
  3793. int err_scale = 1;
  3794. if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
  3795. err_scale = 8;
  3796. total_err += (err * err) * err_scale;
  3797. }
  3798. if (total_err < best_err)
  3799. {
  3800. best_err = total_err;
  3801. best_lo = lo;
  3802. best_hi = hi;
  3803. }
  3804. }
  3805. }
  3806. mapping_best_low[m] = best_lo;
  3807. mapping_best_high[m] = best_hi;
  3808. mapping_best_err[m] = best_err;
  3809. highest_best_err = basisu::maximum(highest_best_err, best_err);
  3810. } // m
  3811. for (uint32_t m = 0; m < NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS; m++)
  3812. {
  3813. uint64_t err = mapping_best_err[m];
  3814. err = basisu::minimum<uint64_t>(err, 0xFFFF);
  3815. fprintf(pFile, "{%u,%u,%u},", mapping_best_low[m], mapping_best_high[m], (uint32_t)err);
  3816. n++;
  3817. if ((n & 31) == 31)
  3818. fprintf(pFile, "\n");
  3819. } // m
  3820. } // sr
  3821. } // g
  3822. } // inten
  3823. fclose(pFile);
  3824. }
  3825. #endif
  3826. #endif
  3827. #if BASISD_SUPPORT_ASTC
  3828. struct astc_block_params
  3829. {
  3830. // 2 groups of 5, but only a max of 8 are used (RRGGBBAA00)
  3831. uint8_t m_endpoints[10];
  3832. uint8_t m_weights[32];
  3833. };
  3834. // Table encodes 5 trits to 8 output bits. 3^5 entries.
  3835. // Inverse of the trit bit manipulation process in https://www.khronos.org/registry/DataFormat/specs/1.2/dataformat.1.2.html#astc-integer-sequence-encoding
  3836. static const uint8_t g_astc_trit_encode[243] = { 0, 1, 2, 4, 5, 6, 8, 9, 10, 16, 17, 18, 20, 21, 22, 24, 25, 26, 3, 7, 11, 19, 23, 27, 12, 13, 14, 32, 33, 34, 36, 37, 38, 40, 41, 42, 48, 49, 50, 52, 53, 54, 56, 57, 58, 35, 39,
  3837. 43, 51, 55, 59, 44, 45, 46, 64, 65, 66, 68, 69, 70, 72, 73, 74, 80, 81, 82, 84, 85, 86, 88, 89, 90, 67, 71, 75, 83, 87, 91, 76, 77, 78, 128, 129, 130, 132, 133, 134, 136, 137, 138, 144, 145, 146, 148, 149, 150, 152, 153, 154,
  3838. 131, 135, 139, 147, 151, 155, 140, 141, 142, 160, 161, 162, 164, 165, 166, 168, 169, 170, 176, 177, 178, 180, 181, 182, 184, 185, 186, 163, 167, 171, 179, 183, 187, 172, 173, 174, 192, 193, 194, 196, 197, 198, 200, 201, 202,
  3839. 208, 209, 210, 212, 213, 214, 216, 217, 218, 195, 199, 203, 211, 215, 219, 204, 205, 206, 96, 97, 98, 100, 101, 102, 104, 105, 106, 112, 113, 114, 116, 117, 118, 120, 121, 122, 99, 103, 107, 115, 119, 123, 108, 109, 110, 224,
  3840. 225, 226, 228, 229, 230, 232, 233, 234, 240, 241, 242, 244, 245, 246, 248, 249, 250, 227, 231, 235, 243, 247, 251, 236, 237, 238, 28, 29, 30, 60, 61, 62, 92, 93, 94, 156, 157, 158, 188, 189, 190, 220, 221, 222, 31, 63, 95, 159,
  3841. 191, 223, 124, 125, 126 };
  3842. // Writes bits to output in an endian safe way
  3843. static inline void astc_set_bits(uint32_t *pOutput, int &bit_pos, uint32_t value, int total_bits)
  3844. {
  3845. uint8_t* pBytes = reinterpret_cast<uint8_t*>(pOutput);
  3846. while (total_bits)
  3847. {
  3848. const uint32_t bits_to_write = std::min(total_bits, 8 - (bit_pos & 7));
  3849. pBytes[bit_pos >> 3] |= static_cast<uint8_t>(value << (bit_pos & 7));
  3850. bit_pos += bits_to_write;
  3851. total_bits -= bits_to_write;
  3852. value >>= bits_to_write;
  3853. }
  3854. }
  3855. // Extracts bits [low,high]
  3856. static inline uint32_t astc_extract_bits(uint32_t bits, int low, int high)
  3857. {
  3858. return (bits >> low) & ((1 << (high - low + 1)) - 1);
  3859. }
  3860. // Encodes 5 values to output, usable for any range that uses trits and bits
  3861. static void astc_encode_trits(uint32_t *pOutput, const uint8_t *pValues, int& bit_pos, int n)
  3862. {
  3863. // First extract the trits and the bits from the 5 input values
  3864. int trits = 0, bits[5];
  3865. const uint32_t bit_mask = (1 << n) - 1;
  3866. for (int i = 0; i < 5; i++)
  3867. {
  3868. static const int s_muls[5] = { 1, 3, 9, 27, 81 };
  3869. const int t = pValues[i] >> n;
  3870. trits += t * s_muls[i];
  3871. bits[i] = pValues[i] & bit_mask;
  3872. }
  3873. // Encode the trits, by inverting the bit manipulations done by the decoder, converting 5 trits into 8-bits.
  3874. // See https://www.khronos.org/registry/DataFormat/specs/1.2/dataformat.1.2.html#astc-integer-sequence-encoding
  3875. assert(trits < 243);
  3876. const int T = g_astc_trit_encode[trits];
  3877. // Now interleave the 8 encoded trit bits with the bits to form the encoded output. See table 94.
  3878. astc_set_bits(pOutput, bit_pos, bits[0] | (astc_extract_bits(T, 0, 1) << n) | (bits[1] << (2 + n)), n * 2 + 2);
  3879. astc_set_bits(pOutput, bit_pos, astc_extract_bits(T, 2, 3) | (bits[2] << 2) | (astc_extract_bits(T, 4, 4) << (2 + n)) | (bits[3] << (3 + n)) | (astc_extract_bits(T, 5, 6) << (3 + n * 2)) |
  3880. (bits[4] << (5 + n * 2)) | (astc_extract_bits(T, 7, 7) << (5 + n * 3)), n * 3 + 6);
  3881. }
  3882. // Packs a single format ASTC block using Color Endpoint Mode 12 (LDR RGBA direct), endpoint BISE range 13, 2-bit weights (range 2).
  3883. // We're always going to output blocks containing alpha, even if the input doesn't have alpha, for simplicity.
  3884. // Each block always has 4x4 weights, uses range 13 BISE encoding on the endpoints (0-47), and each weight ranges from 0-3. This encoding should be roughly equal in quality vs. BC1 for color.
  3885. // 8 total endpoints, stored as RGBA LH LH LH LH order, each ranging from 0-47.
  3886. // Note the input [0,47] endpoint values are not linear - they are encoded as outlined in the ASTC spec:
  3887. // https://www.khronos.org/registry/DataFormat/specs/1.2/dataformat.1.2.html#astc-endpoint-unquantization
  3888. // 32 total weights, stored as 16 CA CA, each ranging from 0-3.
  3889. static void astc_pack_block_cem_12_weight_range2(uint32_t *pOutput, const astc_block_params* pBlock)
  3890. {
  3891. uint8_t* pBytes = reinterpret_cast<uint8_t*>(pOutput);
  3892. // Write constant block mode, color component selector, number of partitions, color endpoint mode
  3893. // https://www.khronos.org/registry/DataFormat/specs/1.2/dataformat.1.2.html#_block_mode
  3894. pBytes[0] = 0x42; pBytes[1] = 0x84; pBytes[2] = 0x01; pBytes[3] = 0x00;
  3895. pBytes[4] = 0x00; pBytes[5] = 0x00; pBytes[6] = 0x00; pBytes[7] = 0xc0;
  3896. pOutput[2] = 0;
  3897. pOutput[3] = 0;
  3898. // Pack 8 endpoints (each ranging between [0,47]) using BISE starting at bit 17
  3899. int bit_pos = 17;
  3900. astc_encode_trits(pOutput, pBlock->m_endpoints, bit_pos, 4);
  3901. astc_encode_trits(pOutput, pBlock->m_endpoints + 5, bit_pos, 4);
  3902. // Pack 32 2-bit weights, which are stored from the top down into the block in opposite bit order.
  3903. for (uint32_t i = 0; i < 32; i++)
  3904. {
  3905. static const uint8_t s_reverse_bits[4] = { 0, 2, 1, 3 };
  3906. const uint32_t ofs = 126 - (i * 2);
  3907. pBytes[ofs >> 3] |= (s_reverse_bits[pBlock->m_weights[i]] << (ofs & 7));
  3908. }
  3909. }
  3910. // CEM mode 12 (LDR RGBA Direct), 8-bit endpoints, 1-bit weights
  3911. // This ASTC mode is basically block truncation coding (BTC) using 1-bit weights and 8-bit/component endpoints - very convenient.
  3912. static void astc_pack_block_cem_12_weight_range0(uint32_t* pOutput, const astc_block_params* pBlock)
  3913. {
  3914. uint8_t* pBytes = reinterpret_cast<uint8_t*>(pOutput);
  3915. // Write constant block mode, color component selector, number of partitions, color endpoint mode
  3916. // https://www.khronos.org/registry/DataFormat/specs/1.2/dataformat.1.2.html#_block_mode
  3917. pBytes[0] = 0x41; pBytes[1] = 0x84; pBytes[2] = 0x01; pBytes[3] = 0x00;
  3918. pOutput[1] = 0;
  3919. pBytes[8] = 0x00; pBytes[9] = 0x00; pBytes[10] = 0x00; pBytes[11] = 0xc0;
  3920. pOutput[3] = 0;
  3921. // Pack 8 endpoints (each ranging between [0,255]) as 8-bits starting at bit 17
  3922. int bit_pos = 17;
  3923. for (uint32_t i = 0; i < 8; i++)
  3924. astc_set_bits(pOutput, bit_pos, pBlock->m_endpoints[i], 8);
  3925. // Pack 32 1-bit weights, which are stored from the top down into the block in opposite bit order.
  3926. for (uint32_t i = 0; i < 32; i++)
  3927. {
  3928. const uint32_t ofs = 127 - i;
  3929. pBytes[ofs >> 3] |= (pBlock->m_weights[i] << (ofs & 7));
  3930. }
  3931. }
  3932. #if BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY
  3933. // Optional 8-bit endpoint packing functions.
  3934. // CEM mode 4 (LDR Luminance+Alpha Direct), 8-bit endpoints, 2 bit weights
  3935. static void astc_pack_block_cem_4_weight_range2(uint32_t* pOutput, const astc_block_params* pBlock)
  3936. {
  3937. uint8_t* pBytes = reinterpret_cast<uint8_t*>(pOutput);
  3938. // Write constant block mode, color component selector, number of partitions, color endpoint mode
  3939. // https://www.khronos.org/registry/DataFormat/specs/1.2/dataformat.1.2.html#_block_mode
  3940. pBytes[0] = 0x42; pBytes[1] = 0x84; pBytes[2] = 0x00; pBytes[3] = 0x00;
  3941. pBytes[4] = 0x00; pBytes[5] = 0x00; pBytes[6] = 0x00; pBytes[7] = 0xc0;
  3942. pOutput[2] = 0;
  3943. pOutput[3] = 0;
  3944. // Pack 4 endpoints (each ranging between [0,255]) as 8-bits starting at bit 17
  3945. int bit_pos = 17;
  3946. for (uint32_t i = 0; i < 4; i++)
  3947. astc_set_bits(pOutput, bit_pos, pBlock->m_endpoints[i], 8);
  3948. // Pack 32 2-bit weights, which are stored from the top down into the block in opposite bit order.
  3949. for (uint32_t i = 0; i < 32; i++)
  3950. {
  3951. static const uint8_t s_reverse_bits[4] = { 0, 2, 1, 3 };
  3952. const uint32_t ofs = 126 - (i * 2);
  3953. pBytes[ofs >> 3] |= (s_reverse_bits[pBlock->m_weights[i]] << (ofs & 7));
  3954. }
  3955. }
  3956. // CEM mode 8 (LDR RGB Direct), 8-bit endpoints, 2 bit weights
  3957. static void astc_pack_block_cem_8_weight_range2(uint32_t* pOutput, const astc_block_params* pBlock)
  3958. {
  3959. uint8_t* pBytes = reinterpret_cast<uint8_t*>(pOutput);
  3960. // Write constant block mode, color component selector, number of partitions, color endpoint mode
  3961. // https://www.khronos.org/registry/DataFormat/specs/1.2/dataformat.1.2.html#_block_mode
  3962. pBytes[0] = 0x42; pBytes[1] = 0x00; pBytes[2] = 0x01; pBytes[3] = 0x00;
  3963. pOutput[1] = 0;
  3964. pOutput[2] = 0;
  3965. pOutput[3] = 0;
  3966. // Pack 6 endpoints (each ranging between [0,255]) as 8-bits starting at bit 17
  3967. int bit_pos = 17;
  3968. for (uint32_t i = 0; i < 6; i++)
  3969. astc_set_bits(pOutput, bit_pos, pBlock->m_endpoints[i], 8);
  3970. // Pack 16 2-bit weights, which are stored from the top down into the block in opposite bit order.
  3971. for (uint32_t i = 0; i < 16; i++)
  3972. {
  3973. static const uint8_t s_reverse_bits[4] = { 0, 2, 1, 3 };
  3974. const uint32_t ofs = 126 - (i * 2);
  3975. pBytes[ofs >> 3] |= (s_reverse_bits[pBlock->m_weights[i]] << (ofs & 7));
  3976. }
  3977. }
  3978. #endif
  3979. // Optimal quantized [0,47] entry to use given [0,255] input
  3980. static uint8_t g_astc_single_color_encoding_0[256];
  3981. // Optimal quantized [0,47] low/high values given [0,255] input assuming a selector of 1
  3982. static struct
  3983. {
  3984. uint8_t m_lo, m_hi;
  3985. } g_astc_single_color_encoding_1[256];
  3986. static void transcoder_init_astc()
  3987. {
  3988. for (uint32_t base_color = 0; base_color < 32; base_color++)
  3989. {
  3990. for (uint32_t inten_table = 0; inten_table < 8; inten_table++)
  3991. {
  3992. for (uint32_t range_index = 0; range_index < NUM_ETC1_TO_ASTC_SELECTOR_RANGES; range_index++)
  3993. {
  3994. const etc1_to_astc_solution* pTable_g = &g_etc1_to_astc[(inten_table * 32 + base_color) * (NUM_ETC1_TO_ASTC_SELECTOR_RANGES * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS) + range_index * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  3995. uint32_t best_mapping = 0;
  3996. uint32_t best_err = UINT32_MAX;
  3997. for (uint32_t mapping_index = 0; mapping_index < NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS; mapping_index++)
  3998. {
  3999. if (pTable_g[mapping_index].m_err < best_err)
  4000. {
  4001. best_err = pTable_g[mapping_index].m_err;
  4002. best_mapping = mapping_index;
  4003. }
  4004. }
  4005. g_etc1_to_astc_best_grayscale_mapping[base_color][inten_table][range_index] = static_cast<uint8_t>(best_mapping);
  4006. }
  4007. }
  4008. }
  4009. #if BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY
  4010. for (uint32_t base_color = 0; base_color < 32; base_color++)
  4011. {
  4012. for (uint32_t inten_table = 0; inten_table < 8; inten_table++)
  4013. {
  4014. for (uint32_t range_index = 0; range_index < NUM_ETC1_TO_ASTC_SELECTOR_RANGES; range_index++)
  4015. {
  4016. const etc1_to_astc_solution* pTable_g = &g_etc1_to_astc_0_255[(inten_table * 32 + base_color) * (NUM_ETC1_TO_ASTC_SELECTOR_RANGES * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS) + range_index * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  4017. uint32_t best_mapping = 0;
  4018. uint32_t best_err = UINT32_MAX;
  4019. for (uint32_t mapping_index = 0; mapping_index < NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS; mapping_index++)
  4020. {
  4021. if (pTable_g[mapping_index].m_err < best_err)
  4022. {
  4023. best_err = pTable_g[mapping_index].m_err;
  4024. best_mapping = mapping_index;
  4025. }
  4026. }
  4027. g_etc1_to_astc_best_grayscale_mapping_0_255[base_color][inten_table][range_index] = static_cast<uint8_t>(best_mapping);
  4028. }
  4029. }
  4030. }
  4031. #endif
  4032. for (uint32_t i = 0; i < NUM_ETC1_TO_ASTC_SELECTOR_RANGES; i++)
  4033. {
  4034. uint32_t l = g_etc1_to_astc_selector_ranges[i].m_low;
  4035. uint32_t h = g_etc1_to_astc_selector_ranges[i].m_high;
  4036. g_etc1_to_astc_selector_range_index[l][h] = i;
  4037. }
  4038. // Endpoint dequantization, see:
  4039. // https://www.khronos.org/registry/DataFormat/specs/1.2/dataformat.1.2.html#astc-endpoint-unquantization
  4040. for (uint32_t trit = 0; trit < 3; trit++)
  4041. {
  4042. for (uint32_t bit = 0; bit < 16; bit++)
  4043. {
  4044. const uint32_t A = (bit & 1) ? 511 : 0;
  4045. const uint32_t B = (bit >> 1) | ((bit >> 1) << 6);
  4046. const uint32_t C = 22;
  4047. const uint32_t D = trit;
  4048. uint32_t unq = D * C + B;
  4049. unq = unq ^ A;
  4050. unq = (A & 0x80) | (unq >> 2);
  4051. g_ise_to_unquant[bit | (trit << 4)] = unq;
  4052. }
  4053. }
  4054. // Compute table used for optimal single color encoding.
  4055. for (int i = 0; i < 256; i++)
  4056. {
  4057. int lowest_e = INT_MAX;
  4058. for (int lo = 0; lo < 48; lo++)
  4059. {
  4060. for (int hi = 0; hi < 48; hi++)
  4061. {
  4062. const int lo_v = g_ise_to_unquant[lo];
  4063. const int hi_v = g_ise_to_unquant[hi];
  4064. int l = lo_v | (lo_v << 8);
  4065. int h = hi_v | (hi_v << 8);
  4066. int v = ((l * (64 - 21) + (h * 21) + 32) / 64) >> 8;
  4067. int e = abs(v - i);
  4068. if (e < lowest_e)
  4069. {
  4070. g_astc_single_color_encoding_1[i].m_hi = static_cast<uint8_t>(hi);
  4071. g_astc_single_color_encoding_1[i].m_lo = static_cast<uint8_t>(lo);
  4072. lowest_e = e;
  4073. }
  4074. } // hi
  4075. } // lo
  4076. }
  4077. for (int i = 0; i < 256; i++)
  4078. {
  4079. int lowest_e = INT_MAX;
  4080. for (int lo = 0; lo < 48; lo++)
  4081. {
  4082. const int lo_v = g_ise_to_unquant[lo];
  4083. int e = abs(lo_v - i);
  4084. if (e < lowest_e)
  4085. {
  4086. g_astc_single_color_encoding_0[i] = static_cast<uint8_t>(lo);
  4087. lowest_e = e;
  4088. }
  4089. } // lo
  4090. }
  4091. }
  4092. // Converts opaque or color+alpha ETC1S block to ASTC 4x4.
  4093. // This function tries to use the best ASTC mode given the block's actual contents.
  4094. static void convert_etc1s_to_astc_4x4(void* pDst_block, const endpoint* pEndpoints, const selector* pSelector,
  4095. bool transcode_alpha, const endpoint *pEndpoint_codebook, const selector *pSelector_codebook)
  4096. {
  4097. astc_block_params blk;
  4098. blk.m_endpoints[8] = 0;
  4099. blk.m_endpoints[9] = 0;
  4100. int constant_alpha_val = 255;
  4101. int num_unique_alpha_selectors = 1;
  4102. if (transcode_alpha)
  4103. {
  4104. const selector& alpha_selectors = pSelector_codebook[((uint16_t*)pDst_block)[1]];
  4105. num_unique_alpha_selectors = alpha_selectors.m_num_unique_selectors;
  4106. if (num_unique_alpha_selectors == 1)
  4107. {
  4108. const endpoint& alpha_endpoint = pEndpoint_codebook[((uint16_t*)pDst_block)[0]];
  4109. const color32& alpha_base_color = alpha_endpoint.m_color5;
  4110. const uint32_t alpha_inten_table = alpha_endpoint.m_inten5;
  4111. int alpha_block_colors[4];
  4112. decoder_etc_block::get_block_colors5_g(alpha_block_colors, alpha_base_color, alpha_inten_table);
  4113. constant_alpha_val = alpha_block_colors[alpha_selectors.m_lo_selector];
  4114. }
  4115. }
  4116. const color32& base_color = pEndpoints->m_color5;
  4117. const uint32_t inten_table = pEndpoints->m_inten5;
  4118. const uint32_t low_selector = pSelector->m_lo_selector;
  4119. const uint32_t high_selector = pSelector->m_hi_selector;
  4120. // Handle solid color or BTC blocks, which can always be encoded from ETC1S to ASTC losslessly.
  4121. if ((pSelector->m_num_unique_selectors == 1) && (num_unique_alpha_selectors == 1))
  4122. {
  4123. // Both color and alpha are constant, write a solid color block and exit.
  4124. // See https://www.khronos.org/registry/DataFormat/specs/1.2/dataformat.1.2.html#astc-void-extent-blocks
  4125. uint32_t r, g, b;
  4126. decoder_etc_block::get_block_color5(base_color, inten_table, low_selector, r, g, b);
  4127. uint32_t* pOutput = static_cast<uint32_t*>(pDst_block);
  4128. uint8_t* pBytes = reinterpret_cast<uint8_t*>(pDst_block);
  4129. pBytes[0] = 0xfc; pBytes[1] = 0xfd; pBytes[2] = 0xff; pBytes[3] = 0xff;
  4130. pOutput[1] = 0xffffffff;
  4131. pOutput[2] = 0;
  4132. pOutput[3] = 0;
  4133. int bit_pos = 64;
  4134. astc_set_bits(pOutput, bit_pos, r | (r << 8), 16);
  4135. astc_set_bits(pOutput, bit_pos, g | (g << 8), 16);
  4136. astc_set_bits(pOutput, bit_pos, b | (b << 8), 16);
  4137. astc_set_bits(pOutput, bit_pos, constant_alpha_val | (constant_alpha_val << 8), 16);
  4138. return;
  4139. }
  4140. else if ((pSelector->m_num_unique_selectors <= 2) && (num_unique_alpha_selectors <= 2))
  4141. {
  4142. // Both color and alpha use <= 2 unique selectors each.
  4143. // Use block truncation coding, which is lossless with ASTC (8-bit endpoints, 1-bit weights).
  4144. color32 block_colors[4];
  4145. decoder_etc_block::get_block_colors5(block_colors, base_color, inten_table);
  4146. blk.m_endpoints[0] = block_colors[low_selector].r;
  4147. blk.m_endpoints[2] = block_colors[low_selector].g;
  4148. blk.m_endpoints[4] = block_colors[low_selector].b;
  4149. blk.m_endpoints[1] = block_colors[high_selector].r;
  4150. blk.m_endpoints[3] = block_colors[high_selector].g;
  4151. blk.m_endpoints[5] = block_colors[high_selector].b;
  4152. int s0 = blk.m_endpoints[0] + blk.m_endpoints[2] + blk.m_endpoints[4];
  4153. int s1 = blk.m_endpoints[1] + blk.m_endpoints[3] + blk.m_endpoints[5];
  4154. bool invert = false;
  4155. if (s1 < s0)
  4156. {
  4157. std::swap(blk.m_endpoints[0], blk.m_endpoints[1]);
  4158. std::swap(blk.m_endpoints[2], blk.m_endpoints[3]);
  4159. std::swap(blk.m_endpoints[4], blk.m_endpoints[5]);
  4160. invert = true;
  4161. }
  4162. if (transcode_alpha)
  4163. {
  4164. const endpoint& alpha_endpoint = pEndpoint_codebook[((uint16_t*)pDst_block)[0]];
  4165. const selector& alpha_selectors = pSelector_codebook[((uint16_t*)pDst_block)[1]];
  4166. const color32& alpha_base_color = alpha_endpoint.m_color5;
  4167. const uint32_t alpha_inten_table = alpha_endpoint.m_inten5;
  4168. const uint32_t alpha_low_selector = alpha_selectors.m_lo_selector;
  4169. const uint32_t alpha_high_selector = alpha_selectors.m_hi_selector;
  4170. int alpha_block_colors[4];
  4171. decoder_etc_block::get_block_colors5_g(alpha_block_colors, alpha_base_color, alpha_inten_table);
  4172. blk.m_endpoints[6] = static_cast<uint8_t>(alpha_block_colors[alpha_low_selector]);
  4173. blk.m_endpoints[7] = static_cast<uint8_t>(alpha_block_colors[alpha_high_selector]);
  4174. for (uint32_t y = 0; y < 4; y++)
  4175. {
  4176. for (uint32_t x = 0; x < 4; x++)
  4177. {
  4178. uint32_t s = alpha_selectors.get_selector(x, y);
  4179. s = (s == alpha_high_selector) ? 1 : 0;
  4180. blk.m_weights[(x + y * 4) * 2 + 1] = static_cast<uint8_t>(s);
  4181. } // x
  4182. } // y
  4183. }
  4184. else
  4185. {
  4186. blk.m_endpoints[6] = 255;
  4187. blk.m_endpoints[7] = 255;
  4188. for (uint32_t i = 0; i < 16; i++)
  4189. blk.m_weights[i * 2 + 1] = 0;
  4190. }
  4191. for (uint32_t y = 0; y < 4; y++)
  4192. {
  4193. for (uint32_t x = 0; x < 4; x++)
  4194. {
  4195. uint32_t s = pSelector->get_selector(x, y);
  4196. s = (s == high_selector) ? 1 : 0;
  4197. if (invert)
  4198. s = 1 - s;
  4199. blk.m_weights[(x + y * 4) * 2] = static_cast<uint8_t>(s);
  4200. } // x
  4201. } // y
  4202. astc_pack_block_cem_12_weight_range0(reinterpret_cast<uint32_t*>(pDst_block), &blk);
  4203. return;
  4204. }
  4205. // Either alpha and/or color use > 2 unique selectors each, so we must do something more complex.
  4206. #if BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY
  4207. // The optional higher quality modes use 8-bits endpoints vs. [0,47] endpoints.
  4208. // If the block's base color is grayscale, all pixels are grayscale, so encode the block as Luminance+Alpha.
  4209. if ((base_color.r == base_color.g) && (base_color.r == base_color.b))
  4210. {
  4211. if (transcode_alpha)
  4212. {
  4213. const endpoint& alpha_endpoint = pEndpoint_codebook[((uint16_t*)pDst_block)[0]];
  4214. const selector& alpha_selectors = pSelector_codebook[((uint16_t*)pDst_block)[1]];
  4215. const color32& alpha_base_color = alpha_endpoint.m_color5;
  4216. const uint32_t alpha_inten_table = alpha_endpoint.m_inten5;
  4217. const uint32_t alpha_low_selector = alpha_selectors.m_lo_selector;
  4218. const uint32_t alpha_high_selector = alpha_selectors.m_hi_selector;
  4219. if (num_unique_alpha_selectors <= 2)
  4220. {
  4221. // Simple alpha block with only 1 or 2 unique values, so use BTC. This is lossless.
  4222. int alpha_block_colors[4];
  4223. decoder_etc_block::get_block_colors5_g(alpha_block_colors, alpha_base_color, alpha_inten_table);
  4224. blk.m_endpoints[2] = static_cast<uint8_t>(alpha_block_colors[alpha_low_selector]);
  4225. blk.m_endpoints[3] = static_cast<uint8_t>(alpha_block_colors[alpha_high_selector]);
  4226. for (uint32_t i = 0; i < 16; i++)
  4227. {
  4228. uint32_t s = alpha_selectors.get_selector(i & 3, i >> 2);
  4229. blk.m_weights[i * 2 + 1] = (s == alpha_high_selector) ? 3 : 0;
  4230. }
  4231. }
  4232. else
  4233. {
  4234. // Convert ETC1S alpha
  4235. const uint32_t alpha_selector_range_table = g_etc1_to_astc_selector_range_index[alpha_low_selector][alpha_high_selector];
  4236. //[32][8][RANGES][MAPPING]
  4237. const etc1_to_astc_solution* pTable_g = &g_etc1_to_astc_0_255[(alpha_inten_table * 32 + alpha_base_color.g) * (NUM_ETC1_TO_ASTC_SELECTOR_RANGES * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS) + alpha_selector_range_table * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  4238. const uint32_t best_mapping = g_etc1_to_astc_best_grayscale_mapping_0_255[alpha_base_color.g][alpha_inten_table][alpha_selector_range_table];
  4239. blk.m_endpoints[2] = pTable_g[best_mapping].m_lo;
  4240. blk.m_endpoints[3] = pTable_g[best_mapping].m_hi;
  4241. const uint8_t* pSelectors_xlat = &g_etc1_to_astc_selector_mappings[best_mapping][0];
  4242. for (uint32_t y = 0; y < 4; y++)
  4243. {
  4244. for (uint32_t x = 0; x < 4; x++)
  4245. {
  4246. uint32_t s = alpha_selectors.get_selector(x, y);
  4247. uint32_t as = pSelectors_xlat[s];
  4248. blk.m_weights[(x + y * 4) * 2 + 1] = static_cast<uint8_t>(as);
  4249. } // x
  4250. } // y
  4251. }
  4252. }
  4253. else
  4254. {
  4255. // No alpha slice - set output alpha to all 255's
  4256. blk.m_endpoints[2] = 255;
  4257. blk.m_endpoints[3] = 255;
  4258. for (uint32_t i = 0; i < 16; i++)
  4259. blk.m_weights[i * 2 + 1] = 0;
  4260. }
  4261. if (pSelector->m_num_unique_selectors <= 2)
  4262. {
  4263. // Simple color block with only 1 or 2 unique values, so use BTC. This is lossless.
  4264. int block_colors[4];
  4265. decoder_etc_block::get_block_colors5_g(block_colors, base_color, inten_table);
  4266. blk.m_endpoints[0] = static_cast<uint8_t>(block_colors[low_selector]);
  4267. blk.m_endpoints[1] = static_cast<uint8_t>(block_colors[high_selector]);
  4268. for (uint32_t i = 0; i < 16; i++)
  4269. {
  4270. uint32_t s = pSelector->get_selector(i & 3, i >> 2);
  4271. blk.m_weights[i * 2] = (s == high_selector) ? 3 : 0;
  4272. }
  4273. }
  4274. else
  4275. {
  4276. // Convert ETC1S alpha
  4277. const uint32_t selector_range_table = g_etc1_to_astc_selector_range_index[low_selector][high_selector];
  4278. //[32][8][RANGES][MAPPING]
  4279. const etc1_to_astc_solution* pTable_g = &g_etc1_to_astc_0_255[(inten_table * 32 + base_color.g) * (NUM_ETC1_TO_ASTC_SELECTOR_RANGES * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  4280. const uint32_t best_mapping = g_etc1_to_astc_best_grayscale_mapping_0_255[base_color.g][inten_table][selector_range_table];
  4281. blk.m_endpoints[0] = pTable_g[best_mapping].m_lo;
  4282. blk.m_endpoints[1] = pTable_g[best_mapping].m_hi;
  4283. const uint8_t* pSelectors_xlat = &g_etc1_to_astc_selector_mappings[best_mapping][0];
  4284. for (uint32_t y = 0; y < 4; y++)
  4285. {
  4286. for (uint32_t x = 0; x < 4; x++)
  4287. {
  4288. uint32_t s = pSelector->get_selector(x, y);
  4289. uint32_t as = pSelectors_xlat[s];
  4290. blk.m_weights[(x + y * 4) * 2] = static_cast<uint8_t>(as);
  4291. } // x
  4292. } // y
  4293. }
  4294. astc_pack_block_cem_4_weight_range2(reinterpret_cast<uint32_t*>(pDst_block), &blk);
  4295. return;
  4296. }
  4297. // The block isn't grayscale and it uses > 2 unique selectors for opaque and/or alpha.
  4298. // Check for fully opaque blocks, if so use 8-bit endpoints for slightly higher opaque quality (higher than BC1, but lower than BC7 mode 6 opaque).
  4299. if ((num_unique_alpha_selectors == 1) && (constant_alpha_val == 255))
  4300. {
  4301. // Convert ETC1S color
  4302. const uint32_t selector_range_table = g_etc1_to_astc_selector_range_index[low_selector][high_selector];
  4303. //[32][8][RANGES][MAPPING]
  4304. const etc1_to_astc_solution* pTable_r = &g_etc1_to_astc_0_255[(inten_table * 32 + base_color.r) * (NUM_ETC1_TO_ASTC_SELECTOR_RANGES * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  4305. const etc1_to_astc_solution* pTable_g = &g_etc1_to_astc_0_255[(inten_table * 32 + base_color.g) * (NUM_ETC1_TO_ASTC_SELECTOR_RANGES * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  4306. const etc1_to_astc_solution* pTable_b = &g_etc1_to_astc_0_255[(inten_table * 32 + base_color.b) * (NUM_ETC1_TO_ASTC_SELECTOR_RANGES * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  4307. uint32_t best_err = UINT_MAX;
  4308. uint32_t best_mapping = 0;
  4309. assert(NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS == 10);
  4310. #define DO_ITER(m) { uint32_t total_err = pTable_r[m].m_err + pTable_g[m].m_err + pTable_b[m].m_err; if (total_err < best_err) { best_err = total_err; best_mapping = m; } }
  4311. DO_ITER(0); DO_ITER(1); DO_ITER(2); DO_ITER(3); DO_ITER(4);
  4312. DO_ITER(5); DO_ITER(6); DO_ITER(7); DO_ITER(8); DO_ITER(9);
  4313. #undef DO_ITER
  4314. blk.m_endpoints[0] = pTable_r[best_mapping].m_lo;
  4315. blk.m_endpoints[1] = pTable_r[best_mapping].m_hi;
  4316. blk.m_endpoints[2] = pTable_g[best_mapping].m_lo;
  4317. blk.m_endpoints[3] = pTable_g[best_mapping].m_hi;
  4318. blk.m_endpoints[4] = pTable_b[best_mapping].m_lo;
  4319. blk.m_endpoints[5] = pTable_b[best_mapping].m_hi;
  4320. int s0 = blk.m_endpoints[0] + blk.m_endpoints[2] + blk.m_endpoints[4];
  4321. int s1 = blk.m_endpoints[1] + blk.m_endpoints[3] + blk.m_endpoints[5];
  4322. bool invert = false;
  4323. if (s1 < s0)
  4324. {
  4325. std::swap(blk.m_endpoints[0], blk.m_endpoints[1]);
  4326. std::swap(blk.m_endpoints[2], blk.m_endpoints[3]);
  4327. std::swap(blk.m_endpoints[4], blk.m_endpoints[5]);
  4328. invert = true;
  4329. }
  4330. const uint8_t* pSelectors_xlat = &g_etc1_to_astc_selector_mappings[best_mapping][0];
  4331. for (uint32_t y = 0; y < 4; y++)
  4332. {
  4333. for (uint32_t x = 0; x < 4; x++)
  4334. {
  4335. uint32_t s = pSelector->get_selector(x, y);
  4336. uint32_t as = pSelectors_xlat[s];
  4337. if (invert)
  4338. as = 3 - as;
  4339. blk.m_weights[x + y * 4] = static_cast<uint8_t>(as);
  4340. } // x
  4341. } // y
  4342. // Now pack to ASTC
  4343. astc_pack_block_cem_8_weight_range2(reinterpret_cast<uint32_t*>(pDst_block), &blk);
  4344. return;
  4345. }
  4346. #endif //#if BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY
  4347. // Nothing else worked, so fall back to CEM Mode 12 (LDR RGBA Direct), [0,47] endpoints, weight range 2 (2-bit weights), dual planes.
  4348. // This mode can handle everything, but at slightly less quality than BC1.
  4349. if (transcode_alpha)
  4350. {
  4351. const endpoint& alpha_endpoint = pEndpoint_codebook[((uint16_t*)pDst_block)[0]];
  4352. const selector& alpha_selectors = pSelector_codebook[((uint16_t*)pDst_block)[1]];
  4353. const color32& alpha_base_color = alpha_endpoint.m_color5;
  4354. const uint32_t alpha_inten_table = alpha_endpoint.m_inten5;
  4355. const uint32_t alpha_low_selector = alpha_selectors.m_lo_selector;
  4356. const uint32_t alpha_high_selector = alpha_selectors.m_hi_selector;
  4357. if (alpha_low_selector == alpha_high_selector)
  4358. {
  4359. // Solid alpha block - use precomputed tables.
  4360. int alpha_block_colors[4];
  4361. decoder_etc_block::get_block_colors5_g(alpha_block_colors, alpha_base_color, alpha_inten_table);
  4362. const uint32_t g = alpha_block_colors[alpha_low_selector];
  4363. blk.m_endpoints[6] = g_astc_single_color_encoding_1[g].m_lo;
  4364. blk.m_endpoints[7] = g_astc_single_color_encoding_1[g].m_hi;
  4365. for (uint32_t i = 0; i < 16; i++)
  4366. blk.m_weights[i * 2 + 1] = 1;
  4367. }
  4368. else if ((alpha_inten_table >= 7) && (alpha_selectors.m_num_unique_selectors == 2) && (alpha_low_selector == 0) && (alpha_high_selector == 3))
  4369. {
  4370. // Handle outlier case where only the two outer colors are used with inten table 7.
  4371. color32 alpha_block_colors[4];
  4372. decoder_etc_block::get_block_colors5(alpha_block_colors, alpha_base_color, alpha_inten_table);
  4373. const uint32_t g0 = alpha_block_colors[0].g;
  4374. const uint32_t g1 = alpha_block_colors[3].g;
  4375. blk.m_endpoints[6] = g_astc_single_color_encoding_0[g0];
  4376. blk.m_endpoints[7] = g_astc_single_color_encoding_0[g1];
  4377. for (uint32_t y = 0; y < 4; y++)
  4378. {
  4379. for (uint32_t x = 0; x < 4; x++)
  4380. {
  4381. uint32_t s = alpha_selectors.get_selector(x, y);
  4382. uint32_t as = (s == alpha_high_selector) ? 3 : 0;
  4383. blk.m_weights[(x + y * 4) * 2 + 1] = static_cast<uint8_t>(as);
  4384. } // x
  4385. } // y
  4386. }
  4387. else
  4388. {
  4389. // Convert ETC1S alpha
  4390. const uint32_t alpha_selector_range_table = g_etc1_to_astc_selector_range_index[alpha_low_selector][alpha_high_selector];
  4391. //[32][8][RANGES][MAPPING]
  4392. const etc1_to_astc_solution* pTable_g = &g_etc1_to_astc[(alpha_inten_table * 32 + alpha_base_color.g) * (NUM_ETC1_TO_ASTC_SELECTOR_RANGES * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS) + alpha_selector_range_table * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  4393. const uint32_t best_mapping = g_etc1_to_astc_best_grayscale_mapping[alpha_base_color.g][alpha_inten_table][alpha_selector_range_table];
  4394. blk.m_endpoints[6] = pTable_g[best_mapping].m_lo;
  4395. blk.m_endpoints[7] = pTable_g[best_mapping].m_hi;
  4396. const uint8_t* pSelectors_xlat = &g_etc1_to_astc_selector_mappings[best_mapping][0];
  4397. for (uint32_t y = 0; y < 4; y++)
  4398. {
  4399. for (uint32_t x = 0; x < 4; x++)
  4400. {
  4401. uint32_t s = alpha_selectors.get_selector(x, y);
  4402. uint32_t as = pSelectors_xlat[s];
  4403. blk.m_weights[(x + y * 4) * 2 + 1] = static_cast<uint8_t>(as);
  4404. } // x
  4405. } // y
  4406. }
  4407. }
  4408. else
  4409. {
  4410. // No alpha slice - set output alpha to all 255's
  4411. // 1 is 255 when dequantized
  4412. blk.m_endpoints[6] = 1;
  4413. blk.m_endpoints[7] = 1;
  4414. for (uint32_t i = 0; i < 16; i++)
  4415. blk.m_weights[i * 2 + 1] = 0;
  4416. }
  4417. if (low_selector == high_selector)
  4418. {
  4419. // Solid color block - use precomputed tables of optimal endpoints assuming selector weights are all 1.
  4420. color32 block_colors[4];
  4421. decoder_etc_block::get_block_colors5(block_colors, base_color, inten_table);
  4422. const uint32_t r = block_colors[low_selector].r;
  4423. const uint32_t g = block_colors[low_selector].g;
  4424. const uint32_t b = block_colors[low_selector].b;
  4425. blk.m_endpoints[0] = g_astc_single_color_encoding_1[r].m_lo;
  4426. blk.m_endpoints[1] = g_astc_single_color_encoding_1[r].m_hi;
  4427. blk.m_endpoints[2] = g_astc_single_color_encoding_1[g].m_lo;
  4428. blk.m_endpoints[3] = g_astc_single_color_encoding_1[g].m_hi;
  4429. blk.m_endpoints[4] = g_astc_single_color_encoding_1[b].m_lo;
  4430. blk.m_endpoints[5] = g_astc_single_color_encoding_1[b].m_hi;
  4431. int s0 = g_ise_to_unquant[blk.m_endpoints[0]] + g_ise_to_unquant[blk.m_endpoints[2]] + g_ise_to_unquant[blk.m_endpoints[4]];
  4432. int s1 = g_ise_to_unquant[blk.m_endpoints[1]] + g_ise_to_unquant[blk.m_endpoints[3]] + g_ise_to_unquant[blk.m_endpoints[5]];
  4433. bool invert = false;
  4434. if (s1 < s0)
  4435. {
  4436. std::swap(blk.m_endpoints[0], blk.m_endpoints[1]);
  4437. std::swap(blk.m_endpoints[2], blk.m_endpoints[3]);
  4438. std::swap(blk.m_endpoints[4], blk.m_endpoints[5]);
  4439. invert = true;
  4440. }
  4441. for (uint32_t i = 0; i < 16; i++)
  4442. blk.m_weights[i * 2] = invert ? 2 : 1;
  4443. }
  4444. else if ((inten_table >= 7) && (pSelector->m_num_unique_selectors == 2) && (pSelector->m_lo_selector == 0) && (pSelector->m_hi_selector == 3))
  4445. {
  4446. // Handle outlier case where only the two outer colors are used with inten table 7.
  4447. color32 block_colors[4];
  4448. decoder_etc_block::get_block_colors5(block_colors, base_color, inten_table);
  4449. const uint32_t r0 = block_colors[0].r;
  4450. const uint32_t g0 = block_colors[0].g;
  4451. const uint32_t b0 = block_colors[0].b;
  4452. const uint32_t r1 = block_colors[3].r;
  4453. const uint32_t g1 = block_colors[3].g;
  4454. const uint32_t b1 = block_colors[3].b;
  4455. blk.m_endpoints[0] = g_astc_single_color_encoding_0[r0];
  4456. blk.m_endpoints[1] = g_astc_single_color_encoding_0[r1];
  4457. blk.m_endpoints[2] = g_astc_single_color_encoding_0[g0];
  4458. blk.m_endpoints[3] = g_astc_single_color_encoding_0[g1];
  4459. blk.m_endpoints[4] = g_astc_single_color_encoding_0[b0];
  4460. blk.m_endpoints[5] = g_astc_single_color_encoding_0[b1];
  4461. int s0 = g_ise_to_unquant[blk.m_endpoints[0]] + g_ise_to_unquant[blk.m_endpoints[2]] + g_ise_to_unquant[blk.m_endpoints[4]];
  4462. int s1 = g_ise_to_unquant[blk.m_endpoints[1]] + g_ise_to_unquant[blk.m_endpoints[3]] + g_ise_to_unquant[blk.m_endpoints[5]];
  4463. bool invert = false;
  4464. if (s1 < s0)
  4465. {
  4466. std::swap(blk.m_endpoints[0], blk.m_endpoints[1]);
  4467. std::swap(blk.m_endpoints[2], blk.m_endpoints[3]);
  4468. std::swap(blk.m_endpoints[4], blk.m_endpoints[5]);
  4469. invert = true;
  4470. }
  4471. for (uint32_t y = 0; y < 4; y++)
  4472. {
  4473. for (uint32_t x = 0; x < 4; x++)
  4474. {
  4475. uint32_t s = pSelector->get_selector(x, y);
  4476. uint32_t as = (s == low_selector) ? 0 : 3;
  4477. if (invert)
  4478. as = 3 - as;
  4479. blk.m_weights[(x + y * 4) * 2] = static_cast<uint8_t>(as);
  4480. } // x
  4481. } // y
  4482. }
  4483. else
  4484. {
  4485. // Convert ETC1S color
  4486. const uint32_t selector_range_table = g_etc1_to_astc_selector_range_index[low_selector][high_selector];
  4487. //[32][8][RANGES][MAPPING]
  4488. const etc1_to_astc_solution* pTable_r = &g_etc1_to_astc[(inten_table * 32 + base_color.r) * (NUM_ETC1_TO_ASTC_SELECTOR_RANGES * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  4489. const etc1_to_astc_solution* pTable_g = &g_etc1_to_astc[(inten_table * 32 + base_color.g) * (NUM_ETC1_TO_ASTC_SELECTOR_RANGES * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  4490. const etc1_to_astc_solution* pTable_b = &g_etc1_to_astc[(inten_table * 32 + base_color.b) * (NUM_ETC1_TO_ASTC_SELECTOR_RANGES * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS];
  4491. uint32_t best_err = UINT_MAX;
  4492. uint32_t best_mapping = 0;
  4493. assert(NUM_ETC1_TO_ASTC_SELECTOR_MAPPINGS == 10);
  4494. #define DO_ITER(m) { uint32_t total_err = pTable_r[m].m_err + pTable_g[m].m_err + pTable_b[m].m_err; if (total_err < best_err) { best_err = total_err; best_mapping = m; } }
  4495. DO_ITER(0); DO_ITER(1); DO_ITER(2); DO_ITER(3); DO_ITER(4);
  4496. DO_ITER(5); DO_ITER(6); DO_ITER(7); DO_ITER(8); DO_ITER(9);
  4497. #undef DO_ITER
  4498. blk.m_endpoints[0] = pTable_r[best_mapping].m_lo;
  4499. blk.m_endpoints[1] = pTable_r[best_mapping].m_hi;
  4500. blk.m_endpoints[2] = pTable_g[best_mapping].m_lo;
  4501. blk.m_endpoints[3] = pTable_g[best_mapping].m_hi;
  4502. blk.m_endpoints[4] = pTable_b[best_mapping].m_lo;
  4503. blk.m_endpoints[5] = pTable_b[best_mapping].m_hi;
  4504. int s0 = g_ise_to_unquant[blk.m_endpoints[0]] + g_ise_to_unquant[blk.m_endpoints[2]] + g_ise_to_unquant[blk.m_endpoints[4]];
  4505. int s1 = g_ise_to_unquant[blk.m_endpoints[1]] + g_ise_to_unquant[blk.m_endpoints[3]] + g_ise_to_unquant[blk.m_endpoints[5]];
  4506. bool invert = false;
  4507. if (s1 < s0)
  4508. {
  4509. std::swap(blk.m_endpoints[0], blk.m_endpoints[1]);
  4510. std::swap(blk.m_endpoints[2], blk.m_endpoints[3]);
  4511. std::swap(blk.m_endpoints[4], blk.m_endpoints[5]);
  4512. invert = true;
  4513. }
  4514. const uint8_t* pSelectors_xlat = &g_etc1_to_astc_selector_mappings[best_mapping][0];
  4515. for (uint32_t y = 0; y < 4; y++)
  4516. {
  4517. for (uint32_t x = 0; x < 4; x++)
  4518. {
  4519. uint32_t s = pSelector->get_selector(x, y);
  4520. uint32_t as = pSelectors_xlat[s];
  4521. if (invert)
  4522. as = 3 - as;
  4523. blk.m_weights[(x + y * 4) * 2] = static_cast<uint8_t>(as);
  4524. } // x
  4525. } // y
  4526. }
  4527. // Now pack to ASTC
  4528. astc_pack_block_cem_12_weight_range2(reinterpret_cast<uint32_t *>(pDst_block), &blk);
  4529. }
  4530. #endif
  4531. #if BASISD_SUPPORT_ATC
  4532. struct etc1s_to_atc_solution
  4533. {
  4534. uint8_t m_lo;
  4535. uint8_t m_hi;
  4536. uint16_t m_err;
  4537. };
  4538. static dxt_selector_range g_etc1s_to_atc_selector_ranges[] =
  4539. {
  4540. { 0, 3 },
  4541. { 1, 3 },
  4542. { 0, 2 },
  4543. { 1, 2 },
  4544. { 2, 3 },
  4545. { 0, 1 },
  4546. };
  4547. const uint32_t NUM_ETC1S_TO_ATC_SELECTOR_RANGES = sizeof(g_etc1s_to_atc_selector_ranges) / sizeof(g_etc1s_to_atc_selector_ranges[0]);
  4548. static uint32_t g_etc1s_to_atc_selector_range_index[4][4];
  4549. const uint32_t NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS = 10;
  4550. static const uint8_t g_etc1s_to_atc_selector_mappings[NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS][4] =
  4551. {
  4552. { 0, 0, 1, 1 },
  4553. { 0, 0, 1, 2 },
  4554. { 0, 0, 1, 3 },
  4555. { 0, 0, 2, 3 },
  4556. { 0, 1, 1, 1 },
  4557. { 0, 1, 2, 2 },
  4558. { 0, 1, 2, 3 }, //6 - identity
  4559. { 0, 2, 3, 3 },
  4560. { 1, 2, 2, 2 },
  4561. { 1, 2, 3, 3 },
  4562. };
  4563. const uint32_t ATC_IDENTITY_SELECTOR_MAPPING_INDEX = 6;
  4564. static const etc1s_to_atc_solution g_etc1s_to_atc_55[32 * 8 * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS * NUM_ETC1S_TO_ATC_SELECTOR_RANGES] = {
  4565. #include "basisu_transcoder_tables_atc_55.inc"
  4566. };
  4567. static const etc1s_to_atc_solution g_etc1s_to_atc_56[32 * 8 * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS * NUM_ETC1S_TO_ATC_SELECTOR_RANGES] = {
  4568. #include "basisu_transcoder_tables_atc_56.inc"
  4569. };
  4570. struct atc_match_entry
  4571. {
  4572. uint8_t m_lo;
  4573. uint8_t m_hi;
  4574. };
  4575. static atc_match_entry g_atc_match55_equals_1[256], g_atc_match56_equals_1[256]; // selector 1
  4576. static atc_match_entry g_atc_match5[256], g_atc_match6[256];
  4577. static void prepare_atc_single_color_table(atc_match_entry* pTable, int size0, int size1, int sel)
  4578. {
  4579. for (int i = 0; i < 256; i++)
  4580. {
  4581. int lowest_e = 256;
  4582. for (int lo = 0; lo < size0; lo++)
  4583. {
  4584. int lo_e = lo;
  4585. if (size0 == 32)
  4586. lo_e = (lo_e << 3) | (lo_e >> 2);
  4587. else
  4588. lo_e = (lo_e << 2) | (lo_e >> 4);
  4589. for (int hi = 0; hi < size1; hi++)
  4590. {
  4591. int hi_e = hi;
  4592. if (size1 == 32)
  4593. hi_e = (hi_e << 3) | (hi_e >> 2);
  4594. else
  4595. hi_e = (hi_e << 2) | (hi_e >> 4);
  4596. int e;
  4597. if (sel == 1)
  4598. {
  4599. // Selector 1
  4600. e = abs(((lo_e * 5 + hi_e * 3) / 8) - i);
  4601. }
  4602. else
  4603. {
  4604. assert(sel == 3);
  4605. // Selector 3
  4606. e = abs(hi_e - i);
  4607. }
  4608. if (e < lowest_e)
  4609. {
  4610. pTable[i].m_lo = static_cast<uint8_t>(lo);
  4611. pTable[i].m_hi = static_cast<uint8_t>(hi);
  4612. lowest_e = e;
  4613. }
  4614. } // hi
  4615. } // lo
  4616. } // i
  4617. }
  4618. static void transcoder_init_atc()
  4619. {
  4620. prepare_atc_single_color_table(g_atc_match55_equals_1, 32, 32, 1);
  4621. prepare_atc_single_color_table(g_atc_match56_equals_1, 32, 64, 1);
  4622. prepare_atc_single_color_table(g_atc_match5, 1, 32, 3);
  4623. prepare_atc_single_color_table(g_atc_match6, 1, 64, 3);
  4624. for (uint32_t i = 0; i < NUM_ETC1S_TO_ATC_SELECTOR_RANGES; i++)
  4625. {
  4626. uint32_t l = g_etc1s_to_atc_selector_ranges[i].m_low;
  4627. uint32_t h = g_etc1s_to_atc_selector_ranges[i].m_high;
  4628. g_etc1s_to_atc_selector_range_index[l][h] = i;
  4629. }
  4630. }
  4631. struct atc_block
  4632. {
  4633. uint8_t m_lo[2];
  4634. uint8_t m_hi[2];
  4635. uint8_t m_sels[4];
  4636. void set_low_color(uint32_t r, uint32_t g, uint32_t b)
  4637. {
  4638. assert((r < 32) && (g < 32) && (b < 32));
  4639. uint32_t x = (r << 10) | (g << 5) | b;
  4640. m_lo[0] = x & 0xFF;
  4641. m_lo[1] = (x >> 8) & 0xFF;
  4642. }
  4643. void set_high_color(uint32_t r, uint32_t g, uint32_t b)
  4644. {
  4645. assert((r < 32) && (g < 64) && (b < 32));
  4646. uint32_t x = (r << 11) | (g << 5) | b;
  4647. m_hi[0] = x & 0xFF;
  4648. m_hi[1] = (x >> 8) & 0xFF;
  4649. }
  4650. };
  4651. static void convert_etc1s_to_atc(void* pDst, const endpoint* pEndpoints, const selector* pSelector)
  4652. {
  4653. atc_block* pBlock = static_cast<atc_block*>(pDst);
  4654. const uint32_t low_selector = pSelector->m_lo_selector;
  4655. const uint32_t high_selector = pSelector->m_hi_selector;
  4656. const color32& base_color = pEndpoints->m_color5;
  4657. const uint32_t inten_table = pEndpoints->m_inten5;
  4658. if (low_selector == high_selector)
  4659. {
  4660. uint32_t r, g, b;
  4661. decoder_etc_block::get_block_color5(base_color, inten_table, low_selector, r, g, b);
  4662. pBlock->set_low_color(g_atc_match55_equals_1[r].m_lo, g_atc_match56_equals_1[g].m_lo, g_atc_match55_equals_1[b].m_lo);
  4663. pBlock->set_high_color(g_atc_match55_equals_1[r].m_hi, g_atc_match56_equals_1[g].m_hi, g_atc_match55_equals_1[b].m_hi);
  4664. pBlock->m_sels[0] = 0x55;
  4665. pBlock->m_sels[1] = 0x55;
  4666. pBlock->m_sels[2] = 0x55;
  4667. pBlock->m_sels[3] = 0x55;
  4668. return;
  4669. }
  4670. else if ((inten_table >= 7) && (pSelector->m_num_unique_selectors == 2) && (pSelector->m_lo_selector == 0) && (pSelector->m_hi_selector == 3))
  4671. {
  4672. color32 block_colors[4];
  4673. decoder_etc_block::get_block_colors5(block_colors, base_color, inten_table);
  4674. const uint32_t r0 = block_colors[0].r;
  4675. const uint32_t g0 = block_colors[0].g;
  4676. const uint32_t b0 = block_colors[0].b;
  4677. const uint32_t r1 = block_colors[3].r;
  4678. const uint32_t g1 = block_colors[3].g;
  4679. const uint32_t b1 = block_colors[3].b;
  4680. pBlock->set_low_color(g_atc_match5[r0].m_hi, g_atc_match5[g0].m_hi, g_atc_match5[b0].m_hi);
  4681. pBlock->set_high_color(g_atc_match5[r1].m_hi, g_atc_match6[g1].m_hi, g_atc_match5[b1].m_hi);
  4682. pBlock->m_sels[0] = pSelector->m_selectors[0];
  4683. pBlock->m_sels[1] = pSelector->m_selectors[1];
  4684. pBlock->m_sels[2] = pSelector->m_selectors[2];
  4685. pBlock->m_sels[3] = pSelector->m_selectors[3];
  4686. return;
  4687. }
  4688. const uint32_t selector_range_table = g_etc1s_to_atc_selector_range_index[low_selector][high_selector];
  4689. //[32][8][RANGES][MAPPING]
  4690. const etc1s_to_atc_solution* pTable_r = &g_etc1s_to_atc_55[(inten_table * 32 + base_color.r) * (NUM_ETC1S_TO_ATC_SELECTOR_RANGES * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS];
  4691. const etc1s_to_atc_solution* pTable_g = &g_etc1s_to_atc_56[(inten_table * 32 + base_color.g) * (NUM_ETC1S_TO_ATC_SELECTOR_RANGES * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS];
  4692. const etc1s_to_atc_solution* pTable_b = &g_etc1s_to_atc_55[(inten_table * 32 + base_color.b) * (NUM_ETC1S_TO_ATC_SELECTOR_RANGES * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS) + selector_range_table * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS];
  4693. uint32_t best_err = UINT_MAX;
  4694. uint32_t best_mapping = 0;
  4695. assert(NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS == 10);
  4696. #define DO_ITER(m) { uint32_t total_err = pTable_r[m].m_err + pTable_g[m].m_err + pTable_b[m].m_err; if (total_err < best_err) { best_err = total_err; best_mapping = m; } }
  4697. DO_ITER(0); DO_ITER(1); DO_ITER(2); DO_ITER(3); DO_ITER(4);
  4698. DO_ITER(5); DO_ITER(6); DO_ITER(7); DO_ITER(8); DO_ITER(9);
  4699. #undef DO_ITER
  4700. pBlock->set_low_color(pTable_r[best_mapping].m_lo, pTable_g[best_mapping].m_lo, pTable_b[best_mapping].m_lo);
  4701. pBlock->set_high_color(pTable_r[best_mapping].m_hi, pTable_g[best_mapping].m_hi, pTable_b[best_mapping].m_hi);
  4702. if (ATC_IDENTITY_SELECTOR_MAPPING_INDEX == best_mapping)
  4703. {
  4704. pBlock->m_sels[0] = pSelector->m_selectors[0];
  4705. pBlock->m_sels[1] = pSelector->m_selectors[1];
  4706. pBlock->m_sels[2] = pSelector->m_selectors[2];
  4707. pBlock->m_sels[3] = pSelector->m_selectors[3];
  4708. }
  4709. else
  4710. {
  4711. const uint8_t* pSelectors_xlat = &g_etc1s_to_atc_selector_mappings[best_mapping][0];
  4712. const uint32_t sel_bits0 = pSelector->m_selectors[0];
  4713. const uint32_t sel_bits1 = pSelector->m_selectors[1];
  4714. const uint32_t sel_bits2 = pSelector->m_selectors[2];
  4715. const uint32_t sel_bits3 = pSelector->m_selectors[3];
  4716. uint32_t atc_sels0 = 0, atc_sels1 = 0, atc_sels2 = 0, atc_sels3 = 0;
  4717. #define DO_X(x) { \
  4718. const uint32_t x_shift = (x) * 2; \
  4719. atc_sels0 |= (pSelectors_xlat[(sel_bits0 >> x_shift) & 3] << x_shift); \
  4720. atc_sels1 |= (pSelectors_xlat[(sel_bits1 >> x_shift) & 3] << x_shift); \
  4721. atc_sels2 |= (pSelectors_xlat[(sel_bits2 >> x_shift) & 3] << x_shift); \
  4722. atc_sels3 |= (pSelectors_xlat[(sel_bits3 >> x_shift) & 3] << x_shift); }
  4723. DO_X(0);
  4724. DO_X(1);
  4725. DO_X(2);
  4726. DO_X(3);
  4727. #undef DO_X
  4728. pBlock->m_sels[0] = (uint8_t)atc_sels0;
  4729. pBlock->m_sels[1] = (uint8_t)atc_sels1;
  4730. pBlock->m_sels[2] = (uint8_t)atc_sels2;
  4731. pBlock->m_sels[3] = (uint8_t)atc_sels3;
  4732. }
  4733. }
  4734. #if BASISD_WRITE_NEW_ATC_TABLES
  4735. static void create_etc1s_to_atc_conversion_tables()
  4736. {
  4737. FILE* pFile = nullptr;
  4738. fopen_s(&pFile, "basisu_transcoder_tables_atc_55.inc", "w");
  4739. uint32_t n = 0;
  4740. for (int inten = 0; inten < 8; inten++)
  4741. {
  4742. for (uint32_t g = 0; g < 32; g++)
  4743. {
  4744. color32 block_colors[4];
  4745. decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
  4746. for (uint32_t sr = 0; sr < NUM_ETC1S_TO_ATC_SELECTOR_RANGES; sr++)
  4747. {
  4748. const uint32_t low_selector = g_etc1s_to_atc_selector_ranges[sr].m_low;
  4749. const uint32_t high_selector = g_etc1s_to_atc_selector_ranges[sr].m_high;
  4750. for (uint32_t m = 0; m < NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS; m++)
  4751. {
  4752. uint32_t best_lo = 0;
  4753. uint32_t best_hi = 0;
  4754. uint64_t best_err = UINT64_MAX;
  4755. for (uint32_t hi = 0; hi <= 31; hi++)
  4756. {
  4757. for (uint32_t lo = 0; lo <= 31; lo++)
  4758. {
  4759. uint32_t colors[4];
  4760. colors[0] = (lo << 3) | (lo >> 2);
  4761. colors[3] = (hi << 3) | (hi >> 2);
  4762. colors[1] = (colors[0] * 5 + colors[3] * 3) / 8;
  4763. colors[2] = (colors[3] * 5 + colors[0] * 3) / 8;
  4764. uint64_t total_err = 0;
  4765. for (uint32_t s = low_selector; s <= high_selector; s++)
  4766. {
  4767. int err = block_colors[s].g - colors[g_etc1s_to_atc_selector_mappings[m][s]];
  4768. int err_scale = 1;
  4769. // Special case when the intensity table is 7, low_selector is 0, and high_selector is 3. In this extreme case, it's likely the encoder is trying to strongly favor
  4770. // the low/high selectors which are clamping to either 0 or 255.
  4771. if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
  4772. err_scale = 5;
  4773. total_err += (err * err) * err_scale;
  4774. }
  4775. if (total_err < best_err)
  4776. {
  4777. best_err = total_err;
  4778. best_lo = lo;
  4779. best_hi = hi;
  4780. }
  4781. }
  4782. }
  4783. //assert(best_err <= 0xFFFF);
  4784. best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF);
  4785. fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err);
  4786. n++;
  4787. if ((n & 31) == 31)
  4788. fprintf(pFile, "\n");
  4789. } // m
  4790. } // sr
  4791. } // g
  4792. } // inten
  4793. fclose(pFile);
  4794. pFile = nullptr;
  4795. fopen_s(&pFile, "basisu_transcoder_tables_atc_56.inc", "w");
  4796. n = 0;
  4797. for (int inten = 0; inten < 8; inten++)
  4798. {
  4799. for (uint32_t g = 0; g < 32; g++)
  4800. {
  4801. color32 block_colors[4];
  4802. decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten);
  4803. for (uint32_t sr = 0; sr < NUM_ETC1S_TO_ATC_SELECTOR_RANGES; sr++)
  4804. {
  4805. const uint32_t low_selector = g_etc1s_to_atc_selector_ranges[sr].m_low;
  4806. const uint32_t high_selector = g_etc1s_to_atc_selector_ranges[sr].m_high;
  4807. for (uint32_t m = 0; m < NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS; m++)
  4808. {
  4809. uint32_t best_lo = 0;
  4810. uint32_t best_hi = 0;
  4811. uint64_t best_err = UINT64_MAX;
  4812. for (uint32_t hi = 0; hi <= 63; hi++)
  4813. {
  4814. for (uint32_t lo = 0; lo <= 31; lo++)
  4815. {
  4816. uint32_t colors[4];
  4817. colors[0] = (lo << 3) | (lo >> 2);
  4818. colors[3] = (hi << 2) | (hi >> 4);
  4819. colors[1] = (colors[0] * 5 + colors[3] * 3) / 8;
  4820. colors[2] = (colors[3] * 5 + colors[0] * 3) / 8;
  4821. uint64_t total_err = 0;
  4822. for (uint32_t s = low_selector; s <= high_selector; s++)
  4823. {
  4824. int err = block_colors[s].g - colors[g_etc1s_to_atc_selector_mappings[m][s]];
  4825. int err_scale = 1;
  4826. // Special case when the intensity table is 7, low_selector is 0, and high_selector is 3. In this extreme case, it's likely the encoder is trying to strongly favor
  4827. // the low/high selectors which are clamping to either 0 or 255.
  4828. if (((inten == 7) && (low_selector == 0) && (high_selector == 3)) && ((s == 0) || (s == 3)))
  4829. err_scale = 5;
  4830. total_err += (err * err) * err_scale;
  4831. }
  4832. if (total_err < best_err)
  4833. {
  4834. best_err = total_err;
  4835. best_lo = lo;
  4836. best_hi = hi;
  4837. }
  4838. }
  4839. }
  4840. //assert(best_err <= 0xFFFF);
  4841. best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF);
  4842. fprintf(pFile, "{%u,%u,%u},", best_lo, best_hi, (uint32_t)best_err);
  4843. n++;
  4844. if ((n & 31) == 31)
  4845. fprintf(pFile, "\n");
  4846. } // m
  4847. } // sr
  4848. } // g
  4849. } // inten
  4850. fclose(pFile);
  4851. }
  4852. #endif // BASISD_WRITE_NEW_ATC_TABLES
  4853. #endif // BASISD_SUPPORT_ATC
  4854. basisu_lowlevel_transcoder::basisu_lowlevel_transcoder(const etc1_global_selector_codebook* pGlobal_sel_codebook) :
  4855. m_pGlobal_sel_codebook(pGlobal_sel_codebook),
  4856. m_selector_history_buf_size(0)
  4857. {
  4858. }
  4859. bool basisu_lowlevel_transcoder::decode_palettes(
  4860. uint32_t num_endpoints, const uint8_t* pEndpoints_data, uint32_t endpoints_data_size,
  4861. uint32_t num_selectors, const uint8_t* pSelectors_data, uint32_t selectors_data_size)
  4862. {
  4863. bitwise_decoder sym_codec;
  4864. huffman_decoding_table color5_delta_model0, color5_delta_model1, color5_delta_model2, inten_delta_model;
  4865. if (!sym_codec.init(pEndpoints_data, endpoints_data_size))
  4866. {
  4867. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 0\n");
  4868. return false;
  4869. }
  4870. if (!sym_codec.read_huffman_table(color5_delta_model0))
  4871. {
  4872. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 1\n");
  4873. return false;
  4874. }
  4875. if (!sym_codec.read_huffman_table(color5_delta_model1))
  4876. {
  4877. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 1a\n");
  4878. return false;
  4879. }
  4880. if (!sym_codec.read_huffman_table(color5_delta_model2))
  4881. {
  4882. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 2a\n");
  4883. return false;
  4884. }
  4885. if (!sym_codec.read_huffman_table(inten_delta_model))
  4886. {
  4887. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 2b\n");
  4888. return false;
  4889. }
  4890. if (!color5_delta_model0.is_valid() || !color5_delta_model1.is_valid() || !color5_delta_model2.is_valid() || !inten_delta_model.is_valid())
  4891. {
  4892. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 2b\n");
  4893. return false;
  4894. }
  4895. const bool endpoints_are_grayscale = sym_codec.get_bits(1) != 0;
  4896. m_endpoints.resize(num_endpoints);
  4897. color32 prev_color5(16, 16, 16, 0);
  4898. uint32_t prev_inten = 0;
  4899. for (uint32_t i = 0; i < num_endpoints; i++)
  4900. {
  4901. uint32_t inten_delta = sym_codec.decode_huffman(inten_delta_model);
  4902. m_endpoints[i].m_inten5 = static_cast<uint8_t>((inten_delta + prev_inten) & 7);
  4903. prev_inten = m_endpoints[i].m_inten5;
  4904. for (uint32_t c = 0; c < (endpoints_are_grayscale ? 1U : 3U); c++)
  4905. {
  4906. int delta;
  4907. if (prev_color5[c] <= basist::COLOR5_PAL0_PREV_HI)
  4908. delta = sym_codec.decode_huffman(color5_delta_model0);
  4909. else if (prev_color5[c] <= basist::COLOR5_PAL1_PREV_HI)
  4910. delta = sym_codec.decode_huffman(color5_delta_model1);
  4911. else
  4912. delta = sym_codec.decode_huffman(color5_delta_model2);
  4913. int v = (prev_color5[c] + delta) & 31;
  4914. m_endpoints[i].m_color5[c] = static_cast<uint8_t>(v);
  4915. prev_color5[c] = static_cast<uint8_t>(v);
  4916. }
  4917. if (endpoints_are_grayscale)
  4918. {
  4919. m_endpoints[i].m_color5[1] = m_endpoints[i].m_color5[0];
  4920. m_endpoints[i].m_color5[2] = m_endpoints[i].m_color5[0];
  4921. }
  4922. }
  4923. sym_codec.stop();
  4924. m_selectors.resize(num_selectors);
  4925. if (!sym_codec.init(pSelectors_data, selectors_data_size))
  4926. {
  4927. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 5\n");
  4928. return false;
  4929. }
  4930. basist::huffman_decoding_table delta_selector_pal_model;
  4931. const bool used_global_selector_cb = (sym_codec.get_bits(1) == 1);
  4932. if (used_global_selector_cb)
  4933. {
  4934. // global selector palette
  4935. uint32_t pal_bits = sym_codec.get_bits(4);
  4936. uint32_t mod_bits = sym_codec.get_bits(4);
  4937. basist::huffman_decoding_table mod_model;
  4938. if (mod_bits)
  4939. {
  4940. if (!sym_codec.read_huffman_table(mod_model))
  4941. {
  4942. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 6\n");
  4943. return false;
  4944. }
  4945. if (!mod_model.is_valid())
  4946. {
  4947. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 6a\n");
  4948. return false;
  4949. }
  4950. }
  4951. for (uint32_t i = 0; i < num_selectors; i++)
  4952. {
  4953. uint32_t pal_index = 0;
  4954. if (pal_bits)
  4955. pal_index = sym_codec.get_bits(pal_bits);
  4956. uint32_t mod_index = 0;
  4957. if (mod_bits)
  4958. mod_index = sym_codec.decode_huffman(mod_model);
  4959. if (pal_index >= m_pGlobal_sel_codebook->size())
  4960. {
  4961. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 7z\n");
  4962. return false;
  4963. }
  4964. const etc1_selector_palette_entry e(m_pGlobal_sel_codebook->get_entry(pal_index, etc1_global_palette_entry_modifier(mod_index)));
  4965. // TODO: Optimize this
  4966. for (uint32_t y = 0; y < 4; y++)
  4967. for (uint32_t x = 0; x < 4; x++)
  4968. m_selectors[i].set_selector(x, y, e[x + y * 4]);
  4969. m_selectors[i].init_flags();
  4970. }
  4971. }
  4972. else
  4973. {
  4974. const bool used_hybrid_selector_cb = (sym_codec.get_bits(1) == 1);
  4975. if (used_hybrid_selector_cb)
  4976. {
  4977. const uint32_t pal_bits = sym_codec.get_bits(4);
  4978. const uint32_t mod_bits = sym_codec.get_bits(4);
  4979. basist::huffman_decoding_table uses_global_cb_bitflags_model;
  4980. if (!sym_codec.read_huffman_table(uses_global_cb_bitflags_model))
  4981. {
  4982. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 7\n");
  4983. return false;
  4984. }
  4985. if (!uses_global_cb_bitflags_model.is_valid())
  4986. {
  4987. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 7a\n");
  4988. return false;
  4989. }
  4990. basist::huffman_decoding_table global_mod_indices_model;
  4991. if (mod_bits)
  4992. {
  4993. if (!sym_codec.read_huffman_table(global_mod_indices_model))
  4994. {
  4995. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 8\n");
  4996. return false;
  4997. }
  4998. if (!global_mod_indices_model.is_valid())
  4999. {
  5000. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 8a\n");
  5001. return false;
  5002. }
  5003. }
  5004. uint32_t cur_uses_global_cb_bitflags = 0;
  5005. uint32_t uses_global_cb_bitflags_remaining = 0;
  5006. for (uint32_t q = 0; q < num_selectors; q++)
  5007. {
  5008. if (!uses_global_cb_bitflags_remaining)
  5009. {
  5010. cur_uses_global_cb_bitflags = sym_codec.decode_huffman(uses_global_cb_bitflags_model);
  5011. uses_global_cb_bitflags_remaining = 8;
  5012. }
  5013. uses_global_cb_bitflags_remaining--;
  5014. const bool used_global_cb_flag = (cur_uses_global_cb_bitflags & 1) != 0;
  5015. cur_uses_global_cb_bitflags >>= 1;
  5016. if (used_global_cb_flag)
  5017. {
  5018. const uint32_t pal_index = pal_bits ? sym_codec.get_bits(pal_bits) : 0;
  5019. const uint32_t mod_index = mod_bits ? sym_codec.decode_huffman(global_mod_indices_model) : 0;
  5020. if (pal_index >= m_pGlobal_sel_codebook->size())
  5021. {
  5022. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 8b\n");
  5023. return false;
  5024. }
  5025. const etc1_selector_palette_entry e(m_pGlobal_sel_codebook->get_entry(pal_index, etc1_global_palette_entry_modifier(mod_index)));
  5026. for (uint32_t y = 0; y < 4; y++)
  5027. for (uint32_t x = 0; x < 4; x++)
  5028. m_selectors[q].set_selector(x, y, e[x + y * 4]);
  5029. }
  5030. else
  5031. {
  5032. for (uint32_t j = 0; j < 4; j++)
  5033. {
  5034. uint32_t cur_byte = sym_codec.get_bits(8);
  5035. for (uint32_t k = 0; k < 4; k++)
  5036. m_selectors[q].set_selector(k, j, (cur_byte >> (k * 2)) & 3);
  5037. }
  5038. }
  5039. m_selectors[q].init_flags();
  5040. }
  5041. }
  5042. else
  5043. {
  5044. const bool used_raw_encoding = (sym_codec.get_bits(1) == 1);
  5045. if (used_raw_encoding)
  5046. {
  5047. for (uint32_t i = 0; i < num_selectors; i++)
  5048. {
  5049. for (uint32_t j = 0; j < 4; j++)
  5050. {
  5051. uint32_t cur_byte = sym_codec.get_bits(8);
  5052. for (uint32_t k = 0; k < 4; k++)
  5053. m_selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3);
  5054. }
  5055. m_selectors[i].init_flags();
  5056. }
  5057. }
  5058. else
  5059. {
  5060. if (!sym_codec.read_huffman_table(delta_selector_pal_model))
  5061. {
  5062. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 10\n");
  5063. return false;
  5064. }
  5065. if ((num_selectors > 1) && (!delta_selector_pal_model.is_valid()))
  5066. {
  5067. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 10a\n");
  5068. return false;
  5069. }
  5070. uint8_t prev_bytes[4] = { 0, 0, 0, 0 };
  5071. for (uint32_t i = 0; i < num_selectors; i++)
  5072. {
  5073. if (!i)
  5074. {
  5075. for (uint32_t j = 0; j < 4; j++)
  5076. {
  5077. uint32_t cur_byte = sym_codec.get_bits(8);
  5078. prev_bytes[j] = static_cast<uint8_t>(cur_byte);
  5079. for (uint32_t k = 0; k < 4; k++)
  5080. m_selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3);
  5081. }
  5082. m_selectors[i].init_flags();
  5083. continue;
  5084. }
  5085. for (uint32_t j = 0; j < 4; j++)
  5086. {
  5087. int delta_byte = sym_codec.decode_huffman(delta_selector_pal_model);
  5088. uint32_t cur_byte = delta_byte ^ prev_bytes[j];
  5089. prev_bytes[j] = static_cast<uint8_t>(cur_byte);
  5090. for (uint32_t k = 0; k < 4; k++)
  5091. m_selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3);
  5092. }
  5093. m_selectors[i].init_flags();
  5094. }
  5095. }
  5096. }
  5097. }
  5098. sym_codec.stop();
  5099. return true;
  5100. }
  5101. bool basisu_lowlevel_transcoder::decode_tables(const uint8_t* pTable_data, uint32_t table_data_size)
  5102. {
  5103. basist::bitwise_decoder sym_codec;
  5104. if (!sym_codec.init(pTable_data, table_data_size))
  5105. {
  5106. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 0\n");
  5107. return false;
  5108. }
  5109. if (!sym_codec.read_huffman_table(m_endpoint_pred_model))
  5110. {
  5111. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 1\n");
  5112. return false;
  5113. }
  5114. if (m_endpoint_pred_model.get_code_sizes().size() == 0)
  5115. {
  5116. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 1a\n");
  5117. return false;
  5118. }
  5119. if (!sym_codec.read_huffman_table(m_delta_endpoint_model))
  5120. {
  5121. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 2\n");
  5122. return false;
  5123. }
  5124. if (m_delta_endpoint_model.get_code_sizes().size() == 0)
  5125. {
  5126. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 2a\n");
  5127. return false;
  5128. }
  5129. if (!sym_codec.read_huffman_table(m_selector_model))
  5130. {
  5131. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 3\n");
  5132. return false;
  5133. }
  5134. if (m_selector_model.get_code_sizes().size() == 0)
  5135. {
  5136. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 3a\n");
  5137. return false;
  5138. }
  5139. if (!sym_codec.read_huffman_table(m_selector_history_buf_rle_model))
  5140. {
  5141. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 4\n");
  5142. return false;
  5143. }
  5144. if (m_selector_history_buf_rle_model.get_code_sizes().size() == 0)
  5145. {
  5146. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 4a\n");
  5147. return false;
  5148. }
  5149. m_selector_history_buf_size = sym_codec.get_bits(13);
  5150. sym_codec.stop();
  5151. return true;
  5152. }
  5153. bool basisu_lowlevel_transcoder::transcode_slice(void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t* pImage_data, uint32_t image_data_size, block_format fmt,
  5154. uint32_t output_block_or_pixel_stride_in_bytes, bool pvrtc_wrap_addressing, bool bc1_allow_threecolor_blocks, const basis_file_header& header, const basis_slice_desc& slice_desc, uint32_t output_row_pitch_in_blocks_or_pixels,
  5155. basisu_transcoder_state* pState, bool transcode_alpha, void *pAlpha_blocks, uint32_t output_rows_in_pixels)
  5156. {
  5157. (void)transcode_alpha;
  5158. (void)pAlpha_blocks;
  5159. (void)pvrtc_wrap_addressing;
  5160. if (!pState)
  5161. pState = &m_def_state;
  5162. const bool is_video = (header.m_tex_type == cBASISTexTypeVideoFrames);
  5163. const uint32_t total_blocks = num_blocks_x * num_blocks_y;
  5164. if (!output_row_pitch_in_blocks_or_pixels)
  5165. {
  5166. if (basis_block_format_is_uncompressed(fmt))
  5167. output_row_pitch_in_blocks_or_pixels = slice_desc.m_orig_width;
  5168. else
  5169. output_row_pitch_in_blocks_or_pixels = num_blocks_x;
  5170. }
  5171. if (basis_block_format_is_uncompressed(fmt))
  5172. {
  5173. if (!output_rows_in_pixels)
  5174. output_rows_in_pixels = slice_desc.m_orig_height;
  5175. }
  5176. std::vector<uint32_t>* pPrev_frame_indices = nullptr;
  5177. if (is_video)
  5178. {
  5179. // TODO: Add check to make sure the caller hasn't tried skipping past p-frames
  5180. const bool alpha_flag = (slice_desc.m_flags & cSliceDescFlagsIsAlphaData) != 0;
  5181. const uint32_t level_index = slice_desc.m_level_index;
  5182. if (level_index >= basisu_transcoder_state::cMaxPrevFrameLevels)
  5183. {
  5184. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: unsupported level_index\n");
  5185. return false;
  5186. }
  5187. pPrev_frame_indices = &pState->m_prev_frame_indices[alpha_flag][level_index];
  5188. if (pPrev_frame_indices->size() < total_blocks)
  5189. pPrev_frame_indices->resize(total_blocks);
  5190. }
  5191. basist::bitwise_decoder sym_codec;
  5192. if (!sym_codec.init(pImage_data, image_data_size))
  5193. {
  5194. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: sym_codec.init failed\n");
  5195. return false;
  5196. }
  5197. approx_move_to_front selector_history_buf(m_selector_history_buf_size);
  5198. const uint32_t SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX = (uint32_t)m_selectors.size();
  5199. const uint32_t SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX = m_selector_history_buf_size + SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX;
  5200. uint32_t cur_selector_rle_count = 0;
  5201. decoder_etc_block block;
  5202. memset(&block, 0, sizeof(block));
  5203. block.set_flip_bit(true);
  5204. block.set_diff_bit(true);
  5205. void* pPVRTC_work_mem = nullptr;
  5206. uint32_t* pPVRTC_endpoints = nullptr;
  5207. if ((fmt == cPVRTC1_4_RGB) || (fmt == cPVRTC1_4_RGBA))
  5208. {
  5209. pPVRTC_work_mem = malloc(num_blocks_x * num_blocks_y * (sizeof(decoder_etc_block) + sizeof(uint32_t)));
  5210. if (!pPVRTC_work_mem)
  5211. {
  5212. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: malloc failed\n");
  5213. return false;
  5214. }
  5215. pPVRTC_endpoints = (uint32_t*) & ((decoder_etc_block*)pPVRTC_work_mem)[num_blocks_x * num_blocks_y];
  5216. }
  5217. if (pState->m_block_endpoint_preds[0].size() < num_blocks_x)
  5218. {
  5219. pState->m_block_endpoint_preds[0].resize(num_blocks_x);
  5220. pState->m_block_endpoint_preds[1].resize(num_blocks_x);
  5221. }
  5222. uint32_t cur_pred_bits = 0;
  5223. int prev_endpoint_pred_sym = 0;
  5224. int endpoint_pred_repeat_count = 0;
  5225. uint32_t prev_endpoint_index = 0;
  5226. for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++)
  5227. {
  5228. const uint32_t cur_block_endpoint_pred_array = block_y & 1;
  5229. for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++)
  5230. {
  5231. // Decode endpoint index predictor symbols
  5232. if ((block_x & 1) == 0)
  5233. {
  5234. if ((block_y & 1) == 0)
  5235. {
  5236. if (endpoint_pred_repeat_count)
  5237. {
  5238. endpoint_pred_repeat_count--;
  5239. cur_pred_bits = prev_endpoint_pred_sym;
  5240. }
  5241. else
  5242. {
  5243. cur_pred_bits = sym_codec.decode_huffman(m_endpoint_pred_model);
  5244. if (cur_pred_bits == ENDPOINT_PRED_REPEAT_LAST_SYMBOL)
  5245. {
  5246. endpoint_pred_repeat_count = sym_codec.decode_vlc(ENDPOINT_PRED_COUNT_VLC_BITS) + ENDPOINT_PRED_MIN_REPEAT_COUNT - 1;
  5247. cur_pred_bits = prev_endpoint_pred_sym;
  5248. }
  5249. else
  5250. {
  5251. prev_endpoint_pred_sym = cur_pred_bits;
  5252. }
  5253. }
  5254. pState->m_block_endpoint_preds[cur_block_endpoint_pred_array ^ 1][block_x].m_pred_bits = (uint8_t)(cur_pred_bits >> 4);
  5255. }
  5256. else
  5257. {
  5258. cur_pred_bits = pState->m_block_endpoint_preds[cur_block_endpoint_pred_array][block_x].m_pred_bits;
  5259. }
  5260. }
  5261. // Decode endpoint index
  5262. uint32_t endpoint_index, selector_index = 0;
  5263. const uint32_t pred = cur_pred_bits & 3;
  5264. cur_pred_bits >>= 2;
  5265. if (pred == 0)
  5266. {
  5267. // Left
  5268. if (!block_x)
  5269. {
  5270. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: invalid datastream (0)\n");
  5271. if (pPVRTC_work_mem)
  5272. free(pPVRTC_work_mem);
  5273. return false;
  5274. }
  5275. endpoint_index = prev_endpoint_index;
  5276. }
  5277. else if (pred == 1)
  5278. {
  5279. // Upper
  5280. if (!block_y)
  5281. {
  5282. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: invalid datastream (1)\n");
  5283. if (pPVRTC_work_mem)
  5284. free(pPVRTC_work_mem);
  5285. return false;
  5286. }
  5287. endpoint_index = pState->m_block_endpoint_preds[cur_block_endpoint_pred_array ^ 1][block_x].m_endpoint_index;
  5288. }
  5289. else if (pred == 2)
  5290. {
  5291. if (is_video)
  5292. {
  5293. assert(pred == CR_ENDPOINT_PRED_INDEX);
  5294. endpoint_index = (*pPrev_frame_indices)[block_x + block_y * num_blocks_x];
  5295. selector_index = endpoint_index >> 16;
  5296. endpoint_index &= 0xFFFFU;
  5297. }
  5298. else
  5299. {
  5300. // Upper left
  5301. if ((!block_x) || (!block_y))
  5302. {
  5303. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: invalid datastream (2)\n");
  5304. if (pPVRTC_work_mem)
  5305. free(pPVRTC_work_mem);
  5306. return false;
  5307. }
  5308. endpoint_index = pState->m_block_endpoint_preds[cur_block_endpoint_pred_array ^ 1][block_x - 1].m_endpoint_index;
  5309. }
  5310. }
  5311. else
  5312. {
  5313. // Decode and apply delta
  5314. const uint32_t delta_sym = sym_codec.decode_huffman(m_delta_endpoint_model);
  5315. endpoint_index = delta_sym + prev_endpoint_index;
  5316. if (endpoint_index >= m_endpoints.size())
  5317. endpoint_index -= (int)m_endpoints.size();
  5318. }
  5319. pState->m_block_endpoint_preds[cur_block_endpoint_pred_array][block_x].m_endpoint_index = (uint16_t)endpoint_index;
  5320. prev_endpoint_index = endpoint_index;
  5321. // Decode selector index
  5322. if ((!is_video) || (pred != CR_ENDPOINT_PRED_INDEX))
  5323. {
  5324. int selector_sym;
  5325. if (cur_selector_rle_count > 0)
  5326. {
  5327. cur_selector_rle_count--;
  5328. selector_sym = (int)m_selectors.size();
  5329. }
  5330. else
  5331. {
  5332. selector_sym = sym_codec.decode_huffman(m_selector_model);
  5333. if (selector_sym == static_cast<int>(SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX))
  5334. {
  5335. int run_sym = sym_codec.decode_huffman(m_selector_history_buf_rle_model);
  5336. if (run_sym == (SELECTOR_HISTORY_BUF_RLE_COUNT_TOTAL - 1))
  5337. cur_selector_rle_count = sym_codec.decode_vlc(7) + SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH;
  5338. else
  5339. cur_selector_rle_count = run_sym + SELECTOR_HISTORY_BUF_RLE_COUNT_THRESH;
  5340. if (cur_selector_rle_count > total_blocks)
  5341. {
  5342. // The file is corrupted or we've got a bug.
  5343. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: invalid datastream (3)\n");
  5344. if (pPVRTC_work_mem)
  5345. free(pPVRTC_work_mem);
  5346. return false;
  5347. }
  5348. selector_sym = (int)m_selectors.size();
  5349. cur_selector_rle_count--;
  5350. }
  5351. }
  5352. if (selector_sym >= (int)m_selectors.size())
  5353. {
  5354. assert(m_selector_history_buf_size > 0);
  5355. int history_buf_index = selector_sym - (int)m_selectors.size();
  5356. if (history_buf_index >= (int)selector_history_buf.size())
  5357. {
  5358. // The file is corrupted or we've got a bug.
  5359. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: invalid datastream (4)\n");
  5360. if (pPVRTC_work_mem)
  5361. free(pPVRTC_work_mem);
  5362. return false;
  5363. }
  5364. selector_index = selector_history_buf[history_buf_index];
  5365. if (history_buf_index != 0)
  5366. selector_history_buf.use(history_buf_index);
  5367. }
  5368. else
  5369. {
  5370. selector_index = selector_sym;
  5371. if (m_selector_history_buf_size)
  5372. selector_history_buf.add(selector_index);
  5373. }
  5374. }
  5375. if ((endpoint_index >= m_endpoints.size()) || (selector_index >= m_selectors.size()))
  5376. {
  5377. // The file is corrupted or we've got a bug.
  5378. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: invalid datastream (5)\n");
  5379. if (pPVRTC_work_mem)
  5380. free(pPVRTC_work_mem);
  5381. return false;
  5382. }
  5383. if (is_video)
  5384. (*pPrev_frame_indices)[block_x + block_y * num_blocks_x] = endpoint_index | (selector_index << 16);
  5385. #if BASISD_ENABLE_DEBUG_FLAGS
  5386. if ((g_debug_flags & cDebugFlagVisCRs) && ((fmt == cETC1) || (fmt == cBC1)))
  5387. {
  5388. if ((is_video) && (pred == 2))
  5389. {
  5390. decoder_etc_block* pDst_block = reinterpret_cast<decoder_etc_block*>(static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes);
  5391. memset(pDst_block, 0xFF, 8);
  5392. continue;
  5393. }
  5394. }
  5395. #endif
  5396. const endpoint* pEndpoints = &m_endpoints[endpoint_index];
  5397. const selector* pSelector = &m_selectors[selector_index];
  5398. switch (fmt)
  5399. {
  5400. case cETC1:
  5401. {
  5402. decoder_etc_block* pDst_block = reinterpret_cast<decoder_etc_block*>(static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes);
  5403. block.set_base5_color(decoder_etc_block::pack_color5(pEndpoints->m_color5, false));
  5404. block.set_inten_table(0, pEndpoints->m_inten5);
  5405. block.set_inten_table(1, pEndpoints->m_inten5);
  5406. pDst_block->m_uint32[0] = block.m_uint32[0];
  5407. pDst_block->set_raw_selector_bits(pSelector->m_bytes[0], pSelector->m_bytes[1], pSelector->m_bytes[2], pSelector->m_bytes[3]);
  5408. break;
  5409. }
  5410. case cBC1:
  5411. {
  5412. void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes;
  5413. #if BASISD_SUPPORT_DXT1
  5414. #if BASISD_ENABLE_DEBUG_FLAGS
  5415. if (g_debug_flags & (cDebugFlagVisBC1Sels | cDebugFlagVisBC1Endpoints))
  5416. convert_etc1s_to_dxt1_vis(static_cast<dxt1_block*>(pDst_block), pEndpoints, pSelector, bc1_allow_threecolor_blocks);
  5417. else
  5418. #endif
  5419. convert_etc1s_to_dxt1(static_cast<dxt1_block*>(pDst_block), pEndpoints, pSelector, bc1_allow_threecolor_blocks);
  5420. #else
  5421. assert(0);
  5422. #endif
  5423. break;
  5424. }
  5425. case cBC4:
  5426. {
  5427. #if BASISD_SUPPORT_DXT5A
  5428. void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes;
  5429. convert_etc1s_to_dxt5a(static_cast<dxt5a_block*>(pDst_block), pEndpoints, pSelector);
  5430. #else
  5431. assert(0);
  5432. #endif
  5433. break;
  5434. }
  5435. case cPVRTC1_4_RGB:
  5436. {
  5437. #if BASISD_SUPPORT_PVRTC1
  5438. block.set_base5_color(decoder_etc_block::pack_color5(pEndpoints->m_color5, false));
  5439. block.set_inten_table(0, pEndpoints->m_inten5);
  5440. block.set_inten_table(1, pEndpoints->m_inten5);
  5441. block.set_raw_selector_bits(pSelector->m_bytes[0], pSelector->m_bytes[1], pSelector->m_bytes[2], pSelector->m_bytes[3]);
  5442. ((decoder_etc_block*)pPVRTC_work_mem)[block_x + block_y * num_blocks_x] = block;
  5443. const color32& base_color = pEndpoints->m_color5;
  5444. const uint32_t inten_table = pEndpoints->m_inten5;
  5445. const uint32_t low_selector = pSelector->m_lo_selector;
  5446. const uint32_t high_selector = pSelector->m_hi_selector;
  5447. // Get block's RGB bounding box
  5448. color32 block_colors[2];
  5449. decoder_etc_block::get_block_colors5_bounds(block_colors, base_color, inten_table, low_selector, high_selector);
  5450. assert(block_colors[0][0] <= block_colors[1][0]);
  5451. assert(block_colors[0][1] <= block_colors[1][1]);
  5452. assert(block_colors[0][2] <= block_colors[1][2]);
  5453. // Set PVRTC1 endpoints to floor/ceil of bounding box's coordinates.
  5454. pvrtc4_block temp;
  5455. temp.set_opaque_endpoint_floor(0, block_colors[0]);
  5456. temp.set_opaque_endpoint_ceil(1, block_colors[1]);
  5457. pPVRTC_endpoints[block_x + block_y * num_blocks_x] = temp.m_endpoints;
  5458. #else
  5459. assert(0);
  5460. #endif
  5461. break;
  5462. }
  5463. case cPVRTC1_4_RGBA:
  5464. {
  5465. #if BASISD_SUPPORT_PVRTC1
  5466. assert(pAlpha_blocks);
  5467. block.set_base5_color(decoder_etc_block::pack_color5(pEndpoints->m_color5, false));
  5468. block.set_inten_table(0, pEndpoints->m_inten5);
  5469. block.set_inten_table(1, pEndpoints->m_inten5);
  5470. block.set_raw_selector_bits(pSelector->m_selectors[0], pSelector->m_selectors[1], pSelector->m_selectors[2], pSelector->m_selectors[3]);
  5471. ((decoder_etc_block*)pPVRTC_work_mem)[block_x + block_y * num_blocks_x] = block;
  5472. // Get block's RGBA bounding box
  5473. const color32& base_color = pEndpoints->m_color5;
  5474. const uint32_t inten_table = pEndpoints->m_inten5;
  5475. const uint32_t low_selector = pSelector->m_lo_selector;
  5476. const uint32_t high_selector = pSelector->m_hi_selector;
  5477. color32 block_colors[2];
  5478. decoder_etc_block::get_block_colors5_bounds(block_colors, base_color, inten_table, low_selector, high_selector);
  5479. assert(block_colors[0][0] <= block_colors[1][0]);
  5480. assert(block_colors[0][1] <= block_colors[1][1]);
  5481. assert(block_colors[0][2] <= block_colors[1][2]);
  5482. const uint16_t* pAlpha_block = reinterpret_cast<uint16_t*>(static_cast<uint8_t*>(pAlpha_blocks) + (block_x + block_y * num_blocks_x) * sizeof(uint32_t));
  5483. const endpoint* pAlpha_endpoints = &m_endpoints[pAlpha_block[0]];
  5484. const selector* pAlpha_selector = &m_selectors[pAlpha_block[1]];
  5485. const color32& alpha_base_color = pAlpha_endpoints->m_color5;
  5486. const uint32_t alpha_inten_table = pAlpha_endpoints->m_inten5;
  5487. const uint32_t alpha_low_selector = pAlpha_selector->m_lo_selector;
  5488. const uint32_t alpha_high_selector = pAlpha_selector->m_hi_selector;
  5489. uint32_t alpha_block_colors[2];
  5490. decoder_etc_block::get_block_colors5_bounds_g(alpha_block_colors, alpha_base_color, alpha_inten_table, alpha_low_selector, alpha_high_selector);
  5491. assert(alpha_block_colors[0] <= alpha_block_colors[1]);
  5492. block_colors[0].a = (uint8_t)alpha_block_colors[0];
  5493. block_colors[1].a = (uint8_t)alpha_block_colors[1];
  5494. // Set PVRTC1 endpoints to floor/ceil of bounding box's coordinates.
  5495. pvrtc4_block temp;
  5496. temp.set_endpoint_floor(0, block_colors[0]);
  5497. temp.set_endpoint_ceil(1, block_colors[1]);
  5498. pPVRTC_endpoints[block_x + block_y * num_blocks_x] = temp.m_endpoints;
  5499. #else
  5500. assert(0);
  5501. #endif
  5502. break;
  5503. }
  5504. case cBC7_M6_OPAQUE_ONLY:
  5505. {
  5506. #if BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY
  5507. void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes;
  5508. convert_etc1s_to_bc7_m6(static_cast<bc7_mode_6*>(pDst_block), pEndpoints, pSelector);
  5509. #else
  5510. assert(0);
  5511. #endif
  5512. break;
  5513. }
  5514. case cBC7_M5_COLOR:
  5515. {
  5516. #if BASISD_SUPPORT_BC7_MODE5
  5517. void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes;
  5518. convert_etc1s_to_bc7_m5_color(pDst_block, pEndpoints, pSelector);
  5519. #else
  5520. assert(0);
  5521. #endif
  5522. break;
  5523. }
  5524. case cBC7_M5_ALPHA:
  5525. {
  5526. #if BASISD_SUPPORT_BC7_MODE5
  5527. void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes;
  5528. convert_etc1s_to_bc7_m5_alpha(pDst_block, pEndpoints, pSelector);
  5529. #else
  5530. assert(0);
  5531. #endif
  5532. break;
  5533. }
  5534. case cETC2_EAC_A8:
  5535. {
  5536. #if BASISD_SUPPORT_ETC2_EAC_A8
  5537. void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes;
  5538. convert_etc1s_to_etc2_eac_a8(static_cast<eac_a8_block*>(pDst_block), pEndpoints, pSelector);
  5539. #else
  5540. assert(0);
  5541. #endif
  5542. break;
  5543. }
  5544. case cASTC_4x4:
  5545. {
  5546. #if BASISD_SUPPORT_ASTC
  5547. void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes;
  5548. convert_etc1s_to_astc_4x4(pDst_block, pEndpoints, pSelector, transcode_alpha, &m_endpoints[0], &m_selectors[0]);
  5549. #else
  5550. assert(0);
  5551. #endif
  5552. break;
  5553. }
  5554. case cATC_RGB:
  5555. {
  5556. #if BASISD_SUPPORT_ATC
  5557. void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes;
  5558. convert_etc1s_to_atc(pDst_block, pEndpoints, pSelector);
  5559. #else
  5560. assert(0);
  5561. #endif
  5562. break;
  5563. }
  5564. case cIndices:
  5565. {
  5566. uint16_t* pDst_block = reinterpret_cast<uint16_t *>(static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes);
  5567. pDst_block[0] = static_cast<uint16_t>(endpoint_index);
  5568. pDst_block[1] = static_cast<uint16_t>(selector_index);
  5569. break;
  5570. }
  5571. case cA32:
  5572. {
  5573. assert(sizeof(uint32_t) == output_block_or_pixel_stride_in_bytes);
  5574. uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint32_t);
  5575. const uint32_t max_x = basisu::minimum<int>(4, output_row_pitch_in_blocks_or_pixels - block_x * 4);
  5576. const uint32_t max_y = basisu::minimum<int>(4, output_rows_in_pixels - block_y * 4);
  5577. int colors[4];
  5578. decoder_etc_block::get_block_colors5_g(colors, pEndpoints->m_color5, pEndpoints->m_inten5);
  5579. if (max_x == 4)
  5580. {
  5581. for (uint32_t y = 0; y < max_y; y++)
  5582. {
  5583. const uint32_t s = pSelector->m_selectors[y];
  5584. pDst_pixels[3] = static_cast<uint8_t>(colors[s & 3]);
  5585. pDst_pixels[3+4] = static_cast<uint8_t>(colors[(s >> 2) & 3]);
  5586. pDst_pixels[3+8] = static_cast<uint8_t>(colors[(s >> 4) & 3]);
  5587. pDst_pixels[3+12] = static_cast<uint8_t>(colors[(s >> 6) & 3]);
  5588. pDst_pixels += output_row_pitch_in_blocks_or_pixels * sizeof(uint32_t);
  5589. }
  5590. }
  5591. else
  5592. {
  5593. for (uint32_t y = 0; y < max_y; y++)
  5594. {
  5595. const uint32_t s = pSelector->m_selectors[y];
  5596. for (uint32_t x = 0; x < max_x; x++)
  5597. pDst_pixels[3 + 4 * x] = static_cast<uint8_t>(colors[(s >> (x * 2)) & 3]);
  5598. pDst_pixels += output_row_pitch_in_blocks_or_pixels * sizeof(uint32_t);
  5599. }
  5600. }
  5601. break;
  5602. }
  5603. case cRGB32:
  5604. {
  5605. assert(sizeof(uint32_t) == output_block_or_pixel_stride_in_bytes);
  5606. uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint32_t);
  5607. const uint32_t max_x = basisu::minimum<int>(4, output_row_pitch_in_blocks_or_pixels - block_x * 4);
  5608. const uint32_t max_y = basisu::minimum<int>(4, output_rows_in_pixels - block_y * 4);
  5609. color32 colors[4];
  5610. decoder_etc_block::get_block_colors5(colors, pEndpoints->m_color5, pEndpoints->m_inten5);
  5611. for (uint32_t y = 0; y < max_y; y++)
  5612. {
  5613. const uint32_t s = pSelector->m_selectors[y];
  5614. for (uint32_t x = 0; x < max_x; x++)
  5615. {
  5616. const color32& c = colors[(s >> (x * 2)) & 3];
  5617. pDst_pixels[0 + 4 * x] = c.r;
  5618. pDst_pixels[1 + 4 * x] = c.g;
  5619. pDst_pixels[2 + 4 * x] = c.b;
  5620. }
  5621. pDst_pixels += output_row_pitch_in_blocks_or_pixels * sizeof(uint32_t);
  5622. }
  5623. break;
  5624. }
  5625. case cRGBA32:
  5626. {
  5627. assert(sizeof(uint32_t) == output_block_or_pixel_stride_in_bytes);
  5628. uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint32_t);
  5629. const uint32_t max_x = basisu::minimum<int>(4, output_row_pitch_in_blocks_or_pixels - block_x * 4);
  5630. const uint32_t max_y = basisu::minimum<int>(4, output_rows_in_pixels - block_y * 4);
  5631. color32 colors[4];
  5632. decoder_etc_block::get_block_colors5(colors, pEndpoints->m_color5, pEndpoints->m_inten5);
  5633. for (uint32_t y = 0; y < max_y; y++)
  5634. {
  5635. const uint32_t s = pSelector->m_selectors[y];
  5636. for (uint32_t x = 0; x < max_x; x++)
  5637. {
  5638. const color32& c = colors[(s >> (x * 2)) & 3];
  5639. pDst_pixels[0 + 4 * x] = c.r;
  5640. pDst_pixels[1 + 4 * x] = c.g;
  5641. pDst_pixels[2 + 4 * x] = c.b;
  5642. pDst_pixels[3 + 4 * x] = 255;
  5643. }
  5644. pDst_pixels += output_row_pitch_in_blocks_or_pixels * sizeof(uint32_t);
  5645. }
  5646. break;
  5647. }
  5648. case cRGB565:
  5649. case cBGR565:
  5650. {
  5651. assert(sizeof(uint16_t) == output_block_or_pixel_stride_in_bytes);
  5652. uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint16_t);
  5653. const uint32_t max_x = basisu::minimum<int>(4, output_row_pitch_in_blocks_or_pixels - block_x * 4);
  5654. const uint32_t max_y = basisu::minimum<int>(4, output_rows_in_pixels - block_y * 4);
  5655. color32 colors[4];
  5656. decoder_etc_block::get_block_colors5(colors, pEndpoints->m_color5, pEndpoints->m_inten5);
  5657. uint16_t packed_colors[4];
  5658. if (fmt == cRGB565)
  5659. {
  5660. for (uint32_t i = 0; i < 4; i++)
  5661. packed_colors[i] = static_cast<uint16_t>(((colors[i].r >> 3) << 11) | ((colors[i].g >> 2) << 5) | (colors[i].b >> 3));
  5662. }
  5663. else
  5664. {
  5665. for (uint32_t i = 0; i < 4; i++)
  5666. packed_colors[i] = static_cast<uint16_t>(((colors[i].b >> 3) << 11) | ((colors[i].g >> 2) << 5) | (colors[i].r >> 3));
  5667. }
  5668. for (uint32_t y = 0; y < max_y; y++)
  5669. {
  5670. const uint32_t s = pSelector->m_selectors[y];
  5671. for (uint32_t x = 0; x < max_x; x++)
  5672. reinterpret_cast<uint16_t *>(pDst_pixels)[x] = packed_colors[(s >> (x * 2)) & 3];
  5673. pDst_pixels += output_row_pitch_in_blocks_or_pixels * sizeof(uint16_t);
  5674. }
  5675. break;
  5676. }
  5677. case cRGBA4444_COLOR:
  5678. {
  5679. assert(sizeof(uint16_t) == output_block_or_pixel_stride_in_bytes);
  5680. uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint16_t);
  5681. const uint32_t max_x = basisu::minimum<int>(4, output_row_pitch_in_blocks_or_pixels - block_x * 4);
  5682. const uint32_t max_y = basisu::minimum<int>(4, output_rows_in_pixels - block_y * 4);
  5683. color32 colors[4];
  5684. decoder_etc_block::get_block_colors5(colors, pEndpoints->m_color5, pEndpoints->m_inten5);
  5685. uint16_t packed_colors[4];
  5686. for (uint32_t i = 0; i < 4; i++)
  5687. packed_colors[i] = static_cast<uint16_t>(((colors[i].r >> 4) << 12) | ((colors[i].g >> 4) << 8) | ((colors[i].b >> 4) << 4));
  5688. for (uint32_t y = 0; y < max_y; y++)
  5689. {
  5690. const uint32_t s = pSelector->m_selectors[y];
  5691. for (uint32_t x = 0; x < max_x; x++)
  5692. {
  5693. uint16_t cur = reinterpret_cast<uint16_t*>(pDst_pixels)[x];
  5694. cur = (cur & 0xF) | packed_colors[(s >> (x * 2)) & 3];
  5695. reinterpret_cast<uint16_t*>(pDst_pixels)[x] = cur;
  5696. }
  5697. pDst_pixels += output_row_pitch_in_blocks_or_pixels * sizeof(uint16_t);
  5698. }
  5699. break;
  5700. }
  5701. case cRGBA4444_COLOR_OPAQUE:
  5702. {
  5703. assert(sizeof(uint16_t) == output_block_or_pixel_stride_in_bytes);
  5704. uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint16_t);
  5705. const uint32_t max_x = basisu::minimum<int>(4, output_row_pitch_in_blocks_or_pixels - block_x * 4);
  5706. const uint32_t max_y = basisu::minimum<int>(4, output_rows_in_pixels - block_y * 4);
  5707. color32 colors[4];
  5708. decoder_etc_block::get_block_colors5(colors, pEndpoints->m_color5, pEndpoints->m_inten5);
  5709. uint16_t packed_colors[4];
  5710. for (uint32_t i = 0; i < 4; i++)
  5711. packed_colors[i] = static_cast<uint16_t>(((colors[i].r >> 4) << 12) | ((colors[i].g >> 4) << 8) | ((colors[i].b >> 4) << 4) | 0xF);
  5712. for (uint32_t y = 0; y < max_y; y++)
  5713. {
  5714. const uint32_t s = pSelector->m_selectors[y];
  5715. for (uint32_t x = 0; x < max_x; x++)
  5716. reinterpret_cast<uint16_t*>(pDst_pixels)[x] = packed_colors[(s >> (x * 2)) & 3];
  5717. pDst_pixels += output_row_pitch_in_blocks_or_pixels * sizeof(uint16_t);
  5718. }
  5719. break;
  5720. }
  5721. case cRGBA4444_ALPHA:
  5722. {
  5723. assert(sizeof(uint16_t) == output_block_or_pixel_stride_in_bytes);
  5724. uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint16_t);
  5725. const uint32_t max_x = basisu::minimum<int>(4, output_row_pitch_in_blocks_or_pixels - block_x * 4);
  5726. const uint32_t max_y = basisu::minimum<int>(4, output_rows_in_pixels - block_y * 4);
  5727. color32 colors[4];
  5728. decoder_etc_block::get_block_colors5(colors, pEndpoints->m_color5, pEndpoints->m_inten5);
  5729. uint16_t packed_colors[4];
  5730. for (uint32_t i = 0; i < 4; i++)
  5731. packed_colors[i] = colors[i].g >> 4;
  5732. for (uint32_t y = 0; y < max_y; y++)
  5733. {
  5734. const uint32_t s = pSelector->m_selectors[y];
  5735. for (uint32_t x = 0; x < max_x; x++)
  5736. reinterpret_cast<uint16_t*>(pDst_pixels)[x] = packed_colors[(s >> (x * 2)) & 3];
  5737. pDst_pixels += output_row_pitch_in_blocks_or_pixels * sizeof(uint16_t);
  5738. }
  5739. break;
  5740. }
  5741. default:
  5742. {
  5743. assert(0);
  5744. break;
  5745. }
  5746. }
  5747. } // block_x
  5748. } // block-y
  5749. if (endpoint_pred_repeat_count != 0)
  5750. {
  5751. BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: endpoint_pred_repeat_count != 0. The file is corrupted or this is a bug\n");
  5752. return false;
  5753. }
  5754. //assert(endpoint_pred_repeat_count == 0);
  5755. #if BASISD_SUPPORT_PVRTC1
  5756. // PVRTC post process - create per-pixel modulation values.
  5757. if (fmt == cPVRTC1_4_RGB)
  5758. fixup_pvrtc1_4_modulation_rgb((decoder_etc_block*)pPVRTC_work_mem, pPVRTC_endpoints, pDst_blocks, num_blocks_x, num_blocks_y, pvrtc_wrap_addressing);
  5759. else if (fmt == cPVRTC1_4_RGBA)
  5760. fixup_pvrtc1_4_modulation_rgba((decoder_etc_block*)pPVRTC_work_mem, pPVRTC_endpoints, pDst_blocks, num_blocks_x, num_blocks_y, pvrtc_wrap_addressing, pAlpha_blocks, &m_endpoints[0], &m_selectors[0]);
  5761. #endif // BASISD_SUPPORT_PVRTC1
  5762. if (pPVRTC_work_mem)
  5763. free(pPVRTC_work_mem);
  5764. return true;
  5765. }
  5766. basisu_transcoder::basisu_transcoder(const etc1_global_selector_codebook* pGlobal_sel_codebook) :
  5767. m_lowlevel_decoder(pGlobal_sel_codebook)
  5768. {
  5769. }
  5770. bool basisu_transcoder::validate_file_checksums(const void* pData, uint32_t data_size, bool full_validation) const
  5771. {
  5772. if (!validate_header(pData, data_size))
  5773. return false;
  5774. const basis_file_header* pHeader = reinterpret_cast<const basis_file_header*>(pData);
  5775. #if !BASISU_NO_HEADER_OR_DATA_CRC16_CHECKS
  5776. if (crc16(&pHeader->m_data_size, sizeof(basis_file_header) - BASISU_OFFSETOF(basis_file_header, m_data_size), 0) != pHeader->m_header_crc16)
  5777. {
  5778. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: header CRC check failed\n");
  5779. return false;
  5780. }
  5781. if (full_validation)
  5782. {
  5783. if (crc16(reinterpret_cast<const uint8_t*>(pData) + sizeof(basis_file_header), pHeader->m_data_size, 0) != pHeader->m_data_crc16)
  5784. {
  5785. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: data CRC check failed\n");
  5786. return false;
  5787. }
  5788. }
  5789. #endif
  5790. return true;
  5791. }
  5792. bool basisu_transcoder::validate_header_quick(const void* pData, uint32_t data_size) const
  5793. {
  5794. if (data_size <= sizeof(basis_file_header))
  5795. return false;
  5796. const basis_file_header* pHeader = reinterpret_cast<const basis_file_header*>(pData);
  5797. if ((pHeader->m_sig != basis_file_header::cBASISSigValue) || (pHeader->m_ver != BASISD_SUPPORTED_BASIS_VERSION) || (pHeader->m_header_size != sizeof(basis_file_header)))
  5798. {
  5799. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: header has an invalid signature, or file version is unsupported\n");
  5800. return false;
  5801. }
  5802. uint32_t expected_file_size = sizeof(basis_file_header) + pHeader->m_data_size;
  5803. if (data_size < expected_file_size)
  5804. {
  5805. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: source buffer is too small\n");
  5806. return false;
  5807. }
  5808. if ((!pHeader->m_total_slices) || (!pHeader->m_total_images))
  5809. {
  5810. BASISU_DEVEL_ERROR("basisu_transcoder::validate_header_quick: header is invalid\n");
  5811. return false;
  5812. }
  5813. if ((pHeader->m_slice_desc_file_ofs >= data_size) ||
  5814. ((data_size - pHeader->m_slice_desc_file_ofs) < (sizeof(basis_slice_desc) * pHeader->m_total_slices))
  5815. )
  5816. {
  5817. BASISU_DEVEL_ERROR("basisu_transcoder::validate_header_quick: passed in buffer is too small or data is corrupted\n");
  5818. return false;
  5819. }
  5820. return true;
  5821. }
  5822. bool basisu_transcoder::validate_header(const void* pData, uint32_t data_size) const
  5823. {
  5824. if (data_size <= sizeof(basis_file_header))
  5825. {
  5826. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: input source buffer is too small\n");
  5827. return false;
  5828. }
  5829. const basis_file_header* pHeader = reinterpret_cast<const basis_file_header*>(pData);
  5830. if ((pHeader->m_sig != basis_file_header::cBASISSigValue) || (pHeader->m_ver != BASISD_SUPPORTED_BASIS_VERSION) || (pHeader->m_header_size != sizeof(basis_file_header)))
  5831. {
  5832. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: header has an invalid signature, or file version is unsupported\n");
  5833. return false;
  5834. }
  5835. uint32_t expected_file_size = sizeof(basis_file_header) + pHeader->m_data_size;
  5836. if (data_size < expected_file_size)
  5837. {
  5838. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: input source buffer is too small, or header is corrupted\n");
  5839. return false;
  5840. }
  5841. if ((!pHeader->m_total_images) || (!pHeader->m_total_slices))
  5842. {
  5843. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: invalid basis file (total images or slices are 0)\n");
  5844. return false;
  5845. }
  5846. if (pHeader->m_total_images > pHeader->m_total_slices)
  5847. {
  5848. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: invalid basis file (too many images)\n");
  5849. return false;
  5850. }
  5851. if (pHeader->m_flags & cBASISHeaderFlagHasAlphaSlices)
  5852. {
  5853. if (pHeader->m_total_slices & 1)
  5854. {
  5855. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: invalid alpha basis file\n");
  5856. return false;
  5857. }
  5858. }
  5859. if ((pHeader->m_flags & cBASISHeaderFlagETC1S) == 0)
  5860. {
  5861. // We only support ETC1S in basis universal
  5862. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: invalid basis file (ETC1S flag check)\n");
  5863. return false;
  5864. }
  5865. if ((pHeader->m_slice_desc_file_ofs >= data_size) ||
  5866. ((data_size - pHeader->m_slice_desc_file_ofs) < (sizeof(basis_slice_desc) * pHeader->m_total_slices))
  5867. )
  5868. {
  5869. BASISU_DEVEL_ERROR("basisu_transcoder::validate_header_quick: passed in buffer is too small or data is corrupted\n");
  5870. return false;
  5871. }
  5872. return true;
  5873. }
  5874. basis_texture_type basisu_transcoder::get_texture_type(const void* pData, uint32_t data_size) const
  5875. {
  5876. if (!validate_header_quick(pData, data_size))
  5877. {
  5878. BASISU_DEVEL_ERROR("basisu_transcoder::get_texture_type: header validation failed\n");
  5879. return cBASISTexType2DArray;
  5880. }
  5881. const basis_file_header* pHeader = static_cast<const basis_file_header*>(pData);
  5882. basis_texture_type btt = static_cast<basis_texture_type>(static_cast<uint8_t>(pHeader->m_tex_type));
  5883. if (btt >= cBASISTexTypeTotal)
  5884. {
  5885. BASISU_DEVEL_ERROR("basisu_transcoder::validate_header_quick: header's texture type field is invalid\n");
  5886. return cBASISTexType2DArray;
  5887. }
  5888. return btt;
  5889. }
  5890. bool basisu_transcoder::get_userdata(const void* pData, uint32_t data_size, uint32_t& userdata0, uint32_t& userdata1) const
  5891. {
  5892. if (!validate_header_quick(pData, data_size))
  5893. {
  5894. BASISU_DEVEL_ERROR("basisu_transcoder::get_userdata: header validation failed\n");
  5895. return false;
  5896. }
  5897. const basis_file_header* pHeader = static_cast<const basis_file_header*>(pData);
  5898. userdata0 = pHeader->m_userdata0;
  5899. userdata1 = pHeader->m_userdata1;
  5900. return true;
  5901. }
  5902. uint32_t basisu_transcoder::get_total_images(const void* pData, uint32_t data_size) const
  5903. {
  5904. if (!validate_header_quick(pData, data_size))
  5905. {
  5906. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: header validation failed\n");
  5907. return 0;
  5908. }
  5909. const basis_file_header* pHeader = static_cast<const basis_file_header*>(pData);
  5910. return pHeader->m_total_images;
  5911. }
  5912. bool basisu_transcoder::get_image_info(const void* pData, uint32_t data_size, basisu_image_info& image_info, uint32_t image_index) const
  5913. {
  5914. if (!validate_header_quick(pData, data_size))
  5915. {
  5916. BASISU_DEVEL_ERROR("basisu_transcoder::get_image_info: header validation failed\n");
  5917. return false;
  5918. }
  5919. int slice_index = find_first_slice_index(pData, data_size, image_index, 0);
  5920. if (slice_index < 0)
  5921. {
  5922. BASISU_DEVEL_ERROR("basisu_transcoder::get_image_info: invalid slice index\n");
  5923. return false;
  5924. }
  5925. const basis_file_header* pHeader = static_cast<const basis_file_header*>(pData);
  5926. if (image_index >= pHeader->m_total_images)
  5927. {
  5928. BASISU_DEVEL_ERROR("basisu_transcoder::get_image_info: invalid image_index\n");
  5929. return false;
  5930. }
  5931. const basis_slice_desc* pSlice_descs = reinterpret_cast<const basis_slice_desc*>(static_cast<const uint8_t*>(pData) + pHeader->m_slice_desc_file_ofs);
  5932. uint32_t total_levels = 1;
  5933. for (uint32_t i = slice_index + 1; i < pHeader->m_total_slices; i++)
  5934. if (pSlice_descs[i].m_image_index == image_index)
  5935. total_levels = basisu::maximum<uint32_t>(total_levels, pSlice_descs[i].m_level_index + 1);
  5936. else
  5937. break;
  5938. if (total_levels > 16)
  5939. {
  5940. BASISU_DEVEL_ERROR("basisu_transcoder::get_image_info: invalid image_index\n");
  5941. return false;
  5942. }
  5943. const basis_slice_desc& slice_desc = pSlice_descs[slice_index];
  5944. image_info.m_image_index = image_index;
  5945. image_info.m_total_levels = total_levels;
  5946. image_info.m_alpha_flag = (pHeader->m_flags & cBASISHeaderFlagHasAlphaSlices) != 0;
  5947. image_info.m_iframe_flag = (slice_desc.m_flags & cSliceDescFlagsFrameIsIFrame) != 0;
  5948. image_info.m_width = slice_desc.m_num_blocks_x * 4;
  5949. image_info.m_height = slice_desc.m_num_blocks_y * 4;
  5950. image_info.m_orig_width = slice_desc.m_orig_width;
  5951. image_info.m_orig_height = slice_desc.m_orig_height;
  5952. image_info.m_num_blocks_x = slice_desc.m_num_blocks_x;
  5953. image_info.m_num_blocks_y = slice_desc.m_num_blocks_y;
  5954. image_info.m_total_blocks = image_info.m_num_blocks_x * image_info.m_num_blocks_y;
  5955. image_info.m_first_slice_index = slice_index;
  5956. return true;
  5957. }
  5958. uint32_t basisu_transcoder::get_total_image_levels(const void* pData, uint32_t data_size, uint32_t image_index) const
  5959. {
  5960. if (!validate_header_quick(pData, data_size))
  5961. {
  5962. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_image_levels: header validation failed\n");
  5963. return false;
  5964. }
  5965. int slice_index = find_first_slice_index(pData, data_size, image_index, 0);
  5966. if (slice_index < 0)
  5967. {
  5968. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_image_levels: failed finding slice\n");
  5969. return false;
  5970. }
  5971. const basis_file_header* pHeader = static_cast<const basis_file_header*>(pData);
  5972. if (image_index >= pHeader->m_total_images)
  5973. {
  5974. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_image_levels: invalid image_index\n");
  5975. return false;
  5976. }
  5977. const basis_slice_desc* pSlice_descs = reinterpret_cast<const basis_slice_desc*>(static_cast<const uint8_t*>(pData) + pHeader->m_slice_desc_file_ofs);
  5978. uint32_t total_levels = 1;
  5979. for (uint32_t i = slice_index + 1; i < pHeader->m_total_slices; i++)
  5980. if (pSlice_descs[i].m_image_index == image_index)
  5981. total_levels = basisu::maximum<uint32_t>(total_levels, pSlice_descs[i].m_level_index + 1);
  5982. else
  5983. break;
  5984. const uint32_t cMaxSupportedLevels = 16;
  5985. if (total_levels > cMaxSupportedLevels)
  5986. {
  5987. BASISU_DEVEL_ERROR("basisu_transcoder::get_total_image_levels: invalid image levels!\n");
  5988. return false;
  5989. }
  5990. return total_levels;
  5991. }
  5992. bool basisu_transcoder::get_image_level_desc(const void* pData, uint32_t data_size, uint32_t image_index, uint32_t level_index, uint32_t& orig_width, uint32_t& orig_height, uint32_t& total_blocks) const
  5993. {
  5994. if (!validate_header_quick(pData, data_size))
  5995. {
  5996. BASISU_DEVEL_ERROR("basisu_transcoder::get_image_level_desc: header validation failed\n");
  5997. return false;
  5998. }
  5999. int slice_index = find_first_slice_index(pData, data_size, image_index, level_index);
  6000. if (slice_index < 0)
  6001. {
  6002. BASISU_DEVEL_ERROR("basisu_transcoder::get_image_level_desc: failed finding slice\n");
  6003. return false;
  6004. }
  6005. const basis_file_header* pHeader = static_cast<const basis_file_header*>(pData);
  6006. if (image_index >= pHeader->m_total_images)
  6007. {
  6008. BASISU_DEVEL_ERROR("basisu_transcoder::get_image_level_desc: invalid image_index\n");
  6009. return false;
  6010. }
  6011. const basis_slice_desc* pSlice_descs = reinterpret_cast<const basis_slice_desc*>(static_cast<const uint8_t*>(pData) + pHeader->m_slice_desc_file_ofs);
  6012. const basis_slice_desc& slice_desc = pSlice_descs[slice_index];
  6013. orig_width = slice_desc.m_orig_width;
  6014. orig_height = slice_desc.m_orig_height;
  6015. total_blocks = slice_desc.m_num_blocks_x * slice_desc.m_num_blocks_y;
  6016. return true;
  6017. }
  6018. bool basisu_transcoder::get_image_level_info(const void* pData, uint32_t data_size, basisu_image_level_info& image_info, uint32_t image_index, uint32_t level_index) const
  6019. {
  6020. if (!validate_header_quick(pData, data_size))
  6021. {
  6022. BASISU_DEVEL_ERROR("basisu_transcoder::get_image_level_info: validate_file_checksums failed\n");
  6023. return false;
  6024. }
  6025. int slice_index = find_first_slice_index(pData, data_size, image_index, level_index);
  6026. if (slice_index < 0)
  6027. {
  6028. BASISU_DEVEL_ERROR("basisu_transcoder::get_image_level_info: failed finding slice\n");
  6029. return false;
  6030. }
  6031. const basis_file_header* pHeader = static_cast<const basis_file_header*>(pData);
  6032. if (image_index >= pHeader->m_total_images)
  6033. {
  6034. BASISU_DEVEL_ERROR("basisu_transcoder::get_image_level_info: invalid image_index\n");
  6035. return false;
  6036. }
  6037. const basis_slice_desc* pSlice_descs = reinterpret_cast<const basis_slice_desc*>(static_cast<const uint8_t*>(pData) + pHeader->m_slice_desc_file_ofs);
  6038. const basis_slice_desc& slice_desc = pSlice_descs[slice_index];
  6039. image_info.m_image_index = image_index;
  6040. image_info.m_level_index = level_index;
  6041. image_info.m_alpha_flag = (pHeader->m_flags & cBASISHeaderFlagHasAlphaSlices) != 0;
  6042. image_info.m_iframe_flag = (slice_desc.m_flags & cSliceDescFlagsFrameIsIFrame) != 0;
  6043. image_info.m_width = slice_desc.m_num_blocks_x * 4;
  6044. image_info.m_height = slice_desc.m_num_blocks_y * 4;
  6045. image_info.m_orig_width = slice_desc.m_orig_width;
  6046. image_info.m_orig_height = slice_desc.m_orig_height;
  6047. image_info.m_num_blocks_x = slice_desc.m_num_blocks_x;
  6048. image_info.m_num_blocks_y = slice_desc.m_num_blocks_y;
  6049. image_info.m_total_blocks = image_info.m_num_blocks_x * image_info.m_num_blocks_y;
  6050. image_info.m_first_slice_index = slice_index;
  6051. return true;
  6052. }
  6053. bool basisu_transcoder::get_file_info(const void* pData, uint32_t data_size, basisu_file_info& file_info) const
  6054. {
  6055. if (!validate_file_checksums(pData, data_size, false))
  6056. {
  6057. BASISU_DEVEL_ERROR("basisu_transcoder::get_file_info: validate_file_checksums failed\n");
  6058. return false;
  6059. }
  6060. const basis_file_header* pHeader = static_cast<const basis_file_header*>(pData);
  6061. const basis_slice_desc* pSlice_descs = reinterpret_cast<const basis_slice_desc*>(static_cast<const uint8_t*>(pData) + pHeader->m_slice_desc_file_ofs);
  6062. file_info.m_version = pHeader->m_ver;
  6063. file_info.m_total_header_size = sizeof(basis_file_header) + pHeader->m_total_slices * sizeof(basis_slice_desc);
  6064. file_info.m_total_selectors = pHeader->m_total_selectors;
  6065. file_info.m_selector_codebook_size = pHeader->m_selector_cb_file_size;
  6066. file_info.m_total_endpoints = pHeader->m_total_endpoints;
  6067. file_info.m_endpoint_codebook_size = pHeader->m_endpoint_cb_file_size;
  6068. file_info.m_tables_size = pHeader->m_tables_file_size;
  6069. file_info.m_etc1s = (pHeader->m_flags & cBASISHeaderFlagETC1S) != 0;
  6070. file_info.m_y_flipped = (pHeader->m_flags & cBASISHeaderFlagYFlipped) != 0;
  6071. file_info.m_has_alpha_slices = (pHeader->m_flags & cBASISHeaderFlagHasAlphaSlices) != 0;
  6072. const uint32_t total_slices = pHeader->m_total_slices;
  6073. file_info.m_slice_info.resize(total_slices);
  6074. file_info.m_slices_size = 0;
  6075. file_info.m_tex_type = static_cast<basis_texture_type>(static_cast<uint8_t>(pHeader->m_tex_type));
  6076. if (file_info.m_tex_type > cBASISTexTypeTotal)
  6077. {
  6078. BASISU_DEVEL_ERROR("basisu_transcoder::get_file_info: invalid texture type, file is corrupted\n");
  6079. return false;
  6080. }
  6081. file_info.m_us_per_frame = pHeader->m_us_per_frame;
  6082. file_info.m_userdata0 = pHeader->m_userdata0;
  6083. file_info.m_userdata1 = pHeader->m_userdata1;
  6084. file_info.m_image_mipmap_levels.resize(0);
  6085. file_info.m_image_mipmap_levels.resize(pHeader->m_total_images);
  6086. file_info.m_total_images = pHeader->m_total_images;
  6087. for (uint32_t i = 0; i < total_slices; i++)
  6088. {
  6089. file_info.m_slices_size += pSlice_descs[i].m_file_size;
  6090. basisu_slice_info& slice_info = file_info.m_slice_info[i];
  6091. slice_info.m_orig_width = pSlice_descs[i].m_orig_width;
  6092. slice_info.m_orig_height = pSlice_descs[i].m_orig_height;
  6093. slice_info.m_width = pSlice_descs[i].m_num_blocks_x * 4;
  6094. slice_info.m_height = pSlice_descs[i].m_num_blocks_y * 4;
  6095. slice_info.m_num_blocks_x = pSlice_descs[i].m_num_blocks_x;
  6096. slice_info.m_num_blocks_y = pSlice_descs[i].m_num_blocks_y;
  6097. slice_info.m_total_blocks = slice_info.m_num_blocks_x * slice_info.m_num_blocks_y;
  6098. slice_info.m_compressed_size = pSlice_descs[i].m_file_size;
  6099. slice_info.m_slice_index = i;
  6100. slice_info.m_image_index = pSlice_descs[i].m_image_index;
  6101. slice_info.m_level_index = pSlice_descs[i].m_level_index;
  6102. slice_info.m_unpacked_slice_crc16 = pSlice_descs[i].m_slice_data_crc16;
  6103. slice_info.m_alpha_flag = (pSlice_descs[i].m_flags & cSliceDescFlagsIsAlphaData) != 0;
  6104. slice_info.m_iframe_flag = (pSlice_descs[i].m_flags & cSliceDescFlagsFrameIsIFrame) != 0;
  6105. if (pSlice_descs[i].m_image_index >= pHeader->m_total_images)
  6106. {
  6107. BASISU_DEVEL_ERROR("basisu_transcoder::get_file_info: slice desc's image index is invalid\n");
  6108. return false;
  6109. }
  6110. file_info.m_image_mipmap_levels[pSlice_descs[i].m_image_index] = basisu::maximum<uint32_t>(file_info.m_image_mipmap_levels[pSlice_descs[i].m_image_index], pSlice_descs[i].m_level_index + 1);
  6111. if (file_info.m_image_mipmap_levels[pSlice_descs[i].m_image_index] > 16)
  6112. {
  6113. BASISU_DEVEL_ERROR("basisu_transcoder::get_file_info: slice mipmap level is invalid\n");
  6114. return false;
  6115. }
  6116. }
  6117. return true;
  6118. }
  6119. bool basisu_transcoder::start_transcoding(const void* pData, uint32_t data_size) const
  6120. {
  6121. if (m_lowlevel_decoder.m_endpoints.size())
  6122. {
  6123. BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: already called start_transcoding\n");
  6124. return true;
  6125. }
  6126. if (!validate_header_quick(pData, data_size))
  6127. {
  6128. BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: header validation failed\n");
  6129. return false;
  6130. }
  6131. const basis_file_header* pHeader = reinterpret_cast<const basis_file_header*>(pData);
  6132. const uint8_t* pDataU8 = static_cast<const uint8_t*>(pData);
  6133. if (!pHeader->m_endpoint_cb_file_size || !pHeader->m_selector_cb_file_size || !pHeader->m_tables_file_size)
  6134. {
  6135. BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted (0)\n");
  6136. }
  6137. if ((pHeader->m_endpoint_cb_file_ofs > data_size) || (pHeader->m_selector_cb_file_ofs > data_size) || (pHeader->m_tables_file_ofs > data_size))
  6138. {
  6139. BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted or passed in buffer too small (1)\n");
  6140. return false;
  6141. }
  6142. if (pHeader->m_endpoint_cb_file_size > (data_size - pHeader->m_endpoint_cb_file_ofs))
  6143. {
  6144. BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted or passed in buffer too small (2)\n");
  6145. return false;
  6146. }
  6147. if (pHeader->m_selector_cb_file_size > (data_size - pHeader->m_selector_cb_file_ofs))
  6148. {
  6149. BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted or passed in buffer too small (3)\n");
  6150. return false;
  6151. }
  6152. if (pHeader->m_tables_file_size > (data_size - pHeader->m_tables_file_ofs))
  6153. {
  6154. BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted or passed in buffer too small (3)\n");
  6155. return false;
  6156. }
  6157. if (!m_lowlevel_decoder.decode_palettes(
  6158. pHeader->m_total_endpoints, pDataU8 + pHeader->m_endpoint_cb_file_ofs, pHeader->m_endpoint_cb_file_size,
  6159. pHeader->m_total_selectors, pDataU8 + pHeader->m_selector_cb_file_ofs, pHeader->m_selector_cb_file_size))
  6160. {
  6161. BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: decode_palettes failed\n");
  6162. return false;
  6163. }
  6164. if (!m_lowlevel_decoder.decode_tables(pDataU8 + pHeader->m_tables_file_ofs, pHeader->m_tables_file_size))
  6165. {
  6166. BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: decode_tables failed\n");
  6167. return false;
  6168. }
  6169. return true;
  6170. }
  6171. bool basisu_transcoder::transcode_slice(const void* pData, uint32_t data_size, uint32_t slice_index, void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, block_format fmt,
  6172. uint32_t output_block_or_pixel_stride_in_bytes, uint32_t decode_flags, uint32_t output_row_pitch_in_blocks_or_pixels, basisu_transcoder_state* pState, void *pAlpha_blocks, uint32_t output_rows_in_pixels) const
  6173. {
  6174. if (!m_lowlevel_decoder.m_endpoints.size())
  6175. {
  6176. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_slice: must call start_transcoding first\n");
  6177. return false;
  6178. }
  6179. if (decode_flags & cDecodeFlagsPVRTCDecodeToNextPow2)
  6180. {
  6181. // TODO: Not yet supported
  6182. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_slice: cDecodeFlagsPVRTCDecodeToNextPow2 currently unsupported\n");
  6183. return false;
  6184. }
  6185. if (!validate_header_quick(pData, data_size))
  6186. {
  6187. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_slice: header validation failed\n");
  6188. return false;
  6189. }
  6190. const basis_file_header* pHeader = reinterpret_cast<const basis_file_header*>(pData);
  6191. const uint8_t* pDataU8 = static_cast<const uint8_t*>(pData);
  6192. if (slice_index >= pHeader->m_total_slices)
  6193. {
  6194. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_slice: slice_index >= pHeader->m_total_slices\n");
  6195. return false;
  6196. }
  6197. const basis_slice_desc& slice_desc = reinterpret_cast<const basis_slice_desc*>(pDataU8 + pHeader->m_slice_desc_file_ofs)[slice_index];
  6198. uint32_t total_blocks = slice_desc.m_num_blocks_x * slice_desc.m_num_blocks_y;
  6199. if (basis_block_format_is_uncompressed(fmt))
  6200. {
  6201. // Assume the output buffer is orig_width by orig_height
  6202. if (!output_row_pitch_in_blocks_or_pixels)
  6203. output_row_pitch_in_blocks_or_pixels = slice_desc.m_orig_width;
  6204. if (!output_rows_in_pixels)
  6205. output_rows_in_pixels = slice_desc.m_orig_height;
  6206. // Now make sure the output buffer is large enough, or we'll overwrite memory.
  6207. if (output_blocks_buf_size_in_blocks_or_pixels < (output_rows_in_pixels * output_row_pitch_in_blocks_or_pixels))
  6208. {
  6209. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_slice: output_blocks_buf_size_in_blocks_or_pixels < (output_rows_in_pixels * output_row_pitch_in_blocks_or_pixels)\n");
  6210. return false;
  6211. }
  6212. }
  6213. else
  6214. {
  6215. if (output_blocks_buf_size_in_blocks_or_pixels < total_blocks)
  6216. {
  6217. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_slice: output_blocks_buf_size_in_blocks_or_pixels < total_blocks\n");
  6218. return false;
  6219. }
  6220. }
  6221. if (fmt != cETC1)
  6222. {
  6223. if ((fmt == cPVRTC1_4_RGB) || (fmt == cPVRTC1_4_RGBA))
  6224. {
  6225. if ((!basisu::is_pow2(slice_desc.m_num_blocks_x * 4)) || (!basisu::is_pow2(slice_desc.m_num_blocks_y * 4)))
  6226. {
  6227. // PVRTC1 only supports power of 2 dimensions
  6228. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_slice: PVRTC1 only supports power of 2 dimensions\n");
  6229. return false;
  6230. }
  6231. }
  6232. }
  6233. if (slice_desc.m_file_ofs > data_size)
  6234. {
  6235. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_slice: invalid slice_desc.m_file_ofs, or passed in buffer too small\n");
  6236. return false;
  6237. }
  6238. const uint32_t data_size_left = data_size - slice_desc.m_file_ofs;
  6239. if (data_size_left < slice_desc.m_file_size)
  6240. {
  6241. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_slice: invalid slice_desc.m_file_size, or passed in buffer too small\n");
  6242. return false;
  6243. }
  6244. return m_lowlevel_decoder.transcode_slice(pOutput_blocks, slice_desc.m_num_blocks_x, slice_desc.m_num_blocks_y,
  6245. pDataU8 + slice_desc.m_file_ofs, slice_desc.m_file_size,
  6246. fmt, output_block_or_pixel_stride_in_bytes, (decode_flags & cDecodeFlagsPVRTCWrapAddressing) != 0, (decode_flags & cDecodeFlagsBC1ForbidThreeColorBlocks) == 0, *pHeader, slice_desc, output_row_pitch_in_blocks_or_pixels, pState,
  6247. (decode_flags & cDecodeFlagsOutputHasAlphaIndices) != 0, pAlpha_blocks, output_rows_in_pixels);
  6248. }
  6249. int basisu_transcoder::find_first_slice_index(const void* pData, uint32_t data_size, uint32_t image_index, uint32_t level_index) const
  6250. {
  6251. (void)data_size;
  6252. const basis_file_header* pHeader = reinterpret_cast<const basis_file_header*>(pData);
  6253. const uint8_t* pDataU8 = static_cast<const uint8_t*>(pData);
  6254. // For very large basis files this search could be painful
  6255. // TODO: Binary search this
  6256. for (uint32_t slice_iter = 0; slice_iter < pHeader->m_total_slices; slice_iter++)
  6257. {
  6258. const basis_slice_desc& slice_desc = reinterpret_cast<const basis_slice_desc*>(pDataU8 + pHeader->m_slice_desc_file_ofs)[slice_iter];
  6259. if ((slice_desc.m_image_index == image_index) && (slice_desc.m_level_index == level_index))
  6260. return slice_iter;
  6261. }
  6262. BASISU_DEVEL_ERROR("basisu_transcoder::find_first_slice_index: didn't find slice\n");
  6263. return -1;
  6264. }
  6265. int basisu_transcoder::find_slice(const void* pData, uint32_t data_size, uint32_t image_index, uint32_t level_index, bool alpha_data) const
  6266. {
  6267. if (!validate_header_quick(pData, data_size))
  6268. {
  6269. BASISU_DEVEL_ERROR("basisu_transcoder::find_slice: header validation failed\n");
  6270. return false;
  6271. }
  6272. const basis_file_header* pHeader = reinterpret_cast<const basis_file_header*>(pData);
  6273. const uint8_t* pDataU8 = static_cast<const uint8_t*>(pData);
  6274. const basis_slice_desc* pSlice_descs = reinterpret_cast<const basis_slice_desc*>(pDataU8 + pHeader->m_slice_desc_file_ofs);
  6275. // For very large basis files this search could be painful
  6276. // TODO: Binary search this
  6277. for (uint32_t slice_iter = 0; slice_iter < pHeader->m_total_slices; slice_iter++)
  6278. {
  6279. const basis_slice_desc& slice_desc = pSlice_descs[slice_iter];
  6280. if ((slice_desc.m_image_index == image_index) && (slice_desc.m_level_index == level_index))
  6281. {
  6282. const bool slice_alpha = (slice_desc.m_flags & cSliceDescFlagsIsAlphaData) != 0;
  6283. if (slice_alpha == alpha_data)
  6284. return slice_iter;
  6285. }
  6286. }
  6287. BASISU_DEVEL_ERROR("basisu_transcoder::find_slice: didn't find slice\n");
  6288. return -1;
  6289. }
  6290. static void write_opaque_alpha_blocks(
  6291. uint32_t num_blocks_x, uint32_t num_blocks_y,
  6292. void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, block_format fmt,
  6293. uint32_t block_stride_in_bytes, uint32_t output_row_pitch_in_blocks_or_pixels)
  6294. {
  6295. BASISU_NOTE_UNUSED(output_blocks_buf_size_in_blocks_or_pixels);
  6296. if (!output_row_pitch_in_blocks_or_pixels)
  6297. output_row_pitch_in_blocks_or_pixels = num_blocks_x;
  6298. if (fmt == cETC2_EAC_A8)
  6299. {
  6300. #if BASISD_SUPPORT_ETC2_EAC_A8
  6301. eac_a8_block blk;
  6302. blk.m_base = 255;
  6303. blk.m_multiplier = 1;
  6304. blk.m_table = 13;
  6305. // Selectors are all 4's
  6306. static const uint8_t s_etc2_eac_a8_sel4[6] = { 0x92, 0x49, 0x24, 0x92, 0x49, 0x24 };
  6307. memcpy(&blk.m_selectors, s_etc2_eac_a8_sel4, sizeof(s_etc2_eac_a8_sel4));
  6308. for (uint32_t y = 0; y < num_blocks_y; y++)
  6309. {
  6310. uint32_t dst_ofs = y * output_row_pitch_in_blocks_or_pixels * block_stride_in_bytes;
  6311. for (uint32_t x = 0; x < num_blocks_x; x++)
  6312. {
  6313. memcpy((uint8_t*)pOutput_blocks + dst_ofs, &blk, sizeof(blk));
  6314. dst_ofs += block_stride_in_bytes;
  6315. }
  6316. }
  6317. #endif
  6318. }
  6319. else if (fmt == cBC4)
  6320. {
  6321. #if BASISD_SUPPORT_DXT5A
  6322. dxt5a_block blk;
  6323. blk.m_endpoints[0] = 255;
  6324. blk.m_endpoints[1] = 255;
  6325. memset(blk.m_selectors, 0, sizeof(blk.m_selectors));
  6326. for (uint32_t y = 0; y < num_blocks_y; y++)
  6327. {
  6328. uint32_t dst_ofs = y * output_row_pitch_in_blocks_or_pixels * block_stride_in_bytes;
  6329. for (uint32_t x = 0; x < num_blocks_x; x++)
  6330. {
  6331. memcpy((uint8_t*)pOutput_blocks + dst_ofs, &blk, sizeof(blk));
  6332. dst_ofs += block_stride_in_bytes;
  6333. }
  6334. }
  6335. #endif
  6336. }
  6337. }
  6338. bool basisu_transcoder::transcode_image_level(
  6339. const void* pData, uint32_t data_size,
  6340. uint32_t image_index, uint32_t level_index,
  6341. void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels,
  6342. transcoder_texture_format fmt,
  6343. uint32_t decode_flags, uint32_t output_row_pitch_in_blocks_or_pixels, basisu_transcoder_state *pState, uint32_t output_rows_in_pixels) const
  6344. {
  6345. const uint32_t bytes_per_block = basis_get_bytes_per_block(fmt);
  6346. if (!m_lowlevel_decoder.m_endpoints.size())
  6347. {
  6348. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: must call start_transcoding() first\n");
  6349. return false;
  6350. }
  6351. const bool transcode_alpha_data_to_opaque_formats = (decode_flags & cDecodeFlagsTranscodeAlphaDataToOpaqueFormats) != 0;
  6352. if (decode_flags & cDecodeFlagsPVRTCDecodeToNextPow2)
  6353. {
  6354. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: cDecodeFlagsPVRTCDecodeToNextPow2 currently unsupported\n");
  6355. // TODO: Not yet supported
  6356. return false;
  6357. }
  6358. if (!validate_header_quick(pData, data_size))
  6359. {
  6360. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: header validation failed\n");
  6361. return false;
  6362. }
  6363. const basis_file_header* pHeader = reinterpret_cast<const basis_file_header*>(pData);
  6364. const uint8_t* pDataU8 = static_cast<const uint8_t*>(pData);
  6365. const basis_slice_desc* pSlice_descs = reinterpret_cast<const basis_slice_desc*>(pDataU8 + pHeader->m_slice_desc_file_ofs);
  6366. const bool basis_file_has_alpha_slices = (pHeader->m_flags & cBASISHeaderFlagHasAlphaSlices) != 0;
  6367. int slice_index = find_first_slice_index(pData, data_size, image_index, level_index);
  6368. if (slice_index < 0)
  6369. {
  6370. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: failed finding slice index\n");
  6371. // Unable to find the requested image/level
  6372. return false;
  6373. }
  6374. if ((fmt == cTFPVRTC1_4_RGBA) && (!basis_file_has_alpha_slices))
  6375. {
  6376. // Switch to PVRTC1 RGB if the input doesn't have alpha.
  6377. fmt = cTFPVRTC1_4_RGB;
  6378. }
  6379. if (pSlice_descs[slice_index].m_flags & cSliceDescFlagsIsAlphaData)
  6380. {
  6381. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: alpha basis file has out of order alpha slice\n");
  6382. // The first slice shouldn't have alpha data in a properly formed basis file
  6383. return false;
  6384. }
  6385. if (basis_file_has_alpha_slices)
  6386. {
  6387. // The alpha data should immediately follow the color data, and have the same resolution.
  6388. if ((slice_index + 1U) >= pHeader->m_total_slices)
  6389. {
  6390. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: alpha basis file has missing alpha slice\n");
  6391. // basis file is missing the alpha slice
  6392. return false;
  6393. }
  6394. // Basic sanity checks
  6395. if ((pSlice_descs[slice_index + 1].m_flags & cSliceDescFlagsIsAlphaData) == 0)
  6396. {
  6397. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: alpha basis file has missing alpha slice (flag check)\n");
  6398. // This slice should have alpha data
  6399. return false;
  6400. }
  6401. if ((pSlice_descs[slice_index].m_num_blocks_x != pSlice_descs[slice_index + 1].m_num_blocks_x) || (pSlice_descs[slice_index].m_num_blocks_y != pSlice_descs[slice_index + 1].m_num_blocks_y))
  6402. {
  6403. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: alpha basis file slice dimensions bad\n");
  6404. // Alpha slice should have been the same res as the color slice
  6405. return false;
  6406. }
  6407. }
  6408. bool status = false;
  6409. const uint32_t total_slice_blocks = pSlice_descs[slice_index].m_num_blocks_x * pSlice_descs[slice_index].m_num_blocks_y;
  6410. if (((fmt == cTFPVRTC1_4_RGB) || (fmt == cTFPVRTC1_4_RGBA)) && (output_blocks_buf_size_in_blocks_or_pixels > total_slice_blocks))
  6411. {
  6412. // The transcoder doesn't write beyond total_slice_blocks, so we need to clear the rest ourselves.
  6413. // For GL usage, PVRTC1 4bpp image size is (max(width, 8)* max(height, 8) * 4 + 7) / 8.
  6414. // However, for KTX and internally in Basis this formula isn't used, it's just ((width+3)/4) * ((height+3)/4) * bytes_per_block. This is all the transcoder actually writes to memory.
  6415. memset(static_cast<uint8_t*>(pOutput_blocks) + total_slice_blocks * bytes_per_block, 0, (output_blocks_buf_size_in_blocks_or_pixels - total_slice_blocks) * bytes_per_block);
  6416. }
  6417. switch (fmt)
  6418. {
  6419. case cTFETC1:
  6420. {
  6421. uint32_t slice_index_to_decode = slice_index;
  6422. // If the caller wants us to transcode the mip level's alpha data, then use the next slice.
  6423. if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats))
  6424. slice_index_to_decode++;
  6425. status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cETC1, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6426. if (!status)
  6427. {
  6428. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ETC1 failed\n");
  6429. }
  6430. break;
  6431. }
  6432. case cTFBC1:
  6433. {
  6434. #if !BASISD_SUPPORT_DXT1
  6435. return false;
  6436. #endif
  6437. uint32_t slice_index_to_decode = slice_index;
  6438. // If the caller wants us to transcode the mip level's alpha data, then use the next slice.
  6439. if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats))
  6440. slice_index_to_decode++;
  6441. status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC1, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6442. if (!status)
  6443. {
  6444. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC1 failed\n");
  6445. }
  6446. break;
  6447. }
  6448. case cTFBC4:
  6449. {
  6450. #if !BASISD_SUPPORT_DXT5A
  6451. return false;
  6452. #endif
  6453. uint32_t slice_index_to_decode = slice_index;
  6454. // If the caller wants us to transcode the mip level's alpha data, then use the next slice.
  6455. if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats))
  6456. slice_index_to_decode++;
  6457. status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC4, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6458. if (!status)
  6459. {
  6460. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC4 failed\n");
  6461. }
  6462. break;
  6463. }
  6464. case cTFPVRTC1_4_RGB:
  6465. {
  6466. #if !BASISD_SUPPORT_PVRTC1
  6467. return false;
  6468. #endif
  6469. uint32_t slice_index_to_decode = slice_index;
  6470. // If the caller wants us to transcode the mip level's alpha data, then use the next slice.
  6471. if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats))
  6472. slice_index_to_decode++;
  6473. // output_row_pitch_in_blocks_or_pixels is actually ignored because we're transcoding to PVRTC1. (Print a dev warning if it's != 0?)
  6474. status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cPVRTC1_4_RGB, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6475. if (!status)
  6476. {
  6477. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to PVRTC1 4 RGB failed\n");
  6478. }
  6479. break;
  6480. }
  6481. case cTFPVRTC1_4_RGBA:
  6482. {
  6483. #if !BASISD_SUPPORT_PVRTC1
  6484. return false;
  6485. #endif
  6486. assert(basis_file_has_alpha_slices);
  6487. // Temp buffer to hold alpha block endpoint/selector indices
  6488. std::vector<uint32_t> temp_block_indices(total_slice_blocks);
  6489. // First transcode alpha data to temp buffer
  6490. status = transcode_slice(pData, data_size, slice_index + 1, &temp_block_indices[0], total_slice_blocks, cIndices, sizeof(uint32_t), decode_flags, pSlice_descs[slice_index].m_num_blocks_x, pState);
  6491. if (!status)
  6492. {
  6493. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to PVRTC1 4 RGBA failed (0)\n");
  6494. }
  6495. else
  6496. {
  6497. // output_row_pitch_in_blocks_or_pixels is actually ignored because we're transcoding to PVRTC1. (Print a dev warning if it's != 0?)
  6498. status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cPVRTC1_4_RGBA, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState, &temp_block_indices[0]);
  6499. if (!status)
  6500. {
  6501. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to PVRTC1 4 RGBA failed (1)\n");
  6502. }
  6503. }
  6504. break;
  6505. }
  6506. case cTFBC7_M6_OPAQUE_ONLY:
  6507. {
  6508. #if !BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY
  6509. return false;
  6510. #endif
  6511. uint32_t slice_index_to_decode = slice_index;
  6512. // If the caller wants us to transcode the mip level's alpha data, then use the next slice.
  6513. if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats))
  6514. slice_index_to_decode++;
  6515. status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC7_M6_OPAQUE_ONLY, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6516. if (!status)
  6517. {
  6518. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC7 m6 opaque only failed\n");
  6519. }
  6520. break;
  6521. }
  6522. case cTFBC7_M5:
  6523. {
  6524. #if !BASISD_SUPPORT_BC7_MODE5
  6525. return false;
  6526. #else
  6527. // First transcode the color slice. The cBC7_M5_COLOR transcoder will output opaque mode 5 blocks.
  6528. status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC7_M5_COLOR, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6529. if ((status) && (basis_file_has_alpha_slices))
  6530. {
  6531. // Now transcode the alpha slice. The cBC7_M5_ALPHA transcoder will now change the opaque mode 5 blocks to blocks with alpha.
  6532. status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC7_M5_ALPHA, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6533. }
  6534. break;
  6535. #endif
  6536. }
  6537. case cTFETC2:
  6538. {
  6539. #if !BASISD_SUPPORT_ETC2_EAC_A8
  6540. return false;
  6541. #endif
  6542. if (basis_file_has_alpha_slices)
  6543. {
  6544. // First decode the alpha data
  6545. status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cETC2_EAC_A8, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6546. }
  6547. else
  6548. {
  6549. write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cETC2_EAC_A8, 16, output_row_pitch_in_blocks_or_pixels);
  6550. status = true;
  6551. }
  6552. if (status)
  6553. {
  6554. // Now decode the color data
  6555. status = transcode_slice(pData, data_size, slice_index, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, cETC1, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6556. if (!status)
  6557. {
  6558. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ETC2 RGB failed\n");
  6559. }
  6560. }
  6561. else
  6562. {
  6563. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ETC2 A failed\n");
  6564. }
  6565. break;
  6566. }
  6567. case cTFBC3:
  6568. {
  6569. #if !BASISD_SUPPORT_DXT1
  6570. return false;
  6571. #endif
  6572. #if !BASISD_SUPPORT_DXT5A
  6573. return false;
  6574. #endif
  6575. // First decode the alpha data
  6576. if (basis_file_has_alpha_slices)
  6577. {
  6578. status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6579. }
  6580. else
  6581. {
  6582. write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC4, 16, output_row_pitch_in_blocks_or_pixels);
  6583. status = true;
  6584. }
  6585. if (status)
  6586. {
  6587. // Now decode the color data. Forbid 3 color blocks, which aren't allowed in BC3.
  6588. status = transcode_slice(pData, data_size, slice_index, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, cBC1, 16, decode_flags | cDecodeFlagsBC1ForbidThreeColorBlocks, output_row_pitch_in_blocks_or_pixels, pState);
  6589. if (!status)
  6590. {
  6591. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC3 RGB failed\n");
  6592. }
  6593. }
  6594. else
  6595. {
  6596. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC3 A failed\n");
  6597. }
  6598. break;
  6599. }
  6600. case cTFBC5:
  6601. {
  6602. #if !BASISD_SUPPORT_DXT5A
  6603. return false;
  6604. #endif
  6605. // Decode the R data (actually the green channel of the color data slice in the basis file)
  6606. status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6607. if (status)
  6608. {
  6609. if (basis_file_has_alpha_slices)
  6610. {
  6611. // Decode the G data (actually the green channel of the alpha data slice in the basis file)
  6612. status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6613. if (!status)
  6614. {
  6615. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC5 1 failed\n");
  6616. }
  6617. }
  6618. else
  6619. {
  6620. write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, cBC4, 16, output_row_pitch_in_blocks_or_pixels);
  6621. status = true;
  6622. }
  6623. }
  6624. else
  6625. {
  6626. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC5 channel 0 failed\n");
  6627. }
  6628. break;
  6629. }
  6630. case cTFASTC_4x4:
  6631. {
  6632. #if !BASISD_SUPPORT_ASTC
  6633. return false;
  6634. #endif
  6635. if (basis_file_has_alpha_slices)
  6636. {
  6637. // First decode the alpha data to the output (we're using the output texture as a temp buffer here).
  6638. status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t*)pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cIndices, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6639. if (!status)
  6640. {
  6641. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to failed\n");
  6642. }
  6643. else
  6644. {
  6645. // Now decode the color data and transcode to ASTC. The transcoder function will read the alpha selector data from the output texture as it converts and
  6646. // transcode both the alpha and color data at the same time to ASTC.
  6647. status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cASTC_4x4, 16, decode_flags | cDecodeFlagsOutputHasAlphaIndices, output_row_pitch_in_blocks_or_pixels, pState);
  6648. }
  6649. }
  6650. else
  6651. status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cASTC_4x4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6652. break;
  6653. }
  6654. case cTFATC_RGB:
  6655. {
  6656. #if !BASISD_SUPPORT_ATC
  6657. return false;
  6658. #endif
  6659. uint32_t slice_index_to_decode = slice_index;
  6660. // If the caller wants us to transcode the mip level's alpha data, then use the next slice.
  6661. if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats))
  6662. slice_index_to_decode++;
  6663. status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cATC_RGB, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6664. if (!status)
  6665. {
  6666. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ATC_RGB failed\n");
  6667. }
  6668. break;
  6669. }
  6670. case cTFATC_RGBA_INTERPOLATED_ALPHA:
  6671. {
  6672. #if !BASISD_SUPPORT_ATC
  6673. return false;
  6674. #endif
  6675. #if !BASISD_SUPPORT_DXT5A
  6676. return false;
  6677. #endif
  6678. // First decode the alpha data
  6679. if (basis_file_has_alpha_slices)
  6680. {
  6681. status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6682. }
  6683. else
  6684. {
  6685. write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cBC4, 16, output_row_pitch_in_blocks_or_pixels);
  6686. status = true;
  6687. }
  6688. if (status)
  6689. {
  6690. status = transcode_slice(pData, data_size, slice_index, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, cATC_RGB, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState);
  6691. if (!status)
  6692. {
  6693. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ATC RGB failed\n");
  6694. }
  6695. }
  6696. else
  6697. {
  6698. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ATC A failed\n");
  6699. }
  6700. break;
  6701. }
  6702. case cTFRGBA32:
  6703. {
  6704. // Raw 32bpp pixels, decoded in the usual raster order (NOT block order) into an image in memory.
  6705. // First decode the alpha data
  6706. if (basis_file_has_alpha_slices)
  6707. status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cA32, sizeof(uint32_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels);
  6708. else
  6709. status = true;
  6710. if (status)
  6711. {
  6712. status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, basis_file_has_alpha_slices ? cRGB32 : cRGBA32, sizeof(uint32_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels);
  6713. if (!status)
  6714. {
  6715. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to RGBA32 RGB failed\n");
  6716. }
  6717. }
  6718. else
  6719. {
  6720. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to RGBA32 A failed\n");
  6721. }
  6722. break;
  6723. }
  6724. case cTFRGB565:
  6725. case cTFBGR565:
  6726. {
  6727. // Raw 16bpp pixels, decoded in the usual raster order (NOT block order) into an image in memory.
  6728. uint32_t slice_index_to_decode = slice_index;
  6729. // If the caller wants us to transcode the mip level's alpha data, then use the next slice.
  6730. if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats))
  6731. slice_index_to_decode++;
  6732. status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, (fmt == cTFRGB565) ? cRGB565 : cBGR565, sizeof(uint16_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels);
  6733. if (!status)
  6734. {
  6735. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to RGB565 RGB failed\n");
  6736. }
  6737. break;
  6738. }
  6739. case cTFRGBA4444:
  6740. {
  6741. // Raw 16bpp pixels, decoded in the usual raster order (NOT block order) into an image in memory.
  6742. // First decode the alpha data
  6743. if (basis_file_has_alpha_slices)
  6744. status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, cRGBA4444_ALPHA, sizeof(uint16_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels);
  6745. else
  6746. status = true;
  6747. if (status)
  6748. {
  6749. status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, basis_file_has_alpha_slices ? cRGBA4444_COLOR : cRGBA4444_COLOR_OPAQUE, sizeof(uint16_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels);
  6750. if (!status)
  6751. {
  6752. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to RGBA4444 RGB failed\n");
  6753. }
  6754. }
  6755. else
  6756. {
  6757. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to RGBA4444 A failed\n");
  6758. }
  6759. break;
  6760. }
  6761. default:
  6762. {
  6763. assert(0);
  6764. BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: Invalid fmt\n");
  6765. break;
  6766. }
  6767. }
  6768. return status;
  6769. }
  6770. uint32_t basis_get_bytes_per_block(transcoder_texture_format fmt)
  6771. {
  6772. switch (fmt)
  6773. {
  6774. case cTFETC1:
  6775. case cTFBC1:
  6776. case cTFBC4:
  6777. case cTFPVRTC1_4_RGB:
  6778. case cTFPVRTC1_4_RGBA:
  6779. case cTFATC_RGB:
  6780. return 8;
  6781. case cTFBC7_M6_OPAQUE_ONLY:
  6782. case cTFBC7_M5:
  6783. case cTFETC2:
  6784. case cTFBC3:
  6785. case cTFBC5:
  6786. case cTFASTC_4x4:
  6787. case cTFATC_RGBA_INTERPOLATED_ALPHA:
  6788. return 16;
  6789. case cTFRGBA32:
  6790. return sizeof(uint32_t) * 16;
  6791. case cTFRGB565:
  6792. case cTFBGR565:
  6793. case cTFRGBA4444:
  6794. return sizeof(uint16_t) * 16;
  6795. default:
  6796. assert(0);
  6797. BASISU_DEVEL_ERROR("basis_get_basisu_texture_format: Invalid fmt\n");
  6798. break;
  6799. }
  6800. return 0;
  6801. }
  6802. const char* basis_get_format_name(transcoder_texture_format fmt)
  6803. {
  6804. switch (fmt)
  6805. {
  6806. case cTFETC1: return "ETC1";
  6807. case cTFBC1: return "BC1";
  6808. case cTFBC4: return "BC4";
  6809. case cTFPVRTC1_4_RGB: return "PVRTC1_4_RGB";
  6810. case cTFPVRTC1_4_RGBA: return "PVRTC1_4_RGBA";
  6811. case cTFBC7_M6_OPAQUE_ONLY: return "BC7_M6_OPAQUE_ONLY";
  6812. case cTFBC7_M5: return "BC7_M5";
  6813. case cTFETC2: return "ETC2";
  6814. case cTFBC3: return "BC3";
  6815. case cTFBC5: return "BC5";
  6816. case cTFASTC_4x4: return "ASTC";
  6817. case cTFATC_RGB: return "ATC_RGB";
  6818. case cTFATC_RGBA_INTERPOLATED_ALPHA: return "ATC_RGBA_INTERPOLATED_ALPHA";
  6819. case cTFRGBA32: return "RGBA32";
  6820. case cTFRGB565: return "RGB565";
  6821. case cTFBGR565: return "BGR565";
  6822. case cTFRGBA4444: return "RGBA4444";
  6823. default:
  6824. assert(0);
  6825. BASISU_DEVEL_ERROR("basis_get_basisu_texture_format: Invalid fmt\n");
  6826. break;
  6827. }
  6828. return "";
  6829. }
  6830. const char* basis_get_texture_type_name(basis_texture_type tex_type)
  6831. {
  6832. switch (tex_type)
  6833. {
  6834. case cBASISTexType2D: return "2D";
  6835. case cBASISTexType2DArray: return "2D array";
  6836. case cBASISTexTypeCubemapArray: return "cubemap array";
  6837. case cBASISTexTypeVideoFrames: return "video";
  6838. case cBASISTexTypeVolume: return "3D";
  6839. default:
  6840. assert(0);
  6841. BASISU_DEVEL_ERROR("basis_get_texture_type_name: Invalid tex_type\n");
  6842. break;
  6843. }
  6844. return "";
  6845. }
  6846. bool basis_transcoder_format_has_alpha(transcoder_texture_format fmt)
  6847. {
  6848. switch (fmt)
  6849. {
  6850. case cTFETC2:
  6851. case cTFBC3:
  6852. case cTFASTC_4x4:
  6853. case cTFBC7_M5:
  6854. case cTFPVRTC1_4_RGBA:
  6855. case cTFATC_RGBA_INTERPOLATED_ALPHA:
  6856. case cTFRGBA32:
  6857. case cTFRGBA4444:
  6858. return true;
  6859. default:
  6860. break;
  6861. }
  6862. return false;
  6863. }
  6864. basisu::texture_format basis_get_basisu_texture_format(transcoder_texture_format fmt)
  6865. {
  6866. switch (fmt)
  6867. {
  6868. case cTFETC1: return basisu::cETC1;
  6869. case cTFBC1: return basisu::cBC1;
  6870. case cTFBC4: return basisu::cBC4;
  6871. case cTFPVRTC1_4_RGB: return basisu::cPVRTC1_4_RGB;
  6872. case cTFPVRTC1_4_RGBA: return basisu::cPVRTC1_4_RGBA;
  6873. case cTFBC7_M6_OPAQUE_ONLY: return basisu::cBC7;
  6874. case cTFBC7_M5: return basisu::cBC7;
  6875. case cTFETC2: return basisu::cETC2_RGBA;
  6876. case cTFBC3: return basisu::cBC3;
  6877. case cTFBC5: return basisu::cBC5;
  6878. case cTFASTC_4x4: return basisu::cASTC4x4;
  6879. case cTFATC_RGB: return basisu::cATC_RGB;
  6880. case cTFATC_RGBA_INTERPOLATED_ALPHA: return basisu::cATC_RGBA_INTERPOLATED_ALPHA;
  6881. case cTFRGBA32: return basisu::cRGBA32;
  6882. case cTFRGB565: return basisu::cRGB565;
  6883. case cTFBGR565: return basisu::cBGR565;
  6884. case cTFRGBA4444: return basisu::cRGBA4444;
  6885. default:
  6886. assert(0);
  6887. BASISU_DEVEL_ERROR("basis_get_basisu_texture_format: Invalid fmt\n");
  6888. break;
  6889. }
  6890. return basisu::cInvalidTextureFormat;
  6891. }
  6892. bool basis_transcoder_format_is_uncompressed(transcoder_texture_format tex_type)
  6893. {
  6894. switch (tex_type)
  6895. {
  6896. case cTFRGBA32:
  6897. case cTFRGB565:
  6898. case cTFBGR565:
  6899. case cTFRGBA4444:
  6900. return true;
  6901. default:
  6902. break;
  6903. }
  6904. return false;
  6905. }
  6906. bool basis_block_format_is_uncompressed(block_format tex_type)
  6907. {
  6908. switch (tex_type)
  6909. {
  6910. case cRGB32:
  6911. case cRGBA32:
  6912. case cA32:
  6913. case cRGB565:
  6914. case cBGR565:
  6915. case cRGBA4444_COLOR:
  6916. case cRGBA4444_ALPHA:
  6917. case cRGBA4444_COLOR_OPAQUE:
  6918. return true;
  6919. default:
  6920. break;
  6921. }
  6922. return false;
  6923. }
  6924. uint32_t basis_get_uncompressed_bytes_per_pixel(transcoder_texture_format fmt)
  6925. {
  6926. switch (fmt)
  6927. {
  6928. case cTFRGBA32:
  6929. return sizeof(uint32_t);
  6930. case cTFRGB565:
  6931. case cTFBGR565:
  6932. case cTFRGBA4444:
  6933. return sizeof(uint16_t);
  6934. default:
  6935. break;
  6936. }
  6937. return 0;
  6938. }
  6939. } // namespace basist