etcpack.cxx 604 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089
  1. // ESENTHEL CHANGED: char -> signed char
  2. //// etcpack v2.74
  3. ////
  4. //// NO WARRANTY
  5. ////
  6. //// BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE THE PROGRAM IS PROVIDED
  7. //// "AS IS". ERICSSON MAKES NO REPRESENTATIONS OF ANY KIND, EXTENDS NO
  8. //// WARRANTIES OR CONDITIONS OF ANY KIND; EITHER EXPRESS, IMPLIED OR
  9. //// STATUTORY; INCLUDING, BUT NOT LIMITED TO, EXPRESS, IMPLIED OR
  10. //// STATUTORY WARRANTIES OR CONDITIONS OF TITLE, MERCHANTABILITY,
  11. //// SATISFACTORY QUALITY, SUITABILITY AND FITNESS FOR A PARTICULAR
  12. //// PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
  13. //// PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
  14. //// THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. ERICSSON
  15. //// MAKES NO WARRANTY THAT THE MANUFACTURE, SALE, OFFERING FOR SALE,
  16. //// DISTRIBUTION, LEASE, USE OR IMPORTATION UNDER THE LICENSE WILL BE FREE
  17. //// FROM INFRINGEMENT OF PATENTS, COPYRIGHTS OR OTHER INTELLECTUAL
  18. //// PROPERTY RIGHTS OF OTHERS, AND THE VALIDITY OF THE LICENSE IS SUBJECT
  19. //// TO YOUR SOLE RESPONSIBILITY TO MAKE SUCH DETERMINATION AND ACQUIRE
  20. //// SUCH LICENSES AS MAY BE NECESSARY WITH RESPECT TO PATENTS, COPYRIGHT
  21. //// AND OTHER INTELLECTUAL PROPERTY OF THIRD PARTIES.
  22. ////
  23. //// FOR THE AVOIDANCE OF DOUBT THE PROGRAM (I) IS NOT LICENSED FOR; (II)
  24. //// IS NOT DESIGNED FOR OR INTENDED FOR; AND (III) MAY NOT BE USED FOR;
  25. //// ANY MISSION CRITICAL APPLICATIONS SUCH AS, BUT NOT LIMITED TO
  26. //// OPERATION OF NUCLEAR OR HEALTHCARE COMPUTER SYSTEMS AND/OR NETWORKS,
  27. //// AIRCRAFT OR TRAIN CONTROL AND/OR COMMUNICATION SYSTEMS OR ANY OTHER
  28. //// COMPUTER SYSTEMS AND/OR NETWORKS OR CONTROL AND/OR COMMUNICATION
  29. //// SYSTEMS ALL IN WHICH CASE THE FAILURE OF THE PROGRAM COULD LEAD TO
  30. //// DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL, MATERIAL OR ENVIRONMENTAL
  31. //// DAMAGE. YOUR RIGHTS UNDER THIS LICENSE WILL TERMINATE AUTOMATICALLY
  32. //// AND IMMEDIATELY WITHOUT NOTICE IF YOU FAIL TO COMPLY WITH THIS
  33. //// PARAGRAPH.
  34. ////
  35. //// IN NO EVENT WILL ERICSSON, BE LIABLE FOR ANY DAMAGES WHATSOEVER,
  36. //// INCLUDING BUT NOT LIMITED TO PERSONAL INJURY, ANY GENERAL, SPECIAL,
  37. //// INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN
  38. //// CONNECTION WITH THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
  39. //// NOT LIMITED TO LOSS OF PROFITS, BUSINESS INTERUPTIONS, OR ANY OTHER
  40. //// COMMERCIAL DAMAGES OR LOSSES, LOSS OF DATA OR DATA BEING RENDERED
  41. //// INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
  42. //// THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) REGARDLESS OF THE
  43. //// THEORY OF LIABILITY (CONTRACT, TORT OR OTHERWISE), EVEN IF SUCH HOLDER
  44. //// OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  45. ////
  46. //// (C) Ericsson AB 2005-2013. All Rights Reserved.
  47. ////
  48. /*#include <stdio.h>
  49. #include <stdlib.h>
  50. #include <string.h>
  51. #include <math.h>
  52. #include <time.h>
  53. #include <sys/timeb.h>*/
  54. // Typedefs
  55. typedef unsigned char uint8;
  56. typedef unsigned short uint16;
  57. typedef short int16;
  58. // Functions needed for decrompession ---- in etcdec.cxx
  59. void read_big_endian_2byte_word(unsigned short *blockadr, FILE *f);
  60. void read_big_endian_4byte_word(unsigned int *blockadr, FILE *f);
  61. void unstuff57bits(unsigned int planar_word1, unsigned int planar_word2, unsigned int &planar57_word1, unsigned int &planar57_word2);
  62. void unstuff59bits(unsigned int thumbT_word1, unsigned int thumbT_word2, unsigned int &thumbT59_word1, unsigned int &thumbT59_word2);
  63. void unstuff58bits(unsigned int thumbH_word1, unsigned int thumbH_word2, unsigned int &thumbH58_word1, unsigned int &thumbH58_word2);
  64. void decompressColor(int R_B, int G_B, int B_B, uint8 (colors_RGB444)[2][3], uint8 (colors)[2][3]);
  65. void calculatePaintColors59T(uint8 d, uint8 p, uint8 (colors)[2][3], uint8 (possible_colors)[4][3]);
  66. void calculatePaintColors58H(uint8 d, uint8 p, uint8 (colors)[2][3], uint8 (possible_colors)[4][3]);
  67. void decompressBlockTHUMB59T(unsigned int block_part1, unsigned int block_part2, uint8 *img,int width,int height,int startx,int starty);
  68. void decompressBlockTHUMB58H(unsigned int block_part1, unsigned int block_part2, uint8 *img,int width,int height,int startx,int starty);
  69. void decompressBlockPlanar57(unsigned int compressed57_1, unsigned int compressed57_2, uint8 *img,int width,int height,int startx,int starty);
  70. void decompressBlockDiffFlip(unsigned int block_part1, unsigned int block_part2, uint8 *img,int width,int height,int startx,int starty);
  71. void decompressBlockETC2(unsigned int block_part1, unsigned int block_part2, uint8 *img,int width,int height,int startx,int starty);
  72. void decompressBlockDifferentialWithAlpha(unsigned int block_part1,unsigned int block_part2, uint8* img, uint8* alpha, int width, int height, int startx, int starty);
  73. void decompressBlockETC21BitAlpha(unsigned int block_part1, unsigned int block_part2, uint8 *img, uint8* alphaimg, int width,int height,int startx,int starty);
  74. void decompressBlockTHUMB58HAlpha(unsigned int block_part1, unsigned int block_part2, uint8 *img, uint8* alpha,int width,int height,int startx,int starty);
  75. void decompressBlockTHUMB59TAlpha(unsigned int block_part1, unsigned int block_part2, uint8 *img, uint8* alpha,int width,int height,int startx,int starty);
  76. uint8 getbit(uint8 input, int frompos, int topos);
  77. int clamp(int val);
  78. void decompressBlockAlpha(uint8* data,uint8* img,int width,int height,int ix,int iy);
  79. uint16 get16bits11bits(int base, int table, int mul, int index);
  80. void decompressBlockAlpha16bit(uint8* data,uint8* img,int width,int height,int ix,int iy);
  81. int16 get16bits11signed(int base, int table, int mul, int index);
  82. void setupAlphaTable();
  83. // This source code is quite long. You can make it shorter by not including the
  84. // code doing the exhaustive code. Then the -slow modes will not work, but the
  85. // code will be approximately half the number of lines of code.
  86. // Then the lines between "exhaustive code starts here" and "exhaustive code ends here"
  87. // can then be removed.
  88. #ifndef EXHAUSTIVE_CODE_ACTIVE // ESENTHEL CHANGED
  89. #define EXHAUSTIVE_CODE_ACTIVE 1
  90. #endif
  91. // Remove warnings for unsafe functions such as strcpy
  92. #pragma warning(disable : 4996)
  93. // Remove warnings for conversions between different time variables
  94. #pragma warning(disable : 4244)
  95. // Remove warnings for negative or too big shifts
  96. //#pragma warning(disable : 4293)
  97. #define CLAMP(ll,x,ul) (((x)<(ll)) ? (ll) : (((x)>(ul)) ? (ul) : (x)))
  98. // The below code works as CLAMP(0, x, 255) if x < 255
  99. #define CLAMP_LEFT_ZERO(x) ((~(((int)(x))>>31))&(x))
  100. // The below code works as CLAMP(0, x, 255) if x is in [0,511]
  101. #define CLAMP_RIGHT_255(x) (((( ((((int)(x))<<23)>>31) ))|(x))&0x000000ff)
  102. #define SQUARE(x) ((x)*(x))
  103. #define JAS_ROUND(x) (((x) < 0.0 ) ? ((int)((x)-0.5)) : ((int)((x)+0.5)))
  104. #define JAS_MIN(a,b) ((a) < (b) ? (a) : (b))
  105. #define JAS_MAX(a,b) ((a) > (b) ? (a) : (b))
  106. // The error metric Wr Wg Wb should be definied so that Wr^2 + Wg^2 + Wb^2 = 1.
  107. // Hence it is easier to first define the squared values and derive the weights
  108. // as their square-roots.
  109. #define PERCEPTUAL_WEIGHT_R_SQUARED 0.299
  110. #define PERCEPTUAL_WEIGHT_G_SQUARED 0.587
  111. #define PERCEPTUAL_WEIGHT_B_SQUARED 0.114
  112. #define PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000 299
  113. #define PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000 587
  114. #define PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000 114
  115. #define RED(img,width,x,y) img[3*(y*width+x)+0]
  116. #define GREEN(img,width,x,y) img[3*(y*width+x)+1]
  117. #define BLUE(img,width,x,y) img[3*(y*width+x)+2]
  118. #define SHIFT(size,startpos) ((startpos)-(size)+1)
  119. #define MASK(size, startpos) (((2u<<(size-1u))-1u) << SHIFT(size,startpos)) // ESENTHEL CHANGED: converted to unsigned constants to silent compiler warnings on Android
  120. #define PUTBITS( dest, data, size, startpos) dest = ((dest & ~MASK(size, startpos)) | ((data << SHIFT(size, startpos)) & MASK(size,startpos)))
  121. #define SHIFTHIGH(size, startpos) (((startpos)-32)-(size)+1)
  122. #define MASKHIGH(size, startpos) (((1<<(size))-1) << SHIFTHIGH(size,startpos))
  123. #define PUTBITSHIGH(dest, data, size, startpos) dest = ((dest & ~MASKHIGH(size, startpos)) | ((data << SHIFTHIGH(size, startpos)) & MASKHIGH(size,startpos)))
  124. #define GETBITS(source, size, startpos) (( (source) >> ((startpos)-(size)+1) ) & ((1<<(size)) -1))
  125. #define GETBITSHIGH(source, size, startpos) (( (source) >> (((startpos)-32)-(size)+1) ) & ((1<<(size)) -1))
  126. // Thumb macros and definitions
  127. #define R_BITS59T 4
  128. #define G_BITS59T 4
  129. #define B_BITS59T 4
  130. #define R_BITS58H 4
  131. #define G_BITS58H 4
  132. #define B_BITS58H 4
  133. #define MAXIMUM_ERROR (255*255*16*1000)
  134. #define R 0
  135. #define G 1
  136. #define B 2
  137. #define BLOCKHEIGHT 4
  138. #define BLOCKWIDTH 4
  139. #define BINPOW(power) (1<<(power))
  140. //#define RADIUS 2
  141. #define TABLE_BITS_59T 3
  142. #define TABLE_BITS_58H 3
  143. // Global tables
  144. //static const uint8 table59T[8] = {3,6,11,16,23,32,41,64}; // 3-bit table for the 59 bit T-mode
  145. //static const uint8 table58H[8] = {3,6,11,16,23,32,41,64}; // 3-bit table for the 58 bit H-mode
  146. static const uint8 weight[3] = {1,1,1}; // Color weight
  147. // Enums
  148. /*enum{PATTERN_H = 0,
  149. PATTERN_T = 1};*/
  150. enum{MODE_ETC1, MODE_THUMB_T, MODE_THUMB_H, MODE_PLANAR};
  151. // The ETC2 package of codecs includes the following codecs:
  152. //
  153. // codec enum
  154. // --------------------------------------------------------
  155. // GL_COMPRESSED_R11_EAC 0x9270
  156. // GL_COMPRESSED_SIGNED_R11_EAC 0x9271
  157. // GL_COMPRESSED_RG11_EAC 0x9272
  158. // GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
  159. // GL_COMPRESSED_RGB8_ETC2 0x9274
  160. // GL_COMPRESSED_SRGB8_ETC2 0x9275
  161. // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
  162. // GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
  163. // GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
  164. // GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
  165. //
  166. // The older codec ETC1 is not included in the package
  167. // GL_ETC1_RGB8_OES 0x8d64
  168. // but since ETC2 is backwards compatible an ETC1 texture can
  169. // be decoded using the RGB8_ETC2 enum (0x9274)
  170. //
  171. // In a PKM-file, the codecs are stored using the following identifiers
  172. //
  173. // identifier value codec
  174. // --------------------------------------------------------------------
  175. // ETC1_RGB_NO_MIPMAPS 0 GL_ETC1_RGB8_OES
  176. // ETC2PACKAGE_RGB_NO_MIPMAPS 1 GL_COMPRESSED_RGB8_ETC2
  177. // ETC2PACKAGE_RGBA_NO_MIPMAPS_OLD 2, not used -
  178. // ETC2PACKAGE_RGBA_NO_MIPMAPS 3 GL_COMPRESSED_RGBA8_ETC2_EAC
  179. // ETC2PACKAGE_RGBA1_NO_MIPMAPS 4 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
  180. // ETC2PACKAGE_R_NO_MIPMAPS 5 GL_COMPRESSED_R11_EAC
  181. // ETC2PACKAGE_RG_NO_MIPMAPS 6 GL_COMPRESSED_RG11_EAC
  182. // ETC2PACKAGE_R_SIGNED_NO_MIPMAPS 7 GL_COMPRESSED_SIGNED_R11_EAC
  183. // ETC2PACKAGE_RG_SIGNED_NO_MIPMAPS 8 GL_COMPRESSED_SIGNED_RG11_EAC
  184. //
  185. // In the code, the identifiers are not always used strictly. For instance, the
  186. // identifier ETC2PACKAGE_R_NO_MIPMAPS is sometimes used for both the unsigned
  187. // (GL_COMPRESSED_R11_EAC) and signed (GL_COMPRESSED_SIGNED_R11_EAC) version of
  188. // the codec.
  189. //
  190. enum{ETC1_RGB_NO_MIPMAPS,ETC2PACKAGE_RGB_NO_MIPMAPS,ETC2PACKAGE_RGBA_NO_MIPMAPS_OLD,ETC2PACKAGE_RGBA_NO_MIPMAPS,ETC2PACKAGE_RGBA1_NO_MIPMAPS,ETC2PACKAGE_R_NO_MIPMAPS,ETC2PACKAGE_RG_NO_MIPMAPS,ETC2PACKAGE_R_SIGNED_NO_MIPMAPS,ETC2PACKAGE_RG_SIGNED_NO_MIPMAPS,ETC2PACKAGE_sRGB_NO_MIPMAPS,ETC2PACKAGE_sRGBA_NO_MIPMAPS,ETC2PACKAGE_sRGBA1_NO_MIPMAPS};
  191. enum {MODE_COMPRESS, MODE_UNCOMPRESS, MODE_PSNR};
  192. enum {SPEED_SLOW, SPEED_FAST, SPEED_MEDIUM};
  193. enum {METRIC_PERCEPTUAL, METRIC_NONPERCEPTUAL};
  194. enum {CODEC_ETC, CODEC_ETC2};
  195. /*int mode = MODE_COMPRESS;
  196. int speed = SPEED_FAST;
  197. int metric = METRIC_PERCEPTUAL;
  198. int codec = CODEC_ETC2;
  199. int format = ETC2PACKAGE_RGB_NO_MIPMAPS;
  200. int verbose = true;
  201. extern int formatSigned;
  202. int ktxFile=0;
  203. bool first_time_message = true;*/
  204. static const int scramble[4] = {3, 2, 0, 1};
  205. //static const int unscramble[4] = {2, 3, 1, 0};
  206. /*typedef struct KTX_header_t
  207. {
  208. uint8 identifier[12];
  209. unsigned int endianness;
  210. unsigned int glType;
  211. unsigned int glTypeSize;
  212. unsigned int glFormat;
  213. unsigned int glInternalFormat;
  214. unsigned int glBaseInternalFormat;
  215. unsigned int pixelWidth;
  216. unsigned int pixelHeight;
  217. unsigned int pixelDepth;
  218. unsigned int numberOfArrayElements;
  219. unsigned int numberOfFaces;
  220. unsigned int numberOfMipmapLevels;
  221. unsigned int bytesOfKeyValueData;
  222. }
  223. KTX_header;
  224. #define KTX_IDENTIFIER_REF { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A }
  225. #define KTX_ENDIAN_REF (0x04030201)
  226. #define KTX_ENDIAN_REF_REV (0x01020304)
  227. enum {GL_R=0x1903,GL_RG=0x8227,GL_RGB=0x1907,GL_RGBA=0x1908};
  228. #define GL_SRGB 0x8C40
  229. #define GL_SRGB8 0x8C41
  230. #define GL_SRGB8_ALPHA8 0x8C43
  231. #define GL_ETC1_RGB8_OES 0x8d64
  232. #define GL_COMPRESSED_R11_EAC 0x9270
  233. #define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
  234. #define GL_COMPRESSED_RG11_EAC 0x9272
  235. #define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
  236. #define GL_COMPRESSED_RGB8_ETC2 0x9274
  237. #define GL_COMPRESSED_SRGB8_ETC2 0x9275
  238. #define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
  239. #define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
  240. #define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
  241. #define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
  242. int ktx_identifier[] = KTX_IDENTIFIER_REF;*/
  243. //converts indices from |a0|a1|e0|e1|i0|i1|m0|m1|b0|b1|f0|f1|j0|j1|n0|n1|c0|c1|g0|g1|k0|k1|o0|o1|d0|d1|h0|h1|l0|l1|p0|p1| previously used by T- and H-modes
  244. // into |p0|o0|n0|m0|l0|k0|j0|i0|h0|g0|f0|e0|d0|c0|b0|a0|p1|o1|n1|m1|l1|k1|j1|i1|h1|g1|f1|e1|d1|c1|b1|a1| which should be used for all modes.
  245. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  246. int indexConversion(int pixelIndices)
  247. {
  248. int correctIndices = 0;
  249. int LSB[4][4];
  250. int MSB[4][4];
  251. int shift=0;
  252. for(int y=3; y>=0; y--)
  253. {
  254. for(int x=3; x>=0; x--)
  255. {
  256. LSB[x][y] = (pixelIndices>>shift)&1;
  257. shift++;
  258. MSB[x][y] = (pixelIndices>>shift)&1;
  259. shift++;
  260. }
  261. }
  262. shift=0;
  263. for(int x=0; x<4; x++)
  264. {
  265. for(int y=0; y<4; y++)
  266. {
  267. correctIndices|=(LSB[x][y]<<shift);
  268. correctIndices|=(MSB[x][y]<<(16+shift));
  269. shift++;
  270. }
  271. }
  272. return correctIndices;
  273. }
  274. // Tests if a file exists.
  275. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  276. /*bool fileExist(char *filename)
  277. {
  278. FILE *f=NULL;
  279. if((f=fopen(filename,"rb"))!=NULL)
  280. {
  281. fclose(f);
  282. return true;
  283. }
  284. return false;
  285. }
  286. // Expand source image so that it is divisible by a factor of four in the x-dimension.
  287. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  288. bool expandToWidthDivByFour(uint8 *&img, int width, int height, int &expandedwidth, int &expandedheight, int bitrate)
  289. {
  290. int wdiv4;
  291. int xx, yy;
  292. uint8 *newimg;
  293. wdiv4 = width /4;
  294. if( !(wdiv4 *4 == width) )
  295. {
  296. expandedwidth = (wdiv4 + 1)*4;
  297. expandedheight = height;
  298. newimg=(uint8*) malloc(3*expandedwidth*expandedheight*bitrate/8);
  299. if(!newimg)
  300. {
  301. printf("Could not allocate memory to expand width\n");
  302. return false;
  303. }
  304. // First copy image
  305. for(yy = 0; yy<height; yy++)
  306. {
  307. for(xx = 0; xx < width; xx++)
  308. {
  309. //we have 3*bitrate/8 bytes for each pixel..
  310. for(int i=0; i<3*bitrate/8; i++)
  311. {
  312. newimg[(yy * expandedwidth+ xx)*3*bitrate/8 + i] = img[(yy * width+xx)*3*bitrate/8 + i];
  313. }
  314. }
  315. }
  316. // Then make the last column of pixels the same as the previous column.
  317. for(yy = 0; yy< height; yy++)
  318. {
  319. for(xx = width; xx < expandedwidth; xx++)
  320. {
  321. for(int i=0; i<3*bitrate/8; i++)
  322. {
  323. newimg[(yy * expandedwidth+xx)*3*bitrate/8 + i] = img[(yy * width+(width-1))*3*bitrate/8 + i];
  324. }
  325. }
  326. }
  327. // Now free the old image
  328. free(img);
  329. // Use the new image
  330. img = newimg;
  331. return true;
  332. }
  333. else
  334. {
  335. printf("Image already of even width\n");
  336. expandedwidth = width;
  337. expandedheight = height;
  338. return false;
  339. }
  340. }
  341. // Expand source image so that it is divisible by a factor of four in the y-dimension.
  342. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  343. bool expandToHeightDivByFour(uint8 *&img, int width, int height, int &expandedwidth, int &expandedheight, int bitrate)
  344. {
  345. int hdiv4;
  346. int xx, yy;
  347. int numlinesmissing;
  348. uint8 *newimg;
  349. hdiv4 = height/4;
  350. if( !(hdiv4 * 4 == height) )
  351. {
  352. expandedwidth = width;
  353. expandedheight = (hdiv4 + 1) * 4;
  354. numlinesmissing = expandedheight - height;
  355. newimg=(uint8*)malloc(3*expandedwidth*expandedheight*bitrate/8);
  356. if(!newimg)
  357. {
  358. printf("Could not allocate memory to expand height\n");
  359. return false;
  360. }
  361. // First copy image. No need to reformat data.
  362. for(xx = 0; xx<3*width*height*bitrate/8; xx++)
  363. newimg[xx] = img[xx];
  364. // Then copy up to three lines.
  365. for(yy = height; yy < height + numlinesmissing; yy++)
  366. {
  367. for(xx = 0; xx<width; xx++)
  368. {
  369. for(int i=0; i<3*bitrate/8; i++)
  370. {
  371. newimg[(yy*width+xx)*3*bitrate/8 + i] = img[((height-1)*width+xx)*3*bitrate/8 + i];
  372. }
  373. }
  374. }
  375. // Now free the old image;
  376. free(img);
  377. // Use the new image:
  378. img = newimg;
  379. return true;
  380. }
  381. else
  382. {
  383. printf("Image height already divisible by four.\n");
  384. expandedwidth = width;
  385. expandedheight = height;
  386. return true;
  387. }
  388. }
  389. // Find the position of a file extension such as .ppm or .pkm
  390. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  391. int find_pos_of_extension(char *src)
  392. {
  393. int q=strlen(src);
  394. while(q>=0) // find file name extension
  395. {
  396. if(src[q]=='.') break;
  397. q--;
  398. }
  399. if(q<0)
  400. return -1;
  401. else
  402. return q;
  403. }
  404. // Read source file. Does conversion if file format is not .ppm.
  405. // Will expand file to be divisible by four in the x- and y- dimension.
  406. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  407. /*bool readSrcFile(char *filename,uint8 *&img,int &width,int &height, int &expandedwidth, int &expandedheight)
  408. {
  409. int w1,h1;
  410. int wdiv4, hdiv4;
  411. char str[255];
  412. // Delete temp file if it exists.
  413. if(fileExist("tmp.ppm"))
  414. {
  415. sprintf(str, "del tmp.ppm\n");
  416. system(str);
  417. }
  418. int q = find_pos_of_extension(filename);
  419. if(!strcmp(&filename[q],".ppm"))
  420. {
  421. // Already a .ppm file. Just copy.
  422. sprintf(str,"copy %s tmp.ppm \n", filename);
  423. printf("Copying source file to tmp.ppm\n", filename);
  424. }
  425. else
  426. {
  427. // Converting from other format to .ppm
  428. //
  429. // Use your favorite command line image converter program,
  430. // for instance Image Magick. Just make sure the syntax can
  431. // be written as below:
  432. //
  433. // C:\imconv source.jpg dest.ppm
  434. //
  435. sprintf(str,"imconv %s tmp.ppm\n", filename);
  436. printf("Converting source file from %s to .ppm\n", filename);
  437. }
  438. // Execute system call
  439. system(str);
  440. int bitrate=8;
  441. if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
  442. bitrate=16;
  443. if(fReadPPM("tmp.ppm",w1,h1,img,bitrate))
  444. {
  445. width=w1;
  446. height=h1;
  447. system("del tmp.ppm");
  448. // Width must be divisible by 4 and height must be
  449. // divisible by 4. Otherwise, we will expand the image
  450. wdiv4 = width / 4;
  451. hdiv4 = height / 4;
  452. expandedwidth = width;
  453. expandedheight = height;
  454. if( !(wdiv4 * 4 == width) )
  455. {
  456. printf(" Width = %d is not divisible by four... ", width);
  457. printf(" expanding image in x-dir... ");
  458. if(expandToWidthDivByFour(img, width, height, expandedwidth, expandedheight,bitrate))
  459. {
  460. printf("OK.\n");
  461. }
  462. else
  463. {
  464. printf("\n Error: could not expand image\n");
  465. return false;
  466. }
  467. }
  468. if( !(hdiv4 * 4 == height))
  469. {
  470. printf(" Height = %d is not divisible by four... ", height);
  471. printf(" expanding image in y-dir...");
  472. if(expandToHeightDivByFour(img, expandedwidth, height, expandedwidth, expandedheight,bitrate))
  473. {
  474. printf("OK.\n");
  475. }
  476. else
  477. {
  478. printf("\n Error: could not expand image\n");
  479. return false;
  480. }
  481. }
  482. if(!(expandedwidth == width && expandedheight == height))
  483. printf("Active pixels: %dx%d. Expanded image: %dx%d\n",width,height,expandedwidth,expandedheight);
  484. return true;
  485. }
  486. else
  487. {
  488. printf("Could not read tmp.ppm file\n");
  489. exit(1);
  490. }
  491. return false;
  492. }
  493. // Reads a file without expanding it to be divisible by 4.
  494. // Is used when doing PSNR calculation between two files.
  495. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  496. bool readSrcFileNoExpand(char *filename,uint8 *&img,int &width,int &height)
  497. {
  498. int w1,h1;
  499. char str[255];
  500. // Delete temp file if it exists.
  501. if(fileExist("tmp.ppm"))
  502. {
  503. sprintf(str, "del tmp.ppm\n");
  504. system(str);
  505. }
  506. int q = find_pos_of_extension(filename);
  507. if(!strcmp(&filename[q],".ppm"))
  508. {
  509. // Already a .ppm file. Just copy.
  510. sprintf(str,"copy %s tmp.ppm \n", filename);
  511. printf("Copying source file to tmp.ppm\n", filename);
  512. }
  513. else
  514. {
  515. // Converting from other format to .ppm
  516. //
  517. // Use your favorite command line image converter program,
  518. // for instance Image Magick. Just make sure the syntax can
  519. // be written as below:
  520. //
  521. // C:\imconv source.jpg dest.ppm
  522. //
  523. sprintf(str,"imconv %s tmp.ppm\n", filename);
  524. // printf("Converting source file from %s to .ppm\n", filename);
  525. }
  526. // Execute system call
  527. system(str);
  528. if(fReadPPM("tmp.ppm",w1,h1,img,8))
  529. {
  530. width=w1;
  531. height=h1;
  532. system("del tmp.ppm");
  533. return true;
  534. }
  535. return false;
  536. }
  537. // Parses the arguments from the command line.
  538. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  539. void readArguments(int argc,char *argv[],char* src,char *dst)
  540. {
  541. int q;
  542. //new code!! do this in a more nicer way!
  543. bool srcfound=false,dstfound=false;
  544. for(int i=1; i<argc; i++)
  545. {
  546. //loop through the arguments!
  547. //first check for flags..
  548. if(argv[i][0]=='-')
  549. {
  550. if(i==argc-1)
  551. {
  552. printf("flag missing argument: %s!\n");
  553. exit(1);
  554. }
  555. //handle speed flag
  556. if(!strcmp(argv[i],"-s"))
  557. {
  558. // We have argument -s. Now check for slow, medium or fast.
  559. if(!strcmp(argv[i+1],"slow"))
  560. speed = SPEED_SLOW;
  561. else if(!strcmp(argv[i+1],"medium"))
  562. speed = SPEED_MEDIUM;
  563. else if(!strcmp(argv[i+1],"fast"))
  564. speed = SPEED_FAST;
  565. else
  566. {
  567. printf("Error: %s not part of flag %s\n",argv[i+1], argv[i]);
  568. exit(1);
  569. }
  570. }
  571. //handle verbose flag
  572. else if(!strcmp(argv[i],"-v"))
  573. {
  574. // We have argument -s. Now check for slow, medium or fast.
  575. if(!strcmp(argv[i+1],"off"))
  576. verbose = false;
  577. else if(!strcmp(argv[i+1],"on"))
  578. verbose = true;
  579. else
  580. {
  581. printf("Error: %s not part of flag %s\n",argv[i+1], argv[i]);
  582. exit(1);
  583. }
  584. }
  585. //error metric flag
  586. else if(!strcmp(argv[i],"-e"))
  587. {
  588. // We have argument -e. Now check for perceptual or nonperceptual
  589. if(!strcmp(argv[i+1],"perceptual"))
  590. metric = METRIC_PERCEPTUAL;
  591. else if(!strcmp(argv[i+1],"nonperceptual"))
  592. metric = METRIC_NONPERCEPTUAL;
  593. else
  594. {
  595. printf("Error: %s not part of flag %s\n",argv[i+1], argv[i]);
  596. exit(1);
  597. }
  598. }
  599. //codec flag
  600. else if(!strcmp(argv[i],"-c"))
  601. {
  602. // We have argument -c. Now check for perceptual or nonperceptual
  603. if(!strcmp(argv[i+1],"etc") || !strcmp(argv[i+1],"etc1"))
  604. codec = CODEC_ETC;
  605. else if(!strcmp(argv[i+1],"etc2"))
  606. codec = CODEC_ETC2;
  607. else
  608. {
  609. printf("Error: %s not part of flag %s\n",argv[i+1], argv[i]);
  610. exit(1);
  611. }
  612. }
  613. //format flag
  614. else if(!strcmp(argv[i],"-f"))
  615. {
  616. if(!strcmp(argv[i+1],"R"))
  617. format=ETC2PACKAGE_R_NO_MIPMAPS;
  618. else if(!strcmp(argv[i+1],"RG"))
  619. format=ETC2PACKAGE_RG_NO_MIPMAPS;
  620. else if(!strcmp(argv[i+1],"R_signed"))
  621. {
  622. format=ETC2PACKAGE_R_NO_MIPMAPS;
  623. formatSigned=1;
  624. }
  625. else if(!strcmp(argv[i+1],"RG_signed"))
  626. {
  627. format=ETC2PACKAGE_RG_NO_MIPMAPS;
  628. formatSigned=1;
  629. }
  630. else if(!strcmp(argv[i+1],"RGB"))
  631. format=ETC2PACKAGE_RGB_NO_MIPMAPS;
  632. else if(!strcmp(argv[i+1],"sRGB"))
  633. format=ETC2PACKAGE_sRGB_NO_MIPMAPS;
  634. else if(!strcmp(argv[i+1],"RGBA")||!strcmp(argv[i+1],"RGBA8"))
  635. format=ETC2PACKAGE_RGBA_NO_MIPMAPS;
  636. else if(!strcmp(argv[i+1],"sRGBA")||!strcmp(argv[i+1],"sRGBA8"))
  637. format=ETC2PACKAGE_sRGBA_NO_MIPMAPS;
  638. else if(!strcmp(argv[i+1],"RGBA1"))
  639. format=ETC2PACKAGE_RGBA1_NO_MIPMAPS;
  640. else if(!strcmp(argv[i+1],"sRGBA1"))
  641. format=ETC2PACKAGE_sRGBA1_NO_MIPMAPS;
  642. else
  643. {
  644. printf("Error: %s not part of flag %s\n",argv[i+1], argv[i]);
  645. exit(1);
  646. }
  647. }
  648. else if(!strcmp(argv[i],"-p"))
  649. {
  650. mode=MODE_PSNR;
  651. i--; //ugly way of negating the increment of i done later because -p doesn't have an argument.
  652. }
  653. else
  654. {
  655. printf("Error: cannot interpret flag %s %s\n",argv[i], argv[i+1]);
  656. exit(1);
  657. }
  658. //don't read the flag argument next iteration..
  659. i++;
  660. }
  661. //this isn't a flag, so must be src or dst
  662. else
  663. {
  664. if(srcfound&&dstfound)
  665. {
  666. printf("too many arguments! expecting src, dst; found %s, %s, %s\n",src,dst,argv[i]);
  667. exit(1);
  668. }
  669. else if(srcfound)
  670. {
  671. strcpy(dst,argv[i]);
  672. dstfound=true;
  673. }
  674. else
  675. {
  676. strcpy(src,argv[i]);
  677. srcfound=true;
  678. }
  679. }
  680. }
  681. if(!srcfound&&dstfound)
  682. {
  683. printf("too few arguments! expecting src, dst\n");
  684. exit(1);
  685. }
  686. if(mode==MODE_PSNR)
  687. return;
  688. //check source/destination.. is this compression or decompression?
  689. q = find_pos_of_extension(src);
  690. if(q<0)
  691. {
  692. printf("invalid source file: %s\n",src);
  693. exit(1);
  694. }
  695. // If we have etcpack img.pkm img.any
  696. if(!strncmp(&src[q],".pkm",4))
  697. {
  698. // First argument is .pkm. Decompress.
  699. mode = MODE_UNCOMPRESS; // uncompress from binary file format .pkm
  700. }
  701. else if(!strncmp(&src[q],".ktx",4))
  702. {
  703. // First argument is .ktx. Decompress.
  704. mode = MODE_UNCOMPRESS; // uncompress from binary file format .pkm
  705. ktxFile=true;
  706. printf("decompressing ktx\n");
  707. }
  708. else
  709. {
  710. // The first argument was not .pkm. The second argument must then be .pkm.
  711. q = find_pos_of_extension(dst);
  712. if(q<0)
  713. {
  714. printf("invalid destination file: %s\n",src);
  715. exit(1);
  716. }
  717. if(!strncmp(&dst[q],".pkm",4))
  718. {
  719. // Second argument is .pkm. Compress.
  720. mode = MODE_COMPRESS; // compress to binary file format .pkm
  721. }
  722. else if(!strncmp(&dst[q],".ktx",4))
  723. {
  724. // Second argument is .ktx. Compress.
  725. ktxFile=true;
  726. mode = MODE_COMPRESS; // compress to binary file format .pkm
  727. printf("compressing to ktx\n");
  728. }
  729. else
  730. {
  731. printf("source or destination must be a .pkm or .ktx file\n");
  732. exit(1);
  733. }
  734. }
  735. //do some sanity check stuff..
  736. if(codec==CODEC_ETC&&format!=ETC2PACKAGE_RGB_NO_MIPMAPS)
  737. {
  738. printf("ETC1 codec only supports RGB format\n");
  739. exit(1);
  740. }
  741. else if(codec==CODEC_ETC)
  742. format=ETC1_RGB_NO_MIPMAPS;
  743. }*/
  744. //static int compressParams[16][4];
  745. const int compressParamsFast[32] = { -8, -2, 2, 8,
  746. -17, -5, 5, 17,
  747. -29, -9, 9, 29,
  748. -42, -13, 13, 42,
  749. -60, -18, 18, 60,
  750. -80, -24, 24, 80,
  751. -106, -33, 33, 106,
  752. -183, -47, 47, 183};
  753. /*bool readCompressParams(void)
  754. {
  755. compressParams[0][0] = -8; compressParams[0][1] = -2; compressParams[0][2] = 2; compressParams[0][3] = 8;
  756. compressParams[1][0] = -8; compressParams[1][1] = -2; compressParams[1][2] = 2; compressParams[1][3] = 8;
  757. compressParams[2][0] = -17; compressParams[2][1] = -5; compressParams[2][2] = 5; compressParams[2][3] = 17;
  758. compressParams[3][0] = -17; compressParams[3][1] = -5; compressParams[3][2] = 5; compressParams[3][3] = 17;
  759. compressParams[4][0] = -29; compressParams[4][1] = -9; compressParams[4][2] = 9; compressParams[4][3] = 29;
  760. compressParams[5][0] = -29; compressParams[5][1] = -9; compressParams[5][2] = 9; compressParams[5][3] = 29;
  761. compressParams[6][0] = -42; compressParams[6][1] = -13; compressParams[6][2] = 13; compressParams[6][3] = 42;
  762. compressParams[7][0] = -42; compressParams[7][1] = -13; compressParams[7][2] = 13; compressParams[7][3] = 42;
  763. compressParams[8][0] = -60; compressParams[8][1] = -18; compressParams[8][2] = 18; compressParams[8][3] = 60;
  764. compressParams[9][0] = -60; compressParams[9][1] = -18; compressParams[9][2] = 18; compressParams[9][3] = 60;
  765. compressParams[10][0] = -80; compressParams[10][1] = -24; compressParams[10][2] = 24; compressParams[10][3] = 80;
  766. compressParams[11][0] = -80; compressParams[11][1] = -24; compressParams[11][2] = 24; compressParams[11][3] = 80;
  767. compressParams[12][0] =-106; compressParams[12][1] = -33; compressParams[12][2] = 33; compressParams[12][3] = 106;
  768. compressParams[13][0] =-106; compressParams[13][1] = -33; compressParams[13][2] = 33; compressParams[13][3] = 106;
  769. compressParams[14][0] =-183; compressParams[14][1] = -47; compressParams[14][2] = 47; compressParams[14][3] = 183;
  770. compressParams[15][0] =-183; compressParams[15][1] = -47; compressParams[15][2] = 47; compressParams[15][3] = 183;
  771. return true;
  772. }*/
  773. // Computes the average color in a 2x4 area and returns the average color as a float.
  774. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  775. void computeAverageColor2x4noQuantFloat(uint8 *img,int width,int height,int startx,int starty,float *avg_color)
  776. {
  777. int r=0,g=0,b=0;
  778. for(int y=starty; y<starty+4; y++)
  779. {
  780. for(int x=startx; x<startx+2; x++)
  781. {
  782. r+=RED(img,width,x,y);
  783. g+=GREEN(img,width,x,y);
  784. b+=BLUE(img,width,x,y);
  785. }
  786. }
  787. avg_color[0]=(float)(r/8.0);
  788. avg_color[1]=(float)(g/8.0);
  789. avg_color[2]=(float)(b/8.0);
  790. }
  791. // Computes the average color in a 4x2 area and returns the average color as a float.
  792. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  793. void computeAverageColor4x2noQuantFloat(uint8 *img,int width,int height,int startx,int starty,float *avg_color)
  794. {
  795. int r=0,g=0,b=0;
  796. for(int y=starty; y<starty+2; y++)
  797. {
  798. for(int x=startx; x<startx+4; x++)
  799. {
  800. r+=RED(img,width,x,y);
  801. g+=GREEN(img,width,x,y);
  802. b+=BLUE(img,width,x,y);
  803. }
  804. }
  805. avg_color[0]=(float)(r/8.0);
  806. avg_color[1]=(float)(g/8.0);
  807. avg_color[2]=(float)(b/8.0);
  808. }
  809. // Finds all pixel indices for a 2x4 block.
  810. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  811. int compressBlockWithTable2x4(uint8 *img,int width,int height,int startx,int starty,uint8 *avg_color,int table,unsigned int *pixel_indices_MSBp, unsigned int *pixel_indices_LSBp)
  812. {
  813. uint8 orig[3],approx[3];
  814. unsigned int pixel_indices_MSB=0, pixel_indices_LSB=0, pixel_indices = 0;
  815. int sum_error=0;
  816. int q, i;
  817. i = 0;
  818. for(int x=startx; x<startx+2; x++)
  819. {
  820. for(int y=starty; y<starty+4; y++)
  821. {
  822. int err;
  823. int best=0;
  824. int min_error=255*255*3*16;
  825. orig[0]=RED(img,width,x,y);
  826. orig[1]=GREEN(img,width,x,y);
  827. orig[2]=BLUE(img,width,x,y);
  828. for(q=0;q<4;q++)
  829. {
  830. approx[0]=CLAMP(0, avg_color[0]+compressParams[table][q],255);
  831. approx[1]=CLAMP(0, avg_color[1]+compressParams[table][q],255);
  832. approx[2]=CLAMP(0, avg_color[2]+compressParams[table][q],255);
  833. // Here we just use equal weights to R, G and B. Although this will
  834. // give visually worse results, it will give a better PSNR score.
  835. err=SQUARE(approx[0]-orig[0]) + SQUARE(approx[1]-orig[1]) + SQUARE(approx[2]-orig[2]);
  836. if(err<min_error)
  837. {
  838. min_error=err;
  839. best=q;
  840. }
  841. }
  842. pixel_indices = scramble[best];
  843. PUTBITS( pixel_indices_MSB, (pixel_indices >> 1), 1, i);
  844. PUTBITS( pixel_indices_LSB, (pixel_indices & 1) , 1, i);
  845. i++;
  846. // In order to simplify hardware, the table {-12, -4, 4, 12} is indexed {11, 10, 00, 01}
  847. // so that first bit is sign bit and the other bit is size bit (4 or 12).
  848. // This means that we have to scramble the bits before storing them.
  849. sum_error+=min_error;
  850. }
  851. }
  852. *pixel_indices_MSBp = pixel_indices_MSB;
  853. *pixel_indices_LSBp = pixel_indices_LSB;
  854. return sum_error;
  855. }
  856. #define MAXERR1000 1000*255*255*16
  857. // Finds all pixel indices for a 2x4 block using perceptual weighting of error.
  858. // Done using fixed poinit arithmetics where weights are multiplied by 1000.
  859. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  860. unsigned int compressBlockWithTable2x4percep1000(uint8 *img,int width,int height,int startx,int starty,uint8 *avg_color,int table,unsigned int *pixel_indices_MSBp, unsigned int *pixel_indices_LSBp)
  861. {
  862. uint8 orig[3],approx[3];
  863. unsigned int pixel_indices_MSB=0, pixel_indices_LSB=0, pixel_indices = 0;
  864. unsigned int sum_error=0;
  865. int q, i;
  866. i = 0;
  867. for(int x=startx; x<startx+2; x++)
  868. {
  869. for(int y=starty; y<starty+4; y++)
  870. {
  871. unsigned int err;
  872. int best=0;
  873. unsigned int min_error=MAXERR1000;
  874. orig[0]=RED(img,width,x,y);
  875. orig[1]=GREEN(img,width,x,y);
  876. orig[2]=BLUE(img,width,x,y);
  877. for(q=0;q<4;q++)
  878. {
  879. approx[0]=CLAMP(0, avg_color[0]+compressParams[table][q],255);
  880. approx[1]=CLAMP(0, avg_color[1]+compressParams[table][q],255);
  881. approx[2]=CLAMP(0, avg_color[2]+compressParams[table][q],255);
  882. // Here we just use equal weights to R, G and B. Although this will
  883. // give visually worse results, it will give a better PSNR score.
  884. err = (PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE((approx[0]-orig[0]))
  885. + PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*SQUARE((approx[1]-orig[1]))
  886. + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*SQUARE((approx[2]-orig[2])));
  887. if(err<min_error)
  888. {
  889. min_error=err;
  890. best=q;
  891. }
  892. }
  893. pixel_indices = scramble[best];
  894. PUTBITS( pixel_indices_MSB, (pixel_indices >> 1), 1, i);
  895. PUTBITS( pixel_indices_LSB, (pixel_indices & 1) , 1, i);
  896. i++;
  897. // In order to simplify hardware, the table {-12, -4, 4, 12} is indexed {11, 10, 00, 01}
  898. // so that first bit is sign bit and the other bit is size bit (4 or 12).
  899. // This means that we have to scramble the bits before storing them.
  900. sum_error+=min_error;
  901. }
  902. }
  903. *pixel_indices_MSBp = pixel_indices_MSB;
  904. *pixel_indices_LSBp = pixel_indices_LSB;
  905. return sum_error;
  906. }
  907. // Finds all pixel indices for a 2x4 block using perceptual weighting of error.
  908. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  909. float compressBlockWithTable2x4percep(uint8 *img,int width,int height,int startx,int starty,uint8 *avg_color,int table,unsigned int *pixel_indices_MSBp, unsigned int *pixel_indices_LSBp)
  910. {
  911. uint8 orig[3],approx[3];
  912. unsigned int pixel_indices_MSB=0, pixel_indices_LSB=0, pixel_indices = 0;
  913. float sum_error=0;
  914. int q, i;
  915. double wR2 = PERCEPTUAL_WEIGHT_R_SQUARED;
  916. double wG2 = PERCEPTUAL_WEIGHT_G_SQUARED;
  917. double wB2 = PERCEPTUAL_WEIGHT_B_SQUARED;
  918. i = 0;
  919. for(int x=startx; x<startx+2; x++)
  920. {
  921. for(int y=starty; y<starty+4; y++)
  922. {
  923. float err;
  924. int best=0;
  925. float min_error=255*255*3*16;
  926. orig[0]=RED(img,width,x,y);
  927. orig[1]=GREEN(img,width,x,y);
  928. orig[2]=BLUE(img,width,x,y);
  929. for(q=0;q<4;q++)
  930. {
  931. approx[0]=CLAMP(0, avg_color[0]+compressParams[table][q],255);
  932. approx[1]=CLAMP(0, avg_color[1]+compressParams[table][q],255);
  933. approx[2]=CLAMP(0, avg_color[2]+compressParams[table][q],255);
  934. // Here we just use equal weights to R, G and B. Although this will
  935. // give visually worse results, it will give a better PSNR score.
  936. err=(float)(wR2*SQUARE((approx[0]-orig[0])) + (float)wG2*SQUARE((approx[1]-orig[1])) + (float)wB2*SQUARE((approx[2]-orig[2])));
  937. if(err<min_error)
  938. {
  939. min_error=err;
  940. best=q;
  941. }
  942. }
  943. pixel_indices = scramble[best];
  944. PUTBITS( pixel_indices_MSB, (pixel_indices >> 1), 1, i);
  945. PUTBITS( pixel_indices_LSB, (pixel_indices & 1) , 1, i);
  946. i++;
  947. // In order to simplify hardware, the table {-12, -4, 4, 12} is indexed {11, 10, 00, 01}
  948. // so that first bit is sign bit and the other bit is size bit (4 or 12).
  949. // This means that we have to scramble the bits before storing them.
  950. sum_error+=min_error;
  951. }
  952. }
  953. *pixel_indices_MSBp = pixel_indices_MSB;
  954. *pixel_indices_LSBp = pixel_indices_LSB;
  955. return sum_error;
  956. }
  957. // Finds all pixel indices for a 4x2 block.
  958. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  959. int compressBlockWithTable4x2(uint8 *img,int width,int height,int startx,int starty,uint8 *avg_color,int table,unsigned int *pixel_indices_MSBp, unsigned int *pixel_indices_LSBp)
  960. {
  961. uint8 orig[3],approx[3];
  962. unsigned int pixel_indices_MSB=0, pixel_indices_LSB=0, pixel_indices = 0;
  963. int sum_error=0;
  964. int q;
  965. int i;
  966. i = 0;
  967. for(int x=startx; x<startx+4; x++)
  968. {
  969. for(int y=starty; y<starty+2; y++)
  970. {
  971. int err;
  972. int best=0;
  973. int min_error=255*255*3*16;
  974. orig[0]=RED(img,width,x,y);
  975. orig[1]=GREEN(img,width,x,y);
  976. orig[2]=BLUE(img,width,x,y);
  977. for(q=0;q<4;q++)
  978. {
  979. approx[0]=CLAMP(0, avg_color[0]+compressParams[table][q],255);
  980. approx[1]=CLAMP(0, avg_color[1]+compressParams[table][q],255);
  981. approx[2]=CLAMP(0, avg_color[2]+compressParams[table][q],255);
  982. // Here we just use equal weights to R, G and B. Although this will
  983. // give visually worse results, it will give a better PSNR score.
  984. err=SQUARE(approx[0]-orig[0]) + SQUARE(approx[1]-orig[1]) + SQUARE(approx[2]-orig[2]);
  985. if(err<min_error)
  986. {
  987. min_error=err;
  988. best=q;
  989. }
  990. }
  991. pixel_indices = scramble[best];
  992. PUTBITS( pixel_indices_MSB, (pixel_indices >> 1), 1, i);
  993. PUTBITS( pixel_indices_LSB, (pixel_indices & 1) , 1, i);
  994. i++;
  995. // In order to simplify hardware, the table {-12, -4, 4, 12} is indexed {11, 10, 00, 01}
  996. // so that first bit is sign bit and the other bit is size bit (4 or 12).
  997. // This means that we have to scramble the bits before storing them.
  998. sum_error+=min_error;
  999. }
  1000. i+=2;
  1001. }
  1002. *pixel_indices_MSBp = pixel_indices_MSB;
  1003. *pixel_indices_LSBp = pixel_indices_LSB;
  1004. return sum_error;
  1005. }
  1006. // Finds all pixel indices for a 4x2 block using perceptual weighting of error.
  1007. // Done using fixed point arithmetics where 1000 corresponds to 1.0.
  1008. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  1009. unsigned int compressBlockWithTable4x2percep1000(uint8 *img,int width,int height,int startx,int starty,uint8 *avg_color,int table,unsigned int *pixel_indices_MSBp, unsigned int *pixel_indices_LSBp)
  1010. {
  1011. uint8 orig[3],approx[3];
  1012. unsigned int pixel_indices_MSB=0, pixel_indices_LSB=0, pixel_indices = 0;
  1013. unsigned int sum_error=0;
  1014. int q;
  1015. int i;
  1016. i = 0;
  1017. for(int x=startx; x<startx+4; x++)
  1018. {
  1019. for(int y=starty; y<starty+2; y++)
  1020. {
  1021. unsigned int err;
  1022. int best=0;
  1023. unsigned int min_error=MAXERR1000;
  1024. orig[0]=RED(img,width,x,y);
  1025. orig[1]=GREEN(img,width,x,y);
  1026. orig[2]=BLUE(img,width,x,y);
  1027. for(q=0;q<4;q++)
  1028. {
  1029. approx[0]=CLAMP(0, avg_color[0]+compressParams[table][q],255);
  1030. approx[1]=CLAMP(0, avg_color[1]+compressParams[table][q],255);
  1031. approx[2]=CLAMP(0, avg_color[2]+compressParams[table][q],255);
  1032. // Here we just use equal weights to R, G and B. Although this will
  1033. // give visually worse results, it will give a better PSNR score.
  1034. err = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE(approx[0]-orig[0])
  1035. + PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*SQUARE(approx[1]-orig[1])
  1036. + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*SQUARE(approx[2]-orig[2]);
  1037. if(err<min_error)
  1038. {
  1039. min_error=err;
  1040. best=q;
  1041. }
  1042. }
  1043. pixel_indices = scramble[best];
  1044. PUTBITS( pixel_indices_MSB, (pixel_indices >> 1), 1, i);
  1045. PUTBITS( pixel_indices_LSB, (pixel_indices & 1) , 1, i);
  1046. i++;
  1047. // In order to simplify hardware, the table {-12, -4, 4, 12} is indexed {11, 10, 00, 01}
  1048. // so that first bit is sign bit and the other bit is size bit (4 or 12).
  1049. // This means that we have to scramble the bits before storing them.
  1050. sum_error+=min_error;
  1051. }
  1052. i+=2;
  1053. }
  1054. *pixel_indices_MSBp = pixel_indices_MSB;
  1055. *pixel_indices_LSBp = pixel_indices_LSB;
  1056. return sum_error;
  1057. }
  1058. // Finds all pixel indices for a 4x2 block using perceptual weighting of error.
  1059. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  1060. float compressBlockWithTable4x2percep(uint8 *img,int width,int height,int startx,int starty,uint8 *avg_color,int table,unsigned int *pixel_indices_MSBp, unsigned int *pixel_indices_LSBp)
  1061. {
  1062. uint8 orig[3],approx[3];
  1063. unsigned int pixel_indices_MSB=0, pixel_indices_LSB=0, pixel_indices = 0;
  1064. float sum_error=0;
  1065. int q;
  1066. int i;
  1067. float wR2 = (float) PERCEPTUAL_WEIGHT_R_SQUARED;
  1068. float wG2 = (float) PERCEPTUAL_WEIGHT_G_SQUARED;
  1069. float wB2 = (float) PERCEPTUAL_WEIGHT_B_SQUARED;
  1070. i = 0;
  1071. for(int x=startx; x<startx+4; x++)
  1072. {
  1073. for(int y=starty; y<starty+2; y++)
  1074. {
  1075. float err;
  1076. int best=0;
  1077. float min_error=255*255*3*16;
  1078. orig[0]=RED(img,width,x,y);
  1079. orig[1]=GREEN(img,width,x,y);
  1080. orig[2]=BLUE(img,width,x,y);
  1081. for(q=0;q<4;q++)
  1082. {
  1083. approx[0]=CLAMP(0, avg_color[0]+compressParams[table][q],255);
  1084. approx[1]=CLAMP(0, avg_color[1]+compressParams[table][q],255);
  1085. approx[2]=CLAMP(0, avg_color[2]+compressParams[table][q],255);
  1086. // Here we just use equal weights to R, G and B. Although this will
  1087. // give visually worse results, it will give a better PSNR score.
  1088. err=(float) wR2*SQUARE(approx[0]-orig[0]) + (float)wG2*SQUARE(approx[1]-orig[1]) + (float)wB2*SQUARE(approx[2]-orig[2]);
  1089. if(err<min_error)
  1090. {
  1091. min_error=err;
  1092. best=q;
  1093. }
  1094. }
  1095. pixel_indices = scramble[best];
  1096. PUTBITS( pixel_indices_MSB, (pixel_indices >> 1), 1, i);
  1097. PUTBITS( pixel_indices_LSB, (pixel_indices & 1) , 1, i);
  1098. i++;
  1099. // In order to simplify hardware, the table {-12, -4, 4, 12} is indexed {11, 10, 00, 01}
  1100. // so that first bit is sign bit and the other bit is size bit (4 or 12).
  1101. // This means that we have to scramble the bits before storing them.
  1102. sum_error+=min_error;
  1103. }
  1104. i+=2;
  1105. }
  1106. *pixel_indices_MSBp = pixel_indices_MSB;
  1107. *pixel_indices_LSBp = pixel_indices_LSB;
  1108. return sum_error;
  1109. }
  1110. // Table for fast implementation of clamping to the interval [0,255] followed by addition of 255.
  1111. const int clamp_table_plus_255[768] = {0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255, 0+255,
  1112. 0+255, 1+255, 2+255, 3+255, 4+255, 5+255, 6+255, 7+255, 8+255, 9+255, 10+255, 11+255, 12+255, 13+255, 14+255, 15+255, 16+255, 17+255, 18+255, 19+255, 20+255, 21+255, 22+255, 23+255, 24+255, 25+255, 26+255, 27+255, 28+255, 29+255, 30+255, 31+255, 32+255, 33+255, 34+255, 35+255, 36+255, 37+255, 38+255, 39+255, 40+255, 41+255, 42+255, 43+255, 44+255, 45+255, 46+255, 47+255, 48+255, 49+255, 50+255, 51+255, 52+255, 53+255, 54+255, 55+255, 56+255, 57+255, 58+255, 59+255, 60+255, 61+255, 62+255, 63+255, 64+255, 65+255, 66+255, 67+255, 68+255, 69+255, 70+255, 71+255, 72+255, 73+255, 74+255, 75+255, 76+255, 77+255, 78+255, 79+255, 80+255, 81+255, 82+255, 83+255, 84+255, 85+255, 86+255, 87+255, 88+255, 89+255, 90+255, 91+255, 92+255, 93+255, 94+255, 95+255, 96+255, 97+255, 98+255, 99+255, 100+255, 101+255, 102+255, 103+255, 104+255, 105+255, 106+255, 107+255, 108+255, 109+255, 110+255, 111+255, 112+255, 113+255, 114+255, 115+255, 116+255, 117+255, 118+255, 119+255, 120+255, 121+255, 122+255, 123+255, 124+255, 125+255, 126+255, 127+255, 128+255, 129+255, 130+255, 131+255, 132+255, 133+255, 134+255, 135+255, 136+255, 137+255, 138+255, 139+255, 140+255, 141+255, 142+255, 143+255, 144+255, 145+255, 146+255, 147+255, 148+255, 149+255, 150+255, 151+255, 152+255, 153+255, 154+255, 155+255, 156+255, 157+255, 158+255, 159+255, 160+255, 161+255, 162+255, 163+255, 164+255, 165+255, 166+255, 167+255, 168+255, 169+255, 170+255, 171+255, 172+255, 173+255, 174+255, 175+255, 176+255, 177+255, 178+255, 179+255, 180+255, 181+255, 182+255, 183+255, 184+255, 185+255, 186+255, 187+255, 188+255, 189+255, 190+255, 191+255, 192+255, 193+255, 194+255, 195+255, 196+255, 197+255, 198+255, 199+255, 200+255, 201+255, 202+255, 203+255, 204+255, 205+255, 206+255, 207+255, 208+255, 209+255, 210+255, 211+255,
  1113. 212+255, 213+255, 214+255, 215+255, 216+255, 217+255, 218+255, 219+255, 220+255, 221+255, 222+255, 223+255, 224+255, 225+255, 226+255, 227+255, 228+255, 229+255, 230+255, 231+255, 232+255, 233+255, 234+255, 235+255, 236+255, 237+255, 238+255, 239+255, 240+255, 241+255, 242+255, 243+255, 244+255, 245+255, 246+255, 247+255, 248+255, 249+255, 250+255, 251+255, 252+255, 253+255, 254+255, 255+255,
  1114. 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255,
  1115. 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255, 255+255};
  1116. // Table for fast implementationi of clamping to the interval [0,255]
  1117. const int clamp_table[768] = {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, 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, 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, 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, 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, 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, 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, 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,
  1118. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
  1119. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255};
  1120. // Table for fast implementation of squaring for numbers in the interval [-255, 255]
  1121. const unsigned int square_table[511] = {65025, 64516, 64009, 63504, 63001, 62500, 62001, 61504, 61009, 60516, 60025, 59536, 59049, 58564, 58081, 57600,
  1122. 57121, 56644, 56169, 55696, 55225, 54756, 54289, 53824, 53361, 52900, 52441, 51984, 51529, 51076, 50625, 50176,
  1123. 49729, 49284, 48841, 48400, 47961, 47524, 47089, 46656, 46225, 45796, 45369, 44944, 44521, 44100, 43681, 43264,
  1124. 42849, 42436, 42025, 41616, 41209, 40804, 40401, 40000, 39601, 39204, 38809, 38416, 38025, 37636, 37249, 36864,
  1125. 36481, 36100, 35721, 35344, 34969, 34596, 34225, 33856, 33489, 33124, 32761, 32400, 32041, 31684, 31329, 30976,
  1126. 30625, 30276, 29929, 29584, 29241, 28900, 28561, 28224, 27889, 27556, 27225, 26896, 26569, 26244, 25921, 25600,
  1127. 25281, 24964, 24649, 24336, 24025, 23716, 23409, 23104, 22801, 22500, 22201, 21904, 21609, 21316, 21025, 20736,
  1128. 20449, 20164, 19881, 19600, 19321, 19044, 18769, 18496, 18225, 17956, 17689, 17424, 17161, 16900, 16641, 16384,
  1129. 16129, 15876, 15625, 15376, 15129, 14884, 14641, 14400, 14161, 13924, 13689, 13456, 13225, 12996, 12769, 12544,
  1130. 12321, 12100, 11881, 11664, 11449, 11236, 11025, 10816, 10609, 10404, 10201, 10000, 9801, 9604, 9409, 9216,
  1131. 9025, 8836, 8649, 8464, 8281, 8100, 7921, 7744, 7569, 7396, 7225, 7056, 6889, 6724, 6561, 6400,
  1132. 6241, 6084, 5929, 5776, 5625, 5476, 5329, 5184, 5041, 4900, 4761, 4624, 4489, 4356, 4225, 4096,
  1133. 3969, 3844, 3721, 3600, 3481, 3364, 3249, 3136, 3025, 2916, 2809, 2704, 2601, 2500, 2401, 2304,
  1134. 2209, 2116, 2025, 1936, 1849, 1764, 1681, 1600, 1521, 1444, 1369, 1296, 1225, 1156, 1089, 1024,
  1135. 961, 900, 841, 784, 729, 676, 625, 576, 529, 484, 441, 400, 361, 324, 289, 256,
  1136. 225, 196, 169, 144, 121, 100, 81, 64, 49, 36, 25, 16, 9, 4, 1,
  1137. 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225,
  1138. 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961,
  1139. 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209,
  1140. 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969,
  1141. 4096, 4225, 4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 5776, 5929, 6084, 6241,
  1142. 6400, 6561, 6724, 6889, 7056, 7225, 7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025,
  1143. 9216, 9409, 9604, 9801, 10000, 10201, 10404, 10609, 10816, 11025, 11236, 11449, 11664, 11881, 12100, 12321,
  1144. 12544, 12769, 12996, 13225, 13456, 13689, 13924, 14161, 14400, 14641, 14884, 15129, 15376, 15625, 15876, 16129,
  1145. 16384, 16641, 16900, 17161, 17424, 17689, 17956, 18225, 18496, 18769, 19044, 19321, 19600, 19881, 20164, 20449,
  1146. 20736, 21025, 21316, 21609, 21904, 22201, 22500, 22801, 23104, 23409, 23716, 24025, 24336, 24649, 24964, 25281,
  1147. 25600, 25921, 26244, 26569, 26896, 27225, 27556, 27889, 28224, 28561, 28900, 29241, 29584, 29929, 30276, 30625,
  1148. 30976, 31329, 31684, 32041, 32400, 32761, 33124, 33489, 33856, 34225, 34596, 34969, 35344, 35721, 36100, 36481,
  1149. 36864, 37249, 37636, 38025, 38416, 38809, 39204, 39601, 40000, 40401, 40804, 41209, 41616, 42025, 42436, 42849,
  1150. 43264, 43681, 44100, 44521, 44944, 45369, 45796, 46225, 46656, 47089, 47524, 47961, 48400, 48841, 49284, 49729,
  1151. 50176, 50625, 51076, 51529, 51984, 52441, 52900, 53361, 53824, 54289, 54756, 55225, 55696, 56169, 56644, 57121,
  1152. 57600, 58081, 58564, 59049, 59536, 60025, 60516, 61009, 61504, 62001, 62500, 63001, 63504, 64009, 64516, 65025};
  1153. // Abbreviated variable names to make below tables smaller in source code size
  1154. #define KR PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000
  1155. #define KG PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000
  1156. #define KB PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000
  1157. // Table for fast implementation of squaring for numbers in the interval [-255, 255] multiplied by the perceptual weight for red.
  1158. const unsigned int square_table_percep_red[511] = {
  1159. 65025*KR, 64516*KR, 64009*KR, 63504*KR, 63001*KR, 62500*KR, 62001*KR, 61504*KR, 61009*KR, 60516*KR, 60025*KR, 59536*KR, 59049*KR, 58564*KR, 58081*KR, 57600*KR,
  1160. 57121*KR, 56644*KR, 56169*KR, 55696*KR, 55225*KR, 54756*KR, 54289*KR, 53824*KR, 53361*KR, 52900*KR, 52441*KR, 51984*KR, 51529*KR, 51076*KR, 50625*KR, 50176*KR,
  1161. 49729*KR, 49284*KR, 48841*KR, 48400*KR, 47961*KR, 47524*KR, 47089*KR, 46656*KR, 46225*KR, 45796*KR, 45369*KR, 44944*KR, 44521*KR, 44100*KR, 43681*KR, 43264*KR,
  1162. 42849*KR, 42436*KR, 42025*KR, 41616*KR, 41209*KR, 40804*KR, 40401*KR, 40000*KR, 39601*KR, 39204*KR, 38809*KR, 38416*KR, 38025*KR, 37636*KR, 37249*KR, 36864*KR,
  1163. 36481*KR, 36100*KR, 35721*KR, 35344*KR, 34969*KR, 34596*KR, 34225*KR, 33856*KR, 33489*KR, 33124*KR, 32761*KR, 32400*KR, 32041*KR, 31684*KR, 31329*KR, 30976*KR,
  1164. 30625*KR, 30276*KR, 29929*KR, 29584*KR, 29241*KR, 28900*KR, 28561*KR, 28224*KR, 27889*KR, 27556*KR, 27225*KR, 26896*KR, 26569*KR, 26244*KR, 25921*KR, 25600*KR,
  1165. 25281*KR, 24964*KR, 24649*KR, 24336*KR, 24025*KR, 23716*KR, 23409*KR, 23104*KR, 22801*KR, 22500*KR, 22201*KR, 21904*KR, 21609*KR, 21316*KR, 21025*KR, 20736*KR,
  1166. 20449*KR, 20164*KR, 19881*KR, 19600*KR, 19321*KR, 19044*KR, 18769*KR, 18496*KR, 18225*KR, 17956*KR, 17689*KR, 17424*KR, 17161*KR, 16900*KR, 16641*KR, 16384*KR,
  1167. 16129*KR, 15876*KR, 15625*KR, 15376*KR, 15129*KR, 14884*KR, 14641*KR, 14400*KR, 14161*KR, 13924*KR, 13689*KR, 13456*KR, 13225*KR, 12996*KR, 12769*KR, 12544*KR,
  1168. 12321*KR, 12100*KR, 11881*KR, 11664*KR, 11449*KR, 11236*KR, 11025*KR, 10816*KR, 10609*KR, 10404*KR, 10201*KR, 10000*KR, 9801*KR, 9604*KR, 9409*KR, 9216*KR,
  1169. 9025*KR, 8836*KR, 8649*KR, 8464*KR, 8281*KR, 8100*KR, 7921*KR, 7744*KR, 7569*KR, 7396*KR, 7225*KR, 7056*KR, 6889*KR, 6724*KR, 6561*KR, 6400*KR,
  1170. 6241*KR, 6084*KR, 5929*KR, 5776*KR, 5625*KR, 5476*KR, 5329*KR, 5184*KR, 5041*KR, 4900*KR, 4761*KR, 4624*KR, 4489*KR, 4356*KR, 4225*KR, 4096*KR,
  1171. 3969*KR, 3844*KR, 3721*KR, 3600*KR, 3481*KR, 3364*KR, 3249*KR, 3136*KR, 3025*KR, 2916*KR, 2809*KR, 2704*KR, 2601*KR, 2500*KR, 2401*KR, 2304*KR,
  1172. 2209*KR, 2116*KR, 2025*KR, 1936*KR, 1849*KR, 1764*KR, 1681*KR, 1600*KR, 1521*KR, 1444*KR, 1369*KR, 1296*KR, 1225*KR, 1156*KR, 1089*KR, 1024*KR,
  1173. 961*KR, 900*KR, 841*KR, 784*KR, 729*KR, 676*KR, 625*KR, 576*KR, 529*KR, 484*KR, 441*KR, 400*KR, 361*KR, 324*KR, 289*KR, 256*KR,
  1174. 225*KR, 196*KR, 169*KR, 144*KR, 121*KR, 100*KR, 81*KR, 64*KR, 49*KR, 36*KR, 25*KR, 16*KR, 9*KR, 4*KR, 1*KR,
  1175. 0*KR, 1*KR, 4*KR, 9*KR, 16*KR, 25*KR, 36*KR, 49*KR, 64*KR, 81*KR, 100*KR, 121*KR, 144*KR, 169*KR, 196*KR, 225*KR,
  1176. 256*KR, 289*KR, 324*KR, 361*KR, 400*KR, 441*KR, 484*KR, 529*KR, 576*KR, 625*KR, 676*KR, 729*KR, 784*KR, 841*KR, 900*KR, 961*KR,
  1177. 1024*KR, 1089*KR, 1156*KR, 1225*KR, 1296*KR, 1369*KR, 1444*KR, 1521*KR, 1600*KR, 1681*KR, 1764*KR, 1849*KR, 1936*KR, 2025*KR, 2116*KR, 2209*KR,
  1178. 2304*KR, 2401*KR, 2500*KR, 2601*KR, 2704*KR, 2809*KR, 2916*KR, 3025*KR, 3136*KR, 3249*KR, 3364*KR, 3481*KR, 3600*KR, 3721*KR, 3844*KR, 3969*KR,
  1179. 4096*KR, 4225*KR, 4356*KR, 4489*KR, 4624*KR, 4761*KR, 4900*KR, 5041*KR, 5184*KR, 5329*KR, 5476*KR, 5625*KR, 5776*KR, 5929*KR, 6084*KR, 6241*KR,
  1180. 6400*KR, 6561*KR, 6724*KR, 6889*KR, 7056*KR, 7225*KR, 7396*KR, 7569*KR, 7744*KR, 7921*KR, 8100*KR, 8281*KR, 8464*KR, 8649*KR, 8836*KR, 9025*KR,
  1181. 9216*KR, 9409*KR, 9604*KR, 9801*KR, 10000*KR, 10201*KR, 10404*KR, 10609*KR, 10816*KR, 11025*KR, 11236*KR, 11449*KR, 11664*KR, 11881*KR, 12100*KR, 12321*KR,
  1182. 12544*KR, 12769*KR, 12996*KR, 13225*KR, 13456*KR, 13689*KR, 13924*KR, 14161*KR, 14400*KR, 14641*KR, 14884*KR, 15129*KR, 15376*KR, 15625*KR, 15876*KR, 16129*KR,
  1183. 16384*KR, 16641*KR, 16900*KR, 17161*KR, 17424*KR, 17689*KR, 17956*KR, 18225*KR, 18496*KR, 18769*KR, 19044*KR, 19321*KR, 19600*KR, 19881*KR, 20164*KR, 20449*KR,
  1184. 20736*KR, 21025*KR, 21316*KR, 21609*KR, 21904*KR, 22201*KR, 22500*KR, 22801*KR, 23104*KR, 23409*KR, 23716*KR, 24025*KR, 24336*KR, 24649*KR, 24964*KR, 25281*KR,
  1185. 25600*KR, 25921*KR, 26244*KR, 26569*KR, 26896*KR, 27225*KR, 27556*KR, 27889*KR, 28224*KR, 28561*KR, 28900*KR, 29241*KR, 29584*KR, 29929*KR, 30276*KR, 30625*KR,
  1186. 30976*KR, 31329*KR, 31684*KR, 32041*KR, 32400*KR, 32761*KR, 33124*KR, 33489*KR, 33856*KR, 34225*KR, 34596*KR, 34969*KR, 35344*KR, 35721*KR, 36100*KR, 36481*KR,
  1187. 36864*KR, 37249*KR, 37636*KR, 38025*KR, 38416*KR, 38809*KR, 39204*KR, 39601*KR, 40000*KR, 40401*KR, 40804*KR, 41209*KR, 41616*KR, 42025*KR, 42436*KR, 42849*KR,
  1188. 43264*KR, 43681*KR, 44100*KR, 44521*KR, 44944*KR, 45369*KR, 45796*KR, 46225*KR, 46656*KR, 47089*KR, 47524*KR, 47961*KR, 48400*KR, 48841*KR, 49284*KR, 49729*KR,
  1189. 50176*KR, 50625*KR, 51076*KR, 51529*KR, 51984*KR, 52441*KR, 52900*KR, 53361*KR, 53824*KR, 54289*KR, 54756*KR, 55225*KR, 55696*KR, 56169*KR, 56644*KR, 57121*KR,
  1190. 57600*KR, 58081*KR, 58564*KR, 59049*KR, 59536*KR, 60025*KR, 60516*KR, 61009*KR, 61504*KR, 62001*KR, 62500*KR, 63001*KR, 63504*KR, 64009*KR, 64516*KR, 65025*KR};
  1191. // Table for fast implementation of squaring for numbers in the interval [-255, 255] multiplied by the perceptual weight for green.
  1192. const unsigned int square_table_percep_green[511] = {
  1193. 65025*KG, 64516*KG, 64009*KG, 63504*KG, 63001*KG, 62500*KG, 62001*KG, 61504*KG, 61009*KG, 60516*KG, 60025*KG, 59536*KG, 59049*KG, 58564*KG, 58081*KG, 57600*KG,
  1194. 57121*KG, 56644*KG, 56169*KG, 55696*KG, 55225*KG, 54756*KG, 54289*KG, 53824*KG, 53361*KG, 52900*KG, 52441*KG, 51984*KG, 51529*KG, 51076*KG, 50625*KG, 50176*KG,
  1195. 49729*KG, 49284*KG, 48841*KG, 48400*KG, 47961*KG, 47524*KG, 47089*KG, 46656*KG, 46225*KG, 45796*KG, 45369*KG, 44944*KG, 44521*KG, 44100*KG, 43681*KG, 43264*KG,
  1196. 42849*KG, 42436*KG, 42025*KG, 41616*KG, 41209*KG, 40804*KG, 40401*KG, 40000*KG, 39601*KG, 39204*KG, 38809*KG, 38416*KG, 38025*KG, 37636*KG, 37249*KG, 36864*KG,
  1197. 36481*KG, 36100*KG, 35721*KG, 35344*KG, 34969*KG, 34596*KG, 34225*KG, 33856*KG, 33489*KG, 33124*KG, 32761*KG, 32400*KG, 32041*KG, 31684*KG, 31329*KG, 30976*KG,
  1198. 30625*KG, 30276*KG, 29929*KG, 29584*KG, 29241*KG, 28900*KG, 28561*KG, 28224*KG, 27889*KG, 27556*KG, 27225*KG, 26896*KG, 26569*KG, 26244*KG, 25921*KG, 25600*KG,
  1199. 25281*KG, 24964*KG, 24649*KG, 24336*KG, 24025*KG, 23716*KG, 23409*KG, 23104*KG, 22801*KG, 22500*KG, 22201*KG, 21904*KG, 21609*KG, 21316*KG, 21025*KG, 20736*KG,
  1200. 20449*KG, 20164*KG, 19881*KG, 19600*KG, 19321*KG, 19044*KG, 18769*KG, 18496*KG, 18225*KG, 17956*KG, 17689*KG, 17424*KG, 17161*KG, 16900*KG, 16641*KG, 16384*KG,
  1201. 16129*KG, 15876*KG, 15625*KG, 15376*KG, 15129*KG, 14884*KG, 14641*KG, 14400*KG, 14161*KG, 13924*KG, 13689*KG, 13456*KG, 13225*KG, 12996*KG, 12769*KG, 12544*KG,
  1202. 12321*KG, 12100*KG, 11881*KG, 11664*KG, 11449*KG, 11236*KG, 11025*KG, 10816*KG, 10609*KG, 10404*KG, 10201*KG, 10000*KG, 9801*KG, 9604*KG, 9409*KG, 9216*KG,
  1203. 9025*KG, 8836*KG, 8649*KG, 8464*KG, 8281*KG, 8100*KG, 7921*KG, 7744*KG, 7569*KG, 7396*KG, 7225*KG, 7056*KG, 6889*KG, 6724*KG, 6561*KG, 6400*KG,
  1204. 6241*KG, 6084*KG, 5929*KG, 5776*KG, 5625*KG, 5476*KG, 5329*KG, 5184*KG, 5041*KG, 4900*KG, 4761*KG, 4624*KG, 4489*KG, 4356*KG, 4225*KG, 4096*KG,
  1205. 3969*KG, 3844*KG, 3721*KG, 3600*KG, 3481*KG, 3364*KG, 3249*KG, 3136*KG, 3025*KG, 2916*KG, 2809*KG, 2704*KG, 2601*KG, 2500*KG, 2401*KG, 2304*KG,
  1206. 2209*KG, 2116*KG, 2025*KG, 1936*KG, 1849*KG, 1764*KG, 1681*KG, 1600*KG, 1521*KG, 1444*KG, 1369*KG, 1296*KG, 1225*KG, 1156*KG, 1089*KG, 1024*KG,
  1207. 961*KG, 900*KG, 841*KG, 784*KG, 729*KG, 676*KG, 625*KG, 576*KG, 529*KG, 484*KG, 441*KG, 400*KG, 361*KG, 324*KG, 289*KG, 256*KG,
  1208. 225*KG, 196*KG, 169*KG, 144*KG, 121*KG, 100*KG, 81*KG, 64*KG, 49*KG, 36*KG, 25*KG, 16*KG, 9*KG, 4*KG, 1*KG,
  1209. 0*KG, 1*KG, 4*KG, 9*KG, 16*KG, 25*KG, 36*KG, 49*KG, 64*KG, 81*KG, 100*KG, 121*KG, 144*KG, 169*KG, 196*KG, 225*KG,
  1210. 256*KG, 289*KG, 324*KG, 361*KG, 400*KG, 441*KG, 484*KG, 529*KG, 576*KG, 625*KG, 676*KG, 729*KG, 784*KG, 841*KG, 900*KG, 961*KG,
  1211. 1024*KG, 1089*KG, 1156*KG, 1225*KG, 1296*KG, 1369*KG, 1444*KG, 1521*KG, 1600*KG, 1681*KG, 1764*KG, 1849*KG, 1936*KG, 2025*KG, 2116*KG, 2209*KG,
  1212. 2304*KG, 2401*KG, 2500*KG, 2601*KG, 2704*KG, 2809*KG, 2916*KG, 3025*KG, 3136*KG, 3249*KG, 3364*KG, 3481*KG, 3600*KG, 3721*KG, 3844*KG, 3969*KG,
  1213. 4096*KG, 4225*KG, 4356*KG, 4489*KG, 4624*KG, 4761*KG, 4900*KG, 5041*KG, 5184*KG, 5329*KG, 5476*KG, 5625*KG, 5776*KG, 5929*KG, 6084*KG, 6241*KG,
  1214. 6400*KG, 6561*KG, 6724*KG, 6889*KG, 7056*KG, 7225*KG, 7396*KG, 7569*KG, 7744*KG, 7921*KG, 8100*KG, 8281*KG, 8464*KG, 8649*KG, 8836*KG, 9025*KG,
  1215. 9216*KG, 9409*KG, 9604*KG, 9801*KG, 10000*KG, 10201*KG, 10404*KG, 10609*KG, 10816*KG, 11025*KG, 11236*KG, 11449*KG, 11664*KG, 11881*KG, 12100*KG, 12321*KG,
  1216. 12544*KG, 12769*KG, 12996*KG, 13225*KG, 13456*KG, 13689*KG, 13924*KG, 14161*KG, 14400*KG, 14641*KG, 14884*KG, 15129*KG, 15376*KG, 15625*KG, 15876*KG, 16129*KG,
  1217. 16384*KG, 16641*KG, 16900*KG, 17161*KG, 17424*KG, 17689*KG, 17956*KG, 18225*KG, 18496*KG, 18769*KG, 19044*KG, 19321*KG, 19600*KG, 19881*KG, 20164*KG, 20449*KG,
  1218. 20736*KG, 21025*KG, 21316*KG, 21609*KG, 21904*KG, 22201*KG, 22500*KG, 22801*KG, 23104*KG, 23409*KG, 23716*KG, 24025*KG, 24336*KG, 24649*KG, 24964*KG, 25281*KG,
  1219. 25600*KG, 25921*KG, 26244*KG, 26569*KG, 26896*KG, 27225*KG, 27556*KG, 27889*KG, 28224*KG, 28561*KG, 28900*KG, 29241*KG, 29584*KG, 29929*KG, 30276*KG, 30625*KG,
  1220. 30976*KG, 31329*KG, 31684*KG, 32041*KG, 32400*KG, 32761*KG, 33124*KG, 33489*KG, 33856*KG, 34225*KG, 34596*KG, 34969*KG, 35344*KG, 35721*KG, 36100*KG, 36481*KG,
  1221. 36864*KG, 37249*KG, 37636*KG, 38025*KG, 38416*KG, 38809*KG, 39204*KG, 39601*KG, 40000*KG, 40401*KG, 40804*KG, 41209*KG, 41616*KG, 42025*KG, 42436*KG, 42849*KG,
  1222. 43264*KG, 43681*KG, 44100*KG, 44521*KG, 44944*KG, 45369*KG, 45796*KG, 46225*KG, 46656*KG, 47089*KG, 47524*KG, 47961*KG, 48400*KG, 48841*KG, 49284*KG, 49729*KG,
  1223. 50176*KG, 50625*KG, 51076*KG, 51529*KG, 51984*KG, 52441*KG, 52900*KG, 53361*KG, 53824*KG, 54289*KG, 54756*KG, 55225*KG, 55696*KG, 56169*KG, 56644*KG, 57121*KG,
  1224. 57600*KG, 58081*KG, 58564*KG, 59049*KG, 59536*KG, 60025*KG, 60516*KG, 61009*KG, 61504*KG, 62001*KG, 62500*KG, 63001*KG, 63504*KG, 64009*KG, 64516*KG, 65025*KG};
  1225. // Table for fast implementation of squaring for numbers in the interval [-255, 255] multiplied by the perceptual weight for blue.
  1226. const unsigned int square_table_percep_blue[511] = {
  1227. 65025*KB, 64516*KB, 64009*KB, 63504*KB, 63001*KB, 62500*KB, 62001*KB, 61504*KB, 61009*KB, 60516*KB, 60025*KB, 59536*KB, 59049*KB, 58564*KB, 58081*KB, 57600*KB,
  1228. 57121*KB, 56644*KB, 56169*KB, 55696*KB, 55225*KB, 54756*KB, 54289*KB, 53824*KB, 53361*KB, 52900*KB, 52441*KB, 51984*KB, 51529*KB, 51076*KB, 50625*KB, 50176*KB,
  1229. 49729*KB, 49284*KB, 48841*KB, 48400*KB, 47961*KB, 47524*KB, 47089*KB, 46656*KB, 46225*KB, 45796*KB, 45369*KB, 44944*KB, 44521*KB, 44100*KB, 43681*KB, 43264*KB,
  1230. 42849*KB, 42436*KB, 42025*KB, 41616*KB, 41209*KB, 40804*KB, 40401*KB, 40000*KB, 39601*KB, 39204*KB, 38809*KB, 38416*KB, 38025*KB, 37636*KB, 37249*KB, 36864*KB,
  1231. 36481*KB, 36100*KB, 35721*KB, 35344*KB, 34969*KB, 34596*KB, 34225*KB, 33856*KB, 33489*KB, 33124*KB, 32761*KB, 32400*KB, 32041*KB, 31684*KB, 31329*KB, 30976*KB,
  1232. 30625*KB, 30276*KB, 29929*KB, 29584*KB, 29241*KB, 28900*KB, 28561*KB, 28224*KB, 27889*KB, 27556*KB, 27225*KB, 26896*KB, 26569*KB, 26244*KB, 25921*KB, 25600*KB,
  1233. 25281*KB, 24964*KB, 24649*KB, 24336*KB, 24025*KB, 23716*KB, 23409*KB, 23104*KB, 22801*KB, 22500*KB, 22201*KB, 21904*KB, 21609*KB, 21316*KB, 21025*KB, 20736*KB,
  1234. 20449*KB, 20164*KB, 19881*KB, 19600*KB, 19321*KB, 19044*KB, 18769*KB, 18496*KB, 18225*KB, 17956*KB, 17689*KB, 17424*KB, 17161*KB, 16900*KB, 16641*KB, 16384*KB,
  1235. 16129*KB, 15876*KB, 15625*KB, 15376*KB, 15129*KB, 14884*KB, 14641*KB, 14400*KB, 14161*KB, 13924*KB, 13689*KB, 13456*KB, 13225*KB, 12996*KB, 12769*KB, 12544*KB,
  1236. 12321*KB, 12100*KB, 11881*KB, 11664*KB, 11449*KB, 11236*KB, 11025*KB, 10816*KB, 10609*KB, 10404*KB, 10201*KB, 10000*KB, 9801*KB, 9604*KB, 9409*KB, 9216*KB,
  1237. 9025*KB, 8836*KB, 8649*KB, 8464*KB, 8281*KB, 8100*KB, 7921*KB, 7744*KB, 7569*KB, 7396*KB, 7225*KB, 7056*KB, 6889*KB, 6724*KB, 6561*KB, 6400*KB,
  1238. 6241*KB, 6084*KB, 5929*KB, 5776*KB, 5625*KB, 5476*KB, 5329*KB, 5184*KB, 5041*KB, 4900*KB, 4761*KB, 4624*KB, 4489*KB, 4356*KB, 4225*KB, 4096*KB,
  1239. 3969*KB, 3844*KB, 3721*KB, 3600*KB, 3481*KB, 3364*KB, 3249*KB, 3136*KB, 3025*KB, 2916*KB, 2809*KB, 2704*KB, 2601*KB, 2500*KB, 2401*KB, 2304*KB,
  1240. 2209*KB, 2116*KB, 2025*KB, 1936*KB, 1849*KB, 1764*KB, 1681*KB, 1600*KB, 1521*KB, 1444*KB, 1369*KB, 1296*KB, 1225*KB, 1156*KB, 1089*KB, 1024*KB,
  1241. 961*KB, 900*KB, 841*KB, 784*KB, 729*KB, 676*KB, 625*KB, 576*KB, 529*KB, 484*KB, 441*KB, 400*KB, 361*KB, 324*KB, 289*KB, 256*KB,
  1242. 225*KB, 196*KB, 169*KB, 144*KB, 121*KB, 100*KB, 81*KB, 64*KB, 49*KB, 36*KB, 25*KB, 16*KB, 9*KB, 4*KB, 1*KB,
  1243. 0*KB, 1*KB, 4*KB, 9*KB, 16*KB, 25*KB, 36*KB, 49*KB, 64*KB, 81*KB, 100*KB, 121*KB, 144*KB, 169*KB, 196*KB, 225*KB,
  1244. 256*KB, 289*KB, 324*KB, 361*KB, 400*KB, 441*KB, 484*KB, 529*KB, 576*KB, 625*KB, 676*KB, 729*KB, 784*KB, 841*KB, 900*KB, 961*KB,
  1245. 1024*KB, 1089*KB, 1156*KB, 1225*KB, 1296*KB, 1369*KB, 1444*KB, 1521*KB, 1600*KB, 1681*KB, 1764*KB, 1849*KB, 1936*KB, 2025*KB, 2116*KB, 2209*KB,
  1246. 2304*KB, 2401*KB, 2500*KB, 2601*KB, 2704*KB, 2809*KB, 2916*KB, 3025*KB, 3136*KB, 3249*KB, 3364*KB, 3481*KB, 3600*KB, 3721*KB, 3844*KB, 3969*KB,
  1247. 4096*KB, 4225*KB, 4356*KB, 4489*KB, 4624*KB, 4761*KB, 4900*KB, 5041*KB, 5184*KB, 5329*KB, 5476*KB, 5625*KB, 5776*KB, 5929*KB, 6084*KB, 6241*KB,
  1248. 6400*KB, 6561*KB, 6724*KB, 6889*KB, 7056*KB, 7225*KB, 7396*KB, 7569*KB, 7744*KB, 7921*KB, 8100*KB, 8281*KB, 8464*KB, 8649*KB, 8836*KB, 9025*KB,
  1249. 9216*KB, 9409*KB, 9604*KB, 9801*KB, 10000*KB, 10201*KB, 10404*KB, 10609*KB, 10816*KB, 11025*KB, 11236*KB, 11449*KB, 11664*KB, 11881*KB, 12100*KB, 12321*KB,
  1250. 12544*KB, 12769*KB, 12996*KB, 13225*KB, 13456*KB, 13689*KB, 13924*KB, 14161*KB, 14400*KB, 14641*KB, 14884*KB, 15129*KB, 15376*KB, 15625*KB, 15876*KB, 16129*KB,
  1251. 16384*KB, 16641*KB, 16900*KB, 17161*KB, 17424*KB, 17689*KB, 17956*KB, 18225*KB, 18496*KB, 18769*KB, 19044*KB, 19321*KB, 19600*KB, 19881*KB, 20164*KB, 20449*KB,
  1252. 20736*KB, 21025*KB, 21316*KB, 21609*KB, 21904*KB, 22201*KB, 22500*KB, 22801*KB, 23104*KB, 23409*KB, 23716*KB, 24025*KB, 24336*KB, 24649*KB, 24964*KB, 25281*KB,
  1253. 25600*KB, 25921*KB, 26244*KB, 26569*KB, 26896*KB, 27225*KB, 27556*KB, 27889*KB, 28224*KB, 28561*KB, 28900*KB, 29241*KB, 29584*KB, 29929*KB, 30276*KB, 30625*KB,
  1254. 30976*KB, 31329*KB, 31684*KB, 32041*KB, 32400*KB, 32761*KB, 33124*KB, 33489*KB, 33856*KB, 34225*KB, 34596*KB, 34969*KB, 35344*KB, 35721*KB, 36100*KB, 36481*KB,
  1255. 36864*KB, 37249*KB, 37636*KB, 38025*KB, 38416*KB, 38809*KB, 39204*KB, 39601*KB, 40000*KB, 40401*KB, 40804*KB, 41209*KB, 41616*KB, 42025*KB, 42436*KB, 42849*KB,
  1256. 43264*KB, 43681*KB, 44100*KB, 44521*KB, 44944*KB, 45369*KB, 45796*KB, 46225*KB, 46656*KB, 47089*KB, 47524*KB, 47961*KB, 48400*KB, 48841*KB, 49284*KB, 49729*KB,
  1257. 50176*KB, 50625*KB, 51076*KB, 51529*KB, 51984*KB, 52441*KB, 52900*KB, 53361*KB, 53824*KB, 54289*KB, 54756*KB, 55225*KB, 55696*KB, 56169*KB, 56644*KB, 57121*KB,
  1258. 57600*KB, 58081*KB, 58564*KB, 59049*KB, 59536*KB, 60025*KB, 60516*KB, 61009*KB, 61504*KB, 62001*KB, 62500*KB, 63001*KB, 63504*KB, 64009*KB, 64516*KB, 65025*KB};
  1259. // Find the best table to use for a 2x4 area by testing all.
  1260. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  1261. int tryalltables_3bittable2x4(uint8 *img,int width,int height,int startx,int starty,uint8 *avg_color, unsigned int &best_table,unsigned int &best_pixel_indices_MSB, unsigned int &best_pixel_indices_LSB)
  1262. {
  1263. int min_error = 3*255*255*16;
  1264. int q;
  1265. int err;
  1266. unsigned int pixel_indices_MSB, pixel_indices_LSB;
  1267. for(q=0;q<16;q+=2) // try all the 8 tables.
  1268. {
  1269. err=compressBlockWithTable2x4(img,width,height,startx,starty,avg_color,q,&pixel_indices_MSB, &pixel_indices_LSB);
  1270. if(err<min_error)
  1271. {
  1272. min_error=err;
  1273. best_pixel_indices_MSB = pixel_indices_MSB;
  1274. best_pixel_indices_LSB = pixel_indices_LSB;
  1275. best_table=q >> 1;
  1276. }
  1277. }
  1278. return min_error;
  1279. }
  1280. // Find the best table to use for a 2x4 area by testing all.
  1281. // Uses perceptual weighting.
  1282. // Uses fixed point implementation where 1000 equals 1.0
  1283. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  1284. unsigned int tryalltables_3bittable2x4percep1000(uint8 *img,int width,int height,int startx,int starty,uint8 *avg_color, unsigned int &best_table,unsigned int &best_pixel_indices_MSB, unsigned int &best_pixel_indices_LSB)
  1285. {
  1286. unsigned int min_error = MAXERR1000;
  1287. int q;
  1288. unsigned int err;
  1289. unsigned int pixel_indices_MSB, pixel_indices_LSB;
  1290. for(q=0;q<16;q+=2) // try all the 8 tables.
  1291. {
  1292. err=compressBlockWithTable2x4percep1000(img,width,height,startx,starty,avg_color,q,&pixel_indices_MSB, &pixel_indices_LSB);
  1293. if(err<min_error)
  1294. {
  1295. min_error=err;
  1296. best_pixel_indices_MSB = pixel_indices_MSB;
  1297. best_pixel_indices_LSB = pixel_indices_LSB;
  1298. best_table=q >> 1;
  1299. }
  1300. }
  1301. return min_error;
  1302. }
  1303. // Find the best table to use for a 2x4 area by testing all.
  1304. // Uses perceptual weighting.
  1305. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  1306. int tryalltables_3bittable2x4percep(uint8 *img,int width,int height,int startx,int starty,uint8 *avg_color, unsigned int &best_table,unsigned int &best_pixel_indices_MSB, unsigned int &best_pixel_indices_LSB)
  1307. {
  1308. float min_error = 3*255*255*16;
  1309. int q;
  1310. float err;
  1311. unsigned int pixel_indices_MSB, pixel_indices_LSB;
  1312. for(q=0;q<16;q+=2) // try all the 8 tables.
  1313. {
  1314. err=compressBlockWithTable2x4percep(img,width,height,startx,starty,avg_color,q,&pixel_indices_MSB, &pixel_indices_LSB);
  1315. if(err<min_error)
  1316. {
  1317. min_error=err;
  1318. best_pixel_indices_MSB = pixel_indices_MSB;
  1319. best_pixel_indices_LSB = pixel_indices_LSB;
  1320. best_table=q >> 1;
  1321. }
  1322. }
  1323. return (int) min_error;
  1324. }
  1325. // Find the best table to use for a 4x2 area by testing all.
  1326. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  1327. int tryalltables_3bittable4x2(uint8 *img,int width,int height,int startx,int starty,uint8 *avg_color, unsigned int &best_table,unsigned int &best_pixel_indices_MSB, unsigned int &best_pixel_indices_LSB)
  1328. {
  1329. int min_error = 3*255*255*16;
  1330. int q;
  1331. int err;
  1332. unsigned int pixel_indices_MSB, pixel_indices_LSB;
  1333. for(q=0;q<16;q+=2) // try all the 8 tables.
  1334. {
  1335. err=compressBlockWithTable4x2(img,width,height,startx,starty,avg_color,q,&pixel_indices_MSB, &pixel_indices_LSB);
  1336. if(err<min_error)
  1337. {
  1338. min_error=err;
  1339. best_pixel_indices_MSB = pixel_indices_MSB;
  1340. best_pixel_indices_LSB = pixel_indices_LSB;
  1341. best_table=q >> 1;
  1342. }
  1343. }
  1344. return min_error;
  1345. }
  1346. // Find the best table to use for a 4x2 area by testing all.
  1347. // Uses perceptual weighting.
  1348. // Uses fixed point implementation where 1000 equals 1.0
  1349. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  1350. unsigned int tryalltables_3bittable4x2percep1000(uint8 *img,int width,int height,int startx,int starty,uint8 *avg_color, unsigned int &best_table,unsigned int &best_pixel_indices_MSB, unsigned int &best_pixel_indices_LSB)
  1351. {
  1352. unsigned int min_error = MAXERR1000;
  1353. int q;
  1354. unsigned int err;
  1355. unsigned int pixel_indices_MSB, pixel_indices_LSB;
  1356. for(q=0;q<16;q+=2) // try all the 8 tables.
  1357. {
  1358. err=compressBlockWithTable4x2percep1000(img,width,height,startx,starty,avg_color,q,&pixel_indices_MSB, &pixel_indices_LSB);
  1359. if(err<min_error)
  1360. {
  1361. min_error=err;
  1362. best_pixel_indices_MSB = pixel_indices_MSB;
  1363. best_pixel_indices_LSB = pixel_indices_LSB;
  1364. best_table=q >> 1;
  1365. }
  1366. }
  1367. return min_error;
  1368. }
  1369. // Find the best table to use for a 4x2 area by testing all.
  1370. // Uses perceptual weighting.
  1371. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  1372. int tryalltables_3bittable4x2percep(uint8 *img,int width,int height,int startx,int starty,uint8 *avg_color, unsigned int &best_table,unsigned int &best_pixel_indices_MSB, unsigned int &best_pixel_indices_LSB)
  1373. {
  1374. float min_error = 3*255*255*16;
  1375. int q;
  1376. float err;
  1377. unsigned int pixel_indices_MSB, pixel_indices_LSB;
  1378. for(q=0;q<16;q+=2) // try all the 8 tables.
  1379. {
  1380. err=compressBlockWithTable4x2percep(img,width,height,startx,starty,avg_color,q,&pixel_indices_MSB, &pixel_indices_LSB);
  1381. if(err<min_error)
  1382. {
  1383. min_error=err;
  1384. best_pixel_indices_MSB = pixel_indices_MSB;
  1385. best_pixel_indices_LSB = pixel_indices_LSB;
  1386. best_table=q >> 1;
  1387. }
  1388. }
  1389. return (int) min_error;
  1390. }
  1391. // The below code quantizes a float RGB value to RGB444.
  1392. //
  1393. // The format often allows a pixel to completely compensate an intensity error of the base
  1394. // color. Hence the closest RGB444 point may not be the best, and the code below uses
  1395. // this fact to find a better RGB444 color as the base color.
  1396. //
  1397. // (See the presentation http://www.jacobstrom.com/publications/PACKMAN.ppt for more info.)
  1398. //
  1399. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  1400. void quantize444ColorCombined(float *avg_col_in, int *enc_color, uint8 *avg_color)
  1401. {
  1402. float dr, dg, db;
  1403. float kr, kg, kb;
  1404. float wR2, wG2, wB2;
  1405. uint8 low_color[3];
  1406. uint8 high_color[3];
  1407. float min_error=255*255*8*3;
  1408. float lowhightable[8];
  1409. unsigned int best_table=0;
  1410. unsigned int best_index=0;
  1411. int q;
  1412. float kval = (float) (255.0/15.0);
  1413. // These are the values that we want to have:
  1414. float red_average, green_average, blue_average;
  1415. int red_4bit_low, green_4bit_low, blue_4bit_low;
  1416. int red_4bit_high, green_4bit_high, blue_4bit_high;
  1417. // These are the values that we approximate with:
  1418. int red_low, green_low, blue_low;
  1419. int red_high, green_high, blue_high;
  1420. red_average = avg_col_in[0];
  1421. green_average = avg_col_in[1];
  1422. blue_average = avg_col_in[2];
  1423. // Find the 5-bit reconstruction levels red_low, red_high
  1424. // so that red_average is in interval [red_low, red_high].
  1425. // (The same with green and blue.)
  1426. red_4bit_low = (int) (red_average/kval);
  1427. green_4bit_low = (int) (green_average/kval);
  1428. blue_4bit_low = (int) (blue_average/kval);
  1429. red_4bit_high = CLAMP(0, red_4bit_low + 1, 15);
  1430. green_4bit_high = CLAMP(0, green_4bit_low + 1, 15);
  1431. blue_4bit_high = CLAMP(0, blue_4bit_low + 1, 15);
  1432. red_low = (red_4bit_low << 4) | (red_4bit_low >> 0);
  1433. green_low = (green_4bit_low << 4) | (green_4bit_low >> 0);
  1434. blue_low = (blue_4bit_low << 4) | (blue_4bit_low >> 0);
  1435. red_high = (red_4bit_high << 4) | (red_4bit_high >> 0);
  1436. green_high = (green_4bit_high << 4) | (green_4bit_high >> 0);
  1437. blue_high = (blue_4bit_high << 4) | (blue_4bit_high >> 0);
  1438. kr = (float)red_high - (float)red_low;
  1439. kg = (float)green_high - (float)green_low;
  1440. kb = (float)blue_high - (float)blue_low;
  1441. // Note that dr, dg, and db are all negative.
  1442. dr = red_low - red_average;
  1443. dg = green_low - green_average;
  1444. db = blue_low - blue_average;
  1445. // Use straight (nonperceptive) weights.
  1446. wR2 = (float) 1.0;
  1447. wG2 = (float) 1.0;
  1448. wB2 = (float) 1.0;
  1449. lowhightable[0] = wR2*wG2*SQUARE( (dr+ 0) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+ 0) );
  1450. lowhightable[1] = wR2*wG2*SQUARE( (dr+kr) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+kr) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+ 0) );
  1451. lowhightable[2] = wR2*wG2*SQUARE( (dr+ 0) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+kg) - (db+ 0) );
  1452. lowhightable[3] = wR2*wG2*SQUARE( (dr+ 0) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+kb) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+kb) );
  1453. lowhightable[4] = wR2*wG2*SQUARE( (dr+kr) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+kr) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+kg) - (db+ 0) );
  1454. lowhightable[5] = wR2*wG2*SQUARE( (dr+kr) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+kr) - (db+kb) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+kb) );
  1455. lowhightable[6] = wR2*wG2*SQUARE( (dr+ 0) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+kb) ) + wG2*wB2*SQUARE( (dg+kg) - (db+kb) );
  1456. lowhightable[7] = wR2*wG2*SQUARE( (dr+kr) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+kr) - (db+kb) ) + wG2*wB2*SQUARE( (dg+kg) - (db+kb) );
  1457. float min_value = lowhightable[0];
  1458. int min_index = 0;
  1459. for(q = 1; q<8; q++)
  1460. {
  1461. if(lowhightable[q] < min_value)
  1462. {
  1463. min_value = lowhightable[q];
  1464. min_index = q;
  1465. }
  1466. }
  1467. float drh = red_high-red_average;
  1468. float dgh = green_high-green_average;
  1469. float dbh = blue_high-blue_average;
  1470. low_color[0] = red_4bit_low;
  1471. low_color[1] = green_4bit_low;
  1472. low_color[2] = blue_4bit_low;
  1473. high_color[0] = red_4bit_high;
  1474. high_color[1] = green_4bit_high;
  1475. high_color[2] = blue_4bit_high;
  1476. switch(min_index)
  1477. {
  1478. case 0:
  1479. // Since the step size is always 17 in RGB444 format (15*17=255),
  1480. // kr = kg = kb = 17, which means that case 0 and case 7 will
  1481. // always have equal projected error. Choose the one that is
  1482. // closer to the desired color.
  1483. if(dr*dr + dg*dg + db*db > 3*8*8)
  1484. {
  1485. enc_color[0] = high_color[0];
  1486. enc_color[1] = high_color[1];
  1487. enc_color[2] = high_color[2];
  1488. }
  1489. else
  1490. {
  1491. enc_color[0] = low_color[0];
  1492. enc_color[1] = low_color[1];
  1493. enc_color[2] = low_color[2];
  1494. }
  1495. break;
  1496. case 1:
  1497. enc_color[0] = high_color[0];
  1498. enc_color[1] = low_color[1];
  1499. enc_color[2] = low_color[2];
  1500. break;
  1501. case 2:
  1502. enc_color[0] = low_color[0];
  1503. enc_color[1] = high_color[1];
  1504. enc_color[2] = low_color[2];
  1505. break;
  1506. case 3:
  1507. enc_color[0] = low_color[0];
  1508. enc_color[1] = low_color[1];
  1509. enc_color[2] = high_color[2];
  1510. break;
  1511. case 4:
  1512. enc_color[0] = high_color[0];
  1513. enc_color[1] = high_color[1];
  1514. enc_color[2] = low_color[2];
  1515. break;
  1516. case 5:
  1517. enc_color[0] = high_color[0];
  1518. enc_color[1] = low_color[1];
  1519. enc_color[2] = high_color[2];
  1520. break;
  1521. case 6:
  1522. enc_color[0] = low_color[0];
  1523. enc_color[1] = high_color[1];
  1524. enc_color[2] = high_color[2];
  1525. break;
  1526. case 7:
  1527. if(dr*dr + dg*dg + db*db > 3*8*8)
  1528. {
  1529. enc_color[0] = high_color[0];
  1530. enc_color[1] = high_color[1];
  1531. enc_color[2] = high_color[2];
  1532. }
  1533. else
  1534. {
  1535. enc_color[0] = low_color[0];
  1536. enc_color[1] = low_color[1];
  1537. enc_color[2] = low_color[2];
  1538. }
  1539. break;
  1540. }
  1541. // Expand 5-bit encoded color to 8-bit color
  1542. avg_color[0] = (enc_color[0] << 3) | (enc_color[0] >> 2);
  1543. avg_color[1] = (enc_color[1] << 3) | (enc_color[1] >> 2);
  1544. avg_color[2] = (enc_color[2] << 3) | (enc_color[2] >> 2);
  1545. }
  1546. // The below code quantizes a float RGB value to RGB555.
  1547. //
  1548. // The format often allows a pixel to completely compensate an intensity error of the base
  1549. // color. Hence the closest RGB555 point may not be the best, and the code below uses
  1550. // this fact to find a better RGB555 color as the base color.
  1551. //
  1552. // (See the presentation http://www.jacobstrom.com/publications/PACKMAN.ppt for more info.)
  1553. //
  1554. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  1555. void quantize555ColorCombined(float *avg_col_in, int *enc_color, uint8 *avg_color)
  1556. {
  1557. float dr, dg, db;
  1558. float kr, kg, kb;
  1559. float wR2, wG2, wB2;
  1560. uint8 low_color[3];
  1561. uint8 high_color[3];
  1562. float min_error=255*255*8*3;
  1563. float lowhightable[8];
  1564. unsigned int best_table=0;
  1565. unsigned int best_index=0;
  1566. int q;
  1567. float kval = (float) (255.0/31.0);
  1568. // These are the values that we want to have:
  1569. float red_average, green_average, blue_average;
  1570. int red_5bit_low, green_5bit_low, blue_5bit_low;
  1571. int red_5bit_high, green_5bit_high, blue_5bit_high;
  1572. // These are the values that we approximate with:
  1573. int red_low, green_low, blue_low;
  1574. int red_high, green_high, blue_high;
  1575. red_average = avg_col_in[0];
  1576. green_average = avg_col_in[1];
  1577. blue_average = avg_col_in[2];
  1578. // Find the 5-bit reconstruction levels red_low, red_high
  1579. // so that red_average is in interval [red_low, red_high].
  1580. // (The same with green and blue.)
  1581. red_5bit_low = (int) (red_average/kval);
  1582. green_5bit_low = (int) (green_average/kval);
  1583. blue_5bit_low = (int) (blue_average/kval);
  1584. red_5bit_high = CLAMP(0, red_5bit_low + 1, 31);
  1585. green_5bit_high = CLAMP(0, green_5bit_low + 1, 31);
  1586. blue_5bit_high = CLAMP(0, blue_5bit_low + 1, 31);
  1587. red_low = (red_5bit_low << 3) | (red_5bit_low >> 2);
  1588. green_low = (green_5bit_low << 3) | (green_5bit_low >> 2);
  1589. blue_low = (blue_5bit_low << 3) | (blue_5bit_low >> 2);
  1590. red_high = (red_5bit_high << 3) | (red_5bit_high >> 2);
  1591. green_high = (green_5bit_high << 3) | (green_5bit_high >> 2);
  1592. blue_high = (blue_5bit_high << 3) | (blue_5bit_high >> 2);
  1593. kr = (float)red_high - (float)red_low;
  1594. kg = (float)green_high - (float)green_low;
  1595. kb = (float)blue_high - (float)blue_low;
  1596. // Note that dr, dg, and db are all negative.
  1597. dr = red_low - red_average;
  1598. dg = green_low - green_average;
  1599. db = blue_low - blue_average;
  1600. // Use straight (nonperceptive) weights.
  1601. wR2 = (float) 1.0;
  1602. wG2 = (float) 1.0;
  1603. wB2 = (float) 1.0;
  1604. lowhightable[0] = wR2*wG2*SQUARE( (dr+ 0) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+ 0) );
  1605. lowhightable[1] = wR2*wG2*SQUARE( (dr+kr) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+kr) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+ 0) );
  1606. lowhightable[2] = wR2*wG2*SQUARE( (dr+ 0) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+kg) - (db+ 0) );
  1607. lowhightable[3] = wR2*wG2*SQUARE( (dr+ 0) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+kb) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+kb) );
  1608. lowhightable[4] = wR2*wG2*SQUARE( (dr+kr) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+kr) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+kg) - (db+ 0) );
  1609. lowhightable[5] = wR2*wG2*SQUARE( (dr+kr) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+kr) - (db+kb) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+kb) );
  1610. lowhightable[6] = wR2*wG2*SQUARE( (dr+ 0) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+kb) ) + wG2*wB2*SQUARE( (dg+kg) - (db+kb) );
  1611. lowhightable[7] = wR2*wG2*SQUARE( (dr+kr) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+kr) - (db+kb) ) + wG2*wB2*SQUARE( (dg+kg) - (db+kb) );
  1612. float min_value = lowhightable[0];
  1613. int min_index = 0;
  1614. for(q = 1; q<8; q++)
  1615. {
  1616. if(lowhightable[q] < min_value)
  1617. {
  1618. min_value = lowhightable[q];
  1619. min_index = q;
  1620. }
  1621. }
  1622. float drh = red_high-red_average;
  1623. float dgh = green_high-green_average;
  1624. float dbh = blue_high-blue_average;
  1625. low_color[0] = red_5bit_low;
  1626. low_color[1] = green_5bit_low;
  1627. low_color[2] = blue_5bit_low;
  1628. high_color[0] = red_5bit_high;
  1629. high_color[1] = green_5bit_high;
  1630. high_color[2] = blue_5bit_high;
  1631. switch(min_index)
  1632. {
  1633. case 0:
  1634. enc_color[0] = low_color[0];
  1635. enc_color[1] = low_color[1];
  1636. enc_color[2] = low_color[2];
  1637. break;
  1638. case 1:
  1639. enc_color[0] = high_color[0];
  1640. enc_color[1] = low_color[1];
  1641. enc_color[2] = low_color[2];
  1642. break;
  1643. case 2:
  1644. enc_color[0] = low_color[0];
  1645. enc_color[1] = high_color[1];
  1646. enc_color[2] = low_color[2];
  1647. break;
  1648. case 3:
  1649. enc_color[0] = low_color[0];
  1650. enc_color[1] = low_color[1];
  1651. enc_color[2] = high_color[2];
  1652. break;
  1653. case 4:
  1654. enc_color[0] = high_color[0];
  1655. enc_color[1] = high_color[1];
  1656. enc_color[2] = low_color[2];
  1657. break;
  1658. case 5:
  1659. enc_color[0] = high_color[0];
  1660. enc_color[1] = low_color[1];
  1661. enc_color[2] = high_color[2];
  1662. break;
  1663. case 6:
  1664. enc_color[0] = low_color[0];
  1665. enc_color[1] = high_color[1];
  1666. enc_color[2] = high_color[2];
  1667. break;
  1668. case 7:
  1669. enc_color[0] = high_color[0];
  1670. enc_color[1] = high_color[1];
  1671. enc_color[2] = high_color[2];
  1672. break;
  1673. }
  1674. // Expand 5-bit encoded color to 8-bit color
  1675. avg_color[0] = (enc_color[0] << 3) | (enc_color[0] >> 2);
  1676. avg_color[1] = (enc_color[1] << 3) | (enc_color[1] >> 2);
  1677. avg_color[2] = (enc_color[2] << 3) | (enc_color[2] >> 2);
  1678. }
  1679. // The below code quantizes a float RGB value to RGB444.
  1680. //
  1681. // The format often allows a pixel to completely compensate an intensity error of the base
  1682. // color. Hence the closest RGB444 point may not be the best, and the code below uses
  1683. // this fact to find a better RGB444 color as the base color.
  1684. //
  1685. // (See the presentation http://www.jacobstrom.com/publications/PACKMAN.ppt for more info.)
  1686. //
  1687. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  1688. void quantize444ColorCombinedPerceptual(float *avg_col_in, int *enc_color, uint8 *avg_color)
  1689. {
  1690. float dr, dg, db;
  1691. float kr, kg, kb;
  1692. float wR2, wG2, wB2;
  1693. uint8 low_color[3];
  1694. uint8 high_color[3];
  1695. float min_error=255*255*8*3;
  1696. float lowhightable[8];
  1697. unsigned int best_table=0;
  1698. unsigned int best_index=0;
  1699. int q;
  1700. float kval = (float) (255.0/15.0);
  1701. // These are the values that we want to have:
  1702. float red_average, green_average, blue_average;
  1703. int red_4bit_low, green_4bit_low, blue_4bit_low;
  1704. int red_4bit_high, green_4bit_high, blue_4bit_high;
  1705. // These are the values that we approximate with:
  1706. int red_low, green_low, blue_low;
  1707. int red_high, green_high, blue_high;
  1708. red_average = avg_col_in[0];
  1709. green_average = avg_col_in[1];
  1710. blue_average = avg_col_in[2];
  1711. // Find the 5-bit reconstruction levels red_low, red_high
  1712. // so that red_average is in interval [red_low, red_high].
  1713. // (The same with green and blue.)
  1714. red_4bit_low = (int) (red_average/kval);
  1715. green_4bit_low = (int) (green_average/kval);
  1716. blue_4bit_low = (int) (blue_average/kval);
  1717. red_4bit_high = CLAMP(0, red_4bit_low + 1, 15);
  1718. green_4bit_high = CLAMP(0, green_4bit_low + 1, 15);
  1719. blue_4bit_high = CLAMP(0, blue_4bit_low + 1, 15);
  1720. red_low = (red_4bit_low << 4) | (red_4bit_low >> 0);
  1721. green_low = (green_4bit_low << 4) | (green_4bit_low >> 0);
  1722. blue_low = (blue_4bit_low << 4) | (blue_4bit_low >> 0);
  1723. red_high = (red_4bit_high << 4) | (red_4bit_high >> 0);
  1724. green_high = (green_4bit_high << 4) | (green_4bit_high >> 0);
  1725. blue_high = (blue_4bit_high << 4) | (blue_4bit_high >> 0);
  1726. low_color[0] = red_4bit_low;
  1727. low_color[1] = green_4bit_low;
  1728. low_color[2] = blue_4bit_low;
  1729. high_color[0] = red_4bit_high;
  1730. high_color[1] = green_4bit_high;
  1731. high_color[2] = blue_4bit_high;
  1732. kr = (float)red_high - (float)red_low;
  1733. kg = (float)green_high - (float)green_low;
  1734. kb = (float)blue_high- (float)blue_low;
  1735. // Note that dr, dg, and db are all negative.
  1736. dr = red_low - red_average;
  1737. dg = green_low - green_average;
  1738. db = blue_low - blue_average;
  1739. // Perceptual weights to use
  1740. wR2 = (float) PERCEPTUAL_WEIGHT_R_SQUARED;
  1741. wG2 = (float) PERCEPTUAL_WEIGHT_G_SQUARED;
  1742. wB2 = (float) PERCEPTUAL_WEIGHT_B_SQUARED;
  1743. lowhightable[0] = wR2*wG2*SQUARE( (dr+ 0) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+ 0) );
  1744. lowhightable[1] = wR2*wG2*SQUARE( (dr+kr) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+kr) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+ 0) );
  1745. lowhightable[2] = wR2*wG2*SQUARE( (dr+ 0) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+kg) - (db+ 0) );
  1746. lowhightable[3] = wR2*wG2*SQUARE( (dr+ 0) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+kb) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+kb) );
  1747. lowhightable[4] = wR2*wG2*SQUARE( (dr+kr) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+kr) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+kg) - (db+ 0) );
  1748. lowhightable[5] = wR2*wG2*SQUARE( (dr+kr) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+kr) - (db+kb) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+kb) );
  1749. lowhightable[6] = wR2*wG2*SQUARE( (dr+ 0) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+kb) ) + wG2*wB2*SQUARE( (dg+kg) - (db+kb) );
  1750. lowhightable[7] = wR2*wG2*SQUARE( (dr+kr) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+kr) - (db+kb) ) + wG2*wB2*SQUARE( (dg+kg) - (db+kb) );
  1751. float min_value = lowhightable[0];
  1752. int min_index = 0;
  1753. for(q = 1; q<8; q++)
  1754. {
  1755. if(lowhightable[q] < min_value)
  1756. {
  1757. min_value = lowhightable[q];
  1758. min_index = q;
  1759. }
  1760. }
  1761. float drh = red_high-red_average;
  1762. float dgh = green_high-green_average;
  1763. float dbh = blue_high-blue_average;
  1764. switch(min_index)
  1765. {
  1766. case 0:
  1767. enc_color[0] = low_color[0];
  1768. enc_color[1] = low_color[1];
  1769. enc_color[2] = low_color[2];
  1770. break;
  1771. case 1:
  1772. enc_color[0] = high_color[0];
  1773. enc_color[1] = low_color[1];
  1774. enc_color[2] = low_color[2];
  1775. break;
  1776. case 2:
  1777. enc_color[0] = low_color[0];
  1778. enc_color[1] = high_color[1];
  1779. enc_color[2] = low_color[2];
  1780. break;
  1781. case 3:
  1782. enc_color[0] = low_color[0];
  1783. enc_color[1] = low_color[1];
  1784. enc_color[2] = high_color[2];
  1785. break;
  1786. case 4:
  1787. enc_color[0] = high_color[0];
  1788. enc_color[1] = high_color[1];
  1789. enc_color[2] = low_color[2];
  1790. break;
  1791. case 5:
  1792. enc_color[0] = high_color[0];
  1793. enc_color[1] = low_color[1];
  1794. enc_color[2] = high_color[2];
  1795. break;
  1796. case 6:
  1797. enc_color[0] = low_color[0];
  1798. enc_color[1] = high_color[1];
  1799. enc_color[2] = high_color[2];
  1800. break;
  1801. case 7:
  1802. enc_color[0] = high_color[0];
  1803. enc_color[1] = high_color[1];
  1804. enc_color[2] = high_color[2];
  1805. break;
  1806. }
  1807. // Expand encoded color to eight bits
  1808. avg_color[0] = (enc_color[0] << 4) | enc_color[0];
  1809. avg_color[1] = (enc_color[1] << 4) | enc_color[1];
  1810. avg_color[2] = (enc_color[2] << 4) | enc_color[2];
  1811. }
  1812. // The below code quantizes a float RGB value to RGB555.
  1813. //
  1814. // The format often allows a pixel to completely compensate an intensity error of the base
  1815. // color. Hence the closest RGB555 point may not be the best, and the code below uses
  1816. // this fact to find a better RGB555 color as the base color.
  1817. //
  1818. // (See the presentation http://www.jacobstrom.com/publications/PACKMAN.ppt for more info.)
  1819. //
  1820. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  1821. void quantize555ColorCombinedPerceptual(float *avg_col_in, int *enc_color, uint8 *avg_color)
  1822. {
  1823. float dr, dg, db;
  1824. float kr, kg, kb;
  1825. float wR2, wG2, wB2;
  1826. uint8 low_color[3];
  1827. uint8 high_color[3];
  1828. float min_error=255*255*8*3;
  1829. float lowhightable[8];
  1830. unsigned int best_table=0;
  1831. unsigned int best_index=0;
  1832. int q;
  1833. float kval = (float) (255.0/31.0);
  1834. // These are the values that we want to have:
  1835. float red_average, green_average, blue_average;
  1836. int red_5bit_low, green_5bit_low, blue_5bit_low;
  1837. int red_5bit_high, green_5bit_high, blue_5bit_high;
  1838. // These are the values that we approximate with:
  1839. int red_low, green_low, blue_low;
  1840. int red_high, green_high, blue_high;
  1841. red_average = avg_col_in[0];
  1842. green_average = avg_col_in[1];
  1843. blue_average = avg_col_in[2];
  1844. // Find the 5-bit reconstruction levels red_low, red_high
  1845. // so that red_average is in interval [red_low, red_high].
  1846. // (The same with green and blue.)
  1847. red_5bit_low = (int) (red_average/kval);
  1848. green_5bit_low = (int) (green_average/kval);
  1849. blue_5bit_low = (int) (blue_average/kval);
  1850. red_5bit_high = CLAMP(0, red_5bit_low + 1, 31);
  1851. green_5bit_high = CLAMP(0, green_5bit_low + 1, 31);
  1852. blue_5bit_high = CLAMP(0, blue_5bit_low + 1, 31);
  1853. red_low = (red_5bit_low << 3) | (red_5bit_low >> 2);
  1854. green_low = (green_5bit_low << 3) | (green_5bit_low >> 2);
  1855. blue_low = (blue_5bit_low << 3) | (blue_5bit_low >> 2);
  1856. red_high = (red_5bit_high << 3) | (red_5bit_high >> 2);
  1857. green_high = (green_5bit_high << 3) | (green_5bit_high >> 2);
  1858. blue_high = (blue_5bit_high << 3) | (blue_5bit_high >> 2);
  1859. low_color[0] = red_5bit_low;
  1860. low_color[1] = green_5bit_low;
  1861. low_color[2] = blue_5bit_low;
  1862. high_color[0] = red_5bit_high;
  1863. high_color[1] = green_5bit_high;
  1864. high_color[2] = blue_5bit_high;
  1865. kr = (float)red_high - (float)red_low;
  1866. kg = (float)green_high - (float)green_low;
  1867. kb = (float)blue_high - (float)blue_low;
  1868. // Note that dr, dg, and db are all negative.
  1869. dr = red_low - red_average;
  1870. dg = green_low - green_average;
  1871. db = blue_low - blue_average;
  1872. // Perceptual weights to use
  1873. wR2 = (float) PERCEPTUAL_WEIGHT_R_SQUARED;
  1874. wG2 = (float) PERCEPTUAL_WEIGHT_G_SQUARED;
  1875. wB2 = (float) PERCEPTUAL_WEIGHT_B_SQUARED;
  1876. lowhightable[0] = wR2*wG2*SQUARE( (dr+ 0) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+ 0) );
  1877. lowhightable[1] = wR2*wG2*SQUARE( (dr+kr) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+kr) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+ 0) );
  1878. lowhightable[2] = wR2*wG2*SQUARE( (dr+ 0) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+kg) - (db+ 0) );
  1879. lowhightable[3] = wR2*wG2*SQUARE( (dr+ 0) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+kb) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+kb) );
  1880. lowhightable[4] = wR2*wG2*SQUARE( (dr+kr) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+kr) - (db+ 0) ) + wG2*wB2*SQUARE( (dg+kg) - (db+ 0) );
  1881. lowhightable[5] = wR2*wG2*SQUARE( (dr+kr) - (dg+ 0) ) + wR2*wB2*SQUARE( (dr+kr) - (db+kb) ) + wG2*wB2*SQUARE( (dg+ 0) - (db+kb) );
  1882. lowhightable[6] = wR2*wG2*SQUARE( (dr+ 0) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+ 0) - (db+kb) ) + wG2*wB2*SQUARE( (dg+kg) - (db+kb) );
  1883. lowhightable[7] = wR2*wG2*SQUARE( (dr+kr) - (dg+kg) ) + wR2*wB2*SQUARE( (dr+kr) - (db+kb) ) + wG2*wB2*SQUARE( (dg+kg) - (db+kb) );
  1884. float min_value = lowhightable[0];
  1885. int min_index = 0;
  1886. for(q = 1; q<8; q++)
  1887. {
  1888. if(lowhightable[q] < min_value)
  1889. {
  1890. min_value = lowhightable[q];
  1891. min_index = q;
  1892. }
  1893. }
  1894. float drh = red_high-red_average;
  1895. float dgh = green_high-green_average;
  1896. float dbh = blue_high-blue_average;
  1897. switch(min_index)
  1898. {
  1899. case 0:
  1900. enc_color[0] = low_color[0];
  1901. enc_color[1] = low_color[1];
  1902. enc_color[2] = low_color[2];
  1903. break;
  1904. case 1:
  1905. enc_color[0] = high_color[0];
  1906. enc_color[1] = low_color[1];
  1907. enc_color[2] = low_color[2];
  1908. break;
  1909. case 2:
  1910. enc_color[0] = low_color[0];
  1911. enc_color[1] = high_color[1];
  1912. enc_color[2] = low_color[2];
  1913. break;
  1914. case 3:
  1915. enc_color[0] = low_color[0];
  1916. enc_color[1] = low_color[1];
  1917. enc_color[2] = high_color[2];
  1918. break;
  1919. case 4:
  1920. enc_color[0] = high_color[0];
  1921. enc_color[1] = high_color[1];
  1922. enc_color[2] = low_color[2];
  1923. break;
  1924. case 5:
  1925. enc_color[0] = high_color[0];
  1926. enc_color[1] = low_color[1];
  1927. enc_color[2] = high_color[2];
  1928. break;
  1929. case 6:
  1930. enc_color[0] = low_color[0];
  1931. enc_color[1] = high_color[1];
  1932. enc_color[2] = high_color[2];
  1933. break;
  1934. case 7:
  1935. enc_color[0] = high_color[0];
  1936. enc_color[1] = high_color[1];
  1937. enc_color[2] = high_color[2];
  1938. break;
  1939. }
  1940. // Expand 5-bit encoded color to 8-bit color
  1941. avg_color[0] = (enc_color[0] << 3) | (enc_color[0] >> 2);
  1942. avg_color[1] = (enc_color[1] << 3) | (enc_color[1] >> 2);
  1943. avg_color[2] = (enc_color[2] << 3) | (enc_color[2] >> 2);
  1944. }
  1945. // Compresses the block using only the individual mode in ETC1/ETC2 using the average color as the base color.
  1946. // Uses a perceptual error metric.
  1947. // Uses fixed point arithmetics where 1000 equals 1.0
  1948. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  1949. unsigned int compressBlockOnlyIndividualAveragePerceptual1000(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2, int *best_enc_color1, int*best_enc_color2, int &best_flip, unsigned int &best_err_upper, unsigned int &best_err_lower, unsigned int &best_err_left, unsigned int &best_err_right, int *best_color_upper, int *best_color_lower, int *best_color_left, int *best_color_right)
  1950. {
  1951. unsigned int compressed1_norm, compressed2_norm;
  1952. unsigned int compressed1_flip, compressed2_flip;
  1953. uint8 avg_color_quant1[3], avg_color_quant2[3];
  1954. float avg_color_float1[3],avg_color_float2[3];
  1955. int enc_color1[3], enc_color2[3];
  1956. unsigned int best_table_indices1=0, best_table_indices2=0;
  1957. unsigned int best_table1=0, best_table2=0;
  1958. int diffbit;
  1959. unsigned int norm_err=0;
  1960. unsigned int flip_err=0;
  1961. unsigned int best_err;
  1962. // First try normal blocks 2x4:
  1963. computeAverageColor2x4noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  1964. computeAverageColor2x4noQuantFloat(img,width,height,startx+2,starty,avg_color_float2);
  1965. enc_color1[0] = int( JAS_ROUND(15.0*avg_color_float1[0]/255.0) );
  1966. enc_color1[1] = int( JAS_ROUND(15.0*avg_color_float1[1]/255.0) );
  1967. enc_color1[2] = int( JAS_ROUND(15.0*avg_color_float1[2]/255.0) );
  1968. enc_color2[0] = int( JAS_ROUND(15.0*avg_color_float2[0]/255.0) );
  1969. enc_color2[1] = int( JAS_ROUND(15.0*avg_color_float2[1]/255.0) );
  1970. enc_color2[2] = int( JAS_ROUND(15.0*avg_color_float2[2]/255.0) );
  1971. diffbit = 0;
  1972. avg_color_quant1[0] = enc_color1[0] << 4 | (enc_color1[0] );
  1973. avg_color_quant1[1] = enc_color1[1] << 4 | (enc_color1[1] );
  1974. avg_color_quant1[2] = enc_color1[2] << 4 | (enc_color1[2] );
  1975. avg_color_quant2[0] = enc_color2[0] << 4 | (enc_color2[0] );
  1976. avg_color_quant2[1] = enc_color2[1] << 4 | (enc_color2[1] );
  1977. avg_color_quant2[2] = enc_color2[2] << 4 | (enc_color2[2] );
  1978. // Pack bits into the first word.
  1979. // ETC1_RGB8_OES:
  1980. //
  1981. // a) bit layout in bits 63 through 32 if diffbit = 0
  1982. //
  1983. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  1984. // ---------------------------------------------------------------------------------------------------
  1985. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  1986. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  1987. // ---------------------------------------------------------------------------------------------------
  1988. //
  1989. // b) bit layout in bits 63 through 32 if diffbit = 1
  1990. //
  1991. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  1992. // ---------------------------------------------------------------------------------------------------
  1993. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |diff|flip|
  1994. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
  1995. // ---------------------------------------------------------------------------------------------------
  1996. //
  1997. // c) bit layout in bits 31 through 0 (in both cases)
  1998. //
  1999. // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  2000. // --------------------------------------------------------------------------------------------------
  2001. // | most significant pixel index bits | least significant pixel index bits |
  2002. // | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a| p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
  2003. // --------------------------------------------------------------------------------------------------
  2004. compressed1_norm = 0;
  2005. PUTBITSHIGH( compressed1_norm, diffbit, 1, 33);
  2006. PUTBITSHIGH( compressed1_norm, enc_color1[0], 4, 63);
  2007. PUTBITSHIGH( compressed1_norm, enc_color1[1], 4, 55);
  2008. PUTBITSHIGH( compressed1_norm, enc_color1[2], 4, 47);
  2009. PUTBITSHIGH( compressed1_norm, enc_color2[0], 4, 59);
  2010. PUTBITSHIGH( compressed1_norm, enc_color2[1], 4, 51);
  2011. PUTBITSHIGH( compressed1_norm, enc_color2[1], 4, 43);
  2012. unsigned int best_pixel_indices1_MSB;
  2013. unsigned int best_pixel_indices1_LSB;
  2014. unsigned int best_pixel_indices2_MSB;
  2015. unsigned int best_pixel_indices2_LSB;
  2016. best_enc_color1[0] = enc_color1[0];
  2017. best_enc_color1[1] = enc_color1[1];
  2018. best_enc_color1[2] = enc_color1[2];
  2019. best_enc_color2[0] = enc_color2[0];
  2020. best_enc_color2[1] = enc_color2[1];
  2021. best_enc_color2[2] = enc_color2[2];
  2022. best_color_left[0] = enc_color1[0];
  2023. best_color_left[1] = enc_color1[1];
  2024. best_color_left[2] = enc_color1[2];
  2025. best_color_right[0] = enc_color2[0];
  2026. best_color_right[1] = enc_color2[1];
  2027. best_color_right[2] = enc_color2[2];
  2028. norm_err = 0;
  2029. // left part of block
  2030. best_err_left = tryalltables_3bittable2x4percep1000(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  2031. norm_err = best_err_left;
  2032. // right part of block
  2033. best_err_right = tryalltables_3bittable2x4percep1000(img,width,height,startx+2,starty,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  2034. norm_err += best_err_right;
  2035. PUTBITSHIGH( compressed1_norm, best_table1, 3, 39);
  2036. PUTBITSHIGH( compressed1_norm, best_table2, 3, 36);
  2037. PUTBITSHIGH( compressed1_norm, 0, 1, 32);
  2038. compressed2_norm = 0;
  2039. PUTBITS( compressed2_norm, (best_pixel_indices1_MSB ), 8, 23);
  2040. PUTBITS( compressed2_norm, (best_pixel_indices2_MSB ), 8, 31);
  2041. PUTBITS( compressed2_norm, (best_pixel_indices1_LSB ), 8, 7);
  2042. PUTBITS( compressed2_norm, (best_pixel_indices2_LSB ), 8, 15);
  2043. // Now try flipped blocks 4x2:
  2044. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  2045. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty+2,avg_color_float2);
  2046. // First test if avg_color1 is similar enough to avg_color2 so that
  2047. // we can use differential coding of colors.
  2048. enc_color1[0] = int( JAS_ROUND(15.0*avg_color_float1[0]/255.0) );
  2049. enc_color1[1] = int( JAS_ROUND(15.0*avg_color_float1[1]/255.0) );
  2050. enc_color1[2] = int( JAS_ROUND(15.0*avg_color_float1[2]/255.0) );
  2051. enc_color2[0] = int( JAS_ROUND(15.0*avg_color_float2[0]/255.0) );
  2052. enc_color2[1] = int( JAS_ROUND(15.0*avg_color_float2[1]/255.0) );
  2053. enc_color2[2] = int( JAS_ROUND(15.0*avg_color_float2[2]/255.0) );
  2054. best_color_upper[0] = enc_color1[0];
  2055. best_color_upper[1] = enc_color1[1];
  2056. best_color_upper[2] = enc_color1[2];
  2057. best_color_lower[0] = enc_color2[0];
  2058. best_color_lower[1] = enc_color2[1];
  2059. best_color_lower[2] = enc_color2[2];
  2060. diffbit = 0;
  2061. avg_color_quant1[0] = enc_color1[0] << 4 | (enc_color1[0] );
  2062. avg_color_quant1[1] = enc_color1[1] << 4 | (enc_color1[1] );
  2063. avg_color_quant1[2] = enc_color1[2] << 4 | (enc_color1[2] );
  2064. avg_color_quant2[0] = enc_color2[0] << 4 | (enc_color2[0] );
  2065. avg_color_quant2[1] = enc_color2[1] << 4 | (enc_color2[1] );
  2066. avg_color_quant2[2] = enc_color2[2] << 4 | (enc_color2[2] );
  2067. // Pack bits into the first word.
  2068. compressed1_flip = 0;
  2069. PUTBITSHIGH( compressed1_flip, diffbit, 1, 33);
  2070. PUTBITSHIGH( compressed1_flip, enc_color1[0], 4, 63);
  2071. PUTBITSHIGH( compressed1_flip, enc_color1[1], 4, 55);
  2072. PUTBITSHIGH( compressed1_flip, enc_color1[2], 4, 47);
  2073. PUTBITSHIGH( compressed1_flip, enc_color2[0], 4, 49);
  2074. PUTBITSHIGH( compressed1_flip, enc_color2[1], 4, 51);
  2075. PUTBITSHIGH( compressed1_flip, enc_color2[2], 4, 43);
  2076. // upper part of block
  2077. best_err_upper = tryalltables_3bittable4x2percep1000(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  2078. flip_err = best_err_upper;
  2079. // lower part of block
  2080. best_err_lower = tryalltables_3bittable4x2percep1000(img,width,height,startx,starty+2,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  2081. flip_err += best_err_lower;
  2082. PUTBITSHIGH( compressed1_flip, best_table1, 3, 39);
  2083. PUTBITSHIGH( compressed1_flip, best_table2, 3, 36);
  2084. PUTBITSHIGH( compressed1_flip, 1, 1, 32);
  2085. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  2086. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  2087. compressed2_flip = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  2088. // Now lets see which is the best table to use. Only 8 tables are possible.
  2089. if(norm_err <= flip_err)
  2090. {
  2091. compressed1 = compressed1_norm | 0;
  2092. compressed2 = compressed2_norm;
  2093. best_err = norm_err;
  2094. best_flip = 0;
  2095. }
  2096. else
  2097. {
  2098. compressed1 = compressed1_flip | 1;
  2099. compressed2 = compressed2_flip;
  2100. best_err = flip_err;
  2101. best_enc_color1[0] = enc_color1[0];
  2102. best_enc_color1[1] = enc_color1[1];
  2103. best_enc_color1[2] = enc_color1[2];
  2104. best_enc_color2[0] = enc_color2[0];
  2105. best_enc_color2[1] = enc_color2[1];
  2106. best_enc_color2[2] = enc_color2[2];
  2107. best_flip = 1;
  2108. }
  2109. return best_err;
  2110. }
  2111. // Compresses the block using only the individual mode in ETC1/ETC2 using the average color as the base color.
  2112. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  2113. int compressBlockOnlyIndividualAverage(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2, int *best_enc_color1, int*best_enc_color2, int &best_flip, unsigned int &best_err_upper, unsigned int &best_err_lower, unsigned int &best_err_left, unsigned int &best_err_right, int *best_color_upper, int *best_color_lower, int *best_color_left, int *best_color_right)
  2114. {
  2115. unsigned int compressed1_norm, compressed2_norm;
  2116. unsigned int compressed1_flip, compressed2_flip;
  2117. uint8 avg_color_quant1[3], avg_color_quant2[3];
  2118. float avg_color_float1[3],avg_color_float2[3];
  2119. int enc_color1[3], enc_color2[3];
  2120. int min_error=255*255*8*3;
  2121. unsigned int best_table_indices1=0, best_table_indices2=0;
  2122. unsigned int best_table1=0, best_table2=0;
  2123. int diffbit;
  2124. int norm_err=0;
  2125. int flip_err=0;
  2126. int best_err;
  2127. // First try normal blocks 2x4:
  2128. computeAverageColor2x4noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  2129. computeAverageColor2x4noQuantFloat(img,width,height,startx+2,starty,avg_color_float2);
  2130. enc_color1[0] = int( JAS_ROUND(15.0*avg_color_float1[0]/255.0) );
  2131. enc_color1[1] = int( JAS_ROUND(15.0*avg_color_float1[1]/255.0) );
  2132. enc_color1[2] = int( JAS_ROUND(15.0*avg_color_float1[2]/255.0) );
  2133. enc_color2[0] = int( JAS_ROUND(15.0*avg_color_float2[0]/255.0) );
  2134. enc_color2[1] = int( JAS_ROUND(15.0*avg_color_float2[1]/255.0) );
  2135. enc_color2[2] = int( JAS_ROUND(15.0*avg_color_float2[2]/255.0) );
  2136. diffbit = 0;
  2137. avg_color_quant1[0] = enc_color1[0] << 4 | (enc_color1[0] );
  2138. avg_color_quant1[1] = enc_color1[1] << 4 | (enc_color1[1] );
  2139. avg_color_quant1[2] = enc_color1[2] << 4 | (enc_color1[2] );
  2140. avg_color_quant2[0] = enc_color2[0] << 4 | (enc_color2[0] );
  2141. avg_color_quant2[1] = enc_color2[1] << 4 | (enc_color2[1] );
  2142. avg_color_quant2[2] = enc_color2[2] << 4 | (enc_color2[2] );
  2143. // Pack bits into the first word.
  2144. // ETC1_RGB8_OES:
  2145. //
  2146. // a) bit layout in bits 63 through 32 if diffbit = 0
  2147. //
  2148. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  2149. // ---------------------------------------------------------------------------------------------------
  2150. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  2151. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  2152. // ---------------------------------------------------------------------------------------------------
  2153. //
  2154. // b) bit layout in bits 63 through 32 if diffbit = 1
  2155. //
  2156. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  2157. // ---------------------------------------------------------------------------------------------------
  2158. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |diff|flip|
  2159. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
  2160. // ---------------------------------------------------------------------------------------------------
  2161. //
  2162. // c) bit layout in bits 31 through 0 (in both cases)
  2163. //
  2164. // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  2165. // --------------------------------------------------------------------------------------------------
  2166. // | most significant pixel index bits | least significant pixel index bits |
  2167. // | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a| p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
  2168. // --------------------------------------------------------------------------------------------------
  2169. compressed1_norm = 0;
  2170. PUTBITSHIGH( compressed1_norm, diffbit, 1, 33);
  2171. PUTBITSHIGH( compressed1_norm, enc_color1[0], 4, 63);
  2172. PUTBITSHIGH( compressed1_norm, enc_color1[1], 4, 55);
  2173. PUTBITSHIGH( compressed1_norm, enc_color1[2], 4, 47);
  2174. PUTBITSHIGH( compressed1_norm, enc_color2[0], 4, 59);
  2175. PUTBITSHIGH( compressed1_norm, enc_color2[1], 4, 51);
  2176. PUTBITSHIGH( compressed1_norm, enc_color2[1], 4, 43);
  2177. unsigned int best_pixel_indices1_MSB;
  2178. unsigned int best_pixel_indices1_LSB;
  2179. unsigned int best_pixel_indices2_MSB;
  2180. unsigned int best_pixel_indices2_LSB;
  2181. best_enc_color1[0] = enc_color1[0];
  2182. best_enc_color1[1] = enc_color1[1];
  2183. best_enc_color1[2] = enc_color1[2];
  2184. best_enc_color2[0] = enc_color2[0];
  2185. best_enc_color2[1] = enc_color2[1];
  2186. best_enc_color2[2] = enc_color2[2];
  2187. best_color_left[0] = enc_color1[0];
  2188. best_color_left[1] = enc_color1[1];
  2189. best_color_left[2] = enc_color1[2];
  2190. best_color_right[0] = enc_color2[0];
  2191. best_color_right[1] = enc_color2[1];
  2192. best_color_right[2] = enc_color2[2];
  2193. norm_err = 0;
  2194. // left part of block
  2195. best_err_left = tryalltables_3bittable2x4(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  2196. norm_err = best_err_left;
  2197. // right part of block
  2198. best_err_right = tryalltables_3bittable2x4(img,width,height,startx+2,starty,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  2199. norm_err += best_err_right;
  2200. PUTBITSHIGH( compressed1_norm, best_table1, 3, 39);
  2201. PUTBITSHIGH( compressed1_norm, best_table2, 3, 36);
  2202. PUTBITSHIGH( compressed1_norm, 0, 1, 32);
  2203. compressed2_norm = 0;
  2204. PUTBITS( compressed2_norm, (best_pixel_indices1_MSB ), 8, 23);
  2205. PUTBITS( compressed2_norm, (best_pixel_indices2_MSB ), 8, 31);
  2206. PUTBITS( compressed2_norm, (best_pixel_indices1_LSB ), 8, 7);
  2207. PUTBITS( compressed2_norm, (best_pixel_indices2_LSB ), 8, 15);
  2208. // Now try flipped blocks 4x2:
  2209. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  2210. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty+2,avg_color_float2);
  2211. // First test if avg_color1 is similar enough to avg_color2 so that
  2212. // we can use differential coding of colors.
  2213. enc_color1[0] = int( JAS_ROUND(15.0*avg_color_float1[0]/255.0) );
  2214. enc_color1[1] = int( JAS_ROUND(15.0*avg_color_float1[1]/255.0) );
  2215. enc_color1[2] = int( JAS_ROUND(15.0*avg_color_float1[2]/255.0) );
  2216. enc_color2[0] = int( JAS_ROUND(15.0*avg_color_float2[0]/255.0) );
  2217. enc_color2[1] = int( JAS_ROUND(15.0*avg_color_float2[1]/255.0) );
  2218. enc_color2[2] = int( JAS_ROUND(15.0*avg_color_float2[2]/255.0) );
  2219. best_color_upper[0] = enc_color1[0];
  2220. best_color_upper[1] = enc_color1[1];
  2221. best_color_upper[2] = enc_color1[2];
  2222. best_color_lower[0] = enc_color2[0];
  2223. best_color_lower[1] = enc_color2[1];
  2224. best_color_lower[2] = enc_color2[2];
  2225. diffbit = 0;
  2226. avg_color_quant1[0] = enc_color1[0] << 4 | (enc_color1[0] );
  2227. avg_color_quant1[1] = enc_color1[1] << 4 | (enc_color1[1] );
  2228. avg_color_quant1[2] = enc_color1[2] << 4 | (enc_color1[2] );
  2229. avg_color_quant2[0] = enc_color2[0] << 4 | (enc_color2[0] );
  2230. avg_color_quant2[1] = enc_color2[1] << 4 | (enc_color2[1] );
  2231. avg_color_quant2[2] = enc_color2[2] << 4 | (enc_color2[2] );
  2232. // Pack bits into the first word.
  2233. compressed1_flip = 0;
  2234. PUTBITSHIGH( compressed1_flip, diffbit, 1, 33);
  2235. PUTBITSHIGH( compressed1_flip, enc_color1[0], 4, 63);
  2236. PUTBITSHIGH( compressed1_flip, enc_color1[1], 4, 55);
  2237. PUTBITSHIGH( compressed1_flip, enc_color1[2], 4, 47);
  2238. PUTBITSHIGH( compressed1_flip, enc_color2[0], 4, 49);
  2239. PUTBITSHIGH( compressed1_flip, enc_color2[1], 4, 51);
  2240. PUTBITSHIGH( compressed1_flip, enc_color2[2], 4, 43);
  2241. // upper part of block
  2242. best_err_upper = tryalltables_3bittable4x2(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  2243. flip_err = best_err_upper;
  2244. // lower part of block
  2245. best_err_lower = tryalltables_3bittable4x2(img,width,height,startx,starty+2,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  2246. flip_err += best_err_lower;
  2247. PUTBITSHIGH( compressed1_flip, best_table1, 3, 39);
  2248. PUTBITSHIGH( compressed1_flip, best_table2, 3, 36);
  2249. PUTBITSHIGH( compressed1_flip, 1, 1, 32);
  2250. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  2251. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  2252. compressed2_flip = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  2253. // Now lets see which is the best table to use. Only 8 tables are possible.
  2254. if(norm_err <= flip_err)
  2255. {
  2256. compressed1 = compressed1_norm | 0;
  2257. compressed2 = compressed2_norm;
  2258. best_err = norm_err;
  2259. best_flip = 0;
  2260. }
  2261. else
  2262. {
  2263. compressed1 = compressed1_flip | 1;
  2264. compressed2 = compressed2_flip;
  2265. best_err = flip_err;
  2266. best_enc_color1[0] = enc_color1[0];
  2267. best_enc_color1[1] = enc_color1[1];
  2268. best_enc_color1[2] = enc_color1[2];
  2269. best_enc_color2[0] = enc_color2[0];
  2270. best_enc_color2[1] = enc_color2[1];
  2271. best_enc_color2[2] = enc_color2[2];
  2272. best_flip = 1;
  2273. }
  2274. return best_err;
  2275. }
  2276. // Compresses the block using either the individual or differential mode in ETC1/ETC2
  2277. // Uses the average color as the base color in each half-block.
  2278. // Tries both flipped and unflipped.
  2279. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  2280. void compressBlockDiffFlipAverage(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  2281. {
  2282. unsigned int compressed1_norm, compressed2_norm;
  2283. unsigned int compressed1_flip, compressed2_flip;
  2284. uint8 avg_color_quant1[3], avg_color_quant2[3];
  2285. float avg_color_float1[3],avg_color_float2[3];
  2286. int enc_color1[3], enc_color2[3], diff[3];
  2287. int min_error=255*255*8*3;
  2288. unsigned int best_table_indices1=0, best_table_indices2=0;
  2289. unsigned int best_table1=0, best_table2=0;
  2290. int diffbit;
  2291. int norm_err=0;
  2292. int flip_err=0;
  2293. // First try normal blocks 2x4:
  2294. computeAverageColor2x4noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  2295. computeAverageColor2x4noQuantFloat(img,width,height,startx+2,starty,avg_color_float2);
  2296. // First test if avg_color1 is similar enough to avg_color2 so that
  2297. // we can use differential coding of colors.
  2298. float eps;
  2299. enc_color1[0] = int( JAS_ROUND(31.0*avg_color_float1[0]/255.0) );
  2300. enc_color1[1] = int( JAS_ROUND(31.0*avg_color_float1[1]/255.0) );
  2301. enc_color1[2] = int( JAS_ROUND(31.0*avg_color_float1[2]/255.0) );
  2302. enc_color2[0] = int( JAS_ROUND(31.0*avg_color_float2[0]/255.0) );
  2303. enc_color2[1] = int( JAS_ROUND(31.0*avg_color_float2[1]/255.0) );
  2304. enc_color2[2] = int( JAS_ROUND(31.0*avg_color_float2[2]/255.0) );
  2305. diff[0] = enc_color2[0]-enc_color1[0];
  2306. diff[1] = enc_color2[1]-enc_color1[1];
  2307. diff[2] = enc_color2[2]-enc_color1[2];
  2308. if( (diff[0] >= -4) && (diff[0] <= 3) && (diff[1] >= -4) && (diff[1] <= 3) && (diff[2] >= -4) && (diff[2] <= 3) )
  2309. {
  2310. diffbit = 1;
  2311. // The difference to be coded:
  2312. diff[0] = enc_color2[0]-enc_color1[0];
  2313. diff[1] = enc_color2[1]-enc_color1[1];
  2314. diff[2] = enc_color2[2]-enc_color1[2];
  2315. avg_color_quant1[0] = enc_color1[0] << 3 | (enc_color1[0] >> 2);
  2316. avg_color_quant1[1] = enc_color1[1] << 3 | (enc_color1[1] >> 2);
  2317. avg_color_quant1[2] = enc_color1[2] << 3 | (enc_color1[2] >> 2);
  2318. avg_color_quant2[0] = enc_color2[0] << 3 | (enc_color2[0] >> 2);
  2319. avg_color_quant2[1] = enc_color2[1] << 3 | (enc_color2[1] >> 2);
  2320. avg_color_quant2[2] = enc_color2[2] << 3 | (enc_color2[2] >> 2);
  2321. // Pack bits into the first word.
  2322. // ETC1_RGB8_OES:
  2323. //
  2324. // a) bit layout in bits 63 through 32 if diffbit = 0
  2325. //
  2326. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  2327. // ---------------------------------------------------------------------------------------------------
  2328. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  2329. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  2330. // ---------------------------------------------------------------------------------------------------
  2331. //
  2332. // b) bit layout in bits 63 through 32 if diffbit = 1
  2333. //
  2334. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  2335. // ---------------------------------------------------------------------------------------------------
  2336. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |diff|flip|
  2337. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
  2338. // ---------------------------------------------------------------------------------------------------
  2339. //
  2340. // c) bit layout in bits 31 through 0 (in both cases)
  2341. //
  2342. // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  2343. // --------------------------------------------------------------------------------------------------
  2344. // | most significant pixel index bits | least significant pixel index bits |
  2345. // | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a| p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
  2346. // --------------------------------------------------------------------------------------------------
  2347. compressed1_norm = 0;
  2348. PUTBITSHIGH( compressed1_norm, diffbit, 1, 33);
  2349. PUTBITSHIGH( compressed1_norm, enc_color1[0], 5, 63);
  2350. PUTBITSHIGH( compressed1_norm, enc_color1[1], 5, 55);
  2351. PUTBITSHIGH( compressed1_norm, enc_color1[2], 5, 47);
  2352. PUTBITSHIGH( compressed1_norm, diff[0], 3, 58);
  2353. PUTBITSHIGH( compressed1_norm, diff[1], 3, 50);
  2354. PUTBITSHIGH( compressed1_norm, diff[2], 3, 42);
  2355. unsigned int best_pixel_indices1_MSB;
  2356. unsigned int best_pixel_indices1_LSB;
  2357. unsigned int best_pixel_indices2_MSB;
  2358. unsigned int best_pixel_indices2_LSB;
  2359. norm_err = 0;
  2360. // left part of block
  2361. norm_err = tryalltables_3bittable2x4(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  2362. // right part of block
  2363. norm_err += tryalltables_3bittable2x4(img,width,height,startx+2,starty,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  2364. PUTBITSHIGH( compressed1_norm, best_table1, 3, 39);
  2365. PUTBITSHIGH( compressed1_norm, best_table2, 3, 36);
  2366. PUTBITSHIGH( compressed1_norm, 0, 1, 32);
  2367. compressed2_norm = 0;
  2368. PUTBITS( compressed2_norm, (best_pixel_indices1_MSB ), 8, 23);
  2369. PUTBITS( compressed2_norm, (best_pixel_indices2_MSB ), 8, 31);
  2370. PUTBITS( compressed2_norm, (best_pixel_indices1_LSB ), 8, 7);
  2371. PUTBITS( compressed2_norm, (best_pixel_indices2_LSB ), 8, 15);
  2372. }
  2373. else
  2374. {
  2375. diffbit = 0;
  2376. // The difference is bigger than what fits in 555 plus delta-333, so we will have
  2377. // to deal with 444 444.
  2378. eps = (float) 0.0001;
  2379. enc_color1[0] = int( ((float) avg_color_float1[0] / (17.0)) +0.5 + eps);
  2380. enc_color1[1] = int( ((float) avg_color_float1[1] / (17.0)) +0.5 + eps);
  2381. enc_color1[2] = int( ((float) avg_color_float1[2] / (17.0)) +0.5 + eps);
  2382. enc_color2[0] = int( ((float) avg_color_float2[0] / (17.0)) +0.5 + eps);
  2383. enc_color2[1] = int( ((float) avg_color_float2[1] / (17.0)) +0.5 + eps);
  2384. enc_color2[2] = int( ((float) avg_color_float2[2] / (17.0)) +0.5 + eps);
  2385. avg_color_quant1[0] = enc_color1[0] << 4 | enc_color1[0];
  2386. avg_color_quant1[1] = enc_color1[1] << 4 | enc_color1[1];
  2387. avg_color_quant1[2] = enc_color1[2] << 4 | enc_color1[2];
  2388. avg_color_quant2[0] = enc_color2[0] << 4 | enc_color2[0];
  2389. avg_color_quant2[1] = enc_color2[1] << 4 | enc_color2[1];
  2390. avg_color_quant2[2] = enc_color2[2] << 4 | enc_color2[2];
  2391. // Pack bits into the first word.
  2392. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  2393. // ---------------------------------------------------------------------------------------------------
  2394. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  2395. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  2396. // ---------------------------------------------------------------------------------------------------
  2397. compressed1_norm = 0;
  2398. PUTBITSHIGH( compressed1_norm, diffbit, 1, 33);
  2399. PUTBITSHIGH( compressed1_norm, enc_color1[0], 4, 63);
  2400. PUTBITSHIGH( compressed1_norm, enc_color1[1], 4, 55);
  2401. PUTBITSHIGH( compressed1_norm, enc_color1[2], 4, 47);
  2402. PUTBITSHIGH( compressed1_norm, enc_color2[0], 4, 59);
  2403. PUTBITSHIGH( compressed1_norm, enc_color2[1], 4, 51);
  2404. PUTBITSHIGH( compressed1_norm, enc_color2[2], 4, 43);
  2405. unsigned int best_pixel_indices1_MSB;
  2406. unsigned int best_pixel_indices1_LSB;
  2407. unsigned int best_pixel_indices2_MSB;
  2408. unsigned int best_pixel_indices2_LSB;
  2409. // left part of block
  2410. norm_err = tryalltables_3bittable2x4(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  2411. // right part of block
  2412. norm_err += tryalltables_3bittable2x4(img,width,height,startx+2,starty,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  2413. PUTBITSHIGH( compressed1_norm, best_table1, 3, 39);
  2414. PUTBITSHIGH( compressed1_norm, best_table2, 3, 36);
  2415. PUTBITSHIGH( compressed1_norm, 0, 1, 32);
  2416. compressed2_norm = 0;
  2417. PUTBITS( compressed2_norm, (best_pixel_indices1_MSB ), 8, 23);
  2418. PUTBITS( compressed2_norm, (best_pixel_indices2_MSB ), 8, 31);
  2419. PUTBITS( compressed2_norm, (best_pixel_indices1_LSB ), 8, 7);
  2420. PUTBITS( compressed2_norm, (best_pixel_indices2_LSB ), 8, 15);
  2421. }
  2422. // Now try flipped blocks 4x2:
  2423. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  2424. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty+2,avg_color_float2);
  2425. // First test if avg_color1 is similar enough to avg_color2 so that
  2426. // we can use differential coding of colors.
  2427. enc_color1[0] = int( JAS_ROUND(31.0*avg_color_float1[0]/255.0) );
  2428. enc_color1[1] = int( JAS_ROUND(31.0*avg_color_float1[1]/255.0) );
  2429. enc_color1[2] = int( JAS_ROUND(31.0*avg_color_float1[2]/255.0) );
  2430. enc_color2[0] = int( JAS_ROUND(31.0*avg_color_float2[0]/255.0) );
  2431. enc_color2[1] = int( JAS_ROUND(31.0*avg_color_float2[1]/255.0) );
  2432. enc_color2[2] = int( JAS_ROUND(31.0*avg_color_float2[2]/255.0) );
  2433. diff[0] = enc_color2[0]-enc_color1[0];
  2434. diff[1] = enc_color2[1]-enc_color1[1];
  2435. diff[2] = enc_color2[2]-enc_color1[2];
  2436. if( (diff[0] >= -4) && (diff[0] <= 3) && (diff[1] >= -4) && (diff[1] <= 3) && (diff[2] >= -4) && (diff[2] <= 3) )
  2437. {
  2438. diffbit = 1;
  2439. // The difference to be coded:
  2440. diff[0] = enc_color2[0]-enc_color1[0];
  2441. diff[1] = enc_color2[1]-enc_color1[1];
  2442. diff[2] = enc_color2[2]-enc_color1[2];
  2443. avg_color_quant1[0] = enc_color1[0] << 3 | (enc_color1[0] >> 2);
  2444. avg_color_quant1[1] = enc_color1[1] << 3 | (enc_color1[1] >> 2);
  2445. avg_color_quant1[2] = enc_color1[2] << 3 | (enc_color1[2] >> 2);
  2446. avg_color_quant2[0] = enc_color2[0] << 3 | (enc_color2[0] >> 2);
  2447. avg_color_quant2[1] = enc_color2[1] << 3 | (enc_color2[1] >> 2);
  2448. avg_color_quant2[2] = enc_color2[2] << 3 | (enc_color2[2] >> 2);
  2449. // Pack bits into the first word.
  2450. compressed1_flip = 0;
  2451. PUTBITSHIGH( compressed1_flip, diffbit, 1, 33);
  2452. PUTBITSHIGH( compressed1_flip, enc_color1[0], 5, 63);
  2453. PUTBITSHIGH( compressed1_flip, enc_color1[1], 5, 55);
  2454. PUTBITSHIGH( compressed1_flip, enc_color1[2], 5, 47);
  2455. PUTBITSHIGH( compressed1_flip, diff[0], 3, 58);
  2456. PUTBITSHIGH( compressed1_flip, diff[1], 3, 50);
  2457. PUTBITSHIGH( compressed1_flip, diff[2], 3, 42);
  2458. unsigned int best_pixel_indices1_MSB;
  2459. unsigned int best_pixel_indices1_LSB;
  2460. unsigned int best_pixel_indices2_MSB;
  2461. unsigned int best_pixel_indices2_LSB;
  2462. // upper part of block
  2463. flip_err = tryalltables_3bittable4x2(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  2464. // lower part of block
  2465. flip_err += tryalltables_3bittable4x2(img,width,height,startx,starty+2,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  2466. PUTBITSHIGH( compressed1_flip, best_table1, 3, 39);
  2467. PUTBITSHIGH( compressed1_flip, best_table2, 3, 36);
  2468. PUTBITSHIGH( compressed1_flip, 1, 1, 32);
  2469. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  2470. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  2471. compressed2_flip = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  2472. }
  2473. else
  2474. {
  2475. diffbit = 0;
  2476. // The difference is bigger than what fits in 555 plus delta-333, so we will have
  2477. // to deal with 444 444.
  2478. eps = (float) 0.0001;
  2479. enc_color1[0] = int( ((float) avg_color_float1[0] / (17.0)) +0.5 + eps);
  2480. enc_color1[1] = int( ((float) avg_color_float1[1] / (17.0)) +0.5 + eps);
  2481. enc_color1[2] = int( ((float) avg_color_float1[2] / (17.0)) +0.5 + eps);
  2482. enc_color2[0] = int( ((float) avg_color_float2[0] / (17.0)) +0.5 + eps);
  2483. enc_color2[1] = int( ((float) avg_color_float2[1] / (17.0)) +0.5 + eps);
  2484. enc_color2[2] = int( ((float) avg_color_float2[2] / (17.0)) +0.5 + eps);
  2485. avg_color_quant1[0] = enc_color1[0] << 4 | enc_color1[0];
  2486. avg_color_quant1[1] = enc_color1[1] << 4 | enc_color1[1];
  2487. avg_color_quant1[2] = enc_color1[2] << 4 | enc_color1[2];
  2488. avg_color_quant2[0] = enc_color2[0] << 4 | enc_color2[0];
  2489. avg_color_quant2[1] = enc_color2[1] << 4 | enc_color2[1];
  2490. avg_color_quant2[2] = enc_color2[2] << 4 | enc_color2[2];
  2491. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  2492. // ---------------------------------------------------------------------------------------------------
  2493. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  2494. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  2495. // ---------------------------------------------------------------------------------------------------
  2496. // Pack bits into the first word.
  2497. compressed1_flip = 0;
  2498. PUTBITSHIGH( compressed1_flip, diffbit, 1, 33);
  2499. PUTBITSHIGH( compressed1_flip, enc_color1[0], 4, 63);
  2500. PUTBITSHIGH( compressed1_flip, enc_color1[1], 4, 55);
  2501. PUTBITSHIGH( compressed1_flip, enc_color1[2], 4, 47);
  2502. PUTBITSHIGH( compressed1_flip, enc_color2[0], 4, 59);
  2503. PUTBITSHIGH( compressed1_flip, enc_color2[1], 4, 51);
  2504. PUTBITSHIGH( compressed1_flip, enc_color2[2], 4, 43);
  2505. unsigned int best_pixel_indices1_MSB;
  2506. unsigned int best_pixel_indices1_LSB;
  2507. unsigned int best_pixel_indices2_MSB;
  2508. unsigned int best_pixel_indices2_LSB;
  2509. // upper part of block
  2510. flip_err = tryalltables_3bittable4x2(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  2511. // lower part of block
  2512. flip_err += tryalltables_3bittable4x2(img,width,height,startx,starty+2,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  2513. PUTBITSHIGH( compressed1_flip, best_table1, 3, 39);
  2514. PUTBITSHIGH( compressed1_flip, best_table2, 3, 36);
  2515. PUTBITSHIGH( compressed1_flip, 1, 1, 32);
  2516. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  2517. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  2518. compressed2_flip = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  2519. }
  2520. // Now lets see which is the best table to use. Only 8 tables are possible.
  2521. if(norm_err <= flip_err)
  2522. {
  2523. compressed1 = compressed1_norm | 0;
  2524. compressed2 = compressed2_norm;
  2525. }
  2526. else
  2527. {
  2528. compressed1 = compressed1_flip | 1;
  2529. compressed2 = compressed2_flip;
  2530. }
  2531. }
  2532. // Compresses the block using only the differential mode in ETC1/ETC2
  2533. // Uses the average color as the base color in each half-block.
  2534. // If average colors are too different, use the average color of the entire block in both half-blocks.
  2535. // Tries both flipped and unflipped.
  2536. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  2537. int compressBlockOnlyDiffFlipAverage(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2, int *best_enc_color1, int*best_enc_color2, int &best_flip)
  2538. {
  2539. unsigned int compressed1_norm, compressed2_norm;
  2540. unsigned int compressed1_flip, compressed2_flip;
  2541. uint8 avg_color_quant1[3], avg_color_quant2[3];
  2542. float avg_color_float1[3],avg_color_float2[3];
  2543. int enc_color1[3], enc_color2[3], diff[3];
  2544. int min_error=255*255*8*3;
  2545. unsigned int best_table_indices1=0, best_table_indices2=0;
  2546. unsigned int best_table1=0, best_table2=0;
  2547. int diffbit;
  2548. int norm_err=0;
  2549. int flip_err=0;
  2550. int best_err;
  2551. // First try normal blocks 2x4:
  2552. computeAverageColor2x4noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  2553. computeAverageColor2x4noQuantFloat(img,width,height,startx+2,starty,avg_color_float2);
  2554. // First test if avg_color1 is similar enough to avg_color2 so that
  2555. // we can use differential coding of colors.
  2556. enc_color1[0] = int( JAS_ROUND(31.0*avg_color_float1[0]/255.0) );
  2557. enc_color1[1] = int( JAS_ROUND(31.0*avg_color_float1[1]/255.0) );
  2558. enc_color1[2] = int( JAS_ROUND(31.0*avg_color_float1[2]/255.0) );
  2559. enc_color2[0] = int( JAS_ROUND(31.0*avg_color_float2[0]/255.0) );
  2560. enc_color2[1] = int( JAS_ROUND(31.0*avg_color_float2[1]/255.0) );
  2561. enc_color2[2] = int( JAS_ROUND(31.0*avg_color_float2[2]/255.0) );
  2562. diff[0] = enc_color2[0]-enc_color1[0];
  2563. diff[1] = enc_color2[1]-enc_color1[1];
  2564. diff[2] = enc_color2[2]-enc_color1[2];
  2565. if( !((diff[0] >= -4) && (diff[0] <= 3) && (diff[1] >= -4) && (diff[1] <= 3) && (diff[2] >= -4) && (diff[2] <= 3)) )
  2566. {
  2567. // The colors are too different. Use the same color in both blocks.
  2568. enc_color1[0] = int( JAS_ROUND(31.0*((avg_color_float1[0]+avg_color_float2[0])/2.0)/255.0) );
  2569. enc_color1[1] = int( JAS_ROUND(31.0*((avg_color_float1[1]+avg_color_float2[1])/2.0)/255.0) );
  2570. enc_color1[2] = int( JAS_ROUND(31.0*((avg_color_float1[2]+avg_color_float2[2])/2.0)/255.0) );
  2571. enc_color2[0] = enc_color1[0];
  2572. enc_color2[1] = enc_color1[1];
  2573. enc_color2[2] = enc_color1[2];
  2574. diff[0] = enc_color2[0]-enc_color1[0];
  2575. diff[1] = enc_color2[1]-enc_color1[1];
  2576. diff[2] = enc_color2[2]-enc_color1[2];
  2577. }
  2578. diffbit = 1;
  2579. // The difference to be coded:
  2580. diff[0] = enc_color2[0]-enc_color1[0];
  2581. diff[1] = enc_color2[1]-enc_color1[1];
  2582. diff[2] = enc_color2[2]-enc_color1[2];
  2583. avg_color_quant1[0] = enc_color1[0] << 3 | (enc_color1[0] >> 2);
  2584. avg_color_quant1[1] = enc_color1[1] << 3 | (enc_color1[1] >> 2);
  2585. avg_color_quant1[2] = enc_color1[2] << 3 | (enc_color1[2] >> 2);
  2586. avg_color_quant2[0] = enc_color2[0] << 3 | (enc_color2[0] >> 2);
  2587. avg_color_quant2[1] = enc_color2[1] << 3 | (enc_color2[1] >> 2);
  2588. avg_color_quant2[2] = enc_color2[2] << 3 | (enc_color2[2] >> 2);
  2589. // Pack bits into the first word.
  2590. // ETC1_RGB8_OES:
  2591. //
  2592. // a) bit layout in bits 63 through 32 if diffbit = 0
  2593. //
  2594. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  2595. // ---------------------------------------------------------------------------------------------------
  2596. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  2597. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  2598. // ---------------------------------------------------------------------------------------------------
  2599. //
  2600. // b) bit layout in bits 63 through 32 if diffbit = 1
  2601. //
  2602. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  2603. // ---------------------------------------------------------------------------------------------------
  2604. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |diff|flip|
  2605. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
  2606. // ---------------------------------------------------------------------------------------------------
  2607. //
  2608. // c) bit layout in bits 31 through 0 (in both cases)
  2609. //
  2610. // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  2611. // --------------------------------------------------------------------------------------------------
  2612. // | most significant pixel index bits | least significant pixel index bits |
  2613. // | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a| p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
  2614. // --------------------------------------------------------------------------------------------------
  2615. compressed1_norm = 0;
  2616. PUTBITSHIGH( compressed1_norm, diffbit, 1, 33);
  2617. PUTBITSHIGH( compressed1_norm, enc_color1[0], 5, 63);
  2618. PUTBITSHIGH( compressed1_norm, enc_color1[1], 5, 55);
  2619. PUTBITSHIGH( compressed1_norm, enc_color1[2], 5, 47);
  2620. PUTBITSHIGH( compressed1_norm, diff[0], 3, 58);
  2621. PUTBITSHIGH( compressed1_norm, diff[1], 3, 50);
  2622. PUTBITSHIGH( compressed1_norm, diff[2], 3, 42);
  2623. unsigned int best_pixel_indices1_MSB;
  2624. unsigned int best_pixel_indices1_LSB;
  2625. unsigned int best_pixel_indices2_MSB;
  2626. unsigned int best_pixel_indices2_LSB;
  2627. best_enc_color1[0] = enc_color1[0];
  2628. best_enc_color1[1] = enc_color1[1];
  2629. best_enc_color1[2] = enc_color1[2];
  2630. best_enc_color2[0] = enc_color2[0];
  2631. best_enc_color2[1] = enc_color2[1];
  2632. best_enc_color2[2] = enc_color2[2];
  2633. norm_err = 0;
  2634. // left part of block
  2635. norm_err = tryalltables_3bittable2x4(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  2636. // right part of block
  2637. norm_err += tryalltables_3bittable2x4(img,width,height,startx+2,starty,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  2638. PUTBITSHIGH( compressed1_norm, best_table1, 3, 39);
  2639. PUTBITSHIGH( compressed1_norm, best_table2, 3, 36);
  2640. PUTBITSHIGH( compressed1_norm, 0, 1, 32);
  2641. compressed2_norm = 0;
  2642. PUTBITS( compressed2_norm, (best_pixel_indices1_MSB ), 8, 23);
  2643. PUTBITS( compressed2_norm, (best_pixel_indices2_MSB ), 8, 31);
  2644. PUTBITS( compressed2_norm, (best_pixel_indices1_LSB ), 8, 7);
  2645. PUTBITS( compressed2_norm, (best_pixel_indices2_LSB ), 8, 15);
  2646. // Now try flipped blocks 4x2:
  2647. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  2648. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty+2,avg_color_float2);
  2649. // First test if avg_color1 is similar enough to avg_color2 so that
  2650. // we can use differential coding of colors.
  2651. enc_color1[0] = int( JAS_ROUND(31.0*avg_color_float1[0]/255.0) );
  2652. enc_color1[1] = int( JAS_ROUND(31.0*avg_color_float1[1]/255.0) );
  2653. enc_color1[2] = int( JAS_ROUND(31.0*avg_color_float1[2]/255.0) );
  2654. enc_color2[0] = int( JAS_ROUND(31.0*avg_color_float2[0]/255.0) );
  2655. enc_color2[1] = int( JAS_ROUND(31.0*avg_color_float2[1]/255.0) );
  2656. enc_color2[2] = int( JAS_ROUND(31.0*avg_color_float2[2]/255.0) );
  2657. diff[0] = enc_color2[0]-enc_color1[0];
  2658. diff[1] = enc_color2[1]-enc_color1[1];
  2659. diff[2] = enc_color2[2]-enc_color1[2];
  2660. if( !((diff[0] >= -4) && (diff[0] <= 3) && (diff[1] >= -4) && (diff[1] <= 3) && (diff[2] >= -4) && (diff[2] <= 3)) )
  2661. {
  2662. // The colors are too different. Use the same color in both blocks.
  2663. enc_color1[0] = int( JAS_ROUND(31.0*((avg_color_float1[0]+avg_color_float2[0])/2.0)/255.0) );
  2664. enc_color1[1] = int( JAS_ROUND(31.0*((avg_color_float1[1]+avg_color_float2[1])/2.0)/255.0) );
  2665. enc_color1[2] = int( JAS_ROUND(31.0*((avg_color_float1[2]+avg_color_float2[2])/2.0)/255.0) );
  2666. enc_color2[0] = enc_color1[0];
  2667. enc_color2[1] = enc_color1[1];
  2668. enc_color2[2] = enc_color1[2];
  2669. diff[0] = enc_color2[0]-enc_color1[0];
  2670. diff[1] = enc_color2[1]-enc_color1[1];
  2671. diff[2] = enc_color2[2]-enc_color1[2];
  2672. }
  2673. diffbit = 1;
  2674. // The difference to be coded:
  2675. diff[0] = enc_color2[0]-enc_color1[0];
  2676. diff[1] = enc_color2[1]-enc_color1[1];
  2677. diff[2] = enc_color2[2]-enc_color1[2];
  2678. avg_color_quant1[0] = enc_color1[0] << 3 | (enc_color1[0] >> 2);
  2679. avg_color_quant1[1] = enc_color1[1] << 3 | (enc_color1[1] >> 2);
  2680. avg_color_quant1[2] = enc_color1[2] << 3 | (enc_color1[2] >> 2);
  2681. avg_color_quant2[0] = enc_color2[0] << 3 | (enc_color2[0] >> 2);
  2682. avg_color_quant2[1] = enc_color2[1] << 3 | (enc_color2[1] >> 2);
  2683. avg_color_quant2[2] = enc_color2[2] << 3 | (enc_color2[2] >> 2);
  2684. // Pack bits into the first word.
  2685. compressed1_flip = 0;
  2686. PUTBITSHIGH( compressed1_flip, diffbit, 1, 33);
  2687. PUTBITSHIGH( compressed1_flip, enc_color1[0], 5, 63);
  2688. PUTBITSHIGH( compressed1_flip, enc_color1[1], 5, 55);
  2689. PUTBITSHIGH( compressed1_flip, enc_color1[2], 5, 47);
  2690. PUTBITSHIGH( compressed1_flip, diff[0], 3, 58);
  2691. PUTBITSHIGH( compressed1_flip, diff[1], 3, 50);
  2692. PUTBITSHIGH( compressed1_flip, diff[2], 3, 42);
  2693. // upper part of block
  2694. flip_err = tryalltables_3bittable4x2(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  2695. // lower part of block
  2696. flip_err += tryalltables_3bittable4x2(img,width,height,startx,starty+2,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  2697. PUTBITSHIGH( compressed1_flip, best_table1, 3, 39);
  2698. PUTBITSHIGH( compressed1_flip, best_table2, 3, 36);
  2699. PUTBITSHIGH( compressed1_flip, 1, 1, 32);
  2700. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  2701. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  2702. compressed2_flip = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  2703. // Now lets see which is the best table to use. Only 8 tables are possible.
  2704. if(norm_err <= flip_err)
  2705. {
  2706. compressed1 = compressed1_norm | 0;
  2707. compressed2 = compressed2_norm;
  2708. best_err = norm_err;
  2709. best_flip = 0;
  2710. }
  2711. else
  2712. {
  2713. compressed1 = compressed1_flip | 1;
  2714. compressed2 = compressed2_flip;
  2715. best_err = flip_err;
  2716. best_enc_color1[0] = enc_color1[0];
  2717. best_enc_color1[1] = enc_color1[1];
  2718. best_enc_color1[2] = enc_color1[2];
  2719. best_enc_color2[0] = enc_color2[0];
  2720. best_enc_color2[1] = enc_color2[1];
  2721. best_enc_color2[2] = enc_color2[2];
  2722. best_flip = 1;
  2723. }
  2724. return best_err;
  2725. }
  2726. // Compresses the block using only the differential mode in ETC1/ETC2
  2727. // Uses the average color as the base color in each half-block.
  2728. // If average colors are too different, use the average color of the entire block in both half-blocks.
  2729. // Tries both flipped and unflipped.
  2730. // Uses fixed point arithmetics where 1000 represents 1.0.
  2731. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  2732. unsigned int compressBlockOnlyDiffFlipAveragePerceptual1000(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  2733. {
  2734. unsigned int compressed1_norm, compressed2_norm;
  2735. unsigned int compressed1_flip, compressed2_flip;
  2736. uint8 avg_color_quant1[3], avg_color_quant2[3];
  2737. float avg_color_float1[3],avg_color_float2[3];
  2738. int enc_color1[3], enc_color2[3], diff[3];
  2739. unsigned int min_error=MAXERR1000;
  2740. unsigned int best_table_indices1=0, best_table_indices2=0;
  2741. unsigned int best_table1=0, best_table2=0;
  2742. int diffbit;
  2743. int norm_err=0;
  2744. int flip_err=0;
  2745. // First try normal blocks 2x4:
  2746. computeAverageColor2x4noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  2747. computeAverageColor2x4noQuantFloat(img,width,height,startx+2,starty,avg_color_float2);
  2748. // First test if avg_color1 is similar enough to avg_color2 so that
  2749. // we can use differential coding of colors.
  2750. enc_color1[0] = int( JAS_ROUND(31.0*avg_color_float1[0]/255.0) );
  2751. enc_color1[1] = int( JAS_ROUND(31.0*avg_color_float1[1]/255.0) );
  2752. enc_color1[2] = int( JAS_ROUND(31.0*avg_color_float1[2]/255.0) );
  2753. enc_color2[0] = int( JAS_ROUND(31.0*avg_color_float2[0]/255.0) );
  2754. enc_color2[1] = int( JAS_ROUND(31.0*avg_color_float2[1]/255.0) );
  2755. enc_color2[2] = int( JAS_ROUND(31.0*avg_color_float2[2]/255.0) );
  2756. diff[0] = enc_color2[0]-enc_color1[0];
  2757. diff[1] = enc_color2[1]-enc_color1[1];
  2758. diff[2] = enc_color2[2]-enc_color1[2];
  2759. if( !((diff[0] >= -4) && (diff[0] <= 3) && (diff[1] >= -4) && (diff[1] <= 3) && (diff[2] >= -4) && (diff[2] <= 3)) )
  2760. {
  2761. enc_color1[0] = (enc_color1[0] + enc_color2[0]) >> 1;
  2762. enc_color1[1] = (enc_color1[1] + enc_color2[1]) >> 1;
  2763. enc_color1[2] = (enc_color1[2] + enc_color2[2]) >> 1;
  2764. enc_color2[0] = enc_color1[0];
  2765. enc_color2[1] = enc_color1[1];
  2766. enc_color2[2] = enc_color1[2];
  2767. }
  2768. {
  2769. diffbit = 1;
  2770. // The difference to be coded:
  2771. diff[0] = enc_color2[0]-enc_color1[0];
  2772. diff[1] = enc_color2[1]-enc_color1[1];
  2773. diff[2] = enc_color2[2]-enc_color1[2];
  2774. avg_color_quant1[0] = enc_color1[0] << 3 | (enc_color1[0] >> 2);
  2775. avg_color_quant1[1] = enc_color1[1] << 3 | (enc_color1[1] >> 2);
  2776. avg_color_quant1[2] = enc_color1[2] << 3 | (enc_color1[2] >> 2);
  2777. avg_color_quant2[0] = enc_color2[0] << 3 | (enc_color2[0] >> 2);
  2778. avg_color_quant2[1] = enc_color2[1] << 3 | (enc_color2[1] >> 2);
  2779. avg_color_quant2[2] = enc_color2[2] << 3 | (enc_color2[2] >> 2);
  2780. // Pack bits into the first word.
  2781. // ETC1_RGB8_OES:
  2782. //
  2783. // a) bit layout in bits 63 through 32 if diffbit = 0
  2784. //
  2785. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  2786. // ---------------------------------------------------------------------------------------------------
  2787. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  2788. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  2789. // ---------------------------------------------------------------------------------------------------
  2790. //
  2791. // b) bit layout in bits 63 through 32 if diffbit = 1
  2792. //
  2793. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  2794. // ---------------------------------------------------------------------------------------------------
  2795. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |diff|flip|
  2796. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
  2797. // ---------------------------------------------------------------------------------------------------
  2798. //
  2799. // c) bit layout in bits 31 through 0 (in both cases)
  2800. //
  2801. // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  2802. // --------------------------------------------------------------------------------------------------
  2803. // | most significant pixel index bits | least significant pixel index bits |
  2804. // | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a| p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
  2805. // --------------------------------------------------------------------------------------------------
  2806. compressed1_norm = 0;
  2807. PUTBITSHIGH( compressed1_norm, diffbit, 1, 33);
  2808. PUTBITSHIGH( compressed1_norm, enc_color1[0], 5, 63);
  2809. PUTBITSHIGH( compressed1_norm, enc_color1[1], 5, 55);
  2810. PUTBITSHIGH( compressed1_norm, enc_color1[2], 5, 47);
  2811. PUTBITSHIGH( compressed1_norm, diff[0], 3, 58);
  2812. PUTBITSHIGH( compressed1_norm, diff[1], 3, 50);
  2813. PUTBITSHIGH( compressed1_norm, diff[2], 3, 42);
  2814. unsigned int best_pixel_indices1_MSB;
  2815. unsigned int best_pixel_indices1_LSB;
  2816. unsigned int best_pixel_indices2_MSB;
  2817. unsigned int best_pixel_indices2_LSB;
  2818. norm_err = 0;
  2819. // left part of block
  2820. norm_err = tryalltables_3bittable2x4percep1000(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  2821. // right part of block
  2822. norm_err += tryalltables_3bittable2x4percep1000(img,width,height,startx+2,starty,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  2823. PUTBITSHIGH( compressed1_norm, best_table1, 3, 39);
  2824. PUTBITSHIGH( compressed1_norm, best_table2, 3, 36);
  2825. PUTBITSHIGH( compressed1_norm, 0, 1, 32);
  2826. compressed2_norm = 0;
  2827. PUTBITS( compressed2_norm, (best_pixel_indices1_MSB ), 8, 23);
  2828. PUTBITS( compressed2_norm, (best_pixel_indices2_MSB ), 8, 31);
  2829. PUTBITS( compressed2_norm, (best_pixel_indices1_LSB ), 8, 7);
  2830. PUTBITS( compressed2_norm, (best_pixel_indices2_LSB ), 8, 15);
  2831. }
  2832. // Now try flipped blocks 4x2:
  2833. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  2834. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty+2,avg_color_float2);
  2835. // First test if avg_color1 is similar enough to avg_color2 so that
  2836. // we can use differential coding of colors.
  2837. enc_color1[0] = int( JAS_ROUND(31.0*avg_color_float1[0]/255.0) );
  2838. enc_color1[1] = int( JAS_ROUND(31.0*avg_color_float1[1]/255.0) );
  2839. enc_color1[2] = int( JAS_ROUND(31.0*avg_color_float1[2]/255.0) );
  2840. enc_color2[0] = int( JAS_ROUND(31.0*avg_color_float2[0]/255.0) );
  2841. enc_color2[1] = int( JAS_ROUND(31.0*avg_color_float2[1]/255.0) );
  2842. enc_color2[2] = int( JAS_ROUND(31.0*avg_color_float2[2]/255.0) );
  2843. diff[0] = enc_color2[0]-enc_color1[0];
  2844. diff[1] = enc_color2[1]-enc_color1[1];
  2845. diff[2] = enc_color2[2]-enc_color1[2];
  2846. if( !((diff[0] >= -4) && (diff[0] <= 3) && (diff[1] >= -4) && (diff[1] <= 3) && (diff[2] >= -4) && (diff[2] <= 3)) )
  2847. {
  2848. enc_color1[0] = (enc_color1[0] + enc_color2[0]) >> 1;
  2849. enc_color1[1] = (enc_color1[1] + enc_color2[1]) >> 1;
  2850. enc_color1[2] = (enc_color1[2] + enc_color2[2]) >> 1;
  2851. enc_color2[0] = enc_color1[0];
  2852. enc_color2[1] = enc_color1[1];
  2853. enc_color2[2] = enc_color1[2];
  2854. }
  2855. {
  2856. diffbit = 1;
  2857. // The difference to be coded:
  2858. diff[0] = enc_color2[0]-enc_color1[0];
  2859. diff[1] = enc_color2[1]-enc_color1[1];
  2860. diff[2] = enc_color2[2]-enc_color1[2];
  2861. avg_color_quant1[0] = enc_color1[0] << 3 | (enc_color1[0] >> 2);
  2862. avg_color_quant1[1] = enc_color1[1] << 3 | (enc_color1[1] >> 2);
  2863. avg_color_quant1[2] = enc_color1[2] << 3 | (enc_color1[2] >> 2);
  2864. avg_color_quant2[0] = enc_color2[0] << 3 | (enc_color2[0] >> 2);
  2865. avg_color_quant2[1] = enc_color2[1] << 3 | (enc_color2[1] >> 2);
  2866. avg_color_quant2[2] = enc_color2[2] << 3 | (enc_color2[2] >> 2);
  2867. // Pack bits into the first word.
  2868. compressed1_flip = 0;
  2869. PUTBITSHIGH( compressed1_flip, diffbit, 1, 33);
  2870. PUTBITSHIGH( compressed1_flip, enc_color1[0], 5, 63);
  2871. PUTBITSHIGH( compressed1_flip, enc_color1[1], 5, 55);
  2872. PUTBITSHIGH( compressed1_flip, enc_color1[2], 5, 47);
  2873. PUTBITSHIGH( compressed1_flip, diff[0], 3, 58);
  2874. PUTBITSHIGH( compressed1_flip, diff[1], 3, 50);
  2875. PUTBITSHIGH( compressed1_flip, diff[2], 3, 42);
  2876. unsigned int best_pixel_indices1_MSB;
  2877. unsigned int best_pixel_indices1_LSB;
  2878. unsigned int best_pixel_indices2_MSB;
  2879. unsigned int best_pixel_indices2_LSB;
  2880. // upper part of block
  2881. flip_err = tryalltables_3bittable4x2percep1000(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  2882. // lower part of block
  2883. flip_err += tryalltables_3bittable4x2percep1000(img,width,height,startx,starty+2,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  2884. PUTBITSHIGH( compressed1_flip, best_table1, 3, 39);
  2885. PUTBITSHIGH( compressed1_flip, best_table2, 3, 36);
  2886. PUTBITSHIGH( compressed1_flip, 1, 1, 32);
  2887. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  2888. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  2889. compressed2_flip = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  2890. }
  2891. unsigned int best_err;
  2892. if(norm_err <= flip_err)
  2893. {
  2894. compressed1 = compressed1_norm | 0;
  2895. compressed2 = compressed2_norm;
  2896. best_err = norm_err;
  2897. }
  2898. else
  2899. {
  2900. compressed1 = compressed1_flip | 1;
  2901. compressed2 = compressed2_flip;
  2902. best_err = flip_err;
  2903. }
  2904. return best_err;
  2905. }
  2906. // Compresses the block using both the individual and the differential mode in ETC1/ETC2
  2907. // Uses the average color as the base color in each half-block.
  2908. // Uses a perceptual error metric.
  2909. // Tries both flipped and unflipped.
  2910. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  2911. double compressBlockDiffFlipAveragePerceptual(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  2912. {
  2913. unsigned int compressed1_norm, compressed2_norm;
  2914. unsigned int compressed1_flip, compressed2_flip;
  2915. uint8 avg_color_quant1[3], avg_color_quant2[3];
  2916. float avg_color_float1[3],avg_color_float2[3];
  2917. int enc_color1[3], enc_color2[3], diff[3];
  2918. int min_error=255*255*8*3;
  2919. unsigned int best_table_indices1=0, best_table_indices2=0;
  2920. unsigned int best_table1=0, best_table2=0;
  2921. int diffbit;
  2922. int norm_err=0;
  2923. int flip_err=0;
  2924. // First try normal blocks 2x4:
  2925. computeAverageColor2x4noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  2926. computeAverageColor2x4noQuantFloat(img,width,height,startx+2,starty,avg_color_float2);
  2927. // First test if avg_color1 is similar enough to avg_color2 so that
  2928. // we can use differential coding of colors.
  2929. float eps;
  2930. enc_color1[0] = int( JAS_ROUND(31.0*avg_color_float1[0]/255.0) );
  2931. enc_color1[1] = int( JAS_ROUND(31.0*avg_color_float1[1]/255.0) );
  2932. enc_color1[2] = int( JAS_ROUND(31.0*avg_color_float1[2]/255.0) );
  2933. enc_color2[0] = int( JAS_ROUND(31.0*avg_color_float2[0]/255.0) );
  2934. enc_color2[1] = int( JAS_ROUND(31.0*avg_color_float2[1]/255.0) );
  2935. enc_color2[2] = int( JAS_ROUND(31.0*avg_color_float2[2]/255.0) );
  2936. diff[0] = enc_color2[0]-enc_color1[0];
  2937. diff[1] = enc_color2[1]-enc_color1[1];
  2938. diff[2] = enc_color2[2]-enc_color1[2];
  2939. if( (diff[0] >= -4) && (diff[0] <= 3) && (diff[1] >= -4) && (diff[1] <= 3) && (diff[2] >= -4) && (diff[2] <= 3) )
  2940. {
  2941. diffbit = 1;
  2942. // The difference to be coded:
  2943. diff[0] = enc_color2[0]-enc_color1[0];
  2944. diff[1] = enc_color2[1]-enc_color1[1];
  2945. diff[2] = enc_color2[2]-enc_color1[2];
  2946. avg_color_quant1[0] = enc_color1[0] << 3 | (enc_color1[0] >> 2);
  2947. avg_color_quant1[1] = enc_color1[1] << 3 | (enc_color1[1] >> 2);
  2948. avg_color_quant1[2] = enc_color1[2] << 3 | (enc_color1[2] >> 2);
  2949. avg_color_quant2[0] = enc_color2[0] << 3 | (enc_color2[0] >> 2);
  2950. avg_color_quant2[1] = enc_color2[1] << 3 | (enc_color2[1] >> 2);
  2951. avg_color_quant2[2] = enc_color2[2] << 3 | (enc_color2[2] >> 2);
  2952. // Pack bits into the first word.
  2953. // ETC1_RGB8_OES:
  2954. //
  2955. // a) bit layout in bits 63 through 32 if diffbit = 0
  2956. //
  2957. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  2958. // ---------------------------------------------------------------------------------------------------
  2959. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  2960. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  2961. // ---------------------------------------------------------------------------------------------------
  2962. //
  2963. // b) bit layout in bits 63 through 32 if diffbit = 1
  2964. //
  2965. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  2966. // ---------------------------------------------------------------------------------------------------
  2967. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |diff|flip|
  2968. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
  2969. // ---------------------------------------------------------------------------------------------------
  2970. //
  2971. // c) bit layout in bits 31 through 0 (in both cases)
  2972. //
  2973. // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  2974. // --------------------------------------------------------------------------------------------------
  2975. // | most significant pixel index bits | least significant pixel index bits |
  2976. // | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a| p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
  2977. // --------------------------------------------------------------------------------------------------
  2978. compressed1_norm = 0;
  2979. PUTBITSHIGH( compressed1_norm, diffbit, 1, 33);
  2980. PUTBITSHIGH( compressed1_norm, enc_color1[0], 5, 63);
  2981. PUTBITSHIGH( compressed1_norm, enc_color1[1], 5, 55);
  2982. PUTBITSHIGH( compressed1_norm, enc_color1[2], 5, 47);
  2983. PUTBITSHIGH( compressed1_norm, diff[0], 3, 58);
  2984. PUTBITSHIGH( compressed1_norm, diff[1], 3, 50);
  2985. PUTBITSHIGH( compressed1_norm, diff[2], 3, 42);
  2986. unsigned int best_pixel_indices1_MSB;
  2987. unsigned int best_pixel_indices1_LSB;
  2988. unsigned int best_pixel_indices2_MSB;
  2989. unsigned int best_pixel_indices2_LSB;
  2990. norm_err = 0;
  2991. // left part of block
  2992. norm_err = tryalltables_3bittable2x4percep(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  2993. // right part of block
  2994. norm_err += tryalltables_3bittable2x4percep(img,width,height,startx+2,starty,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  2995. PUTBITSHIGH( compressed1_norm, best_table1, 3, 39);
  2996. PUTBITSHIGH( compressed1_norm, best_table2, 3, 36);
  2997. PUTBITSHIGH( compressed1_norm, 0, 1, 32);
  2998. compressed2_norm = 0;
  2999. PUTBITS( compressed2_norm, (best_pixel_indices1_MSB ), 8, 23);
  3000. PUTBITS( compressed2_norm, (best_pixel_indices2_MSB ), 8, 31);
  3001. PUTBITS( compressed2_norm, (best_pixel_indices1_LSB ), 8, 7);
  3002. PUTBITS( compressed2_norm, (best_pixel_indices2_LSB ), 8, 15);
  3003. }
  3004. else
  3005. {
  3006. diffbit = 0;
  3007. // The difference is bigger than what fits in 555 plus delta-333, so we will have
  3008. // to deal with 444 444.
  3009. eps = (float) 0.0001;
  3010. enc_color1[0] = int( ((float) avg_color_float1[0] / (17.0)) +0.5 + eps);
  3011. enc_color1[1] = int( ((float) avg_color_float1[1] / (17.0)) +0.5 + eps);
  3012. enc_color1[2] = int( ((float) avg_color_float1[2] / (17.0)) +0.5 + eps);
  3013. enc_color2[0] = int( ((float) avg_color_float2[0] / (17.0)) +0.5 + eps);
  3014. enc_color2[1] = int( ((float) avg_color_float2[1] / (17.0)) +0.5 + eps);
  3015. enc_color2[2] = int( ((float) avg_color_float2[2] / (17.0)) +0.5 + eps);
  3016. avg_color_quant1[0] = enc_color1[0] << 4 | enc_color1[0];
  3017. avg_color_quant1[1] = enc_color1[1] << 4 | enc_color1[1];
  3018. avg_color_quant1[2] = enc_color1[2] << 4 | enc_color1[2];
  3019. avg_color_quant2[0] = enc_color2[0] << 4 | enc_color2[0];
  3020. avg_color_quant2[1] = enc_color2[1] << 4 | enc_color2[1];
  3021. avg_color_quant2[2] = enc_color2[2] << 4 | enc_color2[2];
  3022. // Pack bits into the first word.
  3023. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  3024. // ---------------------------------------------------------------------------------------------------
  3025. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  3026. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  3027. // ---------------------------------------------------------------------------------------------------
  3028. compressed1_norm = 0;
  3029. PUTBITSHIGH( compressed1_norm, diffbit, 1, 33);
  3030. PUTBITSHIGH( compressed1_norm, enc_color1[0], 4, 63);
  3031. PUTBITSHIGH( compressed1_norm, enc_color1[1], 4, 55);
  3032. PUTBITSHIGH( compressed1_norm, enc_color1[2], 4, 47);
  3033. PUTBITSHIGH( compressed1_norm, enc_color2[0], 4, 59);
  3034. PUTBITSHIGH( compressed1_norm, enc_color2[1], 4, 51);
  3035. PUTBITSHIGH( compressed1_norm, enc_color2[2], 4, 43);
  3036. unsigned int best_pixel_indices1_MSB;
  3037. unsigned int best_pixel_indices1_LSB;
  3038. unsigned int best_pixel_indices2_MSB;
  3039. unsigned int best_pixel_indices2_LSB;
  3040. // left part of block
  3041. norm_err = tryalltables_3bittable2x4percep(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  3042. // right part of block
  3043. norm_err += tryalltables_3bittable2x4percep(img,width,height,startx+2,starty,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  3044. PUTBITSHIGH( compressed1_norm, best_table1, 3, 39);
  3045. PUTBITSHIGH( compressed1_norm, best_table2, 3, 36);
  3046. PUTBITSHIGH( compressed1_norm, 0, 1, 32);
  3047. compressed2_norm = 0;
  3048. PUTBITS( compressed2_norm, (best_pixel_indices1_MSB ), 8, 23);
  3049. PUTBITS( compressed2_norm, (best_pixel_indices2_MSB ), 8, 31);
  3050. PUTBITS( compressed2_norm, (best_pixel_indices1_LSB ), 8, 7);
  3051. PUTBITS( compressed2_norm, (best_pixel_indices2_LSB ), 8, 15);
  3052. }
  3053. // Now try flipped blocks 4x2:
  3054. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  3055. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty+2,avg_color_float2);
  3056. // First test if avg_color1 is similar enough to avg_color2 so that
  3057. // we can use differential coding of colors.
  3058. enc_color1[0] = int( JAS_ROUND(31.0*avg_color_float1[0]/255.0) );
  3059. enc_color1[1] = int( JAS_ROUND(31.0*avg_color_float1[1]/255.0) );
  3060. enc_color1[2] = int( JAS_ROUND(31.0*avg_color_float1[2]/255.0) );
  3061. enc_color2[0] = int( JAS_ROUND(31.0*avg_color_float2[0]/255.0) );
  3062. enc_color2[1] = int( JAS_ROUND(31.0*avg_color_float2[1]/255.0) );
  3063. enc_color2[2] = int( JAS_ROUND(31.0*avg_color_float2[2]/255.0) );
  3064. diff[0] = enc_color2[0]-enc_color1[0];
  3065. diff[1] = enc_color2[1]-enc_color1[1];
  3066. diff[2] = enc_color2[2]-enc_color1[2];
  3067. if( (diff[0] >= -4) && (diff[0] <= 3) && (diff[1] >= -4) && (diff[1] <= 3) && (diff[2] >= -4) && (diff[2] <= 3) )
  3068. {
  3069. diffbit = 1;
  3070. // The difference to be coded:
  3071. diff[0] = enc_color2[0]-enc_color1[0];
  3072. diff[1] = enc_color2[1]-enc_color1[1];
  3073. diff[2] = enc_color2[2]-enc_color1[2];
  3074. avg_color_quant1[0] = enc_color1[0] << 3 | (enc_color1[0] >> 2);
  3075. avg_color_quant1[1] = enc_color1[1] << 3 | (enc_color1[1] >> 2);
  3076. avg_color_quant1[2] = enc_color1[2] << 3 | (enc_color1[2] >> 2);
  3077. avg_color_quant2[0] = enc_color2[0] << 3 | (enc_color2[0] >> 2);
  3078. avg_color_quant2[1] = enc_color2[1] << 3 | (enc_color2[1] >> 2);
  3079. avg_color_quant2[2] = enc_color2[2] << 3 | (enc_color2[2] >> 2);
  3080. // Pack bits into the first word.
  3081. compressed1_flip = 0;
  3082. PUTBITSHIGH( compressed1_flip, diffbit, 1, 33);
  3083. PUTBITSHIGH( compressed1_flip, enc_color1[0], 5, 63);
  3084. PUTBITSHIGH( compressed1_flip, enc_color1[1], 5, 55);
  3085. PUTBITSHIGH( compressed1_flip, enc_color1[2], 5, 47);
  3086. PUTBITSHIGH( compressed1_flip, diff[0], 3, 58);
  3087. PUTBITSHIGH( compressed1_flip, diff[1], 3, 50);
  3088. PUTBITSHIGH( compressed1_flip, diff[2], 3, 42);
  3089. unsigned int best_pixel_indices1_MSB;
  3090. unsigned int best_pixel_indices1_LSB;
  3091. unsigned int best_pixel_indices2_MSB;
  3092. unsigned int best_pixel_indices2_LSB;
  3093. // upper part of block
  3094. flip_err = tryalltables_3bittable4x2percep(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  3095. // lower part of block
  3096. flip_err += tryalltables_3bittable4x2percep(img,width,height,startx,starty+2,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  3097. PUTBITSHIGH( compressed1_flip, best_table1, 3, 39);
  3098. PUTBITSHIGH( compressed1_flip, best_table2, 3, 36);
  3099. PUTBITSHIGH( compressed1_flip, 1, 1, 32);
  3100. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  3101. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  3102. compressed2_flip = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  3103. }
  3104. else
  3105. {
  3106. diffbit = 0;
  3107. // The difference is bigger than what fits in 555 plus delta-333, so we will have
  3108. // to deal with 444 444.
  3109. eps = (float) 0.0001;
  3110. enc_color1[0] = int( ((float) avg_color_float1[0] / (17.0)) +0.5 + eps);
  3111. enc_color1[1] = int( ((float) avg_color_float1[1] / (17.0)) +0.5 + eps);
  3112. enc_color1[2] = int( ((float) avg_color_float1[2] / (17.0)) +0.5 + eps);
  3113. enc_color2[0] = int( ((float) avg_color_float2[0] / (17.0)) +0.5 + eps);
  3114. enc_color2[1] = int( ((float) avg_color_float2[1] / (17.0)) +0.5 + eps);
  3115. enc_color2[2] = int( ((float) avg_color_float2[2] / (17.0)) +0.5 + eps);
  3116. avg_color_quant1[0] = enc_color1[0] << 4 | enc_color1[0];
  3117. avg_color_quant1[1] = enc_color1[1] << 4 | enc_color1[1];
  3118. avg_color_quant1[2] = enc_color1[2] << 4 | enc_color1[2];
  3119. avg_color_quant2[0] = enc_color2[0] << 4 | enc_color2[0];
  3120. avg_color_quant2[1] = enc_color2[1] << 4 | enc_color2[1];
  3121. avg_color_quant2[2] = enc_color2[2] << 4 | enc_color2[2];
  3122. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  3123. // ---------------------------------------------------------------------------------------------------
  3124. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  3125. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  3126. // ---------------------------------------------------------------------------------------------------
  3127. // Pack bits into the first word.
  3128. compressed1_flip = 0;
  3129. PUTBITSHIGH( compressed1_flip, diffbit, 1, 33);
  3130. PUTBITSHIGH( compressed1_flip, enc_color1[0], 4, 63);
  3131. PUTBITSHIGH( compressed1_flip, enc_color1[1], 4, 55);
  3132. PUTBITSHIGH( compressed1_flip, enc_color1[2], 4, 47);
  3133. PUTBITSHIGH( compressed1_flip, enc_color2[0], 4, 59);
  3134. PUTBITSHIGH( compressed1_flip, enc_color2[1], 4, 51);
  3135. PUTBITSHIGH( compressed1_flip, enc_color2[2], 4, 43);
  3136. unsigned int best_pixel_indices1_MSB;
  3137. unsigned int best_pixel_indices1_LSB;
  3138. unsigned int best_pixel_indices2_MSB;
  3139. unsigned int best_pixel_indices2_LSB;
  3140. // upper part of block
  3141. flip_err = tryalltables_3bittable4x2percep(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  3142. // lower part of block
  3143. flip_err += tryalltables_3bittable4x2percep(img,width,height,startx,starty+2,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  3144. PUTBITSHIGH( compressed1_flip, best_table1, 3, 39);
  3145. PUTBITSHIGH( compressed1_flip, best_table2, 3, 36);
  3146. PUTBITSHIGH( compressed1_flip, 1, 1, 32);
  3147. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  3148. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  3149. compressed2_flip = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  3150. }
  3151. // Now lets see which is the best table to use. Only 8 tables are possible.
  3152. double best_err;
  3153. if(norm_err <= flip_err)
  3154. {
  3155. compressed1 = compressed1_norm | 0;
  3156. compressed2 = compressed2_norm;
  3157. best_err = norm_err;
  3158. }
  3159. else
  3160. {
  3161. compressed1 = compressed1_flip | 1;
  3162. compressed2 = compressed2_flip;
  3163. best_err = flip_err;
  3164. }
  3165. return best_err;
  3166. }
  3167. // This is our structure for matrix data
  3168. struct dMatrix
  3169. {
  3170. int width; // The number of coloumns in the matrix
  3171. int height; // The number of rows in the matrix
  3172. double *data; // The matrix data in row order
  3173. };
  3174. // Multiplies two matrices
  3175. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3176. dMatrix *multiplyMatrices( dMatrix *Amat, dMatrix *Bmat)
  3177. {
  3178. int xx,yy, q;
  3179. dMatrix *resmatrix;
  3180. if(Amat->width != Bmat->height)
  3181. {
  3182. printf("Cannot multiply matrices -- dimensions do not agree.\n");
  3183. exit(1);
  3184. }
  3185. // Allocate space for result
  3186. resmatrix = (dMatrix*) malloc(sizeof(dMatrix));
  3187. resmatrix->width = Bmat->width;
  3188. resmatrix->height = Amat->height;
  3189. resmatrix->data = (double*) malloc(sizeof(double)*(resmatrix->width)*(resmatrix->height));
  3190. for(yy = 0; yy<resmatrix->height; yy++)
  3191. for(xx = 0; xx<resmatrix->width; xx++)
  3192. for(q=0, resmatrix->data[yy*resmatrix->width+xx] = 0.0; q<Amat->width; q++)
  3193. resmatrix->data[yy*resmatrix->width+xx] += Amat->data[yy*Amat->width + q] * Bmat->data[q*Bmat->width+xx];
  3194. return(resmatrix);
  3195. }
  3196. // Transposes a matrix
  3197. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3198. void transposeMatrix( dMatrix *mat)
  3199. {
  3200. int xx, yy, zz;
  3201. double *temp;
  3202. int newwidth, newheight;
  3203. temp = (double*) malloc (sizeof(double)*(mat->width)*(mat->height));
  3204. for(zz = 0; zz<((mat->width)*(mat->height)); zz++)
  3205. temp[zz] = mat->data[zz];
  3206. newwidth = mat->height;
  3207. newheight= mat->width;
  3208. for(yy = 0; yy<newheight; yy++)
  3209. for(xx = 0; xx<newwidth; xx++)
  3210. mat->data[yy*newwidth+xx] = temp[xx*(mat->width)+yy];
  3211. mat->height = newheight;
  3212. mat->width = newwidth;
  3213. free(temp);
  3214. }
  3215. // In the planar mode in ETC2, the block can be partitioned as follows:
  3216. //
  3217. // O A A A H
  3218. // B D1 D3 C3
  3219. // B D2 C2 D5
  3220. // B C1 D4 D6
  3221. // V
  3222. // Here A-pixels, B-pixels and C-pixels only depend on two values. For instance, B-pixels only depend on O and V.
  3223. // This can be used to quickly rule out combinations of colors.
  3224. // Here we calculate the minimum error for the block if we know the red component for O and V.
  3225. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3226. unsigned int calcBBBred(uint8 *block, int colorO, int colorV)
  3227. {
  3228. colorO = (colorO << 2) | (colorO >> 4);
  3229. colorV = (colorV << 2) | (colorV >> 4);
  3230. unsigned int error = 0;
  3231. // Now first column: B B B
  3232. /* unroll loop for( yy=0; (yy<4) && (error <= best_error_sofar); yy++)*/
  3233. {
  3234. error = error + square_table[(block[4*4 + 0] - clamp_table[ ((((colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3235. error = error + square_table[(block[4*4*2 + 0] - clamp_table[ (((((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3236. error = error + square_table[(block[4*4*3 + 0] - clamp_table[ (((3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3237. }
  3238. return error;
  3239. }
  3240. // Calculating the minimum error for the block if we know the red component for H and V.
  3241. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3242. unsigned int calcCCCred(uint8 *block, int colorH, int colorV)
  3243. {
  3244. colorH = (colorH << 2) | (colorH >> 4);
  3245. colorV = (colorV << 2) | (colorV >> 4);
  3246. unsigned int error=0;
  3247. error = error + square_table[(block[4*4*3 + 4 + 0] - clamp_table[ (((colorH + 3*colorV)+2)>>2) + 255])+255];
  3248. error = error + square_table[(block[4*4*2 + 4*2 + 0] - clamp_table[ (((2*colorH + 2*colorV)+2)>>2) + 255])+255];
  3249. error = error + square_table[(block[4*4 + 4*3 + 0] - clamp_table[ (((3*colorH + colorV)+2)>>2) + 255])+255];
  3250. return error;
  3251. }
  3252. // Calculating the minimum error for the block if we know the red component for O and H.
  3253. // Uses perceptual error metric.
  3254. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3255. unsigned int calcLowestPossibleRedOHperceptual(uint8 *block, int colorO, int colorH, unsigned int best_error_sofar)
  3256. {
  3257. colorO = (colorO << 2) | (colorO >> 4);
  3258. colorH = (colorH << 2) | (colorH >> 4);
  3259. unsigned int error;
  3260. error = square_table_percep_red[(block[0] - colorO) + 255];
  3261. error = error + square_table_percep_red[(block[4] - clamp_table[ ((( (colorH-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3262. if(error <= best_error_sofar)
  3263. {
  3264. error = error + square_table_percep_red[(block[4*2] - clamp_table[ ((( ((colorH-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3265. error = error + square_table_percep_red[(block[4*3] - clamp_table[ ((( 3*(colorH-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3266. }
  3267. return error;
  3268. }
  3269. // Calculating the minimum error for the block (in planar mode) if we know the red component for O and H.
  3270. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3271. unsigned int calcLowestPossibleRedOH(uint8 *block, int colorO, int colorH, unsigned int best_error_sofar)
  3272. {
  3273. colorO = (colorO << 2) | (colorO >> 4);
  3274. colorH = (colorH << 2) | (colorH >> 4);
  3275. unsigned int error;
  3276. error = square_table[(block[0] - colorO) + 255];
  3277. error = error + square_table[(block[4] - clamp_table[ ((( (colorH-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3278. if(error <= best_error_sofar)
  3279. {
  3280. error = error + square_table[(block[4*2] - clamp_table[ ((( ((colorH-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3281. error = error + square_table[(block[4*3] - clamp_table[ ((( 3*(colorH-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3282. }
  3283. return error;
  3284. }
  3285. // Calculating the minimum error for the block (in planar mode) if we know the red component for O and H and V.
  3286. // Uses perceptual error metric.
  3287. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3288. unsigned int calcErrorPlanarOnlyRedPerceptual(uint8 *block, int colorO, int colorH, int colorV, unsigned int lowest_possible_error, unsigned int BBBvalue, unsigned int CCCvalue, unsigned int best_error_sofar)
  3289. {
  3290. colorO = (colorO << 2) | (colorO >> 4);
  3291. colorH = (colorH << 2) | (colorH >> 4);
  3292. colorV = (colorV << 2) | (colorV >> 4);
  3293. unsigned int error;
  3294. // The block can be partitioned into: O A A A
  3295. // B D1 D3 C3
  3296. // B D2 C2 D5
  3297. // B C1 D4 D6
  3298. int xpart_times_4;
  3299. // The first part: O A A A. It equals lowest_possible_error previously calculated.
  3300. // lowest_possible_error is OAAA, BBBvalue is BBB and CCCvalue is C1C2C3.
  3301. error = lowest_possible_error + BBBvalue + CCCvalue;
  3302. // The remaining pixels to cover are D1 through D6.
  3303. if(error <= best_error_sofar)
  3304. {
  3305. // Second column: D1 D2 but not C1
  3306. xpart_times_4 = (colorH-colorO);
  3307. error = error + square_table_percep_red[(block[4*4 + 4 + 0] - clamp_table[ (((xpart_times_4 + (colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3308. error = error + square_table_percep_red[(block[4*4*2 + 4 + 0] - clamp_table[ (((xpart_times_4 + ((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3309. // Third column: D3 notC2 D4
  3310. xpart_times_4 = (colorH-colorO) << 1;
  3311. error = error + square_table_percep_red[(block[4*4 + 4*2 + 0] - clamp_table[ (((xpart_times_4 + (colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3312. if(error <= best_error_sofar)
  3313. {
  3314. error = error + square_table_percep_red[(block[4*4*3 + 4*2 + 0] - clamp_table[ (((xpart_times_4 + 3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3315. // Forth column: notC3 D5 D6
  3316. xpart_times_4 = 3*(colorH-colorO);
  3317. error = error + square_table_percep_red[(block[4*4*2 + 4*3 + 0] - clamp_table[ (((xpart_times_4 + ((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3318. error = error + square_table_percep_red[(block[4*4*3 + 4*3 + 0] - clamp_table[ (((xpart_times_4 + 3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3319. }
  3320. }
  3321. return error;
  3322. }
  3323. // Calculating the minimum error for the block (in planar mode) if we know the red component for O and H and V.
  3324. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3325. unsigned int calcErrorPlanarOnlyRed(uint8 *block, int colorO, int colorH, int colorV, unsigned int lowest_possible_error, unsigned int BBBvalue, unsigned int CCCvalue, unsigned int best_error_sofar)
  3326. {
  3327. colorO = (colorO << 2) | (colorO >> 4);
  3328. colorH = (colorH << 2) | (colorH >> 4);
  3329. colorV = (colorV << 2) | (colorV >> 4);
  3330. unsigned int error;
  3331. // The block can be partitioned into: O A A A
  3332. // B D1 D3 C3
  3333. // B D2 C2 D5
  3334. // B C1 D4 D6
  3335. int xpart_times_4;
  3336. // The first part: O A A A. It equals lowest_possible_error previously calculated.
  3337. // lowest_possible_error is OAAA, BBBvalue is BBB and CCCvalue is C1C2C3.
  3338. error = lowest_possible_error + BBBvalue + CCCvalue;
  3339. // The remaining pixels to cover are D1 through D6.
  3340. if(error <= best_error_sofar)
  3341. {
  3342. // Second column: D1 D2 but not C1
  3343. xpart_times_4 = (colorH-colorO);
  3344. error = error + square_table[(block[4*4 + 4 + 0] - clamp_table[ (((xpart_times_4 + (colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3345. error = error + square_table[(block[4*4*2 + 4 + 0] - clamp_table[ (((xpart_times_4 + ((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3346. // Third column: D3 notC2 D4
  3347. xpart_times_4 = (colorH-colorO) << 1;
  3348. error = error + square_table[(block[4*4 + 4*2 + 0] - clamp_table[ (((xpart_times_4 + (colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3349. if(error <= best_error_sofar)
  3350. {
  3351. error = error + square_table[(block[4*4*3 + 4*2 + 0] - clamp_table[ (((xpart_times_4 + 3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3352. // Forth column: notC3 D5 D6
  3353. xpart_times_4 = 3*(colorH-colorO);
  3354. error = error + square_table[(block[4*4*2 + 4*3 + 0] - clamp_table[ (((xpart_times_4 + ((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3355. error = error + square_table[(block[4*4*3 + 4*3 + 0] - clamp_table[ (((xpart_times_4 + 3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3356. }
  3357. }
  3358. return error;
  3359. }
  3360. // Calculating the minimum error for the block (in planar mode) if we know the red component for O and H.
  3361. // Uses perceptual error metrics.
  3362. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3363. unsigned int calcLowestPossibleGreenOHperceptual(uint8 *block, int colorO, int colorH, unsigned int best_error_sofar)
  3364. {
  3365. colorO = (colorO << 1) | (colorO >> 6);
  3366. colorH = (colorH << 1) | (colorH >> 6);
  3367. unsigned int error;
  3368. error = square_table_percep_green[(block[1] - colorO) + 255];
  3369. error = error + square_table_percep_green[(block[4 + 1] - clamp_table[ ((( (colorH-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3370. if(error <= best_error_sofar)
  3371. {
  3372. error = error + square_table_percep_green[(block[4*2 + 1] - clamp_table[ ((( ((colorH-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3373. error = error + square_table_percep_green[(block[4*3 + 1] - clamp_table[ ((( 3*(colorH-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3374. }
  3375. return error;
  3376. }
  3377. // Calculating the minimum error for the block (in planar mode) if we know the red component for O and H.
  3378. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3379. unsigned int calcLowestPossibleGreenOH(uint8 *block, int colorO, int colorH, unsigned int best_error_sofar)
  3380. {
  3381. colorO = (colorO << 1) | (colorO >> 6);
  3382. colorH = (colorH << 1) | (colorH >> 6);
  3383. unsigned int error;
  3384. error = square_table[(block[1] - colorO) + 255];
  3385. error = error + square_table[(block[4 + 1] - clamp_table[ ((( (colorH-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3386. if(error <= best_error_sofar)
  3387. {
  3388. error = error + square_table[(block[4*2 + 1] - clamp_table[ ((( ((colorH-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3389. error = error + square_table[(block[4*3 + 1] - clamp_table[ ((( 3*(colorH-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3390. }
  3391. return error;
  3392. }
  3393. // Calculating the minimum error for the block (in planar mode) if we know the green component for O and V.
  3394. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3395. unsigned int calcBBBgreen(uint8 *block, int colorO, int colorV)
  3396. {
  3397. colorO = (colorO << 1) | (colorO >> 6);
  3398. colorV = (colorV << 1) | (colorV >> 6);
  3399. unsigned int error = 0;
  3400. // Now first column: B B B
  3401. /* unroll loop for( yy=0; (yy<4) && (error <= best_error_sofar); yy++)*/
  3402. {
  3403. error = error + square_table[(block[4*4 + 1] - clamp_table[ ((((colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3404. error = error + square_table[(block[4*4*2 + 1] - clamp_table[ (((((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3405. error = error + square_table[(block[4*4*3 + 1] - clamp_table[ (((3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3406. }
  3407. return error;
  3408. }
  3409. // Calculating the minimum error for the block (in planar mode) if we know the green component for H and V.
  3410. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3411. unsigned int calcCCCgreen(uint8 *block, int colorH, int colorV)
  3412. {
  3413. colorH = (colorH << 1) | (colorH >> 6);
  3414. colorV = (colorV << 1) | (colorV >> 6);
  3415. unsigned int error=0;
  3416. error = error + square_table[(block[4*4*3 + 4 + 1] - clamp_table[ (((colorH + 3*colorV)+2)>>2) + 255])+255];
  3417. error = error + square_table[(block[4*4*2 + 4*2 + 1] - clamp_table[ (((2*colorH + 2*colorV)+2)>>2) + 255])+255];
  3418. error = error + square_table[(block[4*4 + 4*3 + 1] - clamp_table[ (((3*colorH + colorV)+2)>>2) + 255])+255];
  3419. return error;
  3420. }
  3421. // Calculating the minimum error for the block (in planar mode) if we know the green component for H V and O.
  3422. // Uses perceptual error metric.
  3423. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3424. unsigned int calcErrorPlanarOnlyGreenPerceptual(uint8 *block, int colorO, int colorH, int colorV, unsigned int lowest_possible_error, unsigned int BBBvalue, unsigned int CCCvalue, unsigned int best_error_sofar)
  3425. {
  3426. colorO = (colorO << 1) | (colorO >> 6);
  3427. colorH = (colorH << 1) | (colorH >> 6);
  3428. colorV = (colorV << 1) | (colorV >> 6);
  3429. unsigned int error;
  3430. // The block can be partitioned into: O A A A
  3431. // B D1 D3 C3
  3432. // B D2 C2 D5
  3433. // B C1 D4 D6
  3434. int xpart_times_4;
  3435. // The first part: O A A A. It equals lowest_possible_error previously calculated.
  3436. // lowest_possible_error is OAAA, BBBvalue is BBB and CCCvalue is C1C2C3.
  3437. error = lowest_possible_error + BBBvalue + CCCvalue;
  3438. // The remaining pixels to cover are D1 through D6.
  3439. if(error <= best_error_sofar)
  3440. {
  3441. // Second column: D1 D2 but not C1
  3442. xpart_times_4 = (colorH-colorO);
  3443. error = error + square_table_percep_green[(block[4*4 + 4 + 1] - clamp_table[ (((xpart_times_4 + (colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3444. error = error + square_table_percep_green[(block[4*4*2 + 4 + 1] - clamp_table[ (((xpart_times_4 + ((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3445. // Third column: D3 notC2 D4
  3446. xpart_times_4 = (colorH-colorO) << 1;
  3447. error = error + square_table_percep_green[(block[4*4 + 4*2 + 1] - clamp_table[ (((xpart_times_4 + (colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3448. if(error <= best_error_sofar)
  3449. {
  3450. error = error + square_table_percep_green[(block[4*4*3 + 4*2 + 1] - clamp_table[ (((xpart_times_4 + 3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3451. // Forth column: notC3 D5 D6
  3452. xpart_times_4 = 3*(colorH-colorO);
  3453. error = error + square_table_percep_green[(block[4*4*2 + 4*3 + 1] - clamp_table[ (((xpart_times_4 + ((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3454. error = error + square_table_percep_green[(block[4*4*3 + 4*3 + 1] - clamp_table[ (((xpart_times_4 + 3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3455. }
  3456. }
  3457. return error;
  3458. }
  3459. // Calculating the minimum error for the block (in planar mode) if we know the green component for H V and O.
  3460. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3461. unsigned int calcErrorPlanarOnlyGreen(uint8 *block, int colorO, int colorH, int colorV, unsigned int lowest_possible_error, unsigned int BBBvalue, unsigned int CCCvalue, unsigned int best_error_sofar)
  3462. {
  3463. colorO = (colorO << 1) | (colorO >> 6);
  3464. colorH = (colorH << 1) | (colorH >> 6);
  3465. colorV = (colorV << 1) | (colorV >> 6);
  3466. unsigned int error;
  3467. // The block can be partitioned into: O A A A
  3468. // B D1 D3 C3
  3469. // B D2 C2 D5
  3470. // B C1 D4 D6
  3471. int xpart_times_4;
  3472. // The first part: O A A A. It equals lowest_possible_error previously calculated.
  3473. // lowest_possible_error is OAAA, BBBvalue is BBB and CCCvalue is C1C2C3.
  3474. error = lowest_possible_error + BBBvalue + CCCvalue;
  3475. // The remaining pixels to cover are D1 through D6.
  3476. if(error <= best_error_sofar)
  3477. {
  3478. // Second column: D1 D2 but not C1
  3479. xpart_times_4 = (colorH-colorO);
  3480. error = error + square_table[(block[4*4 + 4 + 1] - clamp_table[ (((xpart_times_4 + (colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3481. error = error + square_table[(block[4*4*2 + 4 + 1] - clamp_table[ (((xpart_times_4 + ((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3482. // Third column: D3 notC2 D4
  3483. xpart_times_4 = (colorH-colorO) << 1;
  3484. error = error + square_table[(block[4*4 + 4*2 + 1] - clamp_table[ (((xpart_times_4 + (colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3485. if(error <= best_error_sofar)
  3486. {
  3487. error = error + square_table[(block[4*4*3 + 4*2 + 1] - clamp_table[ (((xpart_times_4 + 3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3488. // Forth column: notC3 D5 D6
  3489. xpart_times_4 = 3*(colorH-colorO);
  3490. error = error + square_table[(block[4*4*2 + 4*3 + 1] - clamp_table[ (((xpart_times_4 + ((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3491. error = error + square_table[(block[4*4*3 + 4*3 + 1] - clamp_table[ (((xpart_times_4 + 3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3492. }
  3493. }
  3494. return error;
  3495. }
  3496. // Calculating the minimum error for the block (in planar mode) if we know the blue component for O and V.
  3497. // Uses perceptual error metric.
  3498. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3499. unsigned int calcBBBbluePerceptual(uint8 *block, int colorO, int colorV)
  3500. {
  3501. colorO = (colorO << 2) | (colorO >> 4);
  3502. colorV = (colorV << 2) | (colorV >> 4);
  3503. unsigned int error = 0;
  3504. // Now first column: B B B
  3505. /* unroll loop for( yy=0; (yy<4) && (error <= best_error_sofar); yy++)*/
  3506. {
  3507. error = error + square_table_percep_blue[(block[4*4 + 2] - clamp_table[ ((((colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3508. error = error + square_table_percep_blue[(block[4*4*2 + 2] - clamp_table[ (((((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3509. error = error + square_table_percep_blue[(block[4*4*3 + 2] - clamp_table[ (((3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3510. }
  3511. return error;
  3512. }
  3513. // Calculating the minimum error for the block (in planar mode) if we know the blue component for O and V.
  3514. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3515. unsigned int calcBBBblue(uint8 *block, int colorO, int colorV)
  3516. {
  3517. colorO = (colorO << 2) | (colorO >> 4);
  3518. colorV = (colorV << 2) | (colorV >> 4);
  3519. unsigned int error = 0;
  3520. // Now first column: B B B
  3521. /* unroll loop for( yy=0; (yy<4) && (error <= best_error_sofar); yy++)*/
  3522. {
  3523. error = error + square_table[(block[4*4 + 2] - clamp_table[ ((((colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3524. error = error + square_table[(block[4*4*2 + 2] - clamp_table[ (((((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3525. error = error + square_table[(block[4*4*3 + 2] - clamp_table[ (((3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3526. }
  3527. return error;
  3528. }
  3529. // Calculating the minimum error for the block (in planar mode) if we know the blue component for H and V.
  3530. // Uses perceptual error metric.
  3531. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3532. unsigned int calcCCCbluePerceptual(uint8 *block, int colorH, int colorV)
  3533. {
  3534. colorH = (colorH << 2) | (colorH >> 4);
  3535. colorV = (colorV << 2) | (colorV >> 4);
  3536. unsigned int error=0;
  3537. error = error + square_table_percep_blue[(block[4*4*3 + 4 + 2] - clamp_table[ (((colorH + 3*colorV)+2)>>2) + 255])+255];
  3538. error = error + square_table_percep_blue[(block[4*4*2 + 4*2 + 2] - clamp_table[ (((2*colorH + 2*colorV)+2)>>2) + 255])+255];
  3539. error = error + square_table_percep_blue[(block[4*4 + 4*3 + 2] - clamp_table[ (((3*colorH + colorV)+2)>>2) + 255])+255];
  3540. return error;
  3541. }
  3542. // Calculating the minimum error for the block (in planar mode) if we know the blue component for O and V.
  3543. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3544. unsigned int calcCCCblue(uint8 *block, int colorH, int colorV)
  3545. {
  3546. colorH = (colorH << 2) | (colorH >> 4);
  3547. colorV = (colorV << 2) | (colorV >> 4);
  3548. unsigned int error=0;
  3549. error = error + square_table[(block[4*4*3 + 4 + 2] - clamp_table[ (((colorH + 3*colorV)+2)>>2) + 255])+255];
  3550. error = error + square_table[(block[4*4*2 + 4*2 + 2] - clamp_table[ (((2*colorH + 2*colorV)+2)>>2) + 255])+255];
  3551. error = error + square_table[(block[4*4 + 4*3 + 2] - clamp_table[ (((3*colorH + colorV)+2)>>2) + 255])+255];
  3552. return error;
  3553. }
  3554. // Calculating the minimum error for the block (in planar mode) if we know the blue component for O and H.
  3555. // Uses perceptual error metric.
  3556. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3557. unsigned int calcLowestPossibleBlueOHperceptual(uint8 *block, int colorO, int colorH, unsigned int best_error_sofar)
  3558. {
  3559. colorO = (colorO << 2) | (colorO >> 4);
  3560. colorH = (colorH << 2) | (colorH >> 4);
  3561. unsigned int error;
  3562. error = square_table_percep_blue[(block[2] - colorO) + 255];
  3563. error = error + square_table_percep_blue[(block[4+2] - clamp_table[ ((( (colorH-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3564. if(error <= best_error_sofar)
  3565. {
  3566. error = error + square_table_percep_blue[(block[4*2+2] - clamp_table[ ((( ((colorH-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3567. error = error + square_table_percep_blue[(block[4*3+2] - clamp_table[ ((( 3*(colorH-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3568. }
  3569. return error;
  3570. }
  3571. // Calculating the minimum error for the block (in planar mode) if we know the blue component for O and H.
  3572. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3573. unsigned int calcLowestPossibleBlueOH(uint8 *block, int colorO, int colorH, unsigned int best_error_sofar)
  3574. {
  3575. colorO = (colorO << 2) | (colorO >> 4);
  3576. colorH = (colorH << 2) | (colorH >> 4);
  3577. unsigned int error;
  3578. error = square_table[(block[2] - colorO) + 255];
  3579. error = error + square_table[(block[4+2] - clamp_table[ ((( (colorH-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3580. if(error <= best_error_sofar)
  3581. {
  3582. error = error + square_table[(block[4*2+2] - clamp_table[ ((( ((colorH-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3583. error = error + square_table[(block[4*3+2] - clamp_table[ ((( 3*(colorH-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3584. }
  3585. return error;
  3586. }
  3587. // Calculating the minimum error for the block (in planar mode) if we know the blue component for O, V and H.
  3588. // Uses perceptual error metric.
  3589. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3590. unsigned int calcErrorPlanarOnlyBluePerceptual(uint8 *block, int colorO, int colorH, int colorV, unsigned int lowest_possible_error, unsigned int BBBvalue, unsigned int CCCvalue, unsigned int best_error_sofar)
  3591. {
  3592. colorO = (colorO << 2) | (colorO >> 4);
  3593. colorH = (colorH << 2) | (colorH >> 4);
  3594. colorV = (colorV << 2) | (colorV >> 4);
  3595. unsigned int error;
  3596. // The block can be partitioned into: O A A A
  3597. // B D1 D3 C3
  3598. // B D2 C2 D5
  3599. // B C1 D4 D6
  3600. int xpart_times_4;
  3601. // The first part: O A A A. It equals lowest_possible_error previously calculated.
  3602. // lowest_possible_error is OAAA, BBBvalue is BBB and CCCvalue is C1C2C3.
  3603. error = lowest_possible_error + BBBvalue + CCCvalue;
  3604. // The remaining pixels to cover are D1 through D6.
  3605. if(error <= best_error_sofar)
  3606. {
  3607. // Second column: D1 D2 but not C1
  3608. xpart_times_4 = (colorH-colorO);
  3609. error = error + square_table_percep_blue[(block[4*4 + 4 + 2] - clamp_table[ (((xpart_times_4 + (colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3610. error = error + square_table_percep_blue[(block[4*4*2 + 4 + 2] - clamp_table[ (((xpart_times_4 + ((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3611. // Third column: D3 notC2 D4
  3612. xpart_times_4 = (colorH-colorO) << 1;
  3613. error = error + square_table_percep_blue[(block[4*4 + 4*2 + 2] - clamp_table[ (((xpart_times_4 + (colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3614. if(error <= best_error_sofar)
  3615. {
  3616. error = error + square_table_percep_blue[(block[4*4*3 + 4*2 + 2] - clamp_table[ (((xpart_times_4 + 3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3617. // Forth column: notC3 D5 D6
  3618. xpart_times_4 = 3*(colorH-colorO);
  3619. error = error + square_table_percep_blue[(block[4*4*2 + 4*3 + 2] - clamp_table[ (((xpart_times_4 + ((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3620. error = error + square_table_percep_blue[(block[4*4*3 + 4*3 + 2] - clamp_table[ (((xpart_times_4 + 3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3621. }
  3622. }
  3623. return error;
  3624. }
  3625. // Calculating the minimum error for the block (in planar mode) if we know the blue component for O, V and H.
  3626. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3627. unsigned int calcErrorPlanarOnlyBlue(uint8 *block, int colorO, int colorH, int colorV, unsigned int lowest_possible_error, unsigned int BBBvalue, unsigned int CCCvalue, unsigned int best_error_sofar)
  3628. {
  3629. colorO = (colorO << 2) | (colorO >> 4);
  3630. colorH = (colorH << 2) | (colorH >> 4);
  3631. colorV = (colorV << 2) | (colorV >> 4);
  3632. unsigned int error;
  3633. // The block can be partitioned into: O A A A
  3634. // B D1 D3 C3
  3635. // B D2 C2 D5
  3636. // B C1 D4 D6
  3637. int xpart_times_4;
  3638. // The first part: O A A A. It equals lowest_possible_error previously calculated.
  3639. // lowest_possible_error is OAAA, BBBvalue is BBB and CCCvalue is C1C2C3.
  3640. error = lowest_possible_error + BBBvalue + CCCvalue;
  3641. // The remaining pixels to cover are D1 through D6.
  3642. if(error <= best_error_sofar)
  3643. {
  3644. // Second column: D1 D2 but not C1
  3645. xpart_times_4 = (colorH-colorO);
  3646. error = error + square_table[(block[4*4 + 4 + 2] - clamp_table[ (((xpart_times_4 + (colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3647. error = error + square_table[(block[4*4*2 + 4 + 2] - clamp_table[ (((xpart_times_4 + ((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3648. // Third column: D3 notC2 D4
  3649. xpart_times_4 = (colorH-colorO) << 1;
  3650. error = error + square_table[(block[4*4 + 4*2 + 2] - clamp_table[ (((xpart_times_4 + (colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3651. if(error <= best_error_sofar)
  3652. {
  3653. error = error + square_table[(block[4*4*3 + 4*2 + 2] - clamp_table[ (((xpart_times_4 + 3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3654. // Forth column: notC3 D5 D6
  3655. xpart_times_4 = 3*(colorH-colorO);
  3656. error = error + square_table[(block[4*4*2 + 4*3 + 2] - clamp_table[ (((xpart_times_4 + ((colorV-colorO)<<1) + 4*colorO)+2)>>2) + 255])+255];
  3657. error = error + square_table[(block[4*4*3 + 4*3 + 2] - clamp_table[ (((xpart_times_4 + 3*(colorV-colorO) + 4*colorO)+2)>>2) + 255])+255];
  3658. }
  3659. }
  3660. return error;
  3661. }
  3662. // This function uses least squares in order to determine the best values of the plane.
  3663. // This is close to optimal, but not quite, due to nonlinearities in the expantion from 6 and 7 bits to 8, and
  3664. // in the clamping to a number between 0 and the maximum.
  3665. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3666. void compressBlockPlanar57(uint8 *img, int width,int height,int startx,int starty, unsigned int &compressed57_1, unsigned int &compressed57_2)
  3667. {
  3668. // Use least squares to find the solution with the smallest error.
  3669. // That is, find the vector x so that |Ax-b|^2 is minimized, where
  3670. // x = [Ro Rr Rv]';
  3671. // A = [1 3/4 2/4 1/4 3/4 2/4 1/4 0 2/4 1/4 0 -1/4 1/4 0 -1/4 -2/4 ;
  3672. // 0 1/4 2/4 3/4 0 1/4 2/4 3/4 0 1/4 2/4 3/4 0 1/4 2/4 3/4 ;
  3673. // 0 0 0 0 1/4 1/4 1/4 1/4 2/4 2/4 2/4 2/4; 3/4 3/4 3/4 3/4]';
  3674. // b = [r11 r12 r13 r14 r21 r22 r23 r24 r31 r32 r33 r34 r41 r42 r43 r44];
  3675. //
  3676. // That is, find solution x = inv(A' * A) * A' * b
  3677. // = C * A' * b;
  3678. // C is always the same, so we have calculated it off-line here.
  3679. // = C * D
  3680. int xx,yy, cc;
  3681. double coeffsA[48]= { 1.00, 0.00, 0.00,
  3682. 0.75, 0.25, 0.00,
  3683. 0.50, 0.50, 0.00,
  3684. 0.25, 0.75, 0.00,
  3685. 0.75, 0.00, 0.25,
  3686. 0.50, 0.25, 0.25,
  3687. 0.25, 0.50, 0.25,
  3688. 0.00, 0.75, 0.25,
  3689. 0.50, 0.00, 0.50,
  3690. 0.25, 0.25, 0.50,
  3691. 0.00, 0.50, 0.50,
  3692. -0.25, 0.75, 0.50,
  3693. 0.25, 0.00, 0.75,
  3694. 0.00, 0.25, 0.75,
  3695. -0.25, 0.50, 0.75,
  3696. -0.50, 0.75, 0.75};
  3697. double coeffsC[9] = {0.2875, -0.0125, -0.0125, -0.0125, 0.4875, -0.3125, -0.0125, -0.3125, 0.4875};
  3698. double colorO[3], colorH[3], colorV[3];
  3699. uint8 colorO8[3], colorH8[3], colorV8[3];
  3700. dMatrix *D_matrix;
  3701. dMatrix *x_vector;
  3702. dMatrix A_matrix; A_matrix.width = 3; A_matrix.height = 16;
  3703. A_matrix.data = coeffsA;
  3704. dMatrix C_matrix; C_matrix.width = 3; C_matrix.height = 3;
  3705. C_matrix.data = coeffsC;
  3706. dMatrix b_vector; b_vector.width = 1; b_vector.height = 16;
  3707. b_vector.data = (double*) malloc(sizeof(double)*b_vector.width*b_vector.height);
  3708. transposeMatrix(&A_matrix);
  3709. // Red component
  3710. // Load color data into vector b:
  3711. for(cc = 0, yy = 0; yy<4; yy++)
  3712. for(xx = 0; xx<4; xx++)
  3713. b_vector.data[cc++] = img[3*width*(starty+yy) + 3*(startx+xx) + 0];
  3714. D_matrix = multiplyMatrices(&A_matrix, &b_vector);
  3715. x_vector = multiplyMatrices(&C_matrix, D_matrix);
  3716. colorO[0] = CLAMP(0.0, x_vector->data[0], 255.0);
  3717. colorH[0] = CLAMP(0.0, x_vector->data[1], 255.0);
  3718. colorV[0] = CLAMP(0.0, x_vector->data[2], 255.0);
  3719. free(D_matrix->data); free(D_matrix);
  3720. free(x_vector->data); free(x_vector);
  3721. // Green component
  3722. // Load color data into vector b:
  3723. for(cc = 0, yy = 0; yy<4; yy++)
  3724. for(xx = 0; xx<4; xx++)
  3725. b_vector.data[cc++] = img[3*width*(starty+yy) + 3*(startx+xx) + 1];
  3726. D_matrix = multiplyMatrices(&A_matrix, &b_vector);
  3727. x_vector = multiplyMatrices(&C_matrix, D_matrix);
  3728. colorO[1] = CLAMP(0.0, x_vector->data[0], 255.0);
  3729. colorH[1] = CLAMP(0.0, x_vector->data[1], 255.0);
  3730. colorV[1] = CLAMP(0.0, x_vector->data[2], 255.0);
  3731. free(D_matrix->data); free(D_matrix);
  3732. free(x_vector->data); free(x_vector);
  3733. // Blue component
  3734. // Load color data into vector b:
  3735. for(cc = 0, yy = 0; yy<4; yy++)
  3736. for(xx = 0; xx<4; xx++)
  3737. b_vector.data[cc++] = img[3*width*(starty+yy) + 3*(startx+xx) + 2];
  3738. D_matrix = multiplyMatrices(&A_matrix, &b_vector);
  3739. x_vector = multiplyMatrices(&C_matrix, D_matrix);
  3740. colorO[2] = CLAMP(0.0, x_vector->data[0], 255.0);
  3741. colorH[2] = CLAMP(0.0, x_vector->data[1], 255.0);
  3742. colorV[2] = CLAMP(0.0, x_vector->data[2], 255.0);
  3743. free(D_matrix->data); free(D_matrix);
  3744. free(x_vector->data); free(x_vector);
  3745. // Quantize to 6 bits
  3746. double D = 255*(1.0/((1<<6)-1.0) );
  3747. colorO8[0] = JAS_ROUND((1.0*colorO[0])/D);
  3748. colorO8[2] = JAS_ROUND((1.0*colorO[2])/D);
  3749. colorH8[0] = JAS_ROUND((1.0*colorH[0])/D);
  3750. colorH8[2] = JAS_ROUND((1.0*colorH[2])/D);
  3751. colorV8[0] = JAS_ROUND((1.0*colorV[0])/D);
  3752. colorV8[2] = JAS_ROUND((1.0*colorV[2])/D);
  3753. // Quantize to 7 bits
  3754. D = 255*(1.0/((1<<7)-1.0) );
  3755. colorO8[1] = JAS_ROUND((1.0*colorO[1])/D);
  3756. colorH8[1] = JAS_ROUND((1.0*colorH[1])/D);
  3757. colorV8[1] = JAS_ROUND((1.0*colorV[1])/D);
  3758. // Pack bits in 57 bits
  3759. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  3760. // ------------------------------------------------------------------------------------------------
  3761. // | R0 | G0 | B0 | RH | GH |
  3762. // ------------------------------------------------------------------------------------------------
  3763. //
  3764. // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  3765. // ------------------------------------------------------------------------------------------------
  3766. // | BH | RV | GV | BV | not used |
  3767. // ------------------------------------------------------------------------------------------------
  3768. compressed57_1 = 0;
  3769. compressed57_2 = 0;
  3770. PUTBITSHIGH( compressed57_1, colorO8[0], 6, 63);
  3771. PUTBITSHIGH( compressed57_1, colorO8[1], 7, 57);
  3772. PUTBITSHIGH( compressed57_1, colorO8[2], 6, 50);
  3773. PUTBITSHIGH( compressed57_1, colorH8[0], 6, 44);
  3774. PUTBITSHIGH( compressed57_1, colorH8[1], 7, 38);
  3775. PUTBITS( compressed57_2, colorH8[2], 6, 31);
  3776. PUTBITS( compressed57_2, colorV8[0], 6, 25);
  3777. PUTBITS( compressed57_2, colorV8[1], 7, 19);
  3778. PUTBITS( compressed57_2, colorV8[2], 6, 12);
  3779. }
  3780. // During search it is not convenient to store the bits the way they are stored in the
  3781. // file format. Hence, after search, it is converted to this format.
  3782. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3783. void stuff57bits(unsigned int planar57_word1, unsigned int planar57_word2, unsigned int &planar_word1, unsigned int &planar_word2)
  3784. {
  3785. // Put bits in twotimer configuration for 57 bits (red and green dont overflow, green does)
  3786. //
  3787. // Go from this bit layout:
  3788. //
  3789. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  3790. // -----------------------------------------------------------------------------------------------
  3791. // |R0 |G01G02 |B01B02 ;B03 |RH1 |RH2|GH |
  3792. // -----------------------------------------------------------------------------------------------
  3793. //
  3794. // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  3795. // -----------------------------------------------------------------------------------------------
  3796. // |BH |RV |GV |BV | not used |
  3797. // -----------------------------------------------------------------------------------------------
  3798. //
  3799. // To this:
  3800. //
  3801. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  3802. // ------------------------------------------------------------------------------------------------
  3803. // |//|R0 |G01|/|G02 |B01|/ // //|B02 |//|B03 |RH1 |df|RH2|
  3804. // ------------------------------------------------------------------------------------------------
  3805. //
  3806. // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  3807. // -----------------------------------------------------------------------------------------------
  3808. // |GH |BH |RV |GV |BV |
  3809. // -----------------------------------------------------------------------------------------------
  3810. //
  3811. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  3812. // ---------------------------------------------------------------------------------------------------
  3813. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |diff|flip|
  3814. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
  3815. // ---------------------------------------------------------------------------------------------------
  3816. uint8 RO, GO1, GO2, BO1, BO2, BO3, RH1, RH2, GH, BH, RV, GV, BV;
  3817. uint8 bit, a, b, c, d, bits;
  3818. RO = GETBITSHIGH( planar57_word1, 6, 63);
  3819. GO1= GETBITSHIGH( planar57_word1, 1, 57);
  3820. GO2= GETBITSHIGH( planar57_word1, 6, 56);
  3821. BO1= GETBITSHIGH( planar57_word1, 1, 50);
  3822. BO2= GETBITSHIGH( planar57_word1, 2, 49);
  3823. BO3= GETBITSHIGH( planar57_word1, 3, 47);
  3824. RH1= GETBITSHIGH( planar57_word1, 5, 44);
  3825. RH2= GETBITSHIGH( planar57_word1, 1, 39);
  3826. GH = GETBITSHIGH( planar57_word1, 7, 38);
  3827. BH = GETBITS( planar57_word2, 6, 31);
  3828. RV = GETBITS( planar57_word2, 6, 25);
  3829. GV = GETBITS( planar57_word2, 7, 19);
  3830. BV = GETBITS( planar57_word2, 6, 12);
  3831. planar_word1 = 0; planar_word2 = 0;
  3832. PUTBITSHIGH( planar_word1, RO, 6, 62);
  3833. PUTBITSHIGH( planar_word1, GO1, 1, 56);
  3834. PUTBITSHIGH( planar_word1, GO2, 6, 54);
  3835. PUTBITSHIGH( planar_word1, BO1, 1, 48);
  3836. PUTBITSHIGH( planar_word1, BO2, 2, 44);
  3837. PUTBITSHIGH( planar_word1, BO3, 3, 41);
  3838. PUTBITSHIGH( planar_word1, RH1, 5, 38);
  3839. PUTBITSHIGH( planar_word1, RH2, 1, 32);
  3840. PUTBITS( planar_word2, GH, 7, 31);
  3841. PUTBITS( planar_word2, BH, 6, 24);
  3842. PUTBITS( planar_word2, RV, 6, 18);
  3843. PUTBITS( planar_word2, GV, 7, 12);
  3844. PUTBITS( planar_word2, BV, 6, 5);
  3845. // Make sure that red does not overflow:
  3846. bit = GETBITSHIGH( planar_word1, 1, 62);
  3847. PUTBITSHIGH( planar_word1, !bit, 1, 63);
  3848. // Make sure that green does not overflow:
  3849. bit = GETBITSHIGH( planar_word1, 1, 54);
  3850. PUTBITSHIGH( planar_word1, !bit, 1, 55);
  3851. // Make sure that blue overflows:
  3852. a = GETBITSHIGH( planar_word1, 1, 44);
  3853. b = GETBITSHIGH( planar_word1, 1, 43);
  3854. c = GETBITSHIGH( planar_word1, 1, 41);
  3855. d = GETBITSHIGH( planar_word1, 1, 40);
  3856. // The following bit abcd bit sequences should be padded with ones: 0111, 1010, 1011, 1101, 1110, 1111
  3857. // The following logical expression checks for the presence of any of those:
  3858. bit = (a & c) | (!a & b & c & d) | (a & b & !c & d);
  3859. bits = 0xf*bit;
  3860. PUTBITSHIGH( planar_word1, bits, 3, 47);
  3861. PUTBITSHIGH( planar_word1, !bit, 1, 42);
  3862. // Set diffbit
  3863. PUTBITSHIGH( planar_word1, 1, 1, 33);
  3864. }
  3865. // During search it is not convenient to store the bits the way they are stored in the
  3866. // file format. Hence, after search, it is converted to this format.
  3867. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3868. void stuff58bits(unsigned int thumbH58_word1, unsigned int thumbH58_word2, unsigned int &thumbH_word1, unsigned int &thumbH_word2)
  3869. {
  3870. // Put bits in twotimer configuration for 58 (red doesn't overflow, green does)
  3871. //
  3872. // Go from this bit layout:
  3873. //
  3874. //
  3875. // |63 62 61 60 59 58|57 56 55 54|53 52 51 50|49 48 47 46|45 44 43 42|41 40 39 38|37 36 35 34|33 32|
  3876. // |-------empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|d2 d1|
  3877. //
  3878. // |31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  3879. // |---------------------------------------index bits----------------------------------------------|
  3880. //
  3881. // To this:
  3882. //
  3883. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  3884. // -----------------------------------------------------------------------------------------------
  3885. // |//|R0 |G0 |// // //|G0|B0|//|B0b |R1 |G1 |B0 |d2|df|d1|
  3886. // -----------------------------------------------------------------------------------------------
  3887. //
  3888. // |31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  3889. // |---------------------------------------index bits----------------------------------------------|
  3890. //
  3891. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  3892. // -----------------------------------------------------------------------------------------------
  3893. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |df|fp|
  3894. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bt|bt|
  3895. // -----------------------------------------------------------------------------------------------
  3896. //
  3897. //
  3898. // Thus, what we are really doing is going from this bit layout:
  3899. //
  3900. //
  3901. // |63 62 61 60 59 58|57 56 55 54 53 52 51|50 49|48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33|32 |
  3902. // |-------empty-----|part0---------------|part1|part2------------------------------------------|part3|
  3903. //
  3904. // To this:
  3905. //
  3906. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  3907. // --------------------------------------------------------------------------------------------------|
  3908. // |//|part0 |// // //|part1|//|part2 |df|part3|
  3909. // --------------------------------------------------------------------------------------------------|
  3910. unsigned int part0, part1, part2, part3;
  3911. uint8 bit, a, b, c, d, bits;
  3912. // move parts
  3913. part0 = GETBITSHIGH( thumbH58_word1, 7, 57);
  3914. part1 = GETBITSHIGH( thumbH58_word1, 2, 50);
  3915. part2 = GETBITSHIGH( thumbH58_word1,16, 48);
  3916. part3 = GETBITSHIGH( thumbH58_word1, 1, 32);
  3917. thumbH_word1 = 0;
  3918. PUTBITSHIGH( thumbH_word1, part0, 7, 62);
  3919. PUTBITSHIGH( thumbH_word1, part1, 2, 52);
  3920. PUTBITSHIGH( thumbH_word1, part2, 16, 49);
  3921. PUTBITSHIGH( thumbH_word1, part3, 1, 32);
  3922. // Make sure that red does not overflow:
  3923. bit = GETBITSHIGH( thumbH_word1, 1, 62);
  3924. PUTBITSHIGH( thumbH_word1, !bit, 1, 63);
  3925. // Make sure that green overflows:
  3926. a = GETBITSHIGH( thumbH_word1, 1, 52);
  3927. b = GETBITSHIGH( thumbH_word1, 1, 51);
  3928. c = GETBITSHIGH( thumbH_word1, 1, 49);
  3929. d = GETBITSHIGH( thumbH_word1, 1, 48);
  3930. // The following bit abcd bit sequences should be padded with ones: 0111, 1010, 1011, 1101, 1110, 1111
  3931. // The following logical expression checks for the presence of any of those:
  3932. bit = (a & c) | (!a & b & c & d) | (a & b & !c & d);
  3933. bits = 0xf*bit;
  3934. PUTBITSHIGH( thumbH_word1, bits, 3, 55);
  3935. PUTBITSHIGH( thumbH_word1, !bit, 1, 50);
  3936. // Set diffbit
  3937. PUTBITSHIGH( thumbH_word1, 1, 1, 33);
  3938. thumbH_word2 = thumbH58_word2;
  3939. }
  3940. // copy of above, but diffbit is 0
  3941. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3942. void stuff58bitsDiffFalse(unsigned int thumbH58_word1, unsigned int thumbH58_word2, unsigned int &thumbH_word1, unsigned int &thumbH_word2)
  3943. {
  3944. unsigned int part0, part1, part2, part3;
  3945. uint8 bit, a, b, c, d, bits;
  3946. // move parts
  3947. part0 = GETBITSHIGH( thumbH58_word1, 7, 57);
  3948. part1 = GETBITSHIGH( thumbH58_word1, 2, 50);
  3949. part2 = GETBITSHIGH( thumbH58_word1,16, 48);
  3950. part3 = GETBITSHIGH( thumbH58_word1, 1, 32);
  3951. thumbH_word1 = 0;
  3952. PUTBITSHIGH( thumbH_word1, part0, 7, 62);
  3953. PUTBITSHIGH( thumbH_word1, part1, 2, 52);
  3954. PUTBITSHIGH( thumbH_word1, part2, 16, 49);
  3955. PUTBITSHIGH( thumbH_word1, part3, 1, 32);
  3956. // Make sure that red does not overflow:
  3957. bit = GETBITSHIGH( thumbH_word1, 1, 62);
  3958. PUTBITSHIGH( thumbH_word1, !bit, 1, 63);
  3959. // Make sure that green overflows:
  3960. a = GETBITSHIGH( thumbH_word1, 1, 52);
  3961. b = GETBITSHIGH( thumbH_word1, 1, 51);
  3962. c = GETBITSHIGH( thumbH_word1, 1, 49);
  3963. d = GETBITSHIGH( thumbH_word1, 1, 48);
  3964. // The following bit abcd bit sequences should be padded with ones: 0111, 1010, 1011, 1101, 1110, 1111
  3965. // The following logical expression checks for the presence of any of those:
  3966. bit = (a & c) | (!a & b & c & d) | (a & b & !c & d);
  3967. bits = 0xf*bit;
  3968. PUTBITSHIGH( thumbH_word1, bits, 3, 55);
  3969. PUTBITSHIGH( thumbH_word1, !bit, 1, 50);
  3970. // Set diffbit
  3971. PUTBITSHIGH( thumbH_word1, 0, 1, 33);
  3972. thumbH_word2 = thumbH58_word2;
  3973. }
  3974. // During search it is not convenient to store the bits the way they are stored in the
  3975. // file format. Hence, after search, it is converted to this format.
  3976. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  3977. void stuff59bits(unsigned int thumbT59_word1, unsigned int thumbT59_word2, unsigned int &thumbT_word1, unsigned int &thumbT_word2)
  3978. {
  3979. // Put bits in twotimer configuration for 59 (red overflows)
  3980. //
  3981. // Go from this bit layout:
  3982. //
  3983. // |63 62 61 60 59|58 57 56 55|54 53 52 51|50 49 48 47|46 45 44 43|42 41 40 39|38 37 36 35|34 33 32|
  3984. // |----empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|--dist--|
  3985. //
  3986. // |31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  3987. // |----------------------------------------index bits---------------------------------------------|
  3988. //
  3989. //
  3990. // To this:
  3991. //
  3992. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  3993. // -----------------------------------------------------------------------------------------------
  3994. // |// // //|R0a |//|R0b |G0 |B0 |R1 |G1 |B1 |da |df|db|
  3995. // -----------------------------------------------------------------------------------------------
  3996. //
  3997. // |31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  3998. // |----------------------------------------index bits---------------------------------------------|
  3999. //
  4000. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  4001. // -----------------------------------------------------------------------------------------------
  4002. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |df|fp|
  4003. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bt|bt|
  4004. // ------------------------------------------------------------------------------------------------
  4005. uint8 R0a;
  4006. uint8 bit, a, b, c, d, bits;
  4007. R0a = GETBITSHIGH( thumbT59_word1, 2, 58);
  4008. // Fix middle part
  4009. thumbT_word1 = thumbT59_word1 << 1;
  4010. // Fix R0a (top two bits of R0)
  4011. PUTBITSHIGH( thumbT_word1, R0a, 2, 60);
  4012. // Fix db (lowest bit of d)
  4013. PUTBITSHIGH( thumbT_word1, thumbT59_word1, 1, 32);
  4014. //
  4015. // Make sure that red overflows:
  4016. a = GETBITSHIGH( thumbT_word1, 1, 60);
  4017. b = GETBITSHIGH( thumbT_word1, 1, 59);
  4018. c = GETBITSHIGH( thumbT_word1, 1, 57);
  4019. d = GETBITSHIGH( thumbT_word1, 1, 56);
  4020. // The following bit abcd bit sequences should be padded with ones: 0111, 1010, 1011, 1101, 1110, 1111
  4021. // The following logical expression checks for the presence of any of those:
  4022. bit = (a & c) | (!a & b & c & d) | (a & b & !c & d);
  4023. bits = 0xf*bit;
  4024. PUTBITSHIGH( thumbT_word1, bits, 3, 63);
  4025. PUTBITSHIGH( thumbT_word1, !bit, 1, 58);
  4026. // Set diffbit
  4027. PUTBITSHIGH( thumbT_word1, 1, 1, 33);
  4028. thumbT_word2 = thumbT59_word2;
  4029. }
  4030. // Decompress the planar mode and calculate the error per component compared to original image.
  4031. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  4032. void decompressBlockPlanar57errorPerComponent(unsigned int compressed57_1, unsigned int compressed57_2, uint8 *img,int width,int height,int startx,int starty, uint8 *srcimg, unsigned int &error_red, unsigned int &error_green, unsigned int &error_blue)
  4033. {
  4034. uint8 colorO[3], colorH[3], colorV[3];
  4035. colorO[0] = GETBITSHIGH( compressed57_1, 6, 63);
  4036. colorO[1] = GETBITSHIGH( compressed57_1, 7, 57);
  4037. colorO[2] = GETBITSHIGH( compressed57_1, 6, 50);
  4038. colorH[0] = GETBITSHIGH( compressed57_1, 6, 44);
  4039. colorH[1] = GETBITSHIGH( compressed57_1, 7, 38);
  4040. colorH[2] = GETBITS( compressed57_2, 6, 31);
  4041. colorV[0] = GETBITS( compressed57_2, 6, 25);
  4042. colorV[1] = GETBITS( compressed57_2, 7, 19);
  4043. colorV[2] = GETBITS( compressed57_2, 6, 12);
  4044. colorO[0] = (colorO[0] << 2) | (colorO[0] >> 4);
  4045. colorO[1] = (colorO[1] << 1) | (colorO[1] >> 6);
  4046. colorO[2] = (colorO[2] << 2) | (colorO[2] >> 4);
  4047. colorH[0] = (colorH[0] << 2) | (colorH[0] >> 4);
  4048. colorH[1] = (colorH[1] << 1) | (colorH[1] >> 6);
  4049. colorH[2] = (colorH[2] << 2) | (colorH[2] >> 4);
  4050. colorV[0] = (colorV[0] << 2) | (colorV[0] >> 4);
  4051. colorV[1] = (colorV[1] << 1) | (colorV[1] >> 6);
  4052. colorV[2] = (colorV[2] << 2) | (colorV[2] >> 4);
  4053. int xx, yy;
  4054. for( xx=0; xx<4; xx++)
  4055. {
  4056. for( yy=0; yy<4; yy++)
  4057. {
  4058. img[3*width*(starty+yy) + 3*(startx+xx) + 0] = (int)CLAMP(0, JAS_ROUND((xx*(colorH[0]-colorO[0])/4.0 + yy*(colorV[0]-colorO[0])/4.0 + colorO[0])), 255);
  4059. img[3*width*(starty+yy) + 3*(startx+xx) + 1] = (int)CLAMP(0, JAS_ROUND((xx*(colorH[1]-colorO[1])/4.0 + yy*(colorV[1]-colorO[1])/4.0 + colorO[1])), 255);
  4060. img[3*width*(starty+yy) + 3*(startx+xx) + 2] = (int)CLAMP(0, JAS_ROUND((xx*(colorH[2]-colorO[2])/4.0 + yy*(colorV[2]-colorO[2])/4.0 + colorO[2])), 255);
  4061. }
  4062. }
  4063. error_red = 0;
  4064. error_green= 0;
  4065. error_blue = 0;
  4066. for( xx=0; xx<4; xx++)
  4067. {
  4068. for( yy=0; yy<4; yy++)
  4069. {
  4070. error_red = error_red + SQUARE(srcimg[3*width*(starty+yy) + 3*(startx+xx) + 0] - img[3*width*(starty+yy) + 3*(startx+xx) + 0]);
  4071. error_green = error_green + SQUARE(srcimg[3*width*(starty+yy) + 3*(startx+xx) + 1] - img[3*width*(starty+yy) + 3*(startx+xx) + 1]);
  4072. error_blue = error_blue + SQUARE(srcimg[3*width*(starty+yy) + 3*(startx+xx) + 2] - img[3*width*(starty+yy) + 3*(startx+xx) + 2]);
  4073. }
  4074. }
  4075. }
  4076. // Compress using both individual and differential mode in ETC1/ETC2 using combined color
  4077. // quantization. Both flip modes are tried.
  4078. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  4079. void compressBlockDiffFlipCombined(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  4080. {
  4081. unsigned int compressed1_norm, compressed2_norm;
  4082. unsigned int compressed1_flip, compressed2_flip;
  4083. uint8 avg_color_quant1[3], avg_color_quant2[3];
  4084. float avg_color_float1[3],avg_color_float2[3];
  4085. int enc_color1[3], enc_color2[3], diff[3];
  4086. int min_error=255*255*8*3;
  4087. unsigned int best_table_indices1=0, best_table_indices2=0;
  4088. unsigned int best_table1=0, best_table2=0;
  4089. int diffbit;
  4090. int norm_err=0;
  4091. int flip_err=0;
  4092. // First try normal blocks 2x4:
  4093. computeAverageColor2x4noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  4094. computeAverageColor2x4noQuantFloat(img,width,height,startx+2,starty,avg_color_float2);
  4095. // First test if avg_color1 is similar enough to avg_color2 so that
  4096. // we can use differential coding of colors.
  4097. float eps;
  4098. uint8 dummy[3];
  4099. quantize555ColorCombined(avg_color_float1, enc_color1, dummy);
  4100. quantize555ColorCombined(avg_color_float2, enc_color2, dummy);
  4101. diff[0] = enc_color2[0]-enc_color1[0];
  4102. diff[1] = enc_color2[1]-enc_color1[1];
  4103. diff[2] = enc_color2[2]-enc_color1[2];
  4104. if( (diff[0] >= -4) && (diff[0] <= 3) && (diff[1] >= -4) && (diff[1] <= 3) && (diff[2] >= -4) && (diff[2] <= 3) )
  4105. {
  4106. diffbit = 1;
  4107. // The difference to be coded:
  4108. diff[0] = enc_color2[0]-enc_color1[0];
  4109. diff[1] = enc_color2[1]-enc_color1[1];
  4110. diff[2] = enc_color2[2]-enc_color1[2];
  4111. avg_color_quant1[0] = enc_color1[0] << 3 | (enc_color1[0] >> 2);
  4112. avg_color_quant1[1] = enc_color1[1] << 3 | (enc_color1[1] >> 2);
  4113. avg_color_quant1[2] = enc_color1[2] << 3 | (enc_color1[2] >> 2);
  4114. avg_color_quant2[0] = enc_color2[0] << 3 | (enc_color2[0] >> 2);
  4115. avg_color_quant2[1] = enc_color2[1] << 3 | (enc_color2[1] >> 2);
  4116. avg_color_quant2[2] = enc_color2[2] << 3 | (enc_color2[2] >> 2);
  4117. // Pack bits into the first word.
  4118. // ETC1_RGB8_OES:
  4119. //
  4120. // a) bit layout in bits 63 through 32 if diffbit = 0
  4121. //
  4122. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  4123. // ---------------------------------------------------------------------------------------------------
  4124. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  4125. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  4126. // ---------------------------------------------------------------------------------------------------
  4127. //
  4128. // b) bit layout in bits 63 through 32 if diffbit = 1
  4129. //
  4130. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  4131. // ---------------------------------------------------------------------------------------------------
  4132. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |diff|flip|
  4133. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
  4134. // ---------------------------------------------------------------------------------------------------
  4135. //
  4136. // c) bit layout in bits 31 through 0 (in both cases)
  4137. //
  4138. // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  4139. // --------------------------------------------------------------------------------------------------
  4140. // | most significant pixel index bits | least significant pixel index bits |
  4141. // | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a| p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
  4142. // --------------------------------------------------------------------------------------------------
  4143. compressed1_norm = 0;
  4144. PUTBITSHIGH( compressed1_norm, diffbit, 1, 33);
  4145. PUTBITSHIGH( compressed1_norm, enc_color1[0], 5, 63);
  4146. PUTBITSHIGH( compressed1_norm, enc_color1[1], 5, 55);
  4147. PUTBITSHIGH( compressed1_norm, enc_color1[2], 5, 47);
  4148. PUTBITSHIGH( compressed1_norm, diff[0], 3, 58);
  4149. PUTBITSHIGH( compressed1_norm, diff[1], 3, 50);
  4150. PUTBITSHIGH( compressed1_norm, diff[2], 3, 42);
  4151. unsigned int best_pixel_indices1_MSB;
  4152. unsigned int best_pixel_indices1_LSB;
  4153. unsigned int best_pixel_indices2_MSB;
  4154. unsigned int best_pixel_indices2_LSB;
  4155. norm_err = 0;
  4156. // left part of block
  4157. norm_err = tryalltables_3bittable2x4(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  4158. // right part of block
  4159. norm_err += tryalltables_3bittable2x4(img,width,height,startx+2,starty,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  4160. PUTBITSHIGH( compressed1_norm, best_table1, 3, 39);
  4161. PUTBITSHIGH( compressed1_norm, best_table2, 3, 36);
  4162. PUTBITSHIGH( compressed1_norm, 0, 1, 32);
  4163. compressed2_norm = 0;
  4164. PUTBITS( compressed2_norm, (best_pixel_indices1_MSB ), 8, 23);
  4165. PUTBITS( compressed2_norm, (best_pixel_indices2_MSB ), 8, 31);
  4166. PUTBITS( compressed2_norm, (best_pixel_indices1_LSB ), 8, 7);
  4167. PUTBITS( compressed2_norm, (best_pixel_indices2_LSB ), 8, 15);
  4168. }
  4169. else
  4170. {
  4171. diffbit = 0;
  4172. // The difference is bigger than what fits in 555 plus delta-333, so we will have
  4173. // to deal with 444 444.
  4174. eps = (float) 0.0001;
  4175. uint8 dummy[3];
  4176. quantize444ColorCombined(avg_color_float1, enc_color1, dummy);
  4177. quantize444ColorCombined(avg_color_float2, enc_color2, dummy);
  4178. avg_color_quant1[0] = enc_color1[0] << 4 | enc_color1[0];
  4179. avg_color_quant1[1] = enc_color1[1] << 4 | enc_color1[1];
  4180. avg_color_quant1[2] = enc_color1[2] << 4 | enc_color1[2];
  4181. avg_color_quant2[0] = enc_color2[0] << 4 | enc_color2[0];
  4182. avg_color_quant2[1] = enc_color2[1] << 4 | enc_color2[1];
  4183. avg_color_quant2[2] = enc_color2[2] << 4 | enc_color2[2];
  4184. // Pack bits into the first word.
  4185. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  4186. // ---------------------------------------------------------------------------------------------------
  4187. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  4188. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  4189. // ---------------------------------------------------------------------------------------------------
  4190. compressed1_norm = 0;
  4191. PUTBITSHIGH( compressed1_norm, diffbit, 1, 33);
  4192. PUTBITSHIGH( compressed1_norm, enc_color1[0], 4, 63);
  4193. PUTBITSHIGH( compressed1_norm, enc_color1[1], 4, 55);
  4194. PUTBITSHIGH( compressed1_norm, enc_color1[2], 4, 47);
  4195. PUTBITSHIGH( compressed1_norm, enc_color2[0], 4, 59);
  4196. PUTBITSHIGH( compressed1_norm, enc_color2[1], 4, 51);
  4197. PUTBITSHIGH( compressed1_norm, enc_color2[2], 4, 43);
  4198. unsigned int best_pixel_indices1_MSB;
  4199. unsigned int best_pixel_indices1_LSB;
  4200. unsigned int best_pixel_indices2_MSB;
  4201. unsigned int best_pixel_indices2_LSB;
  4202. // left part of block
  4203. norm_err = tryalltables_3bittable2x4(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  4204. // right part of block
  4205. norm_err += tryalltables_3bittable2x4(img,width,height,startx+2,starty,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  4206. PUTBITSHIGH( compressed1_norm, best_table1, 3, 39);
  4207. PUTBITSHIGH( compressed1_norm, best_table2, 3, 36);
  4208. PUTBITSHIGH( compressed1_norm, 0, 1, 32);
  4209. compressed2_norm = 0;
  4210. PUTBITS( compressed2_norm, (best_pixel_indices1_MSB ), 8, 23);
  4211. PUTBITS( compressed2_norm, (best_pixel_indices2_MSB ), 8, 31);
  4212. PUTBITS( compressed2_norm, (best_pixel_indices1_LSB ), 8, 7);
  4213. PUTBITS( compressed2_norm, (best_pixel_indices2_LSB ), 8, 15);
  4214. }
  4215. // Now try flipped blocks 4x2:
  4216. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  4217. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty+2,avg_color_float2);
  4218. // First test if avg_color1 is similar enough to avg_color2 so that
  4219. // we can use differential coding of colors.
  4220. quantize555ColorCombined(avg_color_float1, enc_color1, dummy);
  4221. quantize555ColorCombined(avg_color_float2, enc_color2, dummy);
  4222. diff[0] = enc_color2[0]-enc_color1[0];
  4223. diff[1] = enc_color2[1]-enc_color1[1];
  4224. diff[2] = enc_color2[2]-enc_color1[2];
  4225. if( (diff[0] >= -4) && (diff[0] <= 3) && (diff[1] >= -4) && (diff[1] <= 3) && (diff[2] >= -4) && (diff[2] <= 3) )
  4226. {
  4227. diffbit = 1;
  4228. // The difference to be coded:
  4229. diff[0] = enc_color2[0]-enc_color1[0];
  4230. diff[1] = enc_color2[1]-enc_color1[1];
  4231. diff[2] = enc_color2[2]-enc_color1[2];
  4232. avg_color_quant1[0] = enc_color1[0] << 3 | (enc_color1[0] >> 2);
  4233. avg_color_quant1[1] = enc_color1[1] << 3 | (enc_color1[1] >> 2);
  4234. avg_color_quant1[2] = enc_color1[2] << 3 | (enc_color1[2] >> 2);
  4235. avg_color_quant2[0] = enc_color2[0] << 3 | (enc_color2[0] >> 2);
  4236. avg_color_quant2[1] = enc_color2[1] << 3 | (enc_color2[1] >> 2);
  4237. avg_color_quant2[2] = enc_color2[2] << 3 | (enc_color2[2] >> 2);
  4238. // Pack bits into the first word.
  4239. compressed1_flip = 0;
  4240. PUTBITSHIGH( compressed1_flip, diffbit, 1, 33);
  4241. PUTBITSHIGH( compressed1_flip, enc_color1[0], 5, 63);
  4242. PUTBITSHIGH( compressed1_flip, enc_color1[1], 5, 55);
  4243. PUTBITSHIGH( compressed1_flip, enc_color1[2], 5, 47);
  4244. PUTBITSHIGH( compressed1_flip, diff[0], 3, 58);
  4245. PUTBITSHIGH( compressed1_flip, diff[1], 3, 50);
  4246. PUTBITSHIGH( compressed1_flip, diff[2], 3, 42);
  4247. unsigned int best_pixel_indices1_MSB;
  4248. unsigned int best_pixel_indices1_LSB;
  4249. unsigned int best_pixel_indices2_MSB;
  4250. unsigned int best_pixel_indices2_LSB;
  4251. // upper part of block
  4252. flip_err = tryalltables_3bittable4x2(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  4253. // lower part of block
  4254. flip_err += tryalltables_3bittable4x2(img,width,height,startx,starty+2,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  4255. PUTBITSHIGH( compressed1_flip, best_table1, 3, 39);
  4256. PUTBITSHIGH( compressed1_flip, best_table2, 3, 36);
  4257. PUTBITSHIGH( compressed1_flip, 1, 1, 32);
  4258. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  4259. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  4260. compressed2_flip = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  4261. }
  4262. else
  4263. {
  4264. diffbit = 0;
  4265. // The difference is bigger than what fits in 555 plus delta-333, so we will have
  4266. // to deal with 444 444.
  4267. eps = (float) 0.0001;
  4268. uint8 dummy[3];
  4269. quantize444ColorCombined(avg_color_float1, enc_color1, dummy);
  4270. quantize444ColorCombined(avg_color_float2, enc_color2, dummy);
  4271. avg_color_quant1[0] = enc_color1[0] << 4 | enc_color1[0];
  4272. avg_color_quant1[1] = enc_color1[1] << 4 | enc_color1[1];
  4273. avg_color_quant1[2] = enc_color1[2] << 4 | enc_color1[2];
  4274. avg_color_quant2[0] = enc_color2[0] << 4 | enc_color2[0];
  4275. avg_color_quant2[1] = enc_color2[1] << 4 | enc_color2[1];
  4276. avg_color_quant2[2] = enc_color2[2] << 4 | enc_color2[2];
  4277. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  4278. // ---------------------------------------------------------------------------------------------------
  4279. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  4280. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  4281. // ---------------------------------------------------------------------------------------------------
  4282. // Pack bits into the first word.
  4283. compressed1_flip = 0;
  4284. PUTBITSHIGH( compressed1_flip, diffbit, 1, 33);
  4285. PUTBITSHIGH( compressed1_flip, enc_color1[0], 4, 63);
  4286. PUTBITSHIGH( compressed1_flip, enc_color1[1], 4, 55);
  4287. PUTBITSHIGH( compressed1_flip, enc_color1[2], 4, 47);
  4288. PUTBITSHIGH( compressed1_flip, enc_color2[0], 4, 59);
  4289. PUTBITSHIGH( compressed1_flip, enc_color2[1], 4, 51);
  4290. PUTBITSHIGH( compressed1_flip, enc_color2[2], 4, 43);
  4291. unsigned int best_pixel_indices1_MSB;
  4292. unsigned int best_pixel_indices1_LSB;
  4293. unsigned int best_pixel_indices2_MSB;
  4294. unsigned int best_pixel_indices2_LSB;
  4295. // upper part of block
  4296. flip_err = tryalltables_3bittable4x2(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  4297. // lower part of block
  4298. flip_err += tryalltables_3bittable4x2(img,width,height,startx,starty+2,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  4299. PUTBITSHIGH( compressed1_flip, best_table1, 3, 39);
  4300. PUTBITSHIGH( compressed1_flip, best_table2, 3, 36);
  4301. PUTBITSHIGH( compressed1_flip, 1, 1, 32);
  4302. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  4303. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  4304. compressed2_flip = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  4305. }
  4306. // Now lets see which is the best table to use. Only 8 tables are possible.
  4307. if(norm_err <= flip_err)
  4308. {
  4309. compressed1 = compressed1_norm | 0;
  4310. compressed2 = compressed2_norm;
  4311. }
  4312. else
  4313. {
  4314. compressed1 = compressed1_flip | 1;
  4315. compressed2 = compressed2_flip;
  4316. }
  4317. }
  4318. // Calculation of the two block colors using the LBG-algorithm
  4319. // The following method scales down the intensity, since this can be compensated for anyway by both the H and T mode.
  4320. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  4321. void computeColorLBGHalfIntensityFast(uint8 *img,int width,int startx,int starty, uint8 (LBG_colors)[2][3])
  4322. {
  4323. uint8 block_mask[4][4];
  4324. // reset rand so that we get predictable output per block
  4325. srand(10000);
  4326. //LBG-algorithm
  4327. double D = 0, oldD, bestD = MAXIMUM_ERROR, eps = 0.0000000001;
  4328. double error_a, error_b;
  4329. int number_of_iterations = 10;
  4330. double t_color[2][3];
  4331. double original_colors[4][4][3];
  4332. double current_colors[2][3];
  4333. double best_colors[2][3];
  4334. double max_v[3];
  4335. double min_v[3];
  4336. int x,y,i;
  4337. double red, green, blue;
  4338. bool continue_seeding;
  4339. int maximum_number_of_seedings = 10;
  4340. int seeding;
  4341. bool continue_iterate;
  4342. max_v[R] = -512.0; max_v[G] = -512.0; max_v[B] = -512.0;
  4343. min_v[R] = 512.0; min_v[G] = 512.0; min_v[B] = 512.0;
  4344. // resolve trainingdata
  4345. for (y = 0; y < BLOCKHEIGHT; ++y)
  4346. {
  4347. for (x = 0; x < BLOCKWIDTH; ++x)
  4348. {
  4349. red = img[3*((starty+y)*width+startx+x)+R];
  4350. green = img[3*((starty+y)*width+startx+x)+G];
  4351. blue = img[3*((starty+y)*width+startx+x)+B];
  4352. // Use qrs representation instead of rgb
  4353. // qrs = Q * rgb where Q = [a a a ; b -b 0 ; c c -2c]; a = 1/sqrt(3), b= 1/sqrt(2), c = 1/sqrt(6);
  4354. // rgb = inv(Q)*qrs = Q' * qrs where ' denotes transpose.
  4355. // The q variable holds intensity. r and s hold chrominance.
  4356. // q = [0, sqrt(3)*255], r = [-255/sqrt(2), 255/sqrt(2)], s = [-2*255/sqrt(6), 2*255/sqrt(6)];
  4357. //
  4358. // The LGB algorithm will only act on the r and s variables and not on q.
  4359. //
  4360. original_colors[x][y][R] = (1.0/sqrt(1.0*3))*red + (1.0/sqrt(1.0*3))*green + (1.0/sqrt(1.0*3))*blue;
  4361. original_colors[x][y][G] = (1.0/sqrt(1.0*2))*red - (1.0/sqrt(1.0*2))*green;
  4362. original_colors[x][y][B] = (1.0/sqrt(1.0*6))*red + (1.0/sqrt(1.0*6))*green - (2.0/sqrt(1.0*6))*blue;
  4363. // find max
  4364. if (original_colors[x][y][R] > max_v[R]) max_v[R] = original_colors[x][y][R];
  4365. if (original_colors[x][y][G] > max_v[G]) max_v[G] = original_colors[x][y][G];
  4366. if (original_colors[x][y][B] > max_v[B]) max_v[B] = original_colors[x][y][B];
  4367. // find min
  4368. if (original_colors[x][y][R] < min_v[R]) min_v[R] = original_colors[x][y][R];
  4369. if (original_colors[x][y][G] < min_v[G]) min_v[G] = original_colors[x][y][G];
  4370. if (original_colors[x][y][B] < min_v[B]) min_v[B] = original_colors[x][y][B];
  4371. }
  4372. }
  4373. D = 512*512*3*16.0;
  4374. bestD = 512*512*3*16.0;
  4375. continue_seeding = true;
  4376. // loop seeds
  4377. for (seeding = 0; (seeding < maximum_number_of_seedings) && continue_seeding; seeding++)
  4378. {
  4379. // hopefully we will not need more seedings:
  4380. continue_seeding = false;
  4381. // calculate seeds
  4382. for (uint8 s = 0; s < 2; ++s)
  4383. {
  4384. for (uint8 c = 0; c < 3; ++c)
  4385. {
  4386. current_colors[s][c] = double((double(rand())/RAND_MAX)*(max_v[c]-min_v[c])) + min_v[c];
  4387. }
  4388. }
  4389. // divide into two quantization sets and calculate distortion
  4390. continue_iterate = true;
  4391. for(i = 0; (i < number_of_iterations) && continue_iterate; i++)
  4392. {
  4393. oldD = D;
  4394. D = 0;
  4395. int n = 0;
  4396. for (y = 0; y < BLOCKHEIGHT; ++y)
  4397. {
  4398. for (int x = 0; x < BLOCKWIDTH; ++x)
  4399. {
  4400. error_a = 0.5*SQUARE(original_colors[x][y][R] - current_colors[0][R]) +
  4401. SQUARE(original_colors[x][y][G] - current_colors[0][G]) +
  4402. SQUARE(original_colors[x][y][B] - current_colors[0][B]);
  4403. error_b = 0.5*SQUARE(original_colors[x][y][R] - current_colors[1][R]) +
  4404. SQUARE(original_colors[x][y][G] - current_colors[1][G]) +
  4405. SQUARE(original_colors[x][y][B] - current_colors[1][B]);
  4406. if (error_a < error_b)
  4407. {
  4408. block_mask[x][y] = 0;
  4409. D += error_a;
  4410. ++n;
  4411. }
  4412. else
  4413. {
  4414. block_mask[x][y] = 1;
  4415. D += error_b;
  4416. }
  4417. }
  4418. }
  4419. // compare with old distortion
  4420. if (D == 0)
  4421. {
  4422. // Perfect score -- we dont need to go further iterations.
  4423. continue_iterate = false;
  4424. continue_seeding = false;
  4425. }
  4426. if (D == oldD)
  4427. {
  4428. // Same score as last round -- no need to go for further iterations.
  4429. continue_iterate = false;
  4430. continue_seeding = false;
  4431. }
  4432. if (D < bestD)
  4433. {
  4434. bestD = D;
  4435. for(uint8 s = 0; s < 2; ++s)
  4436. {
  4437. for(uint8 c = 0; c < 3; ++c)
  4438. {
  4439. best_colors[s][c] = current_colors[s][c];
  4440. }
  4441. }
  4442. }
  4443. if (n == 0 || n == BLOCKWIDTH*BLOCKHEIGHT)
  4444. {
  4445. // All colors end up in the same voroni region. We need to reseed.
  4446. continue_iterate = false;
  4447. continue_seeding = true;
  4448. }
  4449. else
  4450. {
  4451. // Calculate new reconstruction points using the centroids
  4452. // Find new construction values from average
  4453. t_color[0][R] = 0;
  4454. t_color[0][G] = 0;
  4455. t_color[0][B] = 0;
  4456. t_color[1][R] = 0;
  4457. t_color[1][G] = 0;
  4458. t_color[1][B] = 0;
  4459. for (y = 0; y < BLOCKHEIGHT; ++y)
  4460. {
  4461. for (int x = 0; x < BLOCKWIDTH; ++x)
  4462. {
  4463. // use dummy value for q-parameter
  4464. t_color[block_mask[x][y]][R] += original_colors[x][y][R];
  4465. t_color[block_mask[x][y]][G] += original_colors[x][y][G];
  4466. t_color[block_mask[x][y]][B] += original_colors[x][y][B];
  4467. }
  4468. }
  4469. current_colors[0][R] = t_color[0][R] / n;
  4470. current_colors[1][R] = t_color[1][R] / (BLOCKWIDTH*BLOCKHEIGHT - n);
  4471. current_colors[0][G] = t_color[0][G] / n;
  4472. current_colors[1][G] = t_color[1][G] / (BLOCKWIDTH*BLOCKHEIGHT - n);
  4473. current_colors[0][B] = t_color[0][B] / n;
  4474. current_colors[1][B] = t_color[1][B] / (BLOCKWIDTH*BLOCKHEIGHT - n);
  4475. }
  4476. }
  4477. }
  4478. for(x=0;x<2;x++)
  4479. {
  4480. double qq, rr, ss;
  4481. qq = best_colors[x][0];
  4482. rr = best_colors[x][1];
  4483. ss = best_colors[x][2];
  4484. current_colors[x][0] = CLAMP(0, (1.0/sqrt(1.0*3))*qq + (1.0/sqrt(1.0*2))*rr + (1.0/sqrt(1.0*6))*ss, 255);
  4485. current_colors[x][1] = CLAMP(0, (1.0/sqrt(1.0*3))*qq - (1.0/sqrt(1.0*2))*rr + (1.0/sqrt(1.0*6))*ss, 255);
  4486. current_colors[x][2] = CLAMP(0, (1.0/sqrt(1.0*3))*qq + (0.0 )*rr - (2.0/sqrt(1.0*6))*ss, 255);
  4487. }
  4488. for(x=0;x<2;x++)
  4489. for(y=0;y<3;y++)
  4490. LBG_colors[x][y] = JAS_ROUND(current_colors[x][y]);
  4491. }
  4492. // Calculation of the two block colors using the LBG-algorithm
  4493. // The following method scales down the intensity, since this can be compensated for anyway by both the H and T mode.
  4494. // Faster version
  4495. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  4496. void computeColorLBGNotIntensityFast(uint8 *img,int width,int startx,int starty, uint8 (LBG_colors)[2][3])
  4497. {
  4498. uint8 block_mask[4][4];
  4499. // reset rand so that we get predictable output per block
  4500. srand(10000);
  4501. //LBG-algorithm
  4502. double D = 0, oldD, bestD = MAXIMUM_ERROR, eps = 0.0000000001;
  4503. double error_a, error_b;
  4504. int number_of_iterations = 10;
  4505. double t_color[2][3];
  4506. double original_colors[4][4][3];
  4507. double current_colors[2][3];
  4508. double best_colors[2][3];
  4509. double max_v[3];
  4510. double min_v[3];
  4511. int x,y,i;
  4512. double red, green, blue;
  4513. bool continue_seeding;
  4514. int maximum_number_of_seedings = 10;
  4515. int seeding;
  4516. bool continue_iterate;
  4517. max_v[R] = -512.0; max_v[G] = -512.0; max_v[B] = -512.0;
  4518. min_v[R] = 512.0; min_v[G] = 512.0; min_v[B] = 512.0;
  4519. // resolve trainingdata
  4520. for (y = 0; y < BLOCKHEIGHT; ++y)
  4521. {
  4522. for (x = 0; x < BLOCKWIDTH; ++x)
  4523. {
  4524. red = img[3*((starty+y)*width+startx+x)+R];
  4525. green = img[3*((starty+y)*width+startx+x)+G];
  4526. blue = img[3*((starty+y)*width+startx+x)+B];
  4527. // Use qrs representation instead of rgb
  4528. // qrs = Q * rgb where Q = [a a a ; b -b 0 ; c c -2c]; a = 1/sqrt(1.0*3), b= 1/sqrt(1.0*2), c = 1/sqrt(1.0*6);
  4529. // rgb = inv(Q)*qrs = Q' * qrs where ' denotes transpose.
  4530. // The q variable holds intensity. r and s hold chrominance.
  4531. // q = [0, sqrt(1.0*3)*255], r = [-255/sqrt(1.0*2), 255/sqrt(1.0*2)], s = [-2*255/sqrt(1.0*6), 2*255/sqrt(1.0*6)];
  4532. //
  4533. // The LGB algorithm will only act on the r and s variables and not on q.
  4534. //
  4535. original_colors[x][y][R] = (1.0/sqrt(1.0*3))*red + (1.0/sqrt(1.0*3))*green + (1.0/sqrt(1.0*3))*blue;
  4536. original_colors[x][y][G] = (1.0/sqrt(1.0*2))*red - (1.0/sqrt(1.0*2))*green;
  4537. original_colors[x][y][B] = (1.0/sqrt(1.0*6))*red + (1.0/sqrt(1.0*6))*green - (2.0/sqrt(1.0*6))*blue;
  4538. // find max
  4539. if (original_colors[x][y][R] > max_v[R]) max_v[R] = original_colors[x][y][R];
  4540. if (original_colors[x][y][G] > max_v[G]) max_v[G] = original_colors[x][y][G];
  4541. if (original_colors[x][y][B] > max_v[B]) max_v[B] = original_colors[x][y][B];
  4542. // find min
  4543. if (original_colors[x][y][R] < min_v[R]) min_v[R] = original_colors[x][y][R];
  4544. if (original_colors[x][y][G] < min_v[G]) min_v[G] = original_colors[x][y][G];
  4545. if (original_colors[x][y][B] < min_v[B]) min_v[B] = original_colors[x][y][B];
  4546. }
  4547. }
  4548. D = 512*512*3*16.0;
  4549. bestD = 512*512*3*16.0;
  4550. continue_seeding = true;
  4551. // loop seeds
  4552. for (seeding = 0; (seeding < maximum_number_of_seedings) && continue_seeding; seeding++)
  4553. {
  4554. // hopefully we will not need more seedings:
  4555. continue_seeding = false;
  4556. // calculate seeds
  4557. for (uint8 s = 0; s < 2; ++s)
  4558. {
  4559. for (uint8 c = 0; c < 3; ++c)
  4560. {
  4561. current_colors[s][c] = double((double(rand())/RAND_MAX)*(max_v[c]-min_v[c])) + min_v[c];
  4562. }
  4563. }
  4564. // divide into two quantization sets and calculate distortion
  4565. continue_iterate = true;
  4566. for(i = 0; (i < number_of_iterations) && continue_iterate; i++)
  4567. {
  4568. oldD = D;
  4569. D = 0;
  4570. int n = 0;
  4571. for (y = 0; y < BLOCKHEIGHT; ++y)
  4572. {
  4573. for (int x = 0; x < BLOCKWIDTH; ++x)
  4574. {
  4575. error_a = 0.0*SQUARE(original_colors[x][y][R] - current_colors[0][R]) +
  4576. SQUARE(original_colors[x][y][G] - current_colors[0][G]) +
  4577. SQUARE(original_colors[x][y][B] - current_colors[0][B]);
  4578. error_b = 0.0*SQUARE(original_colors[x][y][R] - current_colors[1][R]) +
  4579. SQUARE(original_colors[x][y][G] - current_colors[1][G]) +
  4580. SQUARE(original_colors[x][y][B] - current_colors[1][B]);
  4581. if (error_a < error_b)
  4582. {
  4583. block_mask[x][y] = 0;
  4584. D += error_a;
  4585. ++n;
  4586. }
  4587. else
  4588. {
  4589. block_mask[x][y] = 1;
  4590. D += error_b;
  4591. }
  4592. }
  4593. }
  4594. // compare with old distortion
  4595. if (D == 0)
  4596. {
  4597. // Perfect score -- we dont need to go further iterations.
  4598. continue_iterate = false;
  4599. continue_seeding = false;
  4600. }
  4601. if (D == oldD)
  4602. {
  4603. // Same score as last round -- no need to go for further iterations.
  4604. continue_iterate = false;
  4605. continue_seeding = false;
  4606. }
  4607. if (D < bestD)
  4608. {
  4609. bestD = D;
  4610. for(uint8 s = 0; s < 2; ++s)
  4611. {
  4612. for(uint8 c = 0; c < 3; ++c)
  4613. {
  4614. best_colors[s][c] = current_colors[s][c];
  4615. }
  4616. }
  4617. }
  4618. if (n == 0 || n == BLOCKWIDTH*BLOCKHEIGHT)
  4619. {
  4620. // All colors end up in the same voroni region. We need to reseed.
  4621. continue_iterate = false;
  4622. continue_seeding = true;
  4623. }
  4624. else
  4625. {
  4626. // Calculate new reconstruction points using the centroids
  4627. // Find new construction values from average
  4628. t_color[0][R] = 0;
  4629. t_color[0][G] = 0;
  4630. t_color[0][B] = 0;
  4631. t_color[1][R] = 0;
  4632. t_color[1][G] = 0;
  4633. t_color[1][B] = 0;
  4634. for (y = 0; y < BLOCKHEIGHT; ++y)
  4635. {
  4636. for (int x = 0; x < BLOCKWIDTH; ++x)
  4637. {
  4638. // use dummy value for q-parameter
  4639. t_color[block_mask[x][y]][R] += original_colors[x][y][R];
  4640. t_color[block_mask[x][y]][G] += original_colors[x][y][G];
  4641. t_color[block_mask[x][y]][B] += original_colors[x][y][B];
  4642. }
  4643. }
  4644. current_colors[0][R] = t_color[0][R] / n;
  4645. current_colors[1][R] = t_color[1][R] / (BLOCKWIDTH*BLOCKHEIGHT - n);
  4646. current_colors[0][G] = t_color[0][G] / n;
  4647. current_colors[1][G] = t_color[1][G] / (BLOCKWIDTH*BLOCKHEIGHT - n);
  4648. current_colors[0][B] = t_color[0][B] / n;
  4649. current_colors[1][B] = t_color[1][B] / (BLOCKWIDTH*BLOCKHEIGHT - n);
  4650. }
  4651. }
  4652. }
  4653. for(x=0;x<2;x++)
  4654. {
  4655. double qq, rr, ss;
  4656. qq = best_colors[x][0];
  4657. rr = best_colors[x][1];
  4658. ss = best_colors[x][2];
  4659. current_colors[x][0] = CLAMP(0, (1.0/sqrt(1.0*3))*qq + (1.0/sqrt(1.0*2))*rr + (1.0/sqrt(1.0*6))*ss, 255);
  4660. current_colors[x][1] = CLAMP(0, (1.0/sqrt(1.0*3))*qq - (1.0/sqrt(1.0*2))*rr + (1.0/sqrt(1.0*6))*ss, 255);
  4661. current_colors[x][2] = CLAMP(0, (1.0/sqrt(1.0*3))*qq + (0.0 )*rr - (2.0/sqrt(1.0*6))*ss, 255);
  4662. }
  4663. for(x=0;x<2;x++)
  4664. for(y=0;y<3;y++)
  4665. LBG_colors[x][y] = JAS_ROUND(current_colors[x][y]);
  4666. }
  4667. // Calculation of the two block colors using the LBG-algorithm
  4668. // The following method completely ignores the intensity, since this can be compensated for anyway by both the H and T mode.
  4669. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  4670. void computeColorLBGNotIntensity(uint8 *img,int width,int startx,int starty, uint8 (LBG_colors)[2][3])
  4671. {
  4672. uint8 block_mask[4][4];
  4673. // reset rand so that we get predictable output per block
  4674. srand(10000);
  4675. //LBG-algorithm
  4676. double D = 0, oldD, bestD = MAXIMUM_ERROR, eps = 0.0000000001;
  4677. double error_a, error_b;
  4678. int number_of_iterations = 10;
  4679. double t_color[2][3];
  4680. double original_colors[4][4][3];
  4681. double current_colors[2][3];
  4682. double best_colors[2][3];
  4683. double max_v[3];
  4684. double min_v[3];
  4685. int x,y,i;
  4686. double red, green, blue;
  4687. bool continue_seeding;
  4688. int maximum_number_of_seedings = 10;
  4689. int seeding;
  4690. bool continue_iterate;
  4691. max_v[R] = -512.0; max_v[G] = -512.0; max_v[B] = -512.0;
  4692. min_v[R] = 512.0; min_v[G] = 512.0; min_v[B] = 512.0;
  4693. // resolve trainingdata
  4694. for (y = 0; y < BLOCKHEIGHT; ++y)
  4695. {
  4696. for (x = 0; x < BLOCKWIDTH; ++x)
  4697. {
  4698. red = img[3*((starty+y)*width+startx+x)+R];
  4699. green = img[3*((starty+y)*width+startx+x)+G];
  4700. blue = img[3*((starty+y)*width+startx+x)+B];
  4701. // Use qrs representation instead of rgb
  4702. // qrs = Q * rgb where Q = [a a a ; b -b 0 ; c c -2c]; a = 1/sqrt(1.0*3), b= 1/sqrt(1.0*2), c = 1/sqrt(1.0*6);
  4703. // rgb = inv(Q)*qrs = Q' * qrs where ' denotes transpose.
  4704. // The q variable holds intensity. r and s hold chrominance.
  4705. // q = [0, sqrt(1.0*3)*255], r = [-255/sqrt(1.0*2), 255/sqrt(1.0*2)], s = [-2*255/sqrt(1.0*6), 2*255/sqrt(1.0*6)];
  4706. //
  4707. // The LGB algorithm will only act on the r and s variables and not on q.
  4708. //
  4709. original_colors[x][y][R] = (1.0/sqrt(1.0*3))*red + (1.0/sqrt(1.0*3))*green + (1.0/sqrt(1.0*3))*blue;
  4710. original_colors[x][y][G] = (1.0/sqrt(1.0*2))*red - (1.0/sqrt(1.0*2))*green;
  4711. original_colors[x][y][B] = (1.0/sqrt(1.0*6))*red + (1.0/sqrt(1.0*6))*green - (2.0/sqrt(1.0*6))*blue;
  4712. // find max
  4713. if (original_colors[x][y][R] > max_v[R]) max_v[R] = original_colors[x][y][R];
  4714. if (original_colors[x][y][G] > max_v[G]) max_v[G] = original_colors[x][y][G];
  4715. if (original_colors[x][y][B] > max_v[B]) max_v[B] = original_colors[x][y][B];
  4716. // find min
  4717. if (original_colors[x][y][R] < min_v[R]) min_v[R] = original_colors[x][y][R];
  4718. if (original_colors[x][y][G] < min_v[G]) min_v[G] = original_colors[x][y][G];
  4719. if (original_colors[x][y][B] < min_v[B]) min_v[B] = original_colors[x][y][B];
  4720. }
  4721. }
  4722. D = 512*512*3*16.0;
  4723. bestD = 512*512*3*16.0;
  4724. continue_seeding = true;
  4725. // loop seeds
  4726. for (seeding = 0; (seeding < maximum_number_of_seedings) && continue_seeding; seeding++)
  4727. {
  4728. // hopefully we will not need more seedings:
  4729. continue_seeding = false;
  4730. // calculate seeds
  4731. for (uint8 s = 0; s < 2; ++s)
  4732. {
  4733. for (uint8 c = 0; c < 3; ++c)
  4734. {
  4735. current_colors[s][c] = double((double(rand())/RAND_MAX)*(max_v[c]-min_v[c])) + min_v[c];
  4736. }
  4737. }
  4738. // divide into two quantization sets and calculate distortion
  4739. continue_iterate = true;
  4740. for(i = 0; (i < number_of_iterations) && continue_iterate; i++)
  4741. {
  4742. oldD = D;
  4743. D = 0;
  4744. int n = 0;
  4745. for (y = 0; y < BLOCKHEIGHT; ++y)
  4746. {
  4747. for (int x = 0; x < BLOCKWIDTH; ++x)
  4748. {
  4749. error_a = 0.0*SQUARE(original_colors[x][y][R] - current_colors[0][R]) +
  4750. SQUARE(original_colors[x][y][G] - current_colors[0][G]) +
  4751. SQUARE(original_colors[x][y][B] - current_colors[0][B]);
  4752. error_b = 0.0*SQUARE(original_colors[x][y][R] - current_colors[1][R]) +
  4753. SQUARE(original_colors[x][y][G] - current_colors[1][G]) +
  4754. SQUARE(original_colors[x][y][B] - current_colors[1][B]);
  4755. if (error_a < error_b)
  4756. {
  4757. block_mask[x][y] = 0;
  4758. D += error_a;
  4759. ++n;
  4760. }
  4761. else
  4762. {
  4763. block_mask[x][y] = 1;
  4764. D += error_b;
  4765. }
  4766. }
  4767. }
  4768. // compare with old distortion
  4769. if (D == 0)
  4770. {
  4771. // Perfect score -- we dont need to go further iterations.
  4772. continue_iterate = false;
  4773. continue_seeding = false;
  4774. }
  4775. if (D == oldD)
  4776. {
  4777. // Same score as last round -- no need to go for further iterations.
  4778. continue_iterate = false;
  4779. continue_seeding = true;
  4780. }
  4781. if (D < bestD)
  4782. {
  4783. bestD = D;
  4784. for(uint8 s = 0; s < 2; ++s)
  4785. {
  4786. for(uint8 c = 0; c < 3; ++c)
  4787. {
  4788. best_colors[s][c] = current_colors[s][c];
  4789. }
  4790. }
  4791. }
  4792. if (n == 0 || n == BLOCKWIDTH*BLOCKHEIGHT)
  4793. {
  4794. // All colors end up in the same voroni region. We need to reseed.
  4795. continue_iterate = false;
  4796. continue_seeding = true;
  4797. }
  4798. else
  4799. {
  4800. // Calculate new reconstruction points using the centroids
  4801. // Find new construction values from average
  4802. t_color[0][R] = 0;
  4803. t_color[0][G] = 0;
  4804. t_color[0][B] = 0;
  4805. t_color[1][R] = 0;
  4806. t_color[1][G] = 0;
  4807. t_color[1][B] = 0;
  4808. for (y = 0; y < BLOCKHEIGHT; ++y)
  4809. {
  4810. for (int x = 0; x < BLOCKWIDTH; ++x)
  4811. {
  4812. // use dummy value for q-parameter
  4813. t_color[block_mask[x][y]][R] += original_colors[x][y][R];
  4814. t_color[block_mask[x][y]][G] += original_colors[x][y][G];
  4815. t_color[block_mask[x][y]][B] += original_colors[x][y][B];
  4816. }
  4817. }
  4818. current_colors[0][R] = t_color[0][R] / n;
  4819. current_colors[1][R] = t_color[1][R] / (BLOCKWIDTH*BLOCKHEIGHT - n);
  4820. current_colors[0][G] = t_color[0][G] / n;
  4821. current_colors[1][G] = t_color[1][G] / (BLOCKWIDTH*BLOCKHEIGHT - n);
  4822. current_colors[0][B] = t_color[0][B] / n;
  4823. current_colors[1][B] = t_color[1][B] / (BLOCKWIDTH*BLOCKHEIGHT - n);
  4824. }
  4825. }
  4826. }
  4827. for(x=0;x<2;x++)
  4828. {
  4829. double qq, rr, ss;
  4830. qq = best_colors[x][0];
  4831. rr = best_colors[x][1];
  4832. ss = best_colors[x][2];
  4833. current_colors[x][0] = CLAMP(0, (1.0/sqrt(1.0*3))*qq + (1.0/sqrt(1.0*2))*rr + (1.0/sqrt(1.0*6))*ss, 255);
  4834. current_colors[x][1] = CLAMP(0, (1.0/sqrt(1.0*3))*qq - (1.0/sqrt(1.0*2))*rr + (1.0/sqrt(1.0*6))*ss, 255);
  4835. current_colors[x][2] = CLAMP(0, (1.0/sqrt(1.0*3))*qq + (0.0 )*rr - (2.0/sqrt(1.0*6))*ss, 255);
  4836. }
  4837. for(x=0;x<2;x++)
  4838. for(y=0;y<3;y++)
  4839. LBG_colors[x][y] = JAS_ROUND(current_colors[x][y]);
  4840. }
  4841. // Calculation of the two block colors using the LBG-algorithm
  4842. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  4843. void computeColorLBG(uint8 *img,int width,int startx,int starty, uint8 (LBG_colors)[2][3])
  4844. {
  4845. uint8 block_mask[4][4];
  4846. // reset rand so that we get predictable output per block
  4847. srand(10000);
  4848. //LBG-algorithm
  4849. double D = 0, oldD, bestD = MAXIMUM_ERROR, eps = 0.0000000001;
  4850. double error_a, error_b;
  4851. int number_of_iterations = 10;
  4852. double t_color[2][3];
  4853. double original_colors[4][4][3];
  4854. double current_colors[2][3];
  4855. double best_colors[2][3];
  4856. double max_v[3];
  4857. double min_v[3];
  4858. int x,y,i;
  4859. double red, green, blue;
  4860. bool continue_seeding;
  4861. int maximum_number_of_seedings = 10;
  4862. int seeding;
  4863. bool continue_iterate;
  4864. max_v[R] = -512.0; max_v[G] = -512.0; max_v[B] = -512.0;
  4865. min_v[R] = 512.0; min_v[G] = 512.0; min_v[B] = 512.0;
  4866. // resolve trainingdata
  4867. for (y = 0; y < BLOCKHEIGHT; ++y)
  4868. {
  4869. for (x = 0; x < BLOCKWIDTH; ++x)
  4870. {
  4871. red = img[3*((starty+y)*width+startx+x)+R];
  4872. green = img[3*((starty+y)*width+startx+x)+G];
  4873. blue = img[3*((starty+y)*width+startx+x)+B];
  4874. original_colors[x][y][R] = red;
  4875. original_colors[x][y][G] = green;
  4876. original_colors[x][y][B] = blue;
  4877. // find max
  4878. if (original_colors[x][y][R] > max_v[R]) max_v[R] = original_colors[x][y][R];
  4879. if (original_colors[x][y][G] > max_v[G]) max_v[G] = original_colors[x][y][G];
  4880. if (original_colors[x][y][B] > max_v[B]) max_v[B] = original_colors[x][y][B];
  4881. // find min
  4882. if (original_colors[x][y][R] < min_v[R]) min_v[R] = original_colors[x][y][R];
  4883. if (original_colors[x][y][G] < min_v[G]) min_v[G] = original_colors[x][y][G];
  4884. if (original_colors[x][y][B] < min_v[B]) min_v[B] = original_colors[x][y][B];
  4885. }
  4886. }
  4887. D = 512*512*3*16.0;
  4888. bestD = 512*512*3*16.0;
  4889. continue_seeding = true;
  4890. // loop seeds
  4891. for (seeding = 0; (seeding < maximum_number_of_seedings) && continue_seeding; seeding++)
  4892. {
  4893. // hopefully we will not need more seedings:
  4894. continue_seeding = false;
  4895. // calculate seeds
  4896. for (uint8 s = 0; s < 2; ++s)
  4897. {
  4898. for (uint8 c = 0; c < 3; ++c)
  4899. {
  4900. current_colors[s][c] = double((double(rand())/RAND_MAX)*(max_v[c]-min_v[c])) + min_v[c];
  4901. }
  4902. }
  4903. // divide into two quantization sets and calculate distortion
  4904. continue_iterate = true;
  4905. for(i = 0; (i < number_of_iterations) && continue_iterate; i++)
  4906. {
  4907. oldD = D;
  4908. D = 0;
  4909. int n = 0;
  4910. for (y = 0; y < BLOCKHEIGHT; ++y)
  4911. {
  4912. for (int x = 0; x < BLOCKWIDTH; ++x)
  4913. {
  4914. error_a = SQUARE(original_colors[x][y][R] - JAS_ROUND(current_colors[0][R])) +
  4915. SQUARE(original_colors[x][y][G] - JAS_ROUND(current_colors[0][G])) +
  4916. SQUARE(original_colors[x][y][B] - JAS_ROUND(current_colors[0][B]));
  4917. error_b = SQUARE(original_colors[x][y][R] - JAS_ROUND(current_colors[1][R])) +
  4918. SQUARE(original_colors[x][y][G] - JAS_ROUND(current_colors[1][G])) +
  4919. SQUARE(original_colors[x][y][B] - JAS_ROUND(current_colors[1][B]));
  4920. if (error_a < error_b)
  4921. {
  4922. block_mask[x][y] = 0;
  4923. D += error_a;
  4924. ++n;
  4925. }
  4926. else
  4927. {
  4928. block_mask[x][y] = 1;
  4929. D += error_b;
  4930. }
  4931. }
  4932. }
  4933. // compare with old distortion
  4934. if (D == 0)
  4935. {
  4936. // Perfect score -- we dont need to go further iterations.
  4937. continue_iterate = false;
  4938. continue_seeding = false;
  4939. }
  4940. if (D == oldD)
  4941. {
  4942. // Same score as last round -- no need to go for further iterations.
  4943. continue_iterate = false;
  4944. continue_seeding = true;
  4945. }
  4946. if (D < bestD)
  4947. {
  4948. bestD = D;
  4949. for(uint8 s = 0; s < 2; ++s)
  4950. {
  4951. for(uint8 c = 0; c < 3; ++c)
  4952. {
  4953. best_colors[s][c] = current_colors[s][c];
  4954. }
  4955. }
  4956. }
  4957. if (n == 0 || n == BLOCKWIDTH*BLOCKHEIGHT)
  4958. {
  4959. // All colors end up in the same voroni region. We need to reseed.
  4960. continue_iterate = false;
  4961. continue_seeding = true;
  4962. }
  4963. else
  4964. {
  4965. // Calculate new reconstruction points using the centroids
  4966. // Find new construction values from average
  4967. t_color[0][R] = 0;
  4968. t_color[0][G] = 0;
  4969. t_color[0][B] = 0;
  4970. t_color[1][R] = 0;
  4971. t_color[1][G] = 0;
  4972. t_color[1][B] = 0;
  4973. for (y = 0; y < BLOCKHEIGHT; ++y)
  4974. {
  4975. for (int x = 0; x < BLOCKWIDTH; ++x)
  4976. {
  4977. // use dummy value for q-parameter
  4978. t_color[block_mask[x][y]][R] += original_colors[x][y][R];
  4979. t_color[block_mask[x][y]][G] += original_colors[x][y][G];
  4980. t_color[block_mask[x][y]][B] += original_colors[x][y][B];
  4981. }
  4982. }
  4983. current_colors[0][R] = t_color[0][R] / n;
  4984. current_colors[1][R] = t_color[1][R] / (BLOCKWIDTH*BLOCKHEIGHT - n);
  4985. current_colors[0][G] = t_color[0][G] / n;
  4986. current_colors[1][G] = t_color[1][G] / (BLOCKWIDTH*BLOCKHEIGHT - n);
  4987. current_colors[0][B] = t_color[0][B] / n;
  4988. current_colors[1][B] = t_color[1][B] / (BLOCKWIDTH*BLOCKHEIGHT - n);
  4989. }
  4990. }
  4991. }
  4992. // Set the best colors as the final block colors
  4993. for(int s = 0; s < 2; ++s)
  4994. {
  4995. for(uint8 c = 0; c < 3; ++c)
  4996. {
  4997. current_colors[s][c] = best_colors[s][c];
  4998. }
  4999. }
  5000. for(x=0;x<2;x++)
  5001. for(y=0;y<3;y++)
  5002. LBG_colors[x][y] = JAS_ROUND(current_colors[x][y]);
  5003. }
  5004. // Calculation of the two block colors using the LBG-algorithm
  5005. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5006. void computeColorLBGfast(uint8 *img,int width,int startx,int starty, uint8 (LBG_colors)[2][3])
  5007. {
  5008. uint8 block_mask[4][4];
  5009. // reset rand so that we get predictable output per block
  5010. srand(10000);
  5011. //LBG-algorithm
  5012. double D = 0, oldD, bestD = MAXIMUM_ERROR, eps = 0.0000000001;
  5013. double error_a, error_b;
  5014. int number_of_iterations = 10;
  5015. double t_color[2][3];
  5016. uint8 original_colors[4][4][3];
  5017. double current_colors[2][3];
  5018. double best_colors[2][3];
  5019. double max_v[3];
  5020. double min_v[3];
  5021. int x,y,i;
  5022. bool continue_seeding;
  5023. int maximum_number_of_seedings = 10;
  5024. int seeding;
  5025. bool continue_iterate;
  5026. max_v[R] = -512.0; max_v[G] = -512.0; max_v[B] = -512.0;
  5027. min_v[R] = 512.0; min_v[G] = 512.0; min_v[B] = 512.0;
  5028. // resolve trainingdata
  5029. for (y = 0; y < BLOCKHEIGHT; ++y)
  5030. {
  5031. for (x = 0; x < BLOCKWIDTH; ++x)
  5032. {
  5033. original_colors[x][y][R] = img[3*((starty+y)*width+startx+x)+R];
  5034. original_colors[x][y][G] = img[3*((starty+y)*width+startx+x)+G];
  5035. original_colors[x][y][B] = img[3*((starty+y)*width+startx+x)+B];
  5036. // find max
  5037. if (original_colors[x][y][R] > max_v[R]) max_v[R] = original_colors[x][y][R];
  5038. if (original_colors[x][y][G] > max_v[G]) max_v[G] = original_colors[x][y][G];
  5039. if (original_colors[x][y][B] > max_v[B]) max_v[B] = original_colors[x][y][B];
  5040. // find min
  5041. if (original_colors[x][y][R] < min_v[R]) min_v[R] = original_colors[x][y][R];
  5042. if (original_colors[x][y][G] < min_v[G]) min_v[G] = original_colors[x][y][G];
  5043. if (original_colors[x][y][B] < min_v[B]) min_v[B] = original_colors[x][y][B];
  5044. }
  5045. }
  5046. D = 512*512*3*16.0;
  5047. bestD = 512*512*3*16.0;
  5048. continue_seeding = true;
  5049. // loop seeds
  5050. for (seeding = 0; (seeding < maximum_number_of_seedings) && continue_seeding; seeding++)
  5051. {
  5052. // hopefully we will not need more seedings:
  5053. continue_seeding = false;
  5054. // calculate seeds
  5055. for (uint8 s = 0; s < 2; ++s)
  5056. {
  5057. for (uint8 c = 0; c < 3; ++c)
  5058. {
  5059. current_colors[s][c] = double((double(rand())/RAND_MAX)*(max_v[c]-min_v[c])) + min_v[c];
  5060. }
  5061. }
  5062. // divide into two quantization sets and calculate distortion
  5063. continue_iterate = true;
  5064. for(i = 0; (i < number_of_iterations) && continue_iterate; i++)
  5065. {
  5066. oldD = D;
  5067. D = 0;
  5068. int n = 0;
  5069. for (y = 0; y < BLOCKHEIGHT; ++y)
  5070. {
  5071. for (int x = 0; x < BLOCKWIDTH; ++x)
  5072. {
  5073. error_a = SQUARE(original_colors[x][y][R] - JAS_ROUND(current_colors[0][R])) +
  5074. SQUARE(original_colors[x][y][G] - JAS_ROUND(current_colors[0][G])) +
  5075. SQUARE(original_colors[x][y][B] - JAS_ROUND(current_colors[0][B]));
  5076. error_b = SQUARE(original_colors[x][y][R] - JAS_ROUND(current_colors[1][R])) +
  5077. SQUARE(original_colors[x][y][G] - JAS_ROUND(current_colors[1][G])) +
  5078. SQUARE(original_colors[x][y][B] - JAS_ROUND(current_colors[1][B]));
  5079. if (error_a < error_b)
  5080. {
  5081. block_mask[x][y] = 0;
  5082. D += error_a;
  5083. ++n;
  5084. }
  5085. else
  5086. {
  5087. block_mask[x][y] = 1;
  5088. D += error_b;
  5089. }
  5090. }
  5091. }
  5092. // compare with old distortion
  5093. if (D == 0)
  5094. {
  5095. // Perfect score -- we dont need to go further iterations.
  5096. continue_iterate = false;
  5097. continue_seeding = false;
  5098. }
  5099. if (D == oldD)
  5100. {
  5101. // Same score as last round -- no need to go for further iterations.
  5102. continue_iterate = false;
  5103. continue_seeding = false;
  5104. }
  5105. if (D < bestD)
  5106. {
  5107. bestD = D;
  5108. for(uint8 s = 0; s < 2; ++s)
  5109. {
  5110. for(uint8 c = 0; c < 3; ++c)
  5111. {
  5112. best_colors[s][c] = current_colors[s][c];
  5113. }
  5114. }
  5115. }
  5116. if (n == 0 || n == BLOCKWIDTH*BLOCKHEIGHT)
  5117. {
  5118. // All colors end up in the same voroni region. We need to reseed.
  5119. continue_iterate = false;
  5120. continue_seeding = true;
  5121. }
  5122. else
  5123. {
  5124. // Calculate new reconstruction points using the centroids
  5125. // Find new construction values from average
  5126. t_color[0][R] = 0;
  5127. t_color[0][G] = 0;
  5128. t_color[0][B] = 0;
  5129. t_color[1][R] = 0;
  5130. t_color[1][G] = 0;
  5131. t_color[1][B] = 0;
  5132. for (y = 0; y < BLOCKHEIGHT; ++y)
  5133. {
  5134. for (int x = 0; x < BLOCKWIDTH; ++x)
  5135. {
  5136. // use dummy value for q-parameter
  5137. t_color[block_mask[x][y]][R] += original_colors[x][y][R];
  5138. t_color[block_mask[x][y]][G] += original_colors[x][y][G];
  5139. t_color[block_mask[x][y]][B] += original_colors[x][y][B];
  5140. }
  5141. }
  5142. current_colors[0][R] = t_color[0][R] / n;
  5143. current_colors[1][R] = t_color[1][R] / (BLOCKWIDTH*BLOCKHEIGHT - n);
  5144. current_colors[0][G] = t_color[0][G] / n;
  5145. current_colors[1][G] = t_color[1][G] / (BLOCKWIDTH*BLOCKHEIGHT - n);
  5146. current_colors[0][B] = t_color[0][B] / n;
  5147. current_colors[1][B] = t_color[1][B] / (BLOCKWIDTH*BLOCKHEIGHT - n);
  5148. }
  5149. }
  5150. }
  5151. // Set the best colors as the final block colors
  5152. for(int s = 0; s < 2; ++s)
  5153. {
  5154. for(uint8 c = 0; c < 3; ++c)
  5155. {
  5156. current_colors[s][c] = best_colors[s][c];
  5157. }
  5158. }
  5159. for(x=0;x<2;x++)
  5160. for(y=0;y<3;y++)
  5161. LBG_colors[x][y] = JAS_ROUND(current_colors[x][y]);
  5162. }
  5163. // Each color component is compressed to fit in its specified number of bits
  5164. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5165. void compressColor(int R_B, int G_B, int B_B, uint8 (current_color)[2][3], uint8 (quantized_color)[2][3])
  5166. {
  5167. //
  5168. // The color is calculated as:
  5169. //
  5170. // c = (c + (2^(8-b))/2) / (255 / (2^b - 1)) where b is the number of bits
  5171. // to code color c with
  5172. // For instance, if b = 3:
  5173. //
  5174. // c = (c + 16) / (255 / 7) = 7 * (c + 16) / 255
  5175. //
  5176. quantized_color[0][R] = CLAMP(0,(BINPOW(R_B)-1) * (current_color[0][R] + BINPOW(8-R_B-1)) / 255,255);
  5177. quantized_color[0][G] = CLAMP(0,(BINPOW(G_B)-1) * (current_color[0][G] + BINPOW(8-G_B-1)) / 255,255);
  5178. quantized_color[0][B] = CLAMP(0,(BINPOW(B_B)-1) * (current_color[0][B] + BINPOW(8-B_B-1)) / 255,255);
  5179. quantized_color[1][R] = CLAMP(0,(BINPOW(R_B)-1) * (current_color[1][R] + BINPOW(8-R_B-1)) / 255,255);
  5180. quantized_color[1][G] = CLAMP(0,(BINPOW(G_B)-1) * (current_color[1][G] + BINPOW(8-G_B-1)) / 255,255);
  5181. quantized_color[1][B] = CLAMP(0,(BINPOW(B_B)-1) * (current_color[1][B] + BINPOW(8-B_B-1)) / 255,255);
  5182. }
  5183. // Swapping two RGB-colors
  5184. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5185. void swapColors(uint8 (colors)[2][3])
  5186. {
  5187. uint8 temp = colors[0][R];
  5188. colors[0][R] = colors[1][R];
  5189. colors[1][R] = temp;
  5190. temp = colors[0][G];
  5191. colors[0][G] = colors[1][G];
  5192. colors[1][G] = temp;
  5193. temp = colors[0][B];
  5194. colors[0][B] = colors[1][B];
  5195. colors[1][B] = temp;
  5196. }
  5197. // Calculate the paint colors from the block colors
  5198. // using a distance d and one of the H- or T-patterns.
  5199. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5200. // Calculate the error for the block at position (startx,starty)
  5201. // The parameters needed for reconstruction are calculated as well
  5202. //
  5203. // Please note that the function can change the order between the two colors in colorsRGB444
  5204. //
  5205. // In the 59T bit mode, we only have pattern T.
  5206. //
  5207. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5208. unsigned int calculateError59Tperceptual1000(uint8* srcimg, int width, int startx, int starty, uint8 (colorsRGB444)[2][3], uint8 &distance, unsigned int &pixel_indices)
  5209. {
  5210. unsigned int block_error = 0,
  5211. best_block_error = MAXERR1000,
  5212. pixel_error,
  5213. best_pixel_error;
  5214. int diff[3];
  5215. uint8 best_sw;
  5216. unsigned int pixel_colors;
  5217. uint8 colors[2][3];
  5218. uint8 possible_colors[4][3];
  5219. // First use the colors as they are, then swap them
  5220. for (uint8 sw = 0; sw <2; ++sw)
  5221. {
  5222. if (sw == 1)
  5223. {
  5224. swapColors(colorsRGB444);
  5225. }
  5226. decompressColor(R_BITS59T, G_BITS59T, B_BITS59T, colorsRGB444, colors);
  5227. // Test all distances
  5228. for (uint8 d = 0; d < BINPOW(TABLE_BITS_59T); ++d)
  5229. {
  5230. calculatePaintColors59T(d,PATTERN_T, colors, possible_colors);
  5231. block_error = 0;
  5232. pixel_colors = 0;
  5233. // Loop block
  5234. for (size_t y = 0; y < BLOCKHEIGHT; ++y)
  5235. {
  5236. for (size_t x = 0; x < BLOCKWIDTH; ++x)
  5237. {
  5238. best_pixel_error = MAXERR1000;
  5239. pixel_colors <<=2; // Make room for next value
  5240. // Loop possible block colors
  5241. for (uint8 c = 0; c < 4; ++c)
  5242. {
  5243. diff[R] = srcimg[3*((starty+y)*width+startx+x)+R] - CLAMP(0,possible_colors[c][R],255);
  5244. diff[G] = srcimg[3*((starty+y)*width+startx+x)+G] - CLAMP(0,possible_colors[c][G],255);
  5245. diff[B] = srcimg[3*((starty+y)*width+startx+x)+B] - CLAMP(0,possible_colors[c][B],255);
  5246. pixel_error = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE(diff[R]) +
  5247. PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*SQUARE(diff[G]) +
  5248. PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*SQUARE(diff[B]);
  5249. // Choose best error
  5250. if (pixel_error < best_pixel_error)
  5251. {
  5252. best_pixel_error = pixel_error;
  5253. pixel_colors ^= (pixel_colors & 3); // Reset the two first bits
  5254. pixel_colors |= c;
  5255. }
  5256. }
  5257. block_error += best_pixel_error;
  5258. }
  5259. }
  5260. if (block_error < best_block_error)
  5261. {
  5262. best_block_error = block_error;
  5263. distance = d;
  5264. pixel_indices = pixel_colors;
  5265. best_sw = sw;
  5266. }
  5267. }
  5268. if (sw == 1 && best_sw == 0)
  5269. {
  5270. swapColors(colorsRGB444);
  5271. }
  5272. decompressColor(R_BITS59T, G_BITS59T, B_BITS59T, colorsRGB444, colors);
  5273. }
  5274. return best_block_error;
  5275. }
  5276. // Calculate the error for the block at position (startx,starty)
  5277. // The parameters needed for reconstruction is calculated as well
  5278. //
  5279. // Please note that the function can change the order between the two colors in colorsRGB444
  5280. //
  5281. // In the 59T bit mode, we only have pattern T.
  5282. //
  5283. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5284. double calculateError59T(uint8* srcimg, int width, int startx, int starty, uint8 (colorsRGB444)[2][3], uint8 &distance, unsigned int &pixel_indices)
  5285. {
  5286. double block_error = 0,
  5287. best_block_error = MAXIMUM_ERROR,
  5288. pixel_error,
  5289. best_pixel_error;
  5290. int diff[3];
  5291. uint8 best_sw;
  5292. unsigned int pixel_colors;
  5293. uint8 colors[2][3];
  5294. uint8 possible_colors[4][3];
  5295. // First use the colors as they are, then swap them
  5296. for (uint8 sw = 0; sw <2; ++sw)
  5297. {
  5298. if (sw == 1)
  5299. {
  5300. swapColors(colorsRGB444);
  5301. }
  5302. decompressColor(R_BITS59T, G_BITS59T, B_BITS59T, colorsRGB444, colors);
  5303. // Test all distances
  5304. for (uint8 d = 0; d < BINPOW(TABLE_BITS_59T); ++d)
  5305. {
  5306. calculatePaintColors59T(d,PATTERN_T, colors, possible_colors);
  5307. block_error = 0;
  5308. pixel_colors = 0;
  5309. // Loop block
  5310. for (size_t y = 0; y < BLOCKHEIGHT; ++y)
  5311. {
  5312. for (size_t x = 0; x < BLOCKWIDTH; ++x)
  5313. {
  5314. best_pixel_error = MAXIMUM_ERROR;
  5315. pixel_colors <<=2; // Make room for next value
  5316. // Loop possible block colors
  5317. for (uint8 c = 0; c < 4; ++c)
  5318. {
  5319. diff[R] = srcimg[3*((starty+y)*width+startx+x)+R] - CLAMP(0,possible_colors[c][R],255);
  5320. diff[G] = srcimg[3*((starty+y)*width+startx+x)+G] - CLAMP(0,possible_colors[c][G],255);
  5321. diff[B] = srcimg[3*((starty+y)*width+startx+x)+B] - CLAMP(0,possible_colors[c][B],255);
  5322. pixel_error = weight[R]*SQUARE(diff[R]) +
  5323. weight[G]*SQUARE(diff[G]) +
  5324. weight[B]*SQUARE(diff[B]);
  5325. // Choose best error
  5326. if (pixel_error < best_pixel_error)
  5327. {
  5328. best_pixel_error = pixel_error;
  5329. pixel_colors ^= (pixel_colors & 3); // Reset the two first bits
  5330. pixel_colors |= c;
  5331. }
  5332. }
  5333. block_error += best_pixel_error;
  5334. }
  5335. }
  5336. if (block_error < best_block_error)
  5337. {
  5338. best_block_error = block_error;
  5339. distance = d;
  5340. pixel_indices = pixel_colors;
  5341. best_sw = sw;
  5342. }
  5343. }
  5344. if (sw == 1 && best_sw == 0)
  5345. {
  5346. swapColors(colorsRGB444);
  5347. }
  5348. decompressColor(R_BITS59T, G_BITS59T, B_BITS59T, colorsRGB444, colors);
  5349. }
  5350. return best_block_error;
  5351. }
  5352. // Calculate the error for the block at position (startx,starty)
  5353. // The parameters needed for reconstruction is calculated as well
  5354. //
  5355. // In the 59T bit mode, we only have pattern T.
  5356. //
  5357. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5358. unsigned int calculateError59TnoSwapPerceptual1000(uint8* srcimg, int width, int startx, int starty, uint8 (colorsRGB444)[2][3], uint8 &distance, unsigned int &pixel_indices)
  5359. {
  5360. unsigned int block_error = 0,
  5361. best_block_error = MAXERR1000,
  5362. pixel_error,
  5363. best_pixel_error;
  5364. int diff[3];
  5365. unsigned int pixel_colors;
  5366. uint8 colors[2][3];
  5367. uint8 possible_colors[4][3];
  5368. int thebestintheworld;
  5369. // First use the colors as they are, then swap them
  5370. decompressColor(R_BITS59T, G_BITS59T, B_BITS59T, colorsRGB444, colors);
  5371. // Test all distances
  5372. for (uint8 d = 0; d < BINPOW(TABLE_BITS_59T); ++d)
  5373. {
  5374. calculatePaintColors59T(d,PATTERN_T, colors, possible_colors);
  5375. block_error = 0;
  5376. pixel_colors = 0;
  5377. // Loop block
  5378. for (size_t y = 0; y < BLOCKHEIGHT; ++y)
  5379. {
  5380. for (size_t x = 0; x < BLOCKWIDTH; ++x)
  5381. {
  5382. best_pixel_error = MAXERR1000;
  5383. pixel_colors <<=2; // Make room for next value
  5384. // Loop possible block colors
  5385. for (uint8 c = 0; c < 4; ++c)
  5386. {
  5387. diff[R] = srcimg[3*((starty+y)*width+startx+x)+R] - CLAMP(0,possible_colors[c][R],255);
  5388. diff[G] = srcimg[3*((starty+y)*width+startx+x)+G] - CLAMP(0,possible_colors[c][G],255);
  5389. diff[B] = srcimg[3*((starty+y)*width+startx+x)+B] - CLAMP(0,possible_colors[c][B],255);
  5390. pixel_error = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE(diff[R]) +
  5391. PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*SQUARE(diff[G]) +
  5392. PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*SQUARE(diff[B]);
  5393. // Choose best error
  5394. if (pixel_error < best_pixel_error)
  5395. {
  5396. best_pixel_error = pixel_error;
  5397. pixel_colors ^= (pixel_colors & 3); // Reset the two first bits
  5398. pixel_colors |= c;
  5399. thebestintheworld = c;
  5400. }
  5401. }
  5402. block_error += best_pixel_error;
  5403. }
  5404. }
  5405. if (block_error < best_block_error)
  5406. {
  5407. best_block_error = block_error;
  5408. distance = d;
  5409. pixel_indices = pixel_colors;
  5410. }
  5411. }
  5412. decompressColor(R_BITS59T, G_BITS59T, B_BITS59T, colorsRGB444, colors);
  5413. return best_block_error;
  5414. }
  5415. // Calculate the error for the block at position (startx,starty)
  5416. // The parameters needed for reconstruction is calculated as well
  5417. //
  5418. // In the 59T bit mode, we only have pattern T.
  5419. //
  5420. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5421. double calculateError59TnoSwap(uint8* srcimg, int width, int startx, int starty, uint8 (colorsRGB444)[2][3], uint8 &distance, unsigned int &pixel_indices)
  5422. {
  5423. double block_error = 0,
  5424. best_block_error = MAXIMUM_ERROR,
  5425. pixel_error,
  5426. best_pixel_error;
  5427. int diff[3];
  5428. unsigned int pixel_colors;
  5429. uint8 colors[2][3];
  5430. uint8 possible_colors[4][3];
  5431. int thebestintheworld;
  5432. // First use the colors as they are, then swap them
  5433. decompressColor(R_BITS59T, G_BITS59T, B_BITS59T, colorsRGB444, colors);
  5434. // Test all distances
  5435. for (uint8 d = 0; d < BINPOW(TABLE_BITS_59T); ++d)
  5436. {
  5437. calculatePaintColors59T(d,PATTERN_T, colors, possible_colors);
  5438. block_error = 0;
  5439. pixel_colors = 0;
  5440. // Loop block
  5441. for (size_t y = 0; y < BLOCKHEIGHT; ++y)
  5442. {
  5443. for (size_t x = 0; x < BLOCKWIDTH; ++x)
  5444. {
  5445. best_pixel_error = MAXIMUM_ERROR;
  5446. pixel_colors <<=2; // Make room for next value
  5447. // Loop possible block colors
  5448. for (uint8 c = 0; c < 4; ++c)
  5449. {
  5450. diff[R] = srcimg[3*((starty+y)*width+startx+x)+R] - CLAMP(0,possible_colors[c][R],255);
  5451. diff[G] = srcimg[3*((starty+y)*width+startx+x)+G] - CLAMP(0,possible_colors[c][G],255);
  5452. diff[B] = srcimg[3*((starty+y)*width+startx+x)+B] - CLAMP(0,possible_colors[c][B],255);
  5453. pixel_error = weight[R]*SQUARE(diff[R]) +
  5454. weight[G]*SQUARE(diff[G]) +
  5455. weight[B]*SQUARE(diff[B]);
  5456. // Choose best error
  5457. if (pixel_error < best_pixel_error)
  5458. {
  5459. best_pixel_error = pixel_error;
  5460. pixel_colors ^= (pixel_colors & 3); // Reset the two first bits
  5461. pixel_colors |= c;
  5462. thebestintheworld = c;
  5463. }
  5464. }
  5465. block_error += best_pixel_error;
  5466. }
  5467. }
  5468. if (block_error < best_block_error)
  5469. {
  5470. best_block_error = block_error;
  5471. distance = d;
  5472. pixel_indices = pixel_colors;
  5473. }
  5474. }
  5475. decompressColor(R_BITS59T, G_BITS59T, B_BITS59T, colorsRGB444, colors);
  5476. return best_block_error;
  5477. }
  5478. // Put the compress params into the compression block
  5479. //
  5480. //
  5481. //|63 62 61 60 59|58 57 56 55|54 53 52 51|50 49 48 47|46 45 44 43|42 41 40 39|38 37 36 35|34 33 32|
  5482. //|----empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|--dist--|
  5483. //
  5484. //|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  5485. //|----------------------------------------index bits---------------------------------------------|
  5486. //
  5487. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5488. void packBlock59T(uint8 (colors)[2][3], uint8 d, unsigned int pixel_indices, unsigned int &compressed1, unsigned int &compressed2)
  5489. {
  5490. compressed1 = 0;
  5491. PUTBITSHIGH( compressed1, colors[0][R], 4, 58);
  5492. PUTBITSHIGH( compressed1, colors[0][G], 4, 54);
  5493. PUTBITSHIGH( compressed1, colors[0][B], 4, 50);
  5494. PUTBITSHIGH( compressed1, colors[1][R], 4, 46);
  5495. PUTBITSHIGH( compressed1, colors[1][G], 4, 42);
  5496. PUTBITSHIGH( compressed1, colors[1][B], 4, 38);
  5497. PUTBITSHIGH( compressed1, d, TABLE_BITS_59T, 34);
  5498. pixel_indices=indexConversion(pixel_indices);
  5499. compressed2 = 0;
  5500. PUTBITS( compressed2, pixel_indices, 32, 31);
  5501. }
  5502. // Copy colors from source to dest
  5503. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5504. void copyColors(uint8 (source)[2][3], uint8 (dest)[2][3])
  5505. {
  5506. int x,y;
  5507. for (x=0; x<2; x++)
  5508. for (y=0; y<3; y++)
  5509. dest[x][y] = source[x][y];
  5510. }
  5511. // The below code should compress the block to 59 bits.
  5512. //
  5513. //|63 62 61 60 59|58 57 56 55|54 53 52 51|50 49 48 47|46 45 44 43|42 41 40 39|38 37 36 35|34 33 32|
  5514. //|----empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|--dist--|
  5515. //
  5516. //|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  5517. //|----------------------------------------index bits---------------------------------------------|
  5518. //
  5519. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5520. unsigned int compressBlockTHUMB59TFastestOnlyColorPerceptual1000(uint8 *img,int width,int height,int startx,int starty, int (best_colorsRGB444_packed)[2])
  5521. {
  5522. unsigned int best_error = MAXERR1000;
  5523. unsigned int best_pixel_indices;
  5524. uint8 best_distance;
  5525. unsigned int error_no_i;
  5526. uint8 colorsRGB444_no_i[2][3];
  5527. unsigned int pixel_indices_no_i;
  5528. uint8 distance_no_i;
  5529. uint8 colors[2][3];
  5530. // Calculate average color using the LBG-algorithm
  5531. computeColorLBGHalfIntensityFast(img,width,startx,starty, colors);
  5532. compressColor(R_BITS59T, G_BITS59T, B_BITS59T, colors, colorsRGB444_no_i);
  5533. // Determine the parameters for the lowest error
  5534. error_no_i = calculateError59Tperceptual1000(img, width, startx, starty, colorsRGB444_no_i, distance_no_i, pixel_indices_no_i);
  5535. best_error = error_no_i;
  5536. best_distance = distance_no_i;
  5537. best_pixel_indices = pixel_indices_no_i;
  5538. best_colorsRGB444_packed[0] = (colorsRGB444_no_i[0][0] << 8) + (colorsRGB444_no_i[0][1] << 4) + (colorsRGB444_no_i[0][2] << 0);
  5539. best_colorsRGB444_packed[1] = (colorsRGB444_no_i[1][0] << 8) + (colorsRGB444_no_i[1][1] << 4) + (colorsRGB444_no_i[1][2] << 0);
  5540. return best_error;
  5541. }
  5542. // The below code should compress the block to 59 bits.
  5543. // This is supposed to match the first of the three modes in TWOTIMER.
  5544. //
  5545. //|63 62 61 60 59|58 57 56 55|54 53 52 51|50 49 48 47|46 45 44 43|42 41 40 39|38 37 36 35|34 33 32|
  5546. //|----empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|--dist--|
  5547. //
  5548. //|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  5549. //|----------------------------------------index bits---------------------------------------------|
  5550. //
  5551. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5552. double compressBlockTHUMB59TFastestOnlyColor(uint8 *img,int width,int height,int startx,int starty, int (best_colorsRGB444_packed)[2])
  5553. {
  5554. double best_error = MAXIMUM_ERROR;
  5555. unsigned int best_pixel_indices;
  5556. uint8 best_distance;
  5557. double error_no_i;
  5558. uint8 colorsRGB444_no_i[2][3];
  5559. unsigned int pixel_indices_no_i;
  5560. uint8 distance_no_i;
  5561. uint8 colors[2][3];
  5562. // Calculate average color using the LBG-algorithm
  5563. computeColorLBGHalfIntensityFast(img,width,startx,starty, colors);
  5564. compressColor(R_BITS59T, G_BITS59T, B_BITS59T, colors, colorsRGB444_no_i);
  5565. // Determine the parameters for the lowest error
  5566. error_no_i = calculateError59T(img, width, startx, starty, colorsRGB444_no_i, distance_no_i, pixel_indices_no_i);
  5567. best_error = error_no_i;
  5568. best_distance = distance_no_i;
  5569. best_pixel_indices = pixel_indices_no_i;
  5570. best_colorsRGB444_packed[0] = (colorsRGB444_no_i[0][0] << 8) + (colorsRGB444_no_i[0][1] << 4) + (colorsRGB444_no_i[0][2] << 0);
  5571. best_colorsRGB444_packed[1] = (colorsRGB444_no_i[1][0] << 8) + (colorsRGB444_no_i[1][1] << 4) + (colorsRGB444_no_i[1][2] << 0);
  5572. return best_error;
  5573. }
  5574. // The below code should compress the block to 59 bits.
  5575. // This is supposed to match the first of the three modes in TWOTIMER.
  5576. //
  5577. //|63 62 61 60 59|58 57 56 55|54 53 52 51|50 49 48 47|46 45 44 43|42 41 40 39|38 37 36 35|34 33 32|
  5578. //|----empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|--dist--|
  5579. //
  5580. //|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  5581. //|----------------------------------------index bits---------------------------------------------|
  5582. //
  5583. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5584. double compressBlockTHUMB59TFastestPerceptual1000(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  5585. {
  5586. double best_error = MAXIMUM_ERROR;
  5587. uint8 best_colorsRGB444[2][3];
  5588. unsigned int best_pixel_indices;
  5589. uint8 best_distance;
  5590. double error_no_i;
  5591. uint8 colorsRGB444_no_i[2][3];
  5592. unsigned int pixel_indices_no_i;
  5593. uint8 distance_no_i;
  5594. uint8 colors[2][3];
  5595. // Calculate average color using the LBG-algorithm
  5596. computeColorLBGHalfIntensityFast(img,width,startx,starty, colors);
  5597. compressColor(R_BITS59T, G_BITS59T, B_BITS59T, colors, colorsRGB444_no_i);
  5598. // Determine the parameters for the lowest error
  5599. error_no_i = calculateError59Tperceptual1000(img, width, startx, starty, colorsRGB444_no_i, distance_no_i, pixel_indices_no_i);
  5600. best_error = error_no_i;
  5601. best_distance = distance_no_i;
  5602. best_pixel_indices = pixel_indices_no_i;
  5603. copyColors(colorsRGB444_no_i, best_colorsRGB444);
  5604. // Put the compress params into the compression block
  5605. packBlock59T(best_colorsRGB444, best_distance, best_pixel_indices, compressed1, compressed2);
  5606. return best_error;
  5607. }
  5608. // The below code should compress the block to 59 bits.
  5609. // This is supposed to match the first of the three modes in TWOTIMER.
  5610. //
  5611. //|63 62 61 60 59|58 57 56 55|54 53 52 51|50 49 48 47|46 45 44 43|42 41 40 39|38 37 36 35|34 33 32|
  5612. //|----empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|--dist--|
  5613. //
  5614. //|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  5615. //|----------------------------------------index bits---------------------------------------------|
  5616. //
  5617. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5618. double compressBlockTHUMB59TFastest(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  5619. {
  5620. double best_error = MAXIMUM_ERROR;
  5621. uint8 best_colorsRGB444[2][3];
  5622. unsigned int best_pixel_indices;
  5623. uint8 best_distance;
  5624. double error_no_i;
  5625. uint8 colorsRGB444_no_i[2][3];
  5626. unsigned int pixel_indices_no_i;
  5627. uint8 distance_no_i;
  5628. uint8 colors[2][3];
  5629. // Calculate average color using the LBG-algorithm
  5630. computeColorLBGHalfIntensityFast(img,width,startx,starty, colors);
  5631. compressColor(R_BITS59T, G_BITS59T, B_BITS59T, colors, colorsRGB444_no_i);
  5632. // Determine the parameters for the lowest error
  5633. error_no_i = calculateError59T(img, width, startx, starty, colorsRGB444_no_i, distance_no_i, pixel_indices_no_i);
  5634. best_error = error_no_i;
  5635. best_distance = distance_no_i;
  5636. best_pixel_indices = pixel_indices_no_i;
  5637. copyColors(colorsRGB444_no_i, best_colorsRGB444);
  5638. // Put the compress params into the compression block
  5639. packBlock59T(best_colorsRGB444, best_distance, best_pixel_indices, compressed1, compressed2);
  5640. return best_error;
  5641. }
  5642. // The below code should compress the block to 59 bits.
  5643. // This is supposed to match the first of the three modes in TWOTIMER.
  5644. //
  5645. //|63 62 61 60 59|58 57 56 55|54 53 52 51|50 49 48 47|46 45 44 43|42 41 40 39|38 37 36 35|34 33 32|
  5646. //|----empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|--dist--|
  5647. //
  5648. //|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  5649. //|----------------------------------------index bits---------------------------------------------|
  5650. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5651. double compressBlockTHUMB59TFast(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  5652. {
  5653. double best_error = MAXIMUM_ERROR;
  5654. uint8 best_colorsRGB444[2][3];
  5655. unsigned int best_pixel_indices;
  5656. uint8 best_distance;
  5657. double error_no_i;
  5658. uint8 colorsRGB444_no_i[2][3];
  5659. unsigned int pixel_indices_no_i;
  5660. uint8 distance_no_i;
  5661. double error_half_i;
  5662. uint8 colorsRGB444_half_i[2][3];
  5663. unsigned int pixel_indices_half_i;
  5664. uint8 distance_half_i;
  5665. double error;
  5666. uint8 colorsRGB444[2][3];
  5667. unsigned int pixel_indices;
  5668. uint8 distance;
  5669. uint8 colors[2][3];
  5670. // Calculate average color using the LBG-algorithm
  5671. computeColorLBGNotIntensityFast(img,width,startx,starty, colors);
  5672. compressColor(R_BITS59T, G_BITS59T, B_BITS59T, colors, colorsRGB444_no_i);
  5673. // Determine the parameters for the lowest error
  5674. error_no_i = calculateError59T(img, width, startx, starty, colorsRGB444_no_i, distance_no_i, pixel_indices_no_i);
  5675. // Calculate average color using the LBG-algorithm
  5676. computeColorLBGHalfIntensityFast(img,width,startx,starty, colors);
  5677. compressColor(R_BITS59T, G_BITS59T, B_BITS59T, colors, colorsRGB444_half_i);
  5678. // Determine the parameters for the lowest error
  5679. error_half_i = calculateError59T(img, width, startx, starty, colorsRGB444_half_i, distance_half_i, pixel_indices_half_i);
  5680. // Calculate average color using the LBG-algorithm
  5681. computeColorLBGfast(img,width,startx,starty, colors);
  5682. compressColor(R_BITS59T, G_BITS59T, B_BITS59T, colors, colorsRGB444);
  5683. // Determine the parameters for the lowest error
  5684. error = calculateError59T(img, width, startx, starty, colorsRGB444, distance, pixel_indices);
  5685. best_error = error_no_i;
  5686. best_distance = distance_no_i;
  5687. best_pixel_indices = pixel_indices_no_i;
  5688. copyColors(colorsRGB444_no_i, best_colorsRGB444);
  5689. if(error_half_i < best_error)
  5690. {
  5691. best_error = error_half_i;
  5692. best_distance = distance_half_i;
  5693. best_pixel_indices = pixel_indices_half_i;
  5694. copyColors (colorsRGB444_half_i, best_colorsRGB444);
  5695. }
  5696. if(error < best_error)
  5697. {
  5698. best_error = error;
  5699. best_distance = distance;
  5700. best_pixel_indices = pixel_indices;
  5701. copyColors (colorsRGB444, best_colorsRGB444);
  5702. }
  5703. // Put the compress params into the compression block
  5704. packBlock59T(best_colorsRGB444, best_distance, best_pixel_indices, compressed1, compressed2);
  5705. return best_error;
  5706. }
  5707. // Calculate the error for the block at position (startx,starty)
  5708. // The parameters needed for reconstruction is calculated as well
  5709. //
  5710. // In the 58H bit mode, we only have pattern H.
  5711. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5712. unsigned int calculateErrorAndCompress58Hperceptual1000(uint8* srcimg, int width, int startx, int starty, uint8 (colorsRGB444)[2][3], uint8 &distance, unsigned int &pixel_indices)
  5713. {
  5714. unsigned int block_error = 0,
  5715. best_block_error = MAXERR1000,
  5716. pixel_error,
  5717. best_pixel_error;
  5718. int diff[3];
  5719. unsigned int pixel_colors;
  5720. uint8 possible_colors[4][3];
  5721. uint8 colors[2][3];
  5722. decompressColor(R_BITS58H, G_BITS58H, B_BITS58H, colorsRGB444, colors);
  5723. // Test all distances
  5724. for (uint8 d = 0; d < BINPOW(TABLE_BITS_58H); ++d)
  5725. {
  5726. calculatePaintColors58H(d, PATTERN_H, colors, possible_colors);
  5727. block_error = 0;
  5728. pixel_colors = 0;
  5729. // Loop block
  5730. for (size_t y = 0; y < BLOCKHEIGHT; ++y)
  5731. {
  5732. for (size_t x = 0; x < BLOCKWIDTH; ++x)
  5733. {
  5734. best_pixel_error = MAXERR1000;
  5735. pixel_colors <<=2; // Make room for next value
  5736. // Loop possible block colors
  5737. for (uint8 c = 0; c < 4; ++c)
  5738. {
  5739. diff[R] = srcimg[3*((starty+y)*width+startx+x)+R] - CLAMP(0,possible_colors[c][R],255);
  5740. diff[G] = srcimg[3*((starty+y)*width+startx+x)+G] - CLAMP(0,possible_colors[c][G],255);
  5741. diff[B] = srcimg[3*((starty+y)*width+startx+x)+B] - CLAMP(0,possible_colors[c][B],255);
  5742. pixel_error = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE(diff[R]) +
  5743. PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*SQUARE(diff[G]) +
  5744. PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*SQUARE(diff[B]);
  5745. // Choose best error
  5746. if (pixel_error < best_pixel_error)
  5747. {
  5748. best_pixel_error = pixel_error;
  5749. pixel_colors ^= (pixel_colors & 3); // Reset the two first bits
  5750. pixel_colors |= c;
  5751. }
  5752. }
  5753. block_error += best_pixel_error;
  5754. }
  5755. }
  5756. if (block_error < best_block_error)
  5757. {
  5758. best_block_error = block_error;
  5759. distance = d;
  5760. pixel_indices = pixel_colors;
  5761. }
  5762. }
  5763. return best_block_error;
  5764. }
  5765. // The H-mode but with punchthrough alpha
  5766. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5767. double calculateErrorAndCompress58HAlpha(uint8* srcimg, uint8* alphaimg,int width, int startx, int starty, uint8 (colorsRGB444)[2][3], uint8 &distance, unsigned int &pixel_indices)
  5768. {
  5769. double block_error = 0,
  5770. best_block_error = MAXIMUM_ERROR,
  5771. pixel_error,
  5772. best_pixel_error;
  5773. int diff[3];
  5774. unsigned int pixel_colors;
  5775. uint8 possible_colors[4][3];
  5776. uint8 colors[2][3];
  5777. int alphaindex;
  5778. int colorsRGB444_packed[2];
  5779. colorsRGB444_packed[0] = (colorsRGB444[0][R] << 8) + (colorsRGB444[0][G] << 4) + colorsRGB444[0][B];
  5780. colorsRGB444_packed[1] = (colorsRGB444[1][R] << 8) + (colorsRGB444[1][G] << 4) + colorsRGB444[1][B];
  5781. decompressColor(R_BITS58H, G_BITS58H, B_BITS58H, colorsRGB444, colors);
  5782. // Test all distances
  5783. for (uint8 d = 0; d < BINPOW(TABLE_BITS_58H); ++d)
  5784. {
  5785. alphaindex=2;
  5786. if( (colorsRGB444_packed[0] >= colorsRGB444_packed[1]) ^ ((d & 1)==1) )
  5787. {
  5788. //we're going to have to swap the colors to be able to choose this distance.. that means
  5789. //that the indices will be swapped as well, so C1 will be the one with alpha instead of C3..
  5790. alphaindex=0;
  5791. }
  5792. calculatePaintColors58H(d, PATTERN_H, colors, possible_colors);
  5793. block_error = 0;
  5794. pixel_colors = 0;
  5795. // Loop block
  5796. for (size_t y = 0; y < BLOCKHEIGHT; ++y)
  5797. {
  5798. for (size_t x = 0; x < BLOCKWIDTH; ++x)
  5799. {
  5800. int alpha=0;
  5801. if(alphaimg[((starty+y)*width+startx+x)]>0)
  5802. alpha=1;
  5803. if(alphaimg[((starty+y)*width+startx+x)]>0&&alphaimg[((starty+y)*width+startx+x)]<255)
  5804. printf("INVALID ALPHA DATA!!\n");
  5805. best_pixel_error = MAXIMUM_ERROR;
  5806. pixel_colors <<=2; // Make room for next value
  5807. // Loop possible block colors
  5808. for (uint8 c = 0; c < 4; ++c)
  5809. {
  5810. if(c==alphaindex&&alpha)
  5811. {
  5812. pixel_error=0;
  5813. }
  5814. else if(c==alphaindex||alpha)
  5815. {
  5816. pixel_error=MAXIMUM_ERROR;
  5817. }
  5818. else
  5819. {
  5820. diff[R] = srcimg[3*((starty+y)*width+startx+x)+R] - CLAMP(0,possible_colors[c][R],255);
  5821. diff[G] = srcimg[3*((starty+y)*width+startx+x)+G] - CLAMP(0,possible_colors[c][G],255);
  5822. diff[B] = srcimg[3*((starty+y)*width+startx+x)+B] - CLAMP(0,possible_colors[c][B],255);
  5823. pixel_error = weight[R]*SQUARE(diff[R]) +
  5824. weight[G]*SQUARE(diff[G]) +
  5825. weight[B]*SQUARE(diff[B]);
  5826. }
  5827. // Choose best error
  5828. if (pixel_error < best_pixel_error)
  5829. {
  5830. best_pixel_error = pixel_error;
  5831. pixel_colors ^= (pixel_colors & 3); // Reset the two first bits
  5832. pixel_colors |= c;
  5833. }
  5834. }
  5835. block_error += best_pixel_error;
  5836. }
  5837. }
  5838. if (block_error < best_block_error)
  5839. {
  5840. best_block_error = block_error;
  5841. distance = d;
  5842. pixel_indices = pixel_colors;
  5843. }
  5844. }
  5845. return best_block_error;
  5846. }
  5847. // Calculate the error for the block at position (startx,starty)
  5848. // The parameters needed for reconstruction is calculated as well
  5849. //
  5850. // In the 58H bit mode, we only have pattern H.
  5851. //
  5852. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5853. double calculateErrorAndCompress58H(uint8* srcimg, int width, int startx, int starty, uint8 (colorsRGB444)[2][3], uint8 &distance, unsigned int &pixel_indices)
  5854. {
  5855. double block_error = 0,
  5856. best_block_error = MAXIMUM_ERROR,
  5857. pixel_error,
  5858. best_pixel_error;
  5859. int diff[3];
  5860. unsigned int pixel_colors;
  5861. uint8 possible_colors[4][3];
  5862. uint8 colors[2][3];
  5863. decompressColor(R_BITS58H, G_BITS58H, B_BITS58H, colorsRGB444, colors);
  5864. // Test all distances
  5865. for (uint8 d = 0; d < BINPOW(TABLE_BITS_58H); ++d)
  5866. {
  5867. calculatePaintColors58H(d, PATTERN_H, colors, possible_colors);
  5868. block_error = 0;
  5869. pixel_colors = 0;
  5870. // Loop block
  5871. for (size_t y = 0; y < BLOCKHEIGHT; ++y)
  5872. {
  5873. for (size_t x = 0; x < BLOCKWIDTH; ++x)
  5874. {
  5875. best_pixel_error = MAXIMUM_ERROR;
  5876. pixel_colors <<=2; // Make room for next value
  5877. // Loop possible block colors
  5878. for (uint8 c = 0; c < 4; ++c)
  5879. {
  5880. diff[R] = srcimg[3*((starty+y)*width+startx+x)+R] - CLAMP(0,possible_colors[c][R],255);
  5881. diff[G] = srcimg[3*((starty+y)*width+startx+x)+G] - CLAMP(0,possible_colors[c][G],255);
  5882. diff[B] = srcimg[3*((starty+y)*width+startx+x)+B] - CLAMP(0,possible_colors[c][B],255);
  5883. pixel_error = weight[R]*SQUARE(diff[R]) +
  5884. weight[G]*SQUARE(diff[G]) +
  5885. weight[B]*SQUARE(diff[B]);
  5886. // Choose best error
  5887. if (pixel_error < best_pixel_error)
  5888. {
  5889. best_pixel_error = pixel_error;
  5890. pixel_colors ^= (pixel_colors & 3); // Reset the two first bits
  5891. pixel_colors |= c;
  5892. }
  5893. }
  5894. block_error += best_pixel_error;
  5895. }
  5896. }
  5897. if (block_error < best_block_error)
  5898. {
  5899. best_block_error = block_error;
  5900. distance = d;
  5901. pixel_indices = pixel_colors;
  5902. }
  5903. }
  5904. return best_block_error;
  5905. }
  5906. // Makes sure that col0 < col1;
  5907. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5908. void sortColorsRGB444(uint8 (colorsRGB444)[2][3])
  5909. {
  5910. unsigned int col0, col1, tcol;
  5911. // sort colors
  5912. col0 = 16*16*colorsRGB444[0][R] + 16*colorsRGB444[0][G] + colorsRGB444[0][B];
  5913. col1 = 16*16*colorsRGB444[1][R] + 16*colorsRGB444[1][G] + colorsRGB444[1][B];
  5914. // After this, col0 should be smaller than col1 (col0 < col1)
  5915. if( col0 > col1)
  5916. {
  5917. tcol = col0;
  5918. col0 = col1;
  5919. col1 = tcol;
  5920. }
  5921. else
  5922. {
  5923. if(col0 == col1)
  5924. {
  5925. // Both colors are the same. That is useless. If they are both black,
  5926. // col1 can just as well be (0,0,1). Else, col0 can be col1 - 1.
  5927. if(col0 == 0)
  5928. col1 = col0+1;
  5929. else
  5930. col0 = col1-1;
  5931. }
  5932. }
  5933. colorsRGB444[0][R] = GETBITS(col0, 4, 11);
  5934. colorsRGB444[0][G] = GETBITS(col0, 4, 7);
  5935. colorsRGB444[0][B] = GETBITS(col0, 4, 3);
  5936. colorsRGB444[1][R] = GETBITS(col1, 4, 11);
  5937. colorsRGB444[1][G] = GETBITS(col1, 4, 7);
  5938. colorsRGB444[1][B] = GETBITS(col1, 4, 3);
  5939. }
  5940. // The below code should compress the block to 58 bits.
  5941. // The bit layout is thought to be:
  5942. //
  5943. //|63 62 61 60 59 58|57 56 55 54|53 52 51 50|49 48 47 46|45 44 43 42|41 40 39 38|37 36 35 34|33 32|
  5944. //|-------empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|d2 d1|
  5945. //
  5946. //|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  5947. //|----------------------------------------index bits---------------------------------------------|
  5948. //
  5949. // The distance d is three bits, d2 (MSB), d1 and d0 (LSB). d0 is not stored explicitly.
  5950. // Instead if the 12-bit word red0,green0,blue0 < red1,green1,blue1, d0 is assumed to be 0.
  5951. // Else, it is assumed to be 1.
  5952. //
  5953. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  5954. unsigned int compressBlockTHUMB58HFastestPerceptual1000(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  5955. {
  5956. unsigned int best_error = MAXERR1000;
  5957. uint8 best_colorsRGB444[2][3];
  5958. unsigned int best_pixel_indices;
  5959. uint8 best_distance;
  5960. unsigned int error_no_i;
  5961. uint8 colorsRGB444_no_i[2][3];
  5962. unsigned int pixel_indices_no_i;
  5963. uint8 distance_no_i;
  5964. uint8 colors[2][3];
  5965. // Calculate average color using the LBG-algorithm but discarding the intensity in the error function
  5966. computeColorLBGHalfIntensityFast(img, width, startx, starty, colors);
  5967. compressColor(R_BITS58H, G_BITS58H, B_BITS58H, colors, colorsRGB444_no_i);
  5968. sortColorsRGB444(colorsRGB444_no_i);
  5969. error_no_i = calculateErrorAndCompress58Hperceptual1000(img, width, startx, starty, colorsRGB444_no_i, distance_no_i, pixel_indices_no_i);
  5970. best_error = error_no_i;
  5971. best_distance = distance_no_i;
  5972. best_pixel_indices = pixel_indices_no_i;
  5973. copyColors(colorsRGB444_no_i, best_colorsRGB444);
  5974. // | col0 >= col1 col0 < col1
  5975. //------------------------------------------------------
  5976. // (dist & 1) = 1 | no need to swap | need to swap
  5977. // |-----------------+----------------
  5978. // (dist & 1) = 0 | need to swap | no need to swap
  5979. //
  5980. // This can be done with an xor test.
  5981. int best_colorsRGB444_packed[2];
  5982. best_colorsRGB444_packed[0] = (best_colorsRGB444[0][R] << 8) + (best_colorsRGB444[0][G] << 4) + best_colorsRGB444[0][B];
  5983. best_colorsRGB444_packed[1] = (best_colorsRGB444[1][R] << 8) + (best_colorsRGB444[1][G] << 4) + best_colorsRGB444[1][B];
  5984. if( (best_colorsRGB444_packed[0] >= best_colorsRGB444_packed[1]) ^ ((best_distance & 1)==1) )
  5985. {
  5986. swapColors(best_colorsRGB444);
  5987. // Reshuffle pixel indices to to exchange C1 with C3, and C2 with C4
  5988. best_pixel_indices = (0x55555555 & best_pixel_indices) | (0xaaaaaaaa & (~best_pixel_indices));
  5989. }
  5990. // Put the compress params into the compression block
  5991. compressed1 = 0;
  5992. PUTBITSHIGH( compressed1, best_colorsRGB444[0][R], 4, 57);
  5993. PUTBITSHIGH( compressed1, best_colorsRGB444[0][G], 4, 53);
  5994. PUTBITSHIGH( compressed1, best_colorsRGB444[0][B], 4, 49);
  5995. PUTBITSHIGH( compressed1, best_colorsRGB444[1][R], 4, 45);
  5996. PUTBITSHIGH( compressed1, best_colorsRGB444[1][G], 4, 41);
  5997. PUTBITSHIGH( compressed1, best_colorsRGB444[1][B], 4, 37);
  5998. PUTBITSHIGH( compressed1, (best_distance >> 1), 2, 33);
  5999. compressed2 = 0;
  6000. best_pixel_indices=indexConversion(best_pixel_indices);
  6001. PUTBITS( compressed2, best_pixel_indices, 32, 31);
  6002. return best_error;
  6003. }
  6004. // The below code should compress the block to 58 bits.
  6005. // This is supposed to match the first of the three modes in TWOTIMER.
  6006. // The bit layout is thought to be:
  6007. //
  6008. //|63 62 61 60 59 58|57 56 55 54|53 52 51 50|49 48 47 46|45 44 43 42|41 40 39 38|37 36 35 34|33 32|
  6009. //|-------empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|d2 d1|
  6010. //
  6011. //|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  6012. //|----------------------------------------index bits---------------------------------------------|
  6013. //
  6014. // The distance d is three bits, d2 (MSB), d1 and d0 (LSB). d0 is not stored explicitly.
  6015. // Instead if the 12-bit word red0,green0,blue0 < red1,green1,blue1, d0 is assumed to be 0.
  6016. // Else, it is assumed to be 1.
  6017. //
  6018. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  6019. double compressBlockTHUMB58HFastest(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  6020. {
  6021. double best_error = MAXIMUM_ERROR;
  6022. uint8 best_colorsRGB444[2][3];
  6023. unsigned int best_pixel_indices;
  6024. uint8 best_distance;
  6025. double error_no_i;
  6026. uint8 colorsRGB444_no_i[2][3];
  6027. unsigned int pixel_indices_no_i;
  6028. uint8 distance_no_i;
  6029. uint8 colors[2][3];
  6030. // Calculate average color using the LBG-algorithm but discarding the intensity in the error function
  6031. computeColorLBGHalfIntensityFast(img, width, startx, starty, colors);
  6032. compressColor(R_BITS58H, G_BITS58H, B_BITS58H, colors, colorsRGB444_no_i);
  6033. sortColorsRGB444(colorsRGB444_no_i);
  6034. error_no_i = calculateErrorAndCompress58H(img, width, startx, starty, colorsRGB444_no_i, distance_no_i, pixel_indices_no_i);
  6035. best_error = error_no_i;
  6036. best_distance = distance_no_i;
  6037. best_pixel_indices = pixel_indices_no_i;
  6038. copyColors(colorsRGB444_no_i, best_colorsRGB444);
  6039. // | col0 >= col1 col0 < col1
  6040. //------------------------------------------------------
  6041. // (dist & 1) = 1 | no need to swap | need to swap
  6042. // |-----------------+----------------
  6043. // (dist & 1) = 0 | need to swap | no need to swap
  6044. //
  6045. // This can be done with an xor test.
  6046. int best_colorsRGB444_packed[2];
  6047. best_colorsRGB444_packed[0] = (best_colorsRGB444[0][R] << 8) + (best_colorsRGB444[0][G] << 4) + best_colorsRGB444[0][B];
  6048. best_colorsRGB444_packed[1] = (best_colorsRGB444[1][R] << 8) + (best_colorsRGB444[1][G] << 4) + best_colorsRGB444[1][B];
  6049. if( (best_colorsRGB444_packed[0] >= best_colorsRGB444_packed[1]) ^ ((best_distance & 1)==1) )
  6050. {
  6051. swapColors(best_colorsRGB444);
  6052. // Reshuffle pixel indices to to exchange C1 with C3, and C2 with C4
  6053. best_pixel_indices = (0x55555555 & best_pixel_indices) | (0xaaaaaaaa & (~best_pixel_indices));
  6054. }
  6055. // Put the compress params into the compression block
  6056. compressed1 = 0;
  6057. PUTBITSHIGH( compressed1, best_colorsRGB444[0][R], 4, 57);
  6058. PUTBITSHIGH( compressed1, best_colorsRGB444[0][G], 4, 53);
  6059. PUTBITSHIGH( compressed1, best_colorsRGB444[0][B], 4, 49);
  6060. PUTBITSHIGH( compressed1, best_colorsRGB444[1][R], 4, 45);
  6061. PUTBITSHIGH( compressed1, best_colorsRGB444[1][G], 4, 41);
  6062. PUTBITSHIGH( compressed1, best_colorsRGB444[1][B], 4, 37);
  6063. PUTBITSHIGH( compressed1, (best_distance >> 1), 2, 33);
  6064. best_pixel_indices=indexConversion(best_pixel_indices);
  6065. compressed2 = 0;
  6066. PUTBITS( compressed2, best_pixel_indices, 32, 31);
  6067. return best_error;
  6068. }
  6069. //same as above, but with 1-bit alpha
  6070. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  6071. double compressBlockTHUMB58HAlpha(uint8 *img, uint8* alphaimg, int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  6072. {
  6073. double best_error = MAXIMUM_ERROR;
  6074. uint8 best_colorsRGB444[2][3];
  6075. unsigned int best_pixel_indices;
  6076. uint8 best_distance;
  6077. double error_no_i;
  6078. uint8 colorsRGB444_no_i[2][3];
  6079. unsigned int pixel_indices_no_i;
  6080. uint8 distance_no_i;
  6081. uint8 colors[2][3];
  6082. // Calculate average color using the LBG-algorithm but discarding the intensity in the error function
  6083. computeColorLBGHalfIntensityFast(img, width, startx, starty, colors);
  6084. compressColor(R_BITS58H, G_BITS58H, B_BITS58H, colors, colorsRGB444_no_i);
  6085. sortColorsRGB444(colorsRGB444_no_i);
  6086. error_no_i = calculateErrorAndCompress58HAlpha(img, alphaimg,width, startx, starty, colorsRGB444_no_i, distance_no_i, pixel_indices_no_i);
  6087. best_error = error_no_i;
  6088. best_distance = distance_no_i;
  6089. best_pixel_indices = pixel_indices_no_i;
  6090. copyColors(colorsRGB444_no_i, best_colorsRGB444);
  6091. // | col0 >= col1 col0 < col1
  6092. //------------------------------------------------------
  6093. // (dist & 1) = 1 | no need to swap | need to swap
  6094. // |-----------------+----------------
  6095. // (dist & 1) = 0 | need to swap | no need to swap
  6096. //
  6097. // This can be done with an xor test.
  6098. int best_colorsRGB444_packed[2];
  6099. best_colorsRGB444_packed[0] = (best_colorsRGB444[0][R] << 8) + (best_colorsRGB444[0][G] << 4) + best_colorsRGB444[0][B];
  6100. best_colorsRGB444_packed[1] = (best_colorsRGB444[1][R] << 8) + (best_colorsRGB444[1][G] << 4) + best_colorsRGB444[1][B];
  6101. if( (best_colorsRGB444_packed[0] >= best_colorsRGB444_packed[1]) ^ ((best_distance & 1)==1) )
  6102. {
  6103. swapColors(best_colorsRGB444);
  6104. // Reshuffle pixel indices to to exchange C1 with C3, and C2 with C4
  6105. best_pixel_indices = (0x55555555 & best_pixel_indices) | (0xaaaaaaaa & (~best_pixel_indices));
  6106. }
  6107. // Put the compress params into the compression block
  6108. compressed1 = 0;
  6109. PUTBITSHIGH( compressed1, best_colorsRGB444[0][R], 4, 57);
  6110. PUTBITSHIGH( compressed1, best_colorsRGB444[0][G], 4, 53);
  6111. PUTBITSHIGH( compressed1, best_colorsRGB444[0][B], 4, 49);
  6112. PUTBITSHIGH( compressed1, best_colorsRGB444[1][R], 4, 45);
  6113. PUTBITSHIGH( compressed1, best_colorsRGB444[1][G], 4, 41);
  6114. PUTBITSHIGH( compressed1, best_colorsRGB444[1][B], 4, 37);
  6115. PUTBITSHIGH( compressed1, (best_distance >> 1), 2, 33);
  6116. best_pixel_indices=indexConversion(best_pixel_indices);
  6117. compressed2 = 0;
  6118. PUTBITS( compressed2, best_pixel_indices, 32, 31);
  6119. return best_error;
  6120. }
  6121. // The below code should compress the block to 58 bits.
  6122. // This is supposed to match the first of the three modes in TWOTIMER.
  6123. // The bit layout is thought to be:
  6124. //
  6125. //|63 62 61 60 59 58|57 56 55 54|53 52 51 50|49 48 47 46|45 44 43 42|41 40 39 38|37 36 35 34|33 32|
  6126. //|-------empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|d2 d1|
  6127. //
  6128. //|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  6129. //|----------------------------------------index bits---------------------------------------------|
  6130. //
  6131. // The distance d is three bits, d2 (MSB), d1 and d0 (LSB). d0 is not stored explicitly.
  6132. // Instead if the 12-bit word red0,green0,blue0 < red1,green1,blue1, d0 is assumed to be 0.
  6133. // Else, it is assumed to be 1.
  6134. //
  6135. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  6136. double compressBlockTHUMB58HFast(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  6137. {
  6138. double best_error = MAXIMUM_ERROR;
  6139. uint8 best_colorsRGB444[2][3];
  6140. unsigned int best_pixel_indices;
  6141. uint8 best_distance;
  6142. double error_no_i;
  6143. uint8 colorsRGB444_no_i[2][3];
  6144. unsigned int pixel_indices_no_i;
  6145. uint8 distance_no_i;
  6146. double error_half_i;
  6147. uint8 colorsRGB444_half_i[2][3];
  6148. unsigned int pixel_indices_half_i;
  6149. uint8 distance_half_i;
  6150. double error;
  6151. uint8 colorsRGB444[2][3];
  6152. unsigned int pixel_indices;
  6153. uint8 distance;
  6154. uint8 colors[2][3];
  6155. // Calculate average color using the LBG-algorithm but discarding the intensity in the error function
  6156. computeColorLBGNotIntensity(img, width, startx, starty, colors);
  6157. compressColor(R_BITS58H, G_BITS58H, B_BITS58H, colors, colorsRGB444_no_i);
  6158. sortColorsRGB444(colorsRGB444_no_i);
  6159. error_no_i = calculateErrorAndCompress58H(img, width, startx, starty, colorsRGB444_no_i, distance_no_i, pixel_indices_no_i);
  6160. // Calculate average color using the LBG-algorithm but halfing the influence of the intensity in the error function
  6161. computeColorLBGNotIntensity(img, width, startx, starty, colors);
  6162. compressColor(R_BITS58H, G_BITS58H, B_BITS58H, colors, colorsRGB444_half_i);
  6163. sortColorsRGB444(colorsRGB444_half_i);
  6164. error_half_i = calculateErrorAndCompress58H(img, width, startx, starty, colorsRGB444_half_i, distance_half_i, pixel_indices_half_i);
  6165. // Calculate average color using the LBG-algorithm
  6166. computeColorLBG(img, width, startx, starty, colors);
  6167. compressColor(R_BITS58H, G_BITS58H, B_BITS58H, colors, colorsRGB444);
  6168. sortColorsRGB444(colorsRGB444);
  6169. error = calculateErrorAndCompress58H(img, width, startx, starty, colorsRGB444, distance, pixel_indices);
  6170. best_error = error_no_i;
  6171. best_distance = distance_no_i;
  6172. best_pixel_indices = pixel_indices_no_i;
  6173. copyColors(colorsRGB444_no_i, best_colorsRGB444);
  6174. if(error_half_i < best_error)
  6175. {
  6176. best_error = error_half_i;
  6177. best_distance = distance_half_i;
  6178. best_pixel_indices = pixel_indices_half_i;
  6179. copyColors(colorsRGB444_half_i, best_colorsRGB444);
  6180. }
  6181. if(error < best_error)
  6182. {
  6183. best_error = error;
  6184. best_distance = distance;
  6185. best_pixel_indices = pixel_indices;
  6186. copyColors(colorsRGB444, best_colorsRGB444);
  6187. }
  6188. // | col0 >= col1 col0 < col1
  6189. //------------------------------------------------------
  6190. // (dist & 1) = 1 | no need to swap | need to swap
  6191. // |-----------------+----------------
  6192. // (dist & 1) = 0 | need to swap | no need to swap
  6193. //
  6194. // This can be done with an xor test.
  6195. int best_colorsRGB444_packed[2];
  6196. best_colorsRGB444_packed[0] = (best_colorsRGB444[0][R] << 8) + (best_colorsRGB444[0][G] << 4) + best_colorsRGB444[0][B];
  6197. best_colorsRGB444_packed[1] = (best_colorsRGB444[1][R] << 8) + (best_colorsRGB444[1][G] << 4) + best_colorsRGB444[1][B];
  6198. if( (best_colorsRGB444_packed[0] >= best_colorsRGB444_packed[1]) ^ ((best_distance & 1)==1) )
  6199. {
  6200. swapColors(best_colorsRGB444);
  6201. // Reshuffle pixel indices to to exchange C1 with C3, and C2 with C4
  6202. best_pixel_indices = (0x55555555 & best_pixel_indices) | (0xaaaaaaaa & (~best_pixel_indices));
  6203. }
  6204. // Put the compress params into the compression block
  6205. compressed1 = 0;
  6206. PUTBITSHIGH( compressed1, best_colorsRGB444[0][R], 4, 57);
  6207. PUTBITSHIGH( compressed1, best_colorsRGB444[0][G], 4, 53);
  6208. PUTBITSHIGH( compressed1, best_colorsRGB444[0][B], 4, 49);
  6209. PUTBITSHIGH( compressed1, best_colorsRGB444[1][R], 4, 45);
  6210. PUTBITSHIGH( compressed1, best_colorsRGB444[1][G], 4, 41);
  6211. PUTBITSHIGH( compressed1, best_colorsRGB444[1][B], 4, 37);
  6212. PUTBITSHIGH( compressed1, (best_distance >> 1), 2, 33);
  6213. best_pixel_indices=indexConversion(best_pixel_indices);
  6214. compressed2 = 0;
  6215. PUTBITS( compressed2, best_pixel_indices, 32, 31);
  6216. return best_error;
  6217. }
  6218. // Compress block testing both individual and differential mode.
  6219. // Perceptual error metric.
  6220. // Combined quantization for colors.
  6221. // Both flipped and unflipped tested.
  6222. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  6223. void compressBlockDiffFlipCombinedPerceptual(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  6224. {
  6225. unsigned int compressed1_norm, compressed2_norm;
  6226. unsigned int compressed1_flip, compressed2_flip;
  6227. uint8 avg_color_quant1[3], avg_color_quant2[3];
  6228. float avg_color_float1[3],avg_color_float2[3];
  6229. int enc_color1[3], enc_color2[3], diff[3];
  6230. int min_error=255*255*8*3;
  6231. unsigned int best_table_indices1=0, best_table_indices2=0;
  6232. unsigned int best_table1=0, best_table2=0;
  6233. int diffbit;
  6234. int norm_err=0;
  6235. int flip_err=0;
  6236. // First try normal blocks 2x4:
  6237. computeAverageColor2x4noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  6238. computeAverageColor2x4noQuantFloat(img,width,height,startx+2,starty,avg_color_float2);
  6239. // First test if avg_color1 is similar enough to avg_color2 so that
  6240. // we can use differential coding of colors.
  6241. float eps;
  6242. uint8 dummy[3];
  6243. quantize555ColorCombinedPerceptual(avg_color_float1, enc_color1, dummy);
  6244. quantize555ColorCombinedPerceptual(avg_color_float2, enc_color2, dummy);
  6245. diff[0] = enc_color2[0]-enc_color1[0];
  6246. diff[1] = enc_color2[1]-enc_color1[1];
  6247. diff[2] = enc_color2[2]-enc_color1[2];
  6248. if( (diff[0] >= -4) && (diff[0] <= 3) && (diff[1] >= -4) && (diff[1] <= 3) && (diff[2] >= -4) && (diff[2] <= 3) )
  6249. {
  6250. diffbit = 1;
  6251. // The difference to be coded:
  6252. diff[0] = enc_color2[0]-enc_color1[0];
  6253. diff[1] = enc_color2[1]-enc_color1[1];
  6254. diff[2] = enc_color2[2]-enc_color1[2];
  6255. avg_color_quant1[0] = enc_color1[0] << 3 | (enc_color1[0] >> 2);
  6256. avg_color_quant1[1] = enc_color1[1] << 3 | (enc_color1[1] >> 2);
  6257. avg_color_quant1[2] = enc_color1[2] << 3 | (enc_color1[2] >> 2);
  6258. avg_color_quant2[0] = enc_color2[0] << 3 | (enc_color2[0] >> 2);
  6259. avg_color_quant2[1] = enc_color2[1] << 3 | (enc_color2[1] >> 2);
  6260. avg_color_quant2[2] = enc_color2[2] << 3 | (enc_color2[2] >> 2);
  6261. // Pack bits into the first word.
  6262. // ETC1_RGB8_OES:
  6263. //
  6264. // a) bit layout in bits 63 through 32 if diffbit = 0
  6265. //
  6266. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  6267. // ---------------------------------------------------------------------------------------------------
  6268. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  6269. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  6270. // ---------------------------------------------------------------------------------------------------
  6271. //
  6272. // b) bit layout in bits 63 through 32 if diffbit = 1
  6273. //
  6274. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  6275. // ---------------------------------------------------------------------------------------------------
  6276. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |diff|flip|
  6277. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
  6278. // ---------------------------------------------------------------------------------------------------
  6279. //
  6280. // c) bit layout in bits 31 through 0 (in both cases)
  6281. //
  6282. // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  6283. // --------------------------------------------------------------------------------------------------
  6284. // | most significant pixel index bits | least significant pixel index bits |
  6285. // | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a| p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
  6286. // --------------------------------------------------------------------------------------------------
  6287. compressed1_norm = 0;
  6288. PUTBITSHIGH( compressed1_norm, diffbit, 1, 33);
  6289. PUTBITSHIGH( compressed1_norm, enc_color1[0], 5, 63);
  6290. PUTBITSHIGH( compressed1_norm, enc_color1[1], 5, 55);
  6291. PUTBITSHIGH( compressed1_norm, enc_color1[2], 5, 47);
  6292. PUTBITSHIGH( compressed1_norm, diff[0], 3, 58);
  6293. PUTBITSHIGH( compressed1_norm, diff[1], 3, 50);
  6294. PUTBITSHIGH( compressed1_norm, diff[2], 3, 42);
  6295. unsigned int best_pixel_indices1_MSB;
  6296. unsigned int best_pixel_indices1_LSB;
  6297. unsigned int best_pixel_indices2_MSB;
  6298. unsigned int best_pixel_indices2_LSB;
  6299. norm_err = 0;
  6300. // left part of block
  6301. norm_err = tryalltables_3bittable2x4percep(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  6302. // right part of block
  6303. norm_err += tryalltables_3bittable2x4percep(img,width,height,startx+2,starty,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  6304. PUTBITSHIGH( compressed1_norm, best_table1, 3, 39);
  6305. PUTBITSHIGH( compressed1_norm, best_table2, 3, 36);
  6306. PUTBITSHIGH( compressed1_norm, 0, 1, 32);
  6307. compressed2_norm = 0;
  6308. PUTBITS( compressed2_norm, (best_pixel_indices1_MSB ), 8, 23);
  6309. PUTBITS( compressed2_norm, (best_pixel_indices2_MSB ), 8, 31);
  6310. PUTBITS( compressed2_norm, (best_pixel_indices1_LSB ), 8, 7);
  6311. PUTBITS( compressed2_norm, (best_pixel_indices2_LSB ), 8, 15);
  6312. }
  6313. else
  6314. {
  6315. diffbit = 0;
  6316. // The difference is bigger than what fits in 555 plus delta-333, so we will have
  6317. // to deal with 444 444.
  6318. eps = (float) 0.0001;
  6319. quantize444ColorCombinedPerceptual(avg_color_float1, enc_color1, dummy);
  6320. quantize444ColorCombinedPerceptual(avg_color_float2, enc_color2, dummy);
  6321. avg_color_quant1[0] = enc_color1[0] << 4 | enc_color1[0];
  6322. avg_color_quant1[1] = enc_color1[1] << 4 | enc_color1[1];
  6323. avg_color_quant1[2] = enc_color1[2] << 4 | enc_color1[2];
  6324. avg_color_quant2[0] = enc_color2[0] << 4 | enc_color2[0];
  6325. avg_color_quant2[1] = enc_color2[1] << 4 | enc_color2[1];
  6326. avg_color_quant2[2] = enc_color2[2] << 4 | enc_color2[2];
  6327. // Pack bits into the first word.
  6328. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  6329. // ---------------------------------------------------------------------------------------------------
  6330. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  6331. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  6332. // ---------------------------------------------------------------------------------------------------
  6333. compressed1_norm = 0;
  6334. PUTBITSHIGH( compressed1_norm, diffbit, 1, 33);
  6335. PUTBITSHIGH( compressed1_norm, enc_color1[0], 4, 63);
  6336. PUTBITSHIGH( compressed1_norm, enc_color1[1], 4, 55);
  6337. PUTBITSHIGH( compressed1_norm, enc_color1[2], 4, 47);
  6338. PUTBITSHIGH( compressed1_norm, enc_color2[0], 4, 59);
  6339. PUTBITSHIGH( compressed1_norm, enc_color2[1], 4, 51);
  6340. PUTBITSHIGH( compressed1_norm, enc_color2[2], 4, 43);
  6341. unsigned int best_pixel_indices1_MSB;
  6342. unsigned int best_pixel_indices1_LSB;
  6343. unsigned int best_pixel_indices2_MSB;
  6344. unsigned int best_pixel_indices2_LSB;
  6345. // left part of block
  6346. norm_err = tryalltables_3bittable2x4percep(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  6347. // right part of block
  6348. norm_err += tryalltables_3bittable2x4percep(img,width,height,startx+2,starty,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  6349. PUTBITSHIGH( compressed1_norm, best_table1, 3, 39);
  6350. PUTBITSHIGH( compressed1_norm, best_table2, 3, 36);
  6351. PUTBITSHIGH( compressed1_norm, 0, 1, 32);
  6352. compressed2_norm = 0;
  6353. PUTBITS( compressed2_norm, (best_pixel_indices1_MSB ), 8, 23);
  6354. PUTBITS( compressed2_norm, (best_pixel_indices2_MSB ), 8, 31);
  6355. PUTBITS( compressed2_norm, (best_pixel_indices1_LSB ), 8, 7);
  6356. PUTBITS( compressed2_norm, (best_pixel_indices2_LSB ), 8, 15);
  6357. }
  6358. // Now try flipped blocks 4x2:
  6359. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty,avg_color_float1);
  6360. computeAverageColor4x2noQuantFloat(img,width,height,startx,starty+2,avg_color_float2);
  6361. // First test if avg_color1 is similar enough to avg_color2 so that
  6362. // we can use differential coding of colors.
  6363. quantize555ColorCombinedPerceptual(avg_color_float1, enc_color1, dummy);
  6364. quantize555ColorCombinedPerceptual(avg_color_float2, enc_color2, dummy);
  6365. diff[0] = enc_color2[0]-enc_color1[0];
  6366. diff[1] = enc_color2[1]-enc_color1[1];
  6367. diff[2] = enc_color2[2]-enc_color1[2];
  6368. if( (diff[0] >= -4) && (diff[0] <= 3) && (diff[1] >= -4) && (diff[1] <= 3) && (diff[2] >= -4) && (diff[2] <= 3) )
  6369. {
  6370. diffbit = 1;
  6371. // The difference to be coded:
  6372. diff[0] = enc_color2[0]-enc_color1[0];
  6373. diff[1] = enc_color2[1]-enc_color1[1];
  6374. diff[2] = enc_color2[2]-enc_color1[2];
  6375. avg_color_quant1[0] = enc_color1[0] << 3 | (enc_color1[0] >> 2);
  6376. avg_color_quant1[1] = enc_color1[1] << 3 | (enc_color1[1] >> 2);
  6377. avg_color_quant1[2] = enc_color1[2] << 3 | (enc_color1[2] >> 2);
  6378. avg_color_quant2[0] = enc_color2[0] << 3 | (enc_color2[0] >> 2);
  6379. avg_color_quant2[1] = enc_color2[1] << 3 | (enc_color2[1] >> 2);
  6380. avg_color_quant2[2] = enc_color2[2] << 3 | (enc_color2[2] >> 2);
  6381. // Pack bits into the first word.
  6382. compressed1_flip = 0;
  6383. PUTBITSHIGH( compressed1_flip, diffbit, 1, 33);
  6384. PUTBITSHIGH( compressed1_flip, enc_color1[0], 5, 63);
  6385. PUTBITSHIGH( compressed1_flip, enc_color1[1], 5, 55);
  6386. PUTBITSHIGH( compressed1_flip, enc_color1[2], 5, 47);
  6387. PUTBITSHIGH( compressed1_flip, diff[0], 3, 58);
  6388. PUTBITSHIGH( compressed1_flip, diff[1], 3, 50);
  6389. PUTBITSHIGH( compressed1_flip, diff[2], 3, 42);
  6390. unsigned int best_pixel_indices1_MSB;
  6391. unsigned int best_pixel_indices1_LSB;
  6392. unsigned int best_pixel_indices2_MSB;
  6393. unsigned int best_pixel_indices2_LSB;
  6394. // upper part of block
  6395. flip_err = tryalltables_3bittable4x2percep(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  6396. // lower part of block
  6397. flip_err += tryalltables_3bittable4x2percep(img,width,height,startx,starty+2,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  6398. PUTBITSHIGH( compressed1_flip, best_table1, 3, 39);
  6399. PUTBITSHIGH( compressed1_flip, best_table2, 3, 36);
  6400. PUTBITSHIGH( compressed1_flip, 1, 1, 32);
  6401. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  6402. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  6403. compressed2_flip = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  6404. }
  6405. else
  6406. {
  6407. diffbit = 0;
  6408. // The difference is bigger than what fits in 555 plus delta-333, so we will have
  6409. // to deal with 444 444.
  6410. eps = (float) 0.0001;
  6411. quantize444ColorCombinedPerceptual(avg_color_float1, enc_color1, dummy);
  6412. quantize444ColorCombinedPerceptual(avg_color_float2, enc_color2, dummy);
  6413. avg_color_quant1[0] = enc_color1[0] << 4 | enc_color1[0];
  6414. avg_color_quant1[1] = enc_color1[1] << 4 | enc_color1[1];
  6415. avg_color_quant1[2] = enc_color1[2] << 4 | enc_color1[2];
  6416. avg_color_quant2[0] = enc_color2[0] << 4 | enc_color2[0];
  6417. avg_color_quant2[1] = enc_color2[1] << 4 | enc_color2[1];
  6418. avg_color_quant2[2] = enc_color2[2] << 4 | enc_color2[2];
  6419. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  6420. // ---------------------------------------------------------------------------------------------------
  6421. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  6422. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  6423. // ---------------------------------------------------------------------------------------------------
  6424. // Pack bits into the first word.
  6425. compressed1_flip = 0;
  6426. PUTBITSHIGH( compressed1_flip, diffbit, 1, 33);
  6427. PUTBITSHIGH( compressed1_flip, enc_color1[0], 4, 63);
  6428. PUTBITSHIGH( compressed1_flip, enc_color1[1], 4, 55);
  6429. PUTBITSHIGH( compressed1_flip, enc_color1[2], 4, 47);
  6430. PUTBITSHIGH( compressed1_flip, enc_color2[0], 4, 59);
  6431. PUTBITSHIGH( compressed1_flip, enc_color2[1], 4, 51);
  6432. PUTBITSHIGH( compressed1_flip, enc_color2[2], 4, 43);
  6433. unsigned int best_pixel_indices1_MSB;
  6434. unsigned int best_pixel_indices1_LSB;
  6435. unsigned int best_pixel_indices2_MSB;
  6436. unsigned int best_pixel_indices2_LSB;
  6437. // upper part of block
  6438. flip_err = tryalltables_3bittable4x2percep(img,width,height,startx,starty,avg_color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  6439. // lower part of block
  6440. flip_err += tryalltables_3bittable4x2percep(img,width,height,startx,starty+2,avg_color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  6441. PUTBITSHIGH( compressed1_flip, best_table1, 3, 39);
  6442. PUTBITSHIGH( compressed1_flip, best_table2, 3, 36);
  6443. PUTBITSHIGH( compressed1_flip, 1, 1, 32);
  6444. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  6445. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  6446. compressed2_flip = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  6447. }
  6448. // Now lets see which is the best table to use. Only 8 tables are possible.
  6449. if(norm_err <= flip_err)
  6450. {
  6451. compressed1 = compressed1_norm | 0;
  6452. compressed2 = compressed2_norm;
  6453. }
  6454. else
  6455. {
  6456. compressed1 = compressed1_flip | 1;
  6457. compressed2 = compressed2_flip;
  6458. }
  6459. }
  6460. // Calculate the error of a block
  6461. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  6462. double calcBlockErrorRGB(uint8 *img, uint8 *imgdec, int width, int height, int startx, int starty)
  6463. {
  6464. int xx,yy;
  6465. double err;
  6466. err = 0;
  6467. for(xx = startx; xx< startx+4; xx++)
  6468. {
  6469. for(yy = starty; yy<starty+4; yy++)
  6470. {
  6471. err += SQUARE(1.0*RED(img,width,xx,yy) - 1.0*RED(imgdec, width, xx,yy));
  6472. err += SQUARE(1.0*GREEN(img,width,xx,yy)- 1.0*GREEN(imgdec, width, xx,yy));
  6473. err += SQUARE(1.0*BLUE(img,width,xx,yy) - 1.0*BLUE(imgdec, width, xx,yy));
  6474. }
  6475. }
  6476. return err;
  6477. }
  6478. // Calculate the perceptually weighted error of a block
  6479. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  6480. double calcBlockPerceptualErrorRGB(uint8 *img, uint8 *imgdec, int width, int height, int startx, int starty)
  6481. {
  6482. int xx,yy;
  6483. double err;
  6484. err = 0;
  6485. for(xx = startx; xx< startx+4; xx++)
  6486. {
  6487. for(yy = starty; yy<starty+4; yy++)
  6488. {
  6489. err += PERCEPTUAL_WEIGHT_R_SQUARED*SQUARE(1.0*RED(img,width,xx,yy) - 1.0*RED(imgdec, width, xx,yy));
  6490. err += PERCEPTUAL_WEIGHT_G_SQUARED*SQUARE(1.0*GREEN(img,width,xx,yy)- 1.0*GREEN(imgdec, width, xx,yy));
  6491. err += PERCEPTUAL_WEIGHT_B_SQUARED*SQUARE(1.0*BLUE(img,width,xx,yy) - 1.0*BLUE(imgdec, width, xx,yy));
  6492. }
  6493. }
  6494. return err;
  6495. }
  6496. // Compress an ETC1 block (or the individual and differential modes of an ETC2 block)
  6497. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  6498. double compressBlockDiffFlipFast(uint8 *img, uint8 *imgdec,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  6499. {
  6500. unsigned int average_block1;
  6501. unsigned int average_block2;
  6502. double error_average;
  6503. unsigned int combined_block1;
  6504. unsigned int combined_block2;
  6505. double error_combined;
  6506. double best_error;
  6507. // First quantize the average color to the nearest neighbor.
  6508. compressBlockDiffFlipAverage(img, width, height, startx, starty, average_block1, average_block2);
  6509. decompressBlockDiffFlip(average_block1, average_block2, imgdec, width, height, startx, starty);
  6510. error_average = calcBlockErrorRGB(img, imgdec, width, height, startx, starty);
  6511. // Then quantize the average color taking into consideration that intensity can change
  6512. compressBlockDiffFlipCombined(img, width, height, startx, starty, combined_block1, combined_block2);
  6513. decompressBlockDiffFlip(combined_block1, combined_block2, imgdec, width, height, startx, starty);
  6514. error_combined = calcBlockErrorRGB(img, imgdec, width, height, startx, starty);
  6515. if(error_combined < error_average)
  6516. {
  6517. compressed1 = combined_block1;
  6518. compressed2 = combined_block2;
  6519. best_error = error_combined;
  6520. }
  6521. else
  6522. {
  6523. compressed1 = average_block1;
  6524. compressed2 = average_block2;
  6525. best_error = error_average;
  6526. }
  6527. return best_error;
  6528. }
  6529. // Compress an ETC1 block (or the individual and differential modes of an ETC2 block)
  6530. // Uses perceptual error metric.
  6531. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  6532. void compressBlockDiffFlipFastPerceptual(uint8 *img, uint8 *imgdec,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  6533. {
  6534. unsigned int average_block1;
  6535. unsigned int average_block2;
  6536. double error_average;
  6537. unsigned int combined_block1;
  6538. unsigned int combined_block2;
  6539. double error_combined;
  6540. // First quantize the average color to the nearest neighbor.
  6541. compressBlockDiffFlipAveragePerceptual(img, width, height, startx, starty, average_block1, average_block2);
  6542. decompressBlockDiffFlip(average_block1, average_block2, imgdec, width, height, startx, starty);
  6543. error_average = calcBlockPerceptualErrorRGB(img, imgdec, width, height, startx, starty);
  6544. // Then quantize the average color taking into consideration that intensity can change
  6545. compressBlockDiffFlipCombinedPerceptual(img, width, height, startx, starty, combined_block1, combined_block2);
  6546. decompressBlockDiffFlip(combined_block1, combined_block2, imgdec, width, height, startx, starty);
  6547. error_combined = calcBlockPerceptualErrorRGB(img, imgdec, width, height, startx, starty);
  6548. if(error_combined < error_average)
  6549. {
  6550. compressed1 = combined_block1;
  6551. compressed2 = combined_block2;
  6552. }
  6553. else
  6554. {
  6555. compressed1 = average_block1;
  6556. compressed2 = average_block2;
  6557. }
  6558. }
  6559. // Compresses the differential mode of an ETC2 block with punchthrough alpha
  6560. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  6561. int compressBlockDifferentialWithAlpha(bool isTransparent, uint8* img, uint8* alphaimg, uint8* imgdec, int width, int height, int startx, int starty, unsigned int &etc1_word1, unsigned int &etc1_word2)
  6562. {
  6563. unsigned int compressed1_norm, compressed2_norm;
  6564. unsigned int compressed1_flip, compressed2_flip;
  6565. unsigned int compressed1_temp, compressed2_temp;
  6566. uint8 avg_color_quant1[3], avg_color_quant2[3];
  6567. float avg_color_float1[3],avg_color_float2[3];
  6568. int enc_color1[3], enc_color2[3], diff[3];
  6569. int min_error=255*255*8*3;
  6570. int norm_err=0;
  6571. int flip_err=0;
  6572. int temp_err=0;
  6573. for(int flipbit=0; flipbit<2; flipbit++)
  6574. {
  6575. //compute average color for each half.
  6576. for(int c=0; c<3; c++)
  6577. {
  6578. avg_color_float1[c]=0;
  6579. avg_color_float2[c]=0;
  6580. float sum1=0;
  6581. float sum2=0;
  6582. for(int x=0; x<4; x++)
  6583. {
  6584. for(int y=0; y<4; y++)
  6585. {
  6586. float fac=1;
  6587. int index = x+startx+(y+starty)*width;
  6588. //transparent pixels are only barely figured into the average. This ensures that they DO matter if we have only
  6589. //transparent pixels in one half of the block, and not otherwise. A bit ugly perhaps.
  6590. if(alphaimg[index]<128)
  6591. fac=0.0001f;
  6592. float col = fac*img[index*3+c];
  6593. if( (flipbit==0&&x<2) || (flipbit==1&&y<2) )
  6594. {
  6595. sum1+=fac;
  6596. avg_color_float1[c]+=col;
  6597. }
  6598. else
  6599. {
  6600. sum2+=fac;
  6601. avg_color_float2[c]+=col;
  6602. }
  6603. }
  6604. }
  6605. avg_color_float1[c]/=sum1;
  6606. avg_color_float2[c]/=sum2;
  6607. }
  6608. uint8 dummy[3];
  6609. quantize555ColorCombined(avg_color_float1, enc_color1, dummy);
  6610. quantize555ColorCombined(avg_color_float2, enc_color2, dummy);
  6611. diff[0] = enc_color2[0]-enc_color1[0];
  6612. diff[1] = enc_color2[1]-enc_color1[1];
  6613. diff[2] = enc_color2[2]-enc_color1[2];
  6614. //make sure diff is small enough for diff-coding
  6615. for(int c=0; c<3; c++)
  6616. {
  6617. if(diff[c]<-4)
  6618. diff[c]=-4;
  6619. if(diff[c]>3)
  6620. diff[c]=3;
  6621. enc_color2[c]=enc_color1[c]+diff[c];
  6622. }
  6623. avg_color_quant1[0] = enc_color1[0] << 3 | (enc_color1[0] >> 2);
  6624. avg_color_quant1[1] = enc_color1[1] << 3 | (enc_color1[1] >> 2);
  6625. avg_color_quant1[2] = enc_color1[2] << 3 | (enc_color1[2] >> 2);
  6626. avg_color_quant2[0] = enc_color2[0] << 3 | (enc_color2[0] >> 2);
  6627. avg_color_quant2[1] = enc_color2[1] << 3 | (enc_color2[1] >> 2);
  6628. avg_color_quant2[2] = enc_color2[2] << 3 | (enc_color2[2] >> 2);
  6629. // Pack bits into the first word.
  6630. // see regular compressblockdiffflipfast for details
  6631. compressed1_temp = 0;
  6632. PUTBITSHIGH( compressed1_temp, !isTransparent, 1, 33);
  6633. PUTBITSHIGH( compressed1_temp, enc_color1[0], 5, 63);
  6634. PUTBITSHIGH( compressed1_temp, enc_color1[1], 5, 55);
  6635. PUTBITSHIGH( compressed1_temp, enc_color1[2], 5, 47);
  6636. PUTBITSHIGH( compressed1_temp, diff[0], 3, 58);
  6637. PUTBITSHIGH( compressed1_temp, diff[1], 3, 50);
  6638. PUTBITSHIGH( compressed1_temp, diff[2], 3, 42);
  6639. temp_err = 0;
  6640. int besterror[2];
  6641. besterror[0]=255*255*3*16;
  6642. besterror[1]=255*255*3*16;
  6643. int besttable[2];
  6644. int best_indices_LSB[16];
  6645. int best_indices_MSB[16];
  6646. //for each table, we're going to compute the indices required to get minimum error in each half.
  6647. //then we'll check if this was the best table for either half, and set besterror/besttable accordingly.
  6648. for(int table=0; table<8; table++)
  6649. {
  6650. int taberror[2];//count will be sort of an index of each pixel within a half, determining where the index will be placed in the bitstream.
  6651. int pixel_indices_LSB[16],pixel_indices_MSB[16];
  6652. for(int i=0; i<2; i++)
  6653. {
  6654. taberror[i]=0;
  6655. }
  6656. for(int x=0; x<4; x++)
  6657. {
  6658. for(int y=0; y<4; y++)
  6659. {
  6660. int index = x+startx+(y+starty)*width;
  6661. uint8 basecol[3];
  6662. bool transparentPixel=alphaimg[index]<128;
  6663. //determine which half of the block this pixel is in, based on the flipbit.
  6664. int half=0;
  6665. if( (flipbit==0&&x<2) || (flipbit&&y<2) )
  6666. {
  6667. basecol[0]=avg_color_quant1[0];
  6668. basecol[1]=avg_color_quant1[1];
  6669. basecol[2]=avg_color_quant1[2];
  6670. }
  6671. else
  6672. {
  6673. half=1;
  6674. basecol[0]=avg_color_quant2[0];
  6675. basecol[1]=avg_color_quant2[1];
  6676. basecol[2]=avg_color_quant2[2];
  6677. }
  6678. int besterri=255*255*3*2;
  6679. int besti=0;
  6680. int erri;
  6681. for(int i=0; i<4; i++)
  6682. {
  6683. if(i==1&&isTransparent)
  6684. continue;
  6685. erri=0;
  6686. for(int c=0; c<3; c++)
  6687. {
  6688. int col=CLAMP(0,((int)basecol[c])+compressParams[table*2][i],255);
  6689. if(i==2&&isTransparent)
  6690. {
  6691. col=(int)basecol[c];
  6692. }
  6693. int errcol=col-((int)(img[index*3+c]));
  6694. erri=erri+(errcol*errcol);
  6695. }
  6696. if(erri<besterri)
  6697. {
  6698. besterri=erri;
  6699. besti=i;
  6700. }
  6701. }
  6702. if(transparentPixel)
  6703. {
  6704. besterri=0;
  6705. besti=1;
  6706. }
  6707. //the best index for this pixel using this table for its half is known.
  6708. //add its error to error for this table and half.
  6709. taberror[half]+=besterri;
  6710. //store the index! we might toss it later though if this was a bad table.
  6711. int pixel_index = scramble[besti];
  6712. pixel_indices_MSB[x*4+y]=(pixel_index >> 1);
  6713. pixel_indices_LSB[x*4+y]=(pixel_index & 1);
  6714. }
  6715. }
  6716. for(int half=0; half<2; half++)
  6717. {
  6718. if(taberror[half]<besterror[half])
  6719. {
  6720. besterror[half]=taberror[half];
  6721. besttable[half]=table;
  6722. for(int i=0; i<16; i++)
  6723. {
  6724. int thishalf=0;
  6725. int y=i%4;
  6726. int x=i/4;
  6727. if( !(flipbit==0&&x<2) && !(flipbit&&y<2) )
  6728. thishalf=1;
  6729. if(half!=thishalf) //this pixel is not in given half, don't update best index!
  6730. continue;
  6731. best_indices_MSB[i]=pixel_indices_MSB[i];
  6732. best_indices_LSB[i]=pixel_indices_LSB[i];
  6733. }
  6734. }
  6735. }
  6736. }
  6737. PUTBITSHIGH( compressed1_temp, besttable[0], 3, 39);
  6738. PUTBITSHIGH( compressed1_temp, besttable[1], 3, 36);
  6739. PUTBITSHIGH( compressed1_temp, 0, 1, 32);
  6740. compressed2_temp = 0;
  6741. for(int i=0; i<16; i++)
  6742. {
  6743. PUTBITS( compressed2_temp, (best_indices_MSB[i] ), 1, 16+i);
  6744. PUTBITS( compressed2_temp, (best_indices_LSB[i] ), 1, i);
  6745. }
  6746. if(flipbit)
  6747. {
  6748. flip_err=besterror[0]+besterror[1];
  6749. compressed1_flip=compressed1_temp;
  6750. compressed2_flip=compressed2_temp;
  6751. }
  6752. else
  6753. {
  6754. norm_err=besterror[0]+besterror[1];
  6755. compressed1_norm=compressed1_temp;
  6756. compressed2_norm=compressed2_temp;
  6757. }
  6758. }
  6759. // Now to find out if flipping was a good idea or not
  6760. if(norm_err <= flip_err)
  6761. {
  6762. etc1_word1 = compressed1_norm | 0;
  6763. etc1_word2 = compressed2_norm;
  6764. return norm_err;
  6765. }
  6766. else
  6767. {
  6768. etc1_word1 = compressed1_flip | 1;
  6769. etc1_word2 = compressed2_flip;
  6770. return flip_err;
  6771. }
  6772. }
  6773. // Calculate RGBA error --- only count non-transparent pixels (alpha > 128)
  6774. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  6775. double calcBlockErrorRGBA(uint8 *img, uint8 *imgdec, uint8* alpha, int width, int height, int startx, int starty)
  6776. {
  6777. int xx,yy;
  6778. double err;
  6779. err = 0;
  6780. for(xx = startx; xx< startx+4; xx++)
  6781. {
  6782. for(yy = starty; yy<starty+4; yy++)
  6783. {
  6784. //only count non-transparent pixels.
  6785. if(alpha[yy*width+xx]>128)
  6786. {
  6787. err += SQUARE(1.0*RED(img,width,xx,yy) - 1.0*RED(imgdec, width, xx,yy));
  6788. err += SQUARE(1.0*GREEN(img,width,xx,yy)- 1.0*GREEN(imgdec, width, xx,yy));
  6789. err += SQUARE(1.0*BLUE(img,width,xx,yy) - 1.0*BLUE(imgdec, width, xx,yy));
  6790. }
  6791. }
  6792. }
  6793. return err;
  6794. }
  6795. //calculates the error for a block using the given colors, and the paremeters required to obtain the error. This version uses 1-bit punch-through alpha.
  6796. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  6797. double calculateError59TAlpha(uint8* srcimg, uint8* alpha,int width, int startx, int starty, uint8 (colorsRGB444)[2][3], uint8 &distance, unsigned int &pixel_indices)
  6798. {
  6799. double block_error = 0,
  6800. best_block_error = MAXIMUM_ERROR,
  6801. pixel_error,
  6802. best_pixel_error;
  6803. int diff[3];
  6804. uint8 best_sw;
  6805. unsigned int pixel_colors;
  6806. uint8 colors[2][3];
  6807. uint8 possible_colors[4][3];
  6808. // First use the colors as they are, then swap them
  6809. for (uint8 sw = 0; sw <2; ++sw)
  6810. {
  6811. if (sw == 1)
  6812. {
  6813. swapColors(colorsRGB444);
  6814. }
  6815. decompressColor(R_BITS59T, G_BITS59T, B_BITS59T, colorsRGB444, colors);
  6816. // Test all distances
  6817. for (uint8 d = 0; d < BINPOW(TABLE_BITS_59T); ++d)
  6818. {
  6819. calculatePaintColors59T(d,PATTERN_T, colors, possible_colors);
  6820. block_error = 0;
  6821. pixel_colors = 0;
  6822. // Loop block
  6823. for (size_t y = 0; y < BLOCKHEIGHT; ++y)
  6824. {
  6825. for (size_t x = 0; x < BLOCKWIDTH; ++x)
  6826. {
  6827. best_pixel_error = MAXIMUM_ERROR;
  6828. pixel_colors <<=2; // Make room for next value
  6829. // Loop possible block colors
  6830. if(alpha[x+startx+(y+starty)*width]==0)
  6831. {
  6832. best_pixel_error=0;
  6833. pixel_colors ^= (pixel_colors & 3); // Reset the two first bits
  6834. pixel_colors |= 2; //insert the index for this pixel, two meaning transparent.
  6835. }
  6836. else
  6837. {
  6838. for (uint8 c = 0; c < 4; ++c)
  6839. {
  6840. if(c==2)
  6841. continue; //don't use this, because we don't have alpha here and index 2 means transparent.
  6842. diff[R] = srcimg[3*((starty+y)*width+startx+x)+R] - CLAMP(0,possible_colors[c][R],255);
  6843. diff[G] = srcimg[3*((starty+y)*width+startx+x)+G] - CLAMP(0,possible_colors[c][G],255);
  6844. diff[B] = srcimg[3*((starty+y)*width+startx+x)+B] - CLAMP(0,possible_colors[c][B],255);
  6845. pixel_error = weight[R]*SQUARE(diff[R]) +
  6846. weight[G]*SQUARE(diff[G]) +
  6847. weight[B]*SQUARE(diff[B]);
  6848. // Choose best error
  6849. if (pixel_error < best_pixel_error)
  6850. {
  6851. best_pixel_error = pixel_error;
  6852. pixel_colors ^= (pixel_colors & 3); // Reset the two first bits
  6853. pixel_colors |= c; //insert the index for this pixel
  6854. }
  6855. }
  6856. }
  6857. block_error += best_pixel_error;
  6858. }
  6859. }
  6860. if (block_error < best_block_error)
  6861. {
  6862. best_block_error = block_error;
  6863. distance = d;
  6864. pixel_indices = pixel_colors;
  6865. best_sw = sw;
  6866. }
  6867. }
  6868. if (sw == 1 && best_sw == 0)
  6869. {
  6870. swapColors(colorsRGB444);
  6871. }
  6872. decompressColor(R_BITS59T, G_BITS59T, B_BITS59T, colorsRGB444, colors);
  6873. }
  6874. return best_block_error;
  6875. }
  6876. // same as fastest t-mode compressor above, but here one of the colors (the central one in the T) is used to also signal that the pixel is transparent.
  6877. // the only difference is that calculateError has been swapped out to one that considers alpha.
  6878. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  6879. double compressBlockTHUMB59TAlpha(uint8 *img, uint8* alpha, int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  6880. {
  6881. double best_error = MAXIMUM_ERROR;
  6882. uint8 best_colorsRGB444[2][3];
  6883. unsigned int best_pixel_indices;
  6884. uint8 best_distance;
  6885. double error_no_i;
  6886. uint8 colorsRGB444_no_i[2][3];
  6887. unsigned int pixel_indices_no_i;
  6888. uint8 distance_no_i;
  6889. uint8 colors[2][3];
  6890. // Calculate average color using the LBG-algorithm
  6891. computeColorLBGHalfIntensityFast(img,width,startx,starty, colors);
  6892. compressColor(R_BITS59T, G_BITS59T, B_BITS59T, colors, colorsRGB444_no_i);
  6893. // Determine the parameters for the lowest error
  6894. error_no_i = calculateError59TAlpha(img, alpha, width, startx, starty, colorsRGB444_no_i, distance_no_i, pixel_indices_no_i);
  6895. best_error = error_no_i;
  6896. best_distance = distance_no_i;
  6897. best_pixel_indices = pixel_indices_no_i;
  6898. copyColors(colorsRGB444_no_i, best_colorsRGB444);
  6899. // Put the compress params into the compression block
  6900. packBlock59T(best_colorsRGB444, best_distance, best_pixel_indices, compressed1, compressed2);
  6901. return best_error;
  6902. }
  6903. // Put bits in order for the format.
  6904. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  6905. void stuff59bitsDiffFalse(unsigned int thumbT59_word1, unsigned int thumbT59_word2, unsigned int &thumbT_word1, unsigned int &thumbT_word2)
  6906. {
  6907. // Put bits in twotimer configuration for 59 (red overflows)
  6908. //
  6909. // Go from this bit layout:
  6910. //
  6911. // |63 62 61 60 59|58 57 56 55|54 53 52 51|50 49 48 47|46 45 44 43|42 41 40 39|38 37 36 35|34 33 32|
  6912. // |----empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|--dist--|
  6913. //
  6914. // |31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  6915. // |----------------------------------------index bits---------------------------------------------|
  6916. //
  6917. //
  6918. // To this:
  6919. //
  6920. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  6921. // -----------------------------------------------------------------------------------------------
  6922. // |// // //|R0a |//|R0b |G0 |B0 |R1 |G1 |B1 |da |df|db|
  6923. // -----------------------------------------------------------------------------------------------
  6924. //
  6925. // |31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  6926. // |----------------------------------------index bits---------------------------------------------|
  6927. //
  6928. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  6929. // -----------------------------------------------------------------------------------------------
  6930. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |df|fp|
  6931. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bt|bt|
  6932. // ------------------------------------------------------------------------------------------------
  6933. uint8 R0a;
  6934. uint8 bit, a, b, c, d, bits;
  6935. R0a = GETBITSHIGH( thumbT59_word1, 2, 58);
  6936. // Fix middle part
  6937. thumbT_word1 = thumbT59_word1 << 1;
  6938. // Fix R0a (top two bits of R0)
  6939. PUTBITSHIGH( thumbT_word1, R0a, 2, 60);
  6940. // Fix db (lowest bit of d)
  6941. PUTBITSHIGH( thumbT_word1, thumbT59_word1, 1, 32);
  6942. //
  6943. // Make sure that red overflows:
  6944. a = GETBITSHIGH( thumbT_word1, 1, 60);
  6945. b = GETBITSHIGH( thumbT_word1, 1, 59);
  6946. c = GETBITSHIGH( thumbT_word1, 1, 57);
  6947. d = GETBITSHIGH( thumbT_word1, 1, 56);
  6948. // The following bit abcd bit sequences should be padded with ones: 0111, 1010, 1011, 1101, 1110, 1111
  6949. // The following logical expression checks for the presence of any of those:
  6950. bit = (a & c) | (!a & b & c & d) | (a & b & !c & d);
  6951. bits = 0xf*bit;
  6952. PUTBITSHIGH( thumbT_word1, bits, 3, 63);
  6953. PUTBITSHIGH( thumbT_word1, !bit, 1, 58);
  6954. // Set diffbit
  6955. PUTBITSHIGH( thumbT_word1, 0, 1, 33);
  6956. thumbT_word2 = thumbT59_word2;
  6957. }
  6958. // Tests if there is at least one pixel in the image which would get alpha = 0 in punchtrough mode.
  6959. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  6960. bool hasAlpha(uint8* alphaimg, int ix, int iy, int width)
  6961. {
  6962. for(int x=ix; x<ix+4; x++)
  6963. {
  6964. for(int y=iy; y<iy+4; y++)
  6965. {
  6966. int index = x+y*width;
  6967. if(alphaimg[index]<128)
  6968. {
  6969. return true;
  6970. }
  6971. }
  6972. }
  6973. return false;
  6974. }
  6975. // Compress a block with ETC2 RGB
  6976. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  6977. void compressBlockETC2Fast(uint8 *img, uint8* alphaimg, uint8 *imgdec,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2, int format)
  6978. {
  6979. unsigned int etc1_word1;
  6980. unsigned int etc1_word2;
  6981. double error_etc1;
  6982. unsigned int planar57_word1;
  6983. unsigned int planar57_word2;
  6984. unsigned int planar_word1;
  6985. unsigned int planar_word2;
  6986. double error_planar;
  6987. unsigned int thumbT59_word1;
  6988. unsigned int thumbT59_word2;
  6989. unsigned int thumbT_word1;
  6990. unsigned int thumbT_word2;
  6991. double error_thumbT;
  6992. unsigned int thumbH58_word1;
  6993. unsigned int thumbH58_word2;
  6994. unsigned int thumbH_word1;
  6995. unsigned int thumbH_word2;
  6996. double error_thumbH;
  6997. double error_best;
  6998. signed char best_char;
  6999. int best_mode;
  7000. if(format==ETC2PACKAGE_RGBA1_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  7001. {
  7002. /* if we have one-bit alpha, we never use the individual mode,
  7003. instead that bit flags that one of our four offsets will instead
  7004. mean transparent (with 0 offset for color channels) */
  7005. /* the regular ETC individual mode is disabled, but the old T, H and planar modes
  7006. are kept unchanged and may be used for blocks without transparency.
  7007. Introduced are old ETC with only differential coding,
  7008. ETC differential but with 3 offsets and transparent,
  7009. and T-mode with 3 colors plus transparent.*/
  7010. /* in a fairly hackish manner, error_etc1, etc1_word1 and etc1_word2 will
  7011. represent the best out of the three introduced modes, to be compared
  7012. with the three kept modes in the old code*/
  7013. unsigned int tempword1, tempword2;
  7014. double temperror;
  7015. //try regular differential transparent mode
  7016. int testerr= compressBlockDifferentialWithAlpha(true,img,alphaimg, imgdec,width,height,startx,starty,etc1_word1,etc1_word2);
  7017. uint8* alphadec = new uint8[width*height];
  7018. decompressBlockDifferentialWithAlpha(etc1_word1, etc1_word2, imgdec, alphadec,width, height, startx, starty);
  7019. error_etc1 = calcBlockErrorRGBA(img, imgdec, alphaimg,width, height, startx, starty);
  7020. if(error_etc1!=testerr)
  7021. {
  7022. printf("testerr: %d, etcerr: %lf\n",testerr,error_etc1);
  7023. }
  7024. //try T-mode with transparencies
  7025. //for now, skip this...
  7026. compressBlockTHUMB59TAlpha(img,alphaimg,width,height,startx,starty,tempword1,tempword2);
  7027. decompressBlockTHUMB59TAlpha(tempword1,tempword2,imgdec, alphadec, width,height,startx,starty);
  7028. temperror=calcBlockErrorRGBA(img, imgdec, alphaimg, width, height, startx, starty);
  7029. if(temperror<error_etc1)
  7030. {
  7031. error_etc1=temperror;
  7032. stuff59bitsDiffFalse(tempword1,tempword2,etc1_word1,etc1_word2);
  7033. }
  7034. compressBlockTHUMB58HAlpha(img,alphaimg,width,height,startx,starty,tempword1,tempword2);
  7035. decompressBlockTHUMB58HAlpha(tempword1,tempword2,imgdec, alphadec, width,height,startx,starty);
  7036. temperror=calcBlockErrorRGBA(img, imgdec, alphaimg, width, height, startx, starty);
  7037. if(temperror<error_etc1)
  7038. {
  7039. error_etc1=temperror;
  7040. stuff58bitsDiffFalse(tempword1,tempword2,etc1_word1,etc1_word2);
  7041. }
  7042. //if we have transparency in this pixel, we know that one of these two modes was best..
  7043. if(hasAlpha(alphaimg,startx,starty,width))
  7044. {
  7045. compressed1=etc1_word1;
  7046. compressed2=etc1_word2;
  7047. delete[] alphadec; // ESENTHEL CHANGED
  7048. return;
  7049. }
  7050. //error_etc1=255*255*1000;
  7051. //otherwise, they MIGHT have been the best, although that's unlikely.. anyway, try old differential mode now
  7052. compressBlockDifferentialWithAlpha(false,img,alphaimg,imgdec,width,height,startx,starty,tempword1,tempword2);
  7053. decompressBlockDiffFlip(tempword1, tempword2, imgdec, width, height, startx, starty);
  7054. temperror = calcBlockErrorRGB(img, imgdec, width, height, startx, starty);
  7055. decompressBlockDifferentialWithAlpha(tempword1,tempword2,imgdec,alphadec,width,height,startx,starty);
  7056. if(temperror<error_etc1)
  7057. {
  7058. error_etc1=temperror;
  7059. etc1_word1=tempword1;
  7060. etc1_word2=tempword2;
  7061. }
  7062. delete[] alphadec; // ESENTHEL CHANGED
  7063. //drop out of this if, and test old T, H and planar modes (we have already returned if there are transparent pixels in this block)
  7064. }
  7065. else
  7066. {
  7067. //this includes individual mode, and therefore doesn't apply in case of punch-through alpha.
  7068. compressBlockDiffFlipFast(img, imgdec, width, height, startx, starty, etc1_word1, etc1_word2);
  7069. decompressBlockDiffFlip(etc1_word1, etc1_word2, imgdec, width, height, startx, starty);
  7070. error_etc1 = calcBlockErrorRGB(img, imgdec, width, height, startx, starty);
  7071. }
  7072. //these modes apply regardless of whether we want punch-through alpha or not.
  7073. //error etc_1 and etc1_word1/etc1_word2 contain previous best candidate.
  7074. compressBlockPlanar57(img, width, height, startx, starty, planar57_word1, planar57_word2);
  7075. decompressBlockPlanar57(planar57_word1, planar57_word2, imgdec, width, height, startx, starty);
  7076. error_planar = calcBlockErrorRGB(img, imgdec, width, height, startx, starty);
  7077. stuff57bits(planar57_word1, planar57_word2, planar_word1, planar_word2);
  7078. compressBlockTHUMB59TFastest(img,width, height, startx, starty, thumbT59_word1, thumbT59_word2);
  7079. decompressBlockTHUMB59T(thumbT59_word1, thumbT59_word2, imgdec, width, height, startx, starty);
  7080. error_thumbT = calcBlockErrorRGB(img, imgdec, width, height, startx, starty);
  7081. stuff59bits(thumbT59_word1, thumbT59_word2, thumbT_word1, thumbT_word2);
  7082. compressBlockTHUMB58HFastest(img,width,height,startx, starty, thumbH58_word1, thumbH58_word2);
  7083. decompressBlockTHUMB58H(thumbH58_word1, thumbH58_word2, imgdec, width, height, startx, starty);
  7084. error_thumbH = calcBlockErrorRGB(img, imgdec, width, height, startx, starty);
  7085. stuff58bits(thumbH58_word1, thumbH58_word2, thumbH_word1, thumbH_word2);
  7086. error_best = error_etc1;
  7087. compressed1 = etc1_word1;
  7088. compressed2 = etc1_word2;
  7089. best_char = '.';
  7090. best_mode = MODE_ETC1;
  7091. if(error_planar < error_best)
  7092. {
  7093. compressed1 = planar_word1;
  7094. compressed2 = planar_word2;
  7095. best_char = 'p';
  7096. error_best = error_planar;
  7097. best_mode = MODE_PLANAR;
  7098. }
  7099. if(error_thumbT < error_best)
  7100. {
  7101. compressed1 = thumbT_word1;
  7102. compressed2 = thumbT_word2;
  7103. best_char = 'T';
  7104. error_best = error_thumbT;
  7105. best_mode = MODE_THUMB_T;
  7106. }
  7107. if(error_thumbH < error_best)
  7108. {
  7109. compressed1 = thumbH_word1;
  7110. compressed2 = thumbH_word2;
  7111. best_char = 'H';
  7112. error_best = error_thumbH;
  7113. best_mode = MODE_THUMB_H;
  7114. }
  7115. switch(best_mode)
  7116. {
  7117. // Now see which mode won and compress that a little bit harder
  7118. case MODE_THUMB_T:
  7119. compressBlockTHUMB59TFast(img,width, height, startx, starty, thumbT59_word1, thumbT59_word2);
  7120. decompressBlockTHUMB59T(thumbT59_word1, thumbT59_word2, imgdec, width, height, startx, starty);
  7121. error_thumbT = calcBlockErrorRGB(img, imgdec, width, height, startx, starty);
  7122. stuff59bits(thumbT59_word1, thumbT59_word2, thumbT_word1, thumbT_word2);
  7123. if(error_thumbT < error_best)
  7124. {
  7125. compressed1 = thumbT_word1;
  7126. compressed2 = thumbT_word2;
  7127. }
  7128. break;
  7129. case MODE_THUMB_H:
  7130. compressBlockTHUMB58HFast(img,width,height,startx, starty, thumbH58_word1, thumbH58_word2);
  7131. decompressBlockTHUMB58H(thumbH58_word1, thumbH58_word2, imgdec, width, height, startx, starty);
  7132. error_thumbH = calcBlockErrorRGB(img, imgdec, width, height, startx, starty);
  7133. stuff58bits(thumbH58_word1, thumbH58_word2, thumbH_word1, thumbH_word2);
  7134. if(error_thumbH < error_best)
  7135. {
  7136. compressed1 = thumbH_word1;
  7137. compressed2 = thumbH_word2;
  7138. }
  7139. break;
  7140. default:
  7141. break;
  7142. }
  7143. }
  7144. // Compress an ETC2 RGB block using perceptual error metric
  7145. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  7146. void compressBlockETC2FastPerceptual(uint8 *img, uint8 *imgdec,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  7147. {
  7148. unsigned int etc1_word1;
  7149. unsigned int etc1_word2;
  7150. double error_etc1;
  7151. unsigned int planar57_word1;
  7152. unsigned int planar57_word2;
  7153. unsigned int planar_word1;
  7154. unsigned int planar_word2;
  7155. double error_planar;
  7156. unsigned int thumbT59_word1;
  7157. unsigned int thumbT59_word2;
  7158. unsigned int thumbT_word1;
  7159. unsigned int thumbT_word2;
  7160. double error_thumbT;
  7161. unsigned int thumbH58_word1;
  7162. unsigned int thumbH58_word2;
  7163. unsigned int thumbH_word1;
  7164. unsigned int thumbH_word2;
  7165. double error_thumbH;
  7166. double error_best;
  7167. signed char best_char;
  7168. int best_mode;
  7169. compressBlockDiffFlipFastPerceptual(img, imgdec, width, height, startx, starty, etc1_word1, etc1_word2);
  7170. decompressBlockDiffFlip(etc1_word1, etc1_word2, imgdec, width, height, startx, starty);
  7171. error_etc1 = 1000*calcBlockPerceptualErrorRGB(img, imgdec, width, height, startx, starty);
  7172. compressBlockPlanar57(img, width, height, startx, starty, planar57_word1, planar57_word2);
  7173. decompressBlockPlanar57(planar57_word1, planar57_word2, imgdec, width, height, startx, starty);
  7174. error_planar = 1000*calcBlockPerceptualErrorRGB(img, imgdec, width, height, startx, starty);
  7175. stuff57bits(planar57_word1, planar57_word2, planar_word1, planar_word2);
  7176. compressBlockTHUMB59TFastestPerceptual1000(img,width, height, startx, starty, thumbT59_word1, thumbT59_word2);
  7177. decompressBlockTHUMB59T(thumbT59_word1, thumbT59_word2, imgdec, width, height, startx, starty);
  7178. error_thumbT = 1000*calcBlockPerceptualErrorRGB(img, imgdec, width, height, startx, starty);
  7179. stuff59bits(thumbT59_word1, thumbT59_word2, thumbT_word1, thumbT_word2);
  7180. compressBlockTHUMB58HFastestPerceptual1000(img,width,height,startx, starty, thumbH58_word1, thumbH58_word2);
  7181. decompressBlockTHUMB58H(thumbH58_word1, thumbH58_word2, imgdec, width, height, startx, starty);
  7182. error_thumbH = 1000*calcBlockPerceptualErrorRGB(img, imgdec, width, height, startx, starty);
  7183. stuff58bits(thumbH58_word1, thumbH58_word2, thumbH_word1, thumbH_word2);
  7184. error_best = error_etc1;
  7185. compressed1 = etc1_word1;
  7186. compressed2 = etc1_word2;
  7187. best_char = '.';
  7188. best_mode = MODE_ETC1;
  7189. if(error_planar < error_best)
  7190. {
  7191. compressed1 = planar_word1;
  7192. compressed2 = planar_word2;
  7193. best_char = 'p';
  7194. error_best = error_planar;
  7195. best_mode = MODE_PLANAR;
  7196. }
  7197. if(error_thumbT < error_best)
  7198. {
  7199. compressed1 = thumbT_word1;
  7200. compressed2 = thumbT_word2;
  7201. best_char = 'T';
  7202. error_best = error_thumbT;
  7203. best_mode = MODE_THUMB_T;
  7204. }
  7205. if(error_thumbH < error_best)
  7206. {
  7207. compressed1 = thumbH_word1;
  7208. compressed2 = thumbH_word2;
  7209. best_char = 'H';
  7210. error_best = error_thumbH;
  7211. best_mode = MODE_THUMB_H;
  7212. }
  7213. switch(best_mode)
  7214. {
  7215. // Now see which mode won and compress that a little bit harder
  7216. case MODE_THUMB_T:
  7217. compressBlockTHUMB59TFast(img,width, height, startx, starty, thumbT59_word1, thumbT59_word2);
  7218. decompressBlockTHUMB59T(thumbT59_word1, thumbT59_word2, imgdec, width, height, startx, starty);
  7219. error_thumbT = calcBlockErrorRGB(img, imgdec, width, height, startx, starty);
  7220. stuff59bits(thumbT59_word1, thumbT59_word2, thumbT_word1, thumbT_word2);
  7221. if(error_thumbT < error_best)
  7222. {
  7223. compressed1 = thumbT_word1;
  7224. compressed2 = thumbT_word2;
  7225. }
  7226. break;
  7227. case MODE_THUMB_H:
  7228. compressBlockTHUMB58HFast(img,width,height,startx, starty, thumbH58_word1, thumbH58_word2);
  7229. decompressBlockTHUMB58H(thumbH58_word1, thumbH58_word2, imgdec, width, height, startx, starty);
  7230. error_thumbH = calcBlockErrorRGB(img, imgdec, width, height, startx, starty);
  7231. stuff58bits(thumbH58_word1, thumbH58_word2, thumbH_word1, thumbH_word2);
  7232. if(error_thumbH < error_best)
  7233. {
  7234. compressed1 = thumbH_word1;
  7235. compressed2 = thumbH_word2;
  7236. }
  7237. break;
  7238. default:
  7239. break;
  7240. }
  7241. }
  7242. // Write a word in big endian style
  7243. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  7244. /*void write_big_endian_2byte_word(unsigned short *blockadr, FILE *f)
  7245. {
  7246. uint8 bytes[2];
  7247. unsigned short block;
  7248. block = blockadr[0];
  7249. bytes[0] = (block >> 8) & 0xff;
  7250. bytes[1] = (block >> 0) & 0xff;
  7251. fwrite(&bytes[0],1,1,f);
  7252. fwrite(&bytes[1],1,1,f);
  7253. }*/
  7254. // Write a word in big endian style
  7255. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  7256. /*void write_big_endian_4byte_word(unsigned int *blockadr, FILE *f)
  7257. {
  7258. uint8 bytes[4];
  7259. unsigned int block;
  7260. block = blockadr[0];
  7261. bytes[0] = (block >> 24) & 0xff;
  7262. bytes[1] = (block >> 16) & 0xff;
  7263. bytes[2] = (block >> 8) & 0xff;
  7264. bytes[3] = (block >> 0) & 0xff;
  7265. fwrite(&bytes[0],1,1,f);
  7266. fwrite(&bytes[1],1,1,f);
  7267. fwrite(&bytes[2],1,1,f);
  7268. fwrite(&bytes[3],1,1,f);
  7269. }*/
  7270. extern int alphaTable[256][8];
  7271. extern int alphaBase[16][4];
  7272. // valtab holds precalculated data used for compressing using EAC2.
  7273. // Note that valtab is constructed using get16bits11bits, which means
  7274. // that it already is expanded to 16 bits.
  7275. // Note also that it its contents will depend on the value of formatSigned.
  7276. /*int *valtab;
  7277. void setupAlphaTableAndValtab()
  7278. {
  7279. setupAlphaTable();
  7280. //fix precomputation table..!
  7281. valtab = new int[1024*512];
  7282. int16 val16;
  7283. int count=0;
  7284. for(int base=0; base<256; base++)
  7285. {
  7286. for(int tab=0; tab<16; tab++)
  7287. {
  7288. for(int mul=0; mul<16; mul++)
  7289. {
  7290. for(int index=0; index<8; index++)
  7291. {
  7292. if(formatSigned)
  7293. {
  7294. val16=get16bits11signed(base,tab,mul,index);
  7295. valtab[count] = val16 + 256*128;
  7296. }
  7297. else
  7298. valtab[count]=get16bits11bits(base,tab,mul,index);
  7299. count++;
  7300. }
  7301. }
  7302. }
  7303. }
  7304. }
  7305. // Reads alpha data
  7306. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  7307. void readAlpha(uint8* &data, int &width, int &height, int &extendedwidth, int &extendedheight)
  7308. {
  7309. //width and height are already known..?
  7310. uint8* tempdata;
  7311. int wantedBitDepth;
  7312. if(format==ETC2PACKAGE_RGBA_NO_MIPMAPS||format==ETC2PACKAGE_RGBA1_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  7313. {
  7314. wantedBitDepth=8;
  7315. }
  7316. else if(format==ETC2PACKAGE_R_NO_MIPMAPS)
  7317. {
  7318. wantedBitDepth=16;
  7319. }
  7320. else
  7321. {
  7322. printf("invalid format for alpha reading!\n");
  7323. exit(1);
  7324. }
  7325. fReadPGM("alpha.pgm",width,height,tempdata,wantedBitDepth);
  7326. extendedwidth=4*((width+3)/4);
  7327. extendedheight=4*((height+3)/4);
  7328. if(width==extendedwidth&&height==extendedheight)
  7329. {
  7330. data=tempdata;
  7331. }
  7332. else
  7333. {
  7334. data = (uint8*)malloc(extendedwidth*extendedheight*wantedBitDepth/8);
  7335. uint8 last=0;
  7336. uint8 lastlast=0;
  7337. for(int x=0; x<extendedwidth; x++)
  7338. {
  7339. for(int y=0; y<extendedheight; y++)
  7340. {
  7341. if(wantedBitDepth==8)
  7342. {
  7343. if(x<width&&y<height)
  7344. {
  7345. last = tempdata[x+y*width];
  7346. }
  7347. data[x+y*extendedwidth]=last;
  7348. }
  7349. else
  7350. {
  7351. if(x<width&&y<height)
  7352. {
  7353. last = tempdata[(x+y*width)*2];
  7354. lastlast = tempdata[(x+y*width)*2+1];
  7355. }
  7356. data[(x+y*extendedwidth)*2]=last;
  7357. data[(x+y*extendedwidth)*2+1]=lastlast;
  7358. }
  7359. }
  7360. }
  7361. }
  7362. if(format==ETC2PACKAGE_RGBA1_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  7363. {
  7364. for(int x=0; x<extendedwidth; x++)
  7365. {
  7366. for(int y=0; y<extendedheight; y++)
  7367. {
  7368. if(data[x+y*extendedwidth]<128)
  7369. data[x+y*extendedwidth]=0;
  7370. else
  7371. data[x+y*extendedwidth]=255;
  7372. }
  7373. }
  7374. }
  7375. }*/
  7376. // Compresses the alpha part of a GL_COMPRESSED_RGBA8_ETC2_EAC block.
  7377. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  7378. void compressBlockAlphaFast(uint8 * data, int ix, int iy, int width, int height, uint8* returnData)
  7379. {
  7380. int alphasum=0;
  7381. int maxdist=-2;
  7382. for(int x=0; x<4; x++)
  7383. {
  7384. for(int y=0; y<4; y++)
  7385. {
  7386. alphasum+=data[ix+x+(iy+y)*width];
  7387. }
  7388. }
  7389. int alpha = (int)( ((float)alphasum)/16.0f+0.5f); //average pixel value, used as guess for base value.
  7390. for(int x=0; x<4; x++)
  7391. {
  7392. for(int y=0; y<4; y++)
  7393. {
  7394. if(abs(alpha-data[ix+x+(iy+y)*width])>maxdist)
  7395. maxdist=abs(alpha-data[ix+x+(iy+y)*width]); //maximum distance from average
  7396. }
  7397. }
  7398. int approxPos = (maxdist*255)/160-4; //experimentally derived formula for calculating approximate table position given a max distance from average
  7399. if(approxPos>255)
  7400. approxPos=255;
  7401. int startTable=approxPos-15; //first table to be tested
  7402. if(startTable<0)
  7403. startTable=0;
  7404. int endTable=clamp(approxPos+15); //last table to be tested
  7405. int bestsum=1000000000;
  7406. int besttable=-3;
  7407. int bestalpha=128;
  7408. int prevalpha=alpha;
  7409. //main loop: determine best base alpha value and offset table to use for compression
  7410. //try some different alpha tables.
  7411. for(int table = startTable; table<endTable&&bestsum>0; table++)
  7412. {
  7413. int tablealpha=prevalpha;
  7414. int tablebestsum=1000000000;
  7415. //test some different alpha values, trying to find the best one for the given table.
  7416. for(int alphascale=16; alphascale>0; alphascale/=4)
  7417. {
  7418. int startalpha;
  7419. int endalpha;
  7420. if(alphascale==16)
  7421. {
  7422. startalpha = clamp(tablealpha-alphascale*4);
  7423. endalpha = clamp(tablealpha+alphascale*4);
  7424. }
  7425. else
  7426. {
  7427. startalpha = clamp(tablealpha-alphascale*2);
  7428. endalpha = clamp(tablealpha+alphascale*2);
  7429. }
  7430. for(alpha=startalpha; alpha<=endalpha; alpha+=alphascale)
  7431. {
  7432. int sum=0;
  7433. int val,diff,bestdiff=10000000,index;
  7434. for(int x=0; x<4; x++)
  7435. {
  7436. for(int y=0; y<4; y++)
  7437. {
  7438. //compute best offset here, add square difference to sum..
  7439. val=data[ix+x+(iy+y)*width];
  7440. bestdiff=1000000000;
  7441. //the values are always ordered from small to large, with the first 4 being negative and the last 4 positive
  7442. //search is therefore made in the order 0-1-2-3 or 7-6-5-4, stopping when error increases compared to the previous entry tested.
  7443. if(val>alpha)
  7444. {
  7445. for(index=7; index>3; index--)
  7446. {
  7447. diff=clamp_table[alpha+(int)(alphaTable[table][index])+255]-val;
  7448. diff*=diff;
  7449. if(diff<=bestdiff)
  7450. {
  7451. bestdiff=diff;
  7452. }
  7453. else
  7454. break;
  7455. }
  7456. }
  7457. else
  7458. {
  7459. for(index=0; index<4; index++)
  7460. {
  7461. diff=clamp_table[alpha+(int)(alphaTable[table][index])+255]-val;
  7462. diff*=diff;
  7463. if(diff<bestdiff)
  7464. {
  7465. bestdiff=diff;
  7466. }
  7467. else
  7468. break;
  7469. }
  7470. }
  7471. //best diff here is bestdiff, add it to sum!
  7472. sum+=bestdiff;
  7473. //if the sum here is worse than previously best already, there's no use in continuing the count..
  7474. //note that tablebestsum could be used for more precise estimation, but the speedup gained here is deemed more important.
  7475. if(sum>bestsum)
  7476. {
  7477. x=9999; //just to make it large and get out of the x<4 loop
  7478. break;
  7479. }
  7480. }
  7481. }
  7482. if(sum<tablebestsum)
  7483. {
  7484. tablebestsum=sum;
  7485. tablealpha=alpha;
  7486. }
  7487. if(sum<bestsum)
  7488. {
  7489. bestsum=sum;
  7490. besttable=table;
  7491. bestalpha=alpha;
  7492. }
  7493. }
  7494. if(alphascale<=2)
  7495. alphascale=0;
  7496. }
  7497. }
  7498. alpha=bestalpha;
  7499. //"good" alpha value and table are known!
  7500. //store them, then loop through the pixels again and print indices.
  7501. returnData[0]=alpha;
  7502. returnData[1]=besttable;
  7503. for(int pos=2; pos<8; pos++)
  7504. {
  7505. returnData[pos]=0;
  7506. }
  7507. int byte=2;
  7508. int bit=0;
  7509. for(int x=0; x<4; x++)
  7510. {
  7511. for(int y=0; y<4; y++)
  7512. {
  7513. //find correct index
  7514. int besterror=1000000;
  7515. int bestindex=99;
  7516. for(int index=0; index<8; index++) //no clever ordering this time, as this loop is only run once per block anyway
  7517. {
  7518. int error= (clamp(alpha +(int)(alphaTable[besttable][index]))-data[ix+x+(iy+y)*width])*(clamp(alpha +(int)(alphaTable[besttable][index]))-data[ix+x+(iy+y)*width]);
  7519. if(error<besterror)
  7520. {
  7521. besterror=error;
  7522. bestindex=index;
  7523. }
  7524. }
  7525. //best table index has been determined.
  7526. //pack 3-bit index into compressed data, one bit at a time
  7527. for(int numbit=0; numbit<3; numbit++)
  7528. {
  7529. returnData[byte]|=getbit(bestindex,2-numbit,7-bit);
  7530. bit++;
  7531. if(bit>7)
  7532. {
  7533. bit=0;
  7534. byte++;
  7535. }
  7536. }
  7537. }
  7538. }
  7539. }
  7540. // Helper function for the below function
  7541. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  7542. /*int getPremulIndex(int base, int tab, int mul, int index)
  7543. {
  7544. return (base<<11)+(tab<<7)+(mul<<3)+index;
  7545. }
  7546. // Calculates the error used in compressBlockAlpha16()
  7547. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  7548. double calcError(uint8* data, int ix, int iy, int width, int height, int base, int tab, int mul, double prevbest)
  7549. {
  7550. int offset = getPremulIndex(base,tab,mul,0);
  7551. double error=0;
  7552. for (int y=0; y<4; y++)
  7553. {
  7554. for(int x=0; x<4; x++)
  7555. {
  7556. double besthere = (1<<20);
  7557. besthere*=besthere;
  7558. uint8 byte1 = data[2*(x+ix+(y+iy)*width)];
  7559. uint8 byte2 = data[2*(x+ix+(y+iy)*width)+1];
  7560. int alpha = (byte1<<8)+byte2;
  7561. for(int index=0; index<8; index++)
  7562. {
  7563. double indexError;
  7564. indexError = alpha-valtab[offset+index];
  7565. indexError*=indexError;
  7566. if(indexError<besthere)
  7567. besthere=indexError;
  7568. }
  7569. error+=besthere;
  7570. if(error>=prevbest)
  7571. return prevbest+(1<<30);
  7572. }
  7573. }
  7574. return error;
  7575. }
  7576. // compressBlockAlpha16
  7577. //
  7578. // Compresses a block using the 11-bit EAC formats.
  7579. // Depends on the global variable formatSigned.
  7580. //
  7581. // COMPRESSED_R11_EAC (if formatSigned = 0)
  7582. // This is an 11-bit unsigned format. Since we do not have a good 11-bit file format, we use 16-bit pgm instead.
  7583. // Here we assume that, in the input 16-bit pgm file, 0 represents 0.0 and 65535 represents 1.0. The function compressBlockAlpha16
  7584. // will find the compressed block which best matches the data. In detail, it will find the compressed block, which
  7585. // if decompressed, will generate an 11-bit block that after bit replication to 16-bits will generate the closest
  7586. // block to the original 16-bit pgm block.
  7587. //
  7588. // COMPRESSED_SIGNED_R11_EAC (if formatSigned = 1)
  7589. // This is an 11-bit signed format. Since we do not have any signed file formats, we use unsigned 16-bit pgm instead.
  7590. // Hence we assume that, in the input 16-bit pgm file, 1 represents -1.0, 32768 represents 0.0 and 65535 represents 1.0.
  7591. // The function compresseBlockAlpha16 will find the compressed block, which if decompressed, will generate a signed
  7592. // 11-bit block that after bit replication to 16-bits and conversion to unsigned (1 equals -1.0, 32768 equals 0.0 and
  7593. // 65535 equals 1.0) will generate the closest block to the original 16-bit pgm block.
  7594. //
  7595. // COMPRESSED_RG11_EAC is compressed by calling the function twice, dito for COMPRESSED_SIGNED_RG11_EAC.
  7596. //
  7597. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  7598. void compressBlockAlpha16(uint8* data, int ix, int iy, int width, int height, uint8* returnData)
  7599. {
  7600. unsigned int bestbase, besttable, bestmul;
  7601. double besterror;
  7602. besterror=1<<20;
  7603. besterror*=besterror;
  7604. for(int base=0; base<256; base++)
  7605. {
  7606. for(int table=0; table<16; table++)
  7607. {
  7608. for(int mul=0; mul<16; mul++)
  7609. {
  7610. double e = calcError(data, ix, iy, width, height,base,table,mul,besterror);
  7611. if(e<besterror)
  7612. {
  7613. bestbase=base;
  7614. besttable=table;
  7615. bestmul=mul;
  7616. besterror=e;
  7617. }
  7618. }
  7619. }
  7620. }
  7621. returnData[0]=bestbase;
  7622. returnData[1]=(bestmul<<4)+besttable;
  7623. if(formatSigned)
  7624. {
  7625. //if we have a signed format, the base value should be given as a signed byte.
  7626. signed char signedbase = bestbase-128;
  7627. returnData[0]=*((uint8*)(&signedbase));
  7628. }
  7629. for(int i=2; i<8; i++)
  7630. {
  7631. returnData[i]=0;
  7632. }
  7633. int byte=2;
  7634. int bit=0;
  7635. for (int x=0; x<4; x++)
  7636. {
  7637. for(int y=0; y<4; y++)
  7638. {
  7639. double besterror=255*255;
  7640. besterror*=besterror;
  7641. int bestindex=99;
  7642. uint8 byte1 = data[2*(x+ix+(y+iy)*width)];
  7643. uint8 byte2 = data[2*(x+ix+(y+iy)*width)+1];
  7644. int alpha = (byte1<<8)+byte2;
  7645. for(unsigned int index=0; index<8; index++)
  7646. {
  7647. double indexError;
  7648. if(formatSigned)
  7649. {
  7650. int16 val16;
  7651. int val;
  7652. val16 = get16bits11signed(bestbase,besttable,bestmul,index);
  7653. val = val16 + 256*128;
  7654. indexError = alpha-val;
  7655. }
  7656. else
  7657. indexError = alpha-get16bits11bits(bestbase,besttable,bestmul,index);
  7658. indexError*=indexError;
  7659. if(indexError<besterror)
  7660. {
  7661. besterror=indexError;
  7662. bestindex=index;
  7663. }
  7664. }
  7665. for(int numbit=0; numbit<3; numbit++)
  7666. {
  7667. returnData[byte]|=getbit(bestindex,2-numbit,7-bit);
  7668. bit++;
  7669. if(bit>7)
  7670. {
  7671. bit=0;
  7672. byte++;
  7673. }
  7674. }
  7675. }
  7676. }
  7677. }*/
  7678. // Exhaustive compression of alpha compression in a GL_COMPRESSED_RGB8_ETC2 block
  7679. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  7680. void compressBlockAlphaSlow(uint8* data, int ix, int iy, int width, int height, uint8* returnData)
  7681. {
  7682. //determine the best table and base alpha value for this block using MSE
  7683. int alphasum=0;
  7684. int maxdist=-2;
  7685. for(int x=0; x<4; x++)
  7686. {
  7687. for(int y=0; y<4; y++)
  7688. {
  7689. alphasum+=data[ix+x+(iy+y)*width];
  7690. }
  7691. }
  7692. int alpha = (int)( ((float)alphasum)/16.0f+0.5f); //average pixel value, used as guess for base value.
  7693. int bestsum=1000000000;
  7694. int besttable=-3;
  7695. int bestalpha=128;
  7696. int prevalpha=alpha;
  7697. //main loop: determine best base alpha value and offset table to use for compression
  7698. //try some different alpha tables.
  7699. for(int table = 0; table<256&&bestsum>0; table++)
  7700. {
  7701. int tablealpha=prevalpha;
  7702. int tablebestsum=1000000000;
  7703. //test some different alpha values, trying to find the best one for the given table.
  7704. for(int alphascale=32; alphascale>0; alphascale/=8)
  7705. {
  7706. int startalpha = clamp(tablealpha-alphascale*4);
  7707. int endalpha = clamp(tablealpha+alphascale*4);
  7708. for(alpha=startalpha; alpha<=endalpha; alpha+=alphascale) {
  7709. int sum=0;
  7710. int val,diff,bestdiff=10000000,index;
  7711. for(int x=0; x<4; x++)
  7712. {
  7713. for(int y=0; y<4; y++)
  7714. {
  7715. //compute best offset here, add square difference to sum..
  7716. val=data[ix+x+(iy+y)*width];
  7717. bestdiff=1000000000;
  7718. //the values are always ordered from small to large, with the first 4 being negative and the last 4 positive
  7719. //search is therefore made in the order 0-1-2-3 or 7-6-5-4, stopping when error increases compared to the previous entry tested.
  7720. if(val>alpha)
  7721. {
  7722. for(index=7; index>3; index--)
  7723. {
  7724. diff=clamp_table[alpha+(alphaTable[table][index])+255]-val;
  7725. diff*=diff;
  7726. if(diff<=bestdiff)
  7727. {
  7728. bestdiff=diff;
  7729. }
  7730. else
  7731. break;
  7732. }
  7733. }
  7734. else
  7735. {
  7736. for(index=0; index<5; index++)
  7737. {
  7738. diff=clamp_table[alpha+(alphaTable[table][index])+255]-val;
  7739. diff*=diff;
  7740. if(diff<bestdiff)
  7741. {
  7742. bestdiff=diff;
  7743. }
  7744. else
  7745. break;
  7746. }
  7747. }
  7748. //best diff here is bestdiff, add it to sum!
  7749. sum+=bestdiff;
  7750. //if the sum here is worse than previously best already, there's no use in continuing the count..
  7751. if(sum>tablebestsum)
  7752. {
  7753. x=9999; //just to make it large and get out of the x<4 loop
  7754. break;
  7755. }
  7756. }
  7757. }
  7758. if(sum<tablebestsum)
  7759. {
  7760. tablebestsum=sum;
  7761. tablealpha=alpha;
  7762. }
  7763. if(sum<bestsum)
  7764. {
  7765. bestsum=sum;
  7766. besttable=table;
  7767. bestalpha=alpha;
  7768. }
  7769. }
  7770. if(alphascale==4)
  7771. alphascale=8;
  7772. }
  7773. }
  7774. alpha=bestalpha;
  7775. //the best alpha value and table are known!
  7776. //store them, then loop through the pixels again and print indices.
  7777. returnData[0]=alpha;
  7778. returnData[1]=besttable;
  7779. for(int pos=2; pos<8; pos++)
  7780. {
  7781. returnData[pos]=0;
  7782. }
  7783. int byte=2;
  7784. int bit=0;
  7785. for(int x=0; x<4; x++)
  7786. {
  7787. for(int y=0; y<4; y++)
  7788. {
  7789. //find correct index
  7790. int besterror=1000000;
  7791. int bestindex=99;
  7792. for(int index=0; index<8; index++) //no clever ordering this time, as this loop is only run once per block anyway
  7793. {
  7794. int error= (clamp(alpha +(int)(alphaTable[besttable][index]))-data[ix+x+(iy+y)*width])*(clamp(alpha +(int)(alphaTable[besttable][index]))-data[ix+x+(iy+y)*width]);
  7795. if(error<besterror)
  7796. {
  7797. besterror=error;
  7798. bestindex=index;
  7799. }
  7800. }
  7801. //best table index has been determined.
  7802. //pack 3-bit index into compressed data, one bit at a time
  7803. for(int numbit=0; numbit<3; numbit++)
  7804. {
  7805. returnData[byte]|=getbit(bestindex,2-numbit,7-bit);
  7806. bit++;
  7807. if(bit>7)
  7808. {
  7809. bit=0;
  7810. byte++;
  7811. }
  7812. }
  7813. }
  7814. }
  7815. }
  7816. // Calculate weighted PSNR
  7817. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  7818. /*double calculateWeightedPSNR(uint8 *lossyimg, uint8 *origimg, int width, int height, double w1, double w2, double w3)
  7819. {
  7820. // Note: This calculation of PSNR uses the formula
  7821. //
  7822. // PSNR = 10 * log_10 ( 255^2 / wMSE )
  7823. //
  7824. // where the wMSE is calculated as
  7825. //
  7826. // 1/(N*M) * sum ( ( w1*(R' - R)^2 + w2*(G' - G)^2 + w3*(B' - B)^2) )
  7827. //
  7828. // typical weights are 0.299, 0.587, 0.114 for perceptually weighted PSNR and
  7829. // 1.0/3.0, 1.0/3.0, 1.0/3.0 for nonweighted PSNR
  7830. int x,y;
  7831. double wMSE;
  7832. double PSNR;
  7833. double err;
  7834. wMSE = 0;
  7835. for(y=0;y<height;y++)
  7836. {
  7837. for(x=0;x<width;x++)
  7838. {
  7839. err = lossyimg[y*width*3+x*3+0] - origimg[y*width*3+x*3+0];
  7840. wMSE = wMSE + (w1*(err * err));
  7841. err = lossyimg[y*width*3+x*3+1] - origimg[y*width*3+x*3+1];
  7842. wMSE = wMSE + (w2*(err * err));
  7843. err = lossyimg[y*width*3+x*3+2] - origimg[y*width*3+x*3+2];
  7844. wMSE = wMSE + (w3*(err * err));
  7845. }
  7846. }
  7847. wMSE = wMSE / (width * height);
  7848. if(wMSE == 0)
  7849. {
  7850. printf("********************************************************************\n");
  7851. printf("There is no difference at all between image files --- infinite PSNR.\n");
  7852. printf("********************************************************************\n");
  7853. }
  7854. PSNR = 10*log((1.0*255*255)/wMSE)/log(10.0);
  7855. return PSNR;
  7856. }
  7857. // Calculate unweighted PSNR (weights are (1,1,1))
  7858. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  7859. double calculatePSNR(uint8 *lossyimg, uint8 *origimg, int width, int height)
  7860. {
  7861. // Note: This calculation of PSNR uses the formula
  7862. //
  7863. // PSNR = 10 * log_10 ( 255^2 / MSE )
  7864. //
  7865. // where the MSE is calculated as
  7866. //
  7867. // 1/(N*M) * sum ( 1/3 * ((R' - R)^2 + (G' - G)^2 + (B' - B)^2) )
  7868. //
  7869. // The reason for having the 1/3 factor is the following:
  7870. // Presume we have a grayscale image, that is acutally just the red component
  7871. // of a color image.. The squared error is then (R' - R)^2.
  7872. // Assume that we have a certain signal to noise ratio, say 30 dB. If we add
  7873. // another two components (say green and blue) with the same signal to noise
  7874. // ratio, we want the total signal to noise ratio be the same. For the
  7875. // squared error to remain constant we must divide by three after adding
  7876. // together the squared errors of the components.
  7877. return calculateWeightedPSNR(lossyimg, origimg, width, height, (1.0/3.0), (1.0/3.0), (1.0/3.0));
  7878. }
  7879. // Decompresses a file
  7880. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  7881. void uncompressFile(char *srcfile, uint8* &img, uint8 *&alphaimg, int& active_width, int& active_height)
  7882. {
  7883. FILE *f;
  7884. int width,height;
  7885. unsigned int block_part1, block_part2;
  7886. uint8 *newimg, *newalphaimg, *alphaimg2;
  7887. unsigned short w, h;
  7888. int xx, yy;
  7889. unsigned char magic[4];
  7890. unsigned char version[2];
  7891. unsigned short texture_type;
  7892. if(f=fopen(srcfile,"rb"))
  7893. {
  7894. // Load table
  7895. readCompressParams();
  7896. if(ktxFile)
  7897. {
  7898. //read ktx header..
  7899. KTX_header header;
  7900. fread(&header,sizeof(KTX_header),1,f);
  7901. //read size parameter, which we don't actually need..
  7902. unsigned int bitsize;
  7903. fread(&bitsize,sizeof(unsigned int),1,f);
  7904. active_width=header.pixelWidth;
  7905. active_height = header.pixelHeight;
  7906. w = ((active_width+3)/4)*4;
  7907. h = ((active_height+3)/4)*4;
  7908. width=w;
  7909. height=h;
  7910. if(header.glInternalFormat==GL_COMPRESSED_SIGNED_R11_EAC)
  7911. {
  7912. format=ETC2PACKAGE_R_NO_MIPMAPS;
  7913. formatSigned=1;
  7914. }
  7915. else if(header.glInternalFormat==GL_COMPRESSED_R11_EAC)
  7916. {
  7917. format=ETC2PACKAGE_R_NO_MIPMAPS;
  7918. }
  7919. else if(header.glInternalFormat==GL_COMPRESSED_SIGNED_RG11_EAC)
  7920. {
  7921. format=ETC2PACKAGE_RG_NO_MIPMAPS;
  7922. formatSigned=1;
  7923. }
  7924. else if(header.glInternalFormat==GL_COMPRESSED_RG11_EAC)
  7925. {
  7926. format=ETC2PACKAGE_RG_NO_MIPMAPS;
  7927. }
  7928. else if(header.glInternalFormat==GL_COMPRESSED_RGB8_ETC2)
  7929. {
  7930. format=ETC2PACKAGE_RGB_NO_MIPMAPS;
  7931. }
  7932. else if(header.glInternalFormat==GL_COMPRESSED_SRGB8_ETC2)
  7933. {
  7934. format=ETC2PACKAGE_sRGB_NO_MIPMAPS;
  7935. }
  7936. else if(header.glInternalFormat==GL_COMPRESSED_RGBA8_ETC2_EAC)
  7937. {
  7938. format=ETC2PACKAGE_RGBA_NO_MIPMAPS;
  7939. }
  7940. else if(header.glInternalFormat==GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC)
  7941. {
  7942. format=ETC2PACKAGE_sRGBA_NO_MIPMAPS;
  7943. }
  7944. else if(header.glInternalFormat==GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2)
  7945. {
  7946. format=ETC2PACKAGE_RGBA1_NO_MIPMAPS;
  7947. }
  7948. else if(header.glInternalFormat==GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2)
  7949. {
  7950. format=ETC2PACKAGE_sRGBA1_NO_MIPMAPS;
  7951. }
  7952. else if(header.glInternalFormat==GL_ETC1_RGB8_OES)
  7953. {
  7954. format=ETC1_RGB_NO_MIPMAPS;
  7955. codec=CODEC_ETC;
  7956. }
  7957. else
  7958. {
  7959. printf("ktx file has unknown glInternalFormat (not etc compressed)!\n");
  7960. exit(1);
  7961. }
  7962. }
  7963. else
  7964. {
  7965. // Read magic nunmber
  7966. fread(&magic[0], sizeof(unsigned char), 1, f);
  7967. fread(&magic[1], sizeof(unsigned char), 1, f);
  7968. fread(&magic[2], sizeof(unsigned char), 1, f);
  7969. fread(&magic[3], sizeof(unsigned char), 1, f);
  7970. if(!(magic[0] == 'P' && magic[1] == 'K' && magic[2] == 'M' && magic[3] == ' '))
  7971. {
  7972. printf("\n\n The file %s is not a .pkm file.\n",srcfile);
  7973. exit(1);
  7974. }
  7975. // Read version
  7976. fread(&version[0], sizeof(unsigned char), 1, f);
  7977. fread(&version[1], sizeof(unsigned char), 1, f);
  7978. if( version[0] == '1' && version[1] == '0' )
  7979. {
  7980. // Read texture type
  7981. read_big_endian_2byte_word(&texture_type, f);
  7982. if(!(texture_type == ETC1_RGB_NO_MIPMAPS))
  7983. {
  7984. printf("\n\n The file %s (of version %c.%c) does not contain a texture of known format.\n", srcfile, version[0],version[1]);
  7985. printf("Known formats: ETC1_RGB_NO_MIPMAPS.\n", srcfile);
  7986. exit(1);
  7987. }
  7988. }
  7989. else if( version[0] == '2' && version[1] == '0' )
  7990. {
  7991. // Read texture type
  7992. read_big_endian_2byte_word(&texture_type, f);
  7993. if(texture_type==ETC2PACKAGE_RG_SIGNED_NO_MIPMAPS)
  7994. {
  7995. texture_type=ETC2PACKAGE_RG_NO_MIPMAPS;
  7996. formatSigned=1;
  7997. //printf("Decompressing 2-channel signed data\n");
  7998. }
  7999. if(texture_type==ETC2PACKAGE_R_SIGNED_NO_MIPMAPS)
  8000. {
  8001. texture_type=ETC2PACKAGE_R_NO_MIPMAPS;
  8002. formatSigned=1;
  8003. //printf("Decompressing 1-channel signed data\n");
  8004. }
  8005. if(texture_type==ETC2PACKAGE_sRGB_NO_MIPMAPS)
  8006. {
  8007. // The SRGB formats are decoded just as RGB formats -- use RGB format for decompression.
  8008. texture_type=ETC2PACKAGE_RGB_NO_MIPMAPS;
  8009. }
  8010. if(texture_type==ETC2PACKAGE_sRGBA_NO_MIPMAPS)
  8011. {
  8012. // The SRGB formats are decoded just as RGB formats -- use RGB format for decompression.
  8013. texture_type=ETC2PACKAGE_RGBA_NO_MIPMAPS;
  8014. }
  8015. if(texture_type==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  8016. {
  8017. // The SRGB formats are decoded just as RGB formats -- use RGB format for decompression.
  8018. texture_type=ETC2PACKAGE_sRGBA1_NO_MIPMAPS;
  8019. }
  8020. if(texture_type==ETC2PACKAGE_RGBA_NO_MIPMAPS_OLD)
  8021. {
  8022. printf("\n\nThe file %s contains a compressed texture created using an old version of ETCPACK.\n",srcfile);
  8023. printf("decompression is not supported in this version.\n");
  8024. exit(1);
  8025. }
  8026. if(!(texture_type==ETC2PACKAGE_RGB_NO_MIPMAPS||texture_type==ETC2PACKAGE_sRGB_NO_MIPMAPS||texture_type==ETC2PACKAGE_RGBA_NO_MIPMAPS||texture_type==ETC2PACKAGE_sRGBA_NO_MIPMAPS||texture_type==ETC2PACKAGE_R_NO_MIPMAPS||texture_type==ETC2PACKAGE_RG_NO_MIPMAPS||texture_type==ETC2PACKAGE_RGBA1_NO_MIPMAPS||texture_type==ETC2PACKAGE_sRGBA1_NO_MIPMAPS))
  8027. {
  8028. printf("\n\n The file %s does not contain a texture of known format.\n", srcfile);
  8029. printf("Known formats: ETC2PACKAGE_RGB_NO_MIPMAPS.\n", srcfile);
  8030. exit(1);
  8031. }
  8032. }
  8033. else
  8034. {
  8035. printf("\n\n The file %s is not of version 1.0 or 2.0 but of version %c.%c.\n",srcfile, version[0], version[1]);
  8036. printf("Aborting.\n");
  8037. exit(1);
  8038. }
  8039. format=texture_type;
  8040. printf("textype: %d\n",texture_type);
  8041. // ETC2 is backwards compatible, which means that an ETC2-capable decompressor can also handle
  8042. // old ETC1 textures without any problems. Thus a version 1.0 file with ETC1_RGB_NO_MIPMAPS and a
  8043. // version 2.0 file with ETC2PACKAGE_RGB_NO_MIPMAPS can be handled by the same ETC2-capable decompressor
  8044. // Read how many pixels the blocks make up
  8045. read_big_endian_2byte_word(&w, f);
  8046. read_big_endian_2byte_word(&h, f);
  8047. width = w;
  8048. height = h;
  8049. // Read how many pixels contain active data (the rest are just
  8050. // for making sure we have a 4*a x 4*b size).
  8051. read_big_endian_2byte_word(&w, f);
  8052. read_big_endian_2byte_word(&h, f);
  8053. active_width = w;
  8054. active_height = h;
  8055. }
  8056. printf("Width = %d, Height = %d\n",width, height);
  8057. printf("active pixel area: top left %d x %d area.\n",active_width, active_height);
  8058. if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
  8059. img=(uint8*)malloc(3*width*height*2);
  8060. else
  8061. img=(uint8*)malloc(3*width*height);
  8062. if(!img)
  8063. {
  8064. printf("Error: could not allocate memory\n");
  8065. exit(0);
  8066. }
  8067. if(format==ETC2PACKAGE_RGBA_NO_MIPMAPS||format==ETC2PACKAGE_R_NO_MIPMAPS||format==ETC2PACKAGE_RG_NO_MIPMAPS||format==ETC2PACKAGE_RGBA1_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  8068. {
  8069. //printf("alpha channel decompression\n");
  8070. alphaimg=(uint8*)malloc(width*height*2);
  8071. setupAlphaTableAndValtab();
  8072. if(!alphaimg)
  8073. {
  8074. printf("Error: could not allocate memory for alpha\n");
  8075. exit(0);
  8076. }
  8077. }
  8078. if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
  8079. {
  8080. alphaimg2=(uint8*)malloc(width*height*2);
  8081. if(!alphaimg2)
  8082. {
  8083. printf("Error: could not allocate memory\n");
  8084. exit(0);
  8085. }
  8086. }
  8087. for(int y=0;y<height/4;y++)
  8088. {
  8089. for(int x=0;x<width/4;x++)
  8090. {
  8091. //decode alpha channel for RGBA
  8092. if(format==ETC2PACKAGE_RGBA_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA_NO_MIPMAPS)
  8093. {
  8094. uint8 alphablock[8];
  8095. fread(alphablock,1,8,f);
  8096. decompressBlockAlpha(alphablock,alphaimg,width,height,4*x,4*y);
  8097. }
  8098. //color channels for most normal modes
  8099. if(format!=ETC2PACKAGE_R_NO_MIPMAPS&&format!=ETC2PACKAGE_RG_NO_MIPMAPS)
  8100. {
  8101. //we have normal ETC2 color channels, decompress these
  8102. read_big_endian_4byte_word(&block_part1,f);
  8103. read_big_endian_4byte_word(&block_part2,f);
  8104. if(format==ETC2PACKAGE_RGBA1_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  8105. decompressBlockETC21BitAlpha(block_part1, block_part2,img,alphaimg,width,height,4*x,4*y);
  8106. else
  8107. decompressBlockETC2(block_part1, block_part2,img,width,height,4*x,4*y);
  8108. }
  8109. //one or two 11-bit alpha channels for R or RG.
  8110. if(format==ETC2PACKAGE_R_NO_MIPMAPS||format==ETC2PACKAGE_RG_NO_MIPMAPS)
  8111. {
  8112. uint8 alphablock[8];
  8113. fread(alphablock,1,8,f);
  8114. decompressBlockAlpha16bit(alphablock,alphaimg,width,height,4*x,4*y);
  8115. }
  8116. if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
  8117. {
  8118. uint8 alphablock[8];
  8119. fread(alphablock,1,8,f);
  8120. decompressBlockAlpha16bit(alphablock,alphaimg2,width,height,4*x,4*y);
  8121. }
  8122. }
  8123. }
  8124. if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
  8125. {
  8126. for(int y=0;y<height;y++)
  8127. {
  8128. for(int x=0;x<width;x++)
  8129. {
  8130. img[6*(y*width+x)]=alphaimg[2*(y*width+x)];
  8131. img[6*(y*width+x)+1]=alphaimg[2*(y*width+x)+1];
  8132. img[6*(y*width+x)+2]=alphaimg2[2*(y*width+x)];
  8133. img[6*(y*width+x)+3]=alphaimg2[2*(y*width+x)+1];
  8134. img[6*(y*width+x)+4]=0;
  8135. img[6*(y*width+x)+5]=0;
  8136. }
  8137. }
  8138. }
  8139. // Ok, and now only write out the active pixels to the .ppm file.
  8140. // (But only if the active pixels differ from the total pixels)
  8141. if( !(height == active_height && width == active_width) )
  8142. {
  8143. if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
  8144. newimg=(uint8*)malloc(3*active_width*active_height*2);
  8145. else
  8146. newimg=(uint8*)malloc(3*active_width*active_height);
  8147. if(format==ETC2PACKAGE_RGBA_NO_MIPMAPS||format==ETC2PACKAGE_RGBA1_NO_MIPMAPS||format==ETC2PACKAGE_R_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  8148. {
  8149. newalphaimg = (uint8*)malloc(active_width*active_height*2);
  8150. }
  8151. if(!newimg)
  8152. {
  8153. printf("Error: could not allocate memory\n");
  8154. exit(0);
  8155. }
  8156. // Convert from total area to active area:
  8157. for(yy = 0; yy<active_height; yy++)
  8158. {
  8159. for(xx = 0; xx< active_width; xx++)
  8160. {
  8161. if(format!=ETC2PACKAGE_R_NO_MIPMAPS&&format!=ETC2PACKAGE_RG_NO_MIPMAPS)
  8162. {
  8163. newimg[ (yy*active_width)*3 + xx*3 + 0 ] = img[ (yy*width)*3 + xx*3 + 0];
  8164. newimg[ (yy*active_width)*3 + xx*3 + 1 ] = img[ (yy*width)*3 + xx*3 + 1];
  8165. newimg[ (yy*active_width)*3 + xx*3 + 2 ] = img[ (yy*width)*3 + xx*3 + 2];
  8166. }
  8167. else if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
  8168. {
  8169. newimg[ (yy*active_width)*6 + xx*6 + 0 ] = img[ (yy*width)*6 + xx*6 + 0];
  8170. newimg[ (yy*active_width)*6 + xx*6 + 1 ] = img[ (yy*width)*6 + xx*6 + 1];
  8171. newimg[ (yy*active_width)*6 + xx*6 + 2 ] = img[ (yy*width)*6 + xx*6 + 2];
  8172. newimg[ (yy*active_width)*6 + xx*6 + 3 ] = img[ (yy*width)*6 + xx*6 + 3];
  8173. newimg[ (yy*active_width)*6 + xx*6 + 4 ] = img[ (yy*width)*6 + xx*6 + 4];
  8174. newimg[ (yy*active_width)*6 + xx*6 + 5 ] = img[ (yy*width)*6 + xx*6 + 5];
  8175. }
  8176. if(format==ETC2PACKAGE_R_NO_MIPMAPS)
  8177. {
  8178. newalphaimg[ ((yy*active_width) + xx)*2] = alphaimg[2*((yy*width) + xx)];
  8179. newalphaimg[ ((yy*active_width) + xx)*2+1] = alphaimg[2*((yy*width) + xx)+1];
  8180. }
  8181. if(format==ETC2PACKAGE_RGBA_NO_MIPMAPS||format==ETC2PACKAGE_RGBA1_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  8182. {
  8183. newalphaimg[ ((yy*active_width) + xx)] = alphaimg[((yy*width) + xx)];
  8184. }
  8185. }
  8186. }
  8187. free(img);
  8188. img = newimg;
  8189. if(format==ETC2PACKAGE_RGBA_NO_MIPMAPS||format==ETC2PACKAGE_RGBA1_NO_MIPMAPS||format==ETC2PACKAGE_R_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  8190. {
  8191. free(alphaimg);
  8192. alphaimg=newalphaimg;
  8193. }
  8194. if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
  8195. {
  8196. free(alphaimg);
  8197. free(alphaimg2);
  8198. alphaimg = NULL;
  8199. alphaimg2 = NULL;
  8200. }
  8201. }
  8202. }
  8203. else
  8204. {
  8205. printf("Error: could not open <%s>.\n",srcfile);
  8206. exit(1);
  8207. }
  8208. height=active_height;
  8209. width=active_width;
  8210. fclose(f);
  8211. }
  8212. // Writes output file
  8213. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  8214. void writeOutputFile(char *dstfile, uint8* img, uint8* alphaimg, int width, int height)
  8215. {
  8216. char str[300];
  8217. if(format!=ETC2PACKAGE_R_NO_MIPMAPS&&format!=ETC2PACKAGE_RG_NO_MIPMAPS)
  8218. {
  8219. fWritePPM("tmp.ppm",width,height,img,8,false);
  8220. printf("Saved file tmp.ppm \n\n");
  8221. }
  8222. else if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
  8223. {
  8224. fWritePPM("tmp.ppm",width,height,img,16,false);
  8225. }
  8226. if(format==ETC2PACKAGE_RGBA_NO_MIPMAPS||format==ETC2PACKAGE_RGBA1_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  8227. fWritePGM("alphaout.pgm",width,height,alphaimg,false,8);
  8228. if(format==ETC2PACKAGE_R_NO_MIPMAPS)
  8229. fWritePGM("alphaout.pgm",width,height,alphaimg,false,16);
  8230. // Delete destination file if it exists
  8231. if(fileExist(dstfile))
  8232. {
  8233. sprintf(str, "del %s\n",dstfile);
  8234. system(str);
  8235. }
  8236. int q = find_pos_of_extension(dstfile);
  8237. if(!strcmp(&dstfile[q],".ppm")&&format!=ETC2PACKAGE_R_NO_MIPMAPS)
  8238. {
  8239. // Already a .ppm file. Just rename.
  8240. sprintf(str,"move tmp.ppm %s\n",dstfile);
  8241. printf("Renaming destination file to %s\n",dstfile);
  8242. }
  8243. else
  8244. {
  8245. // Converting from .ppm to other file format
  8246. //
  8247. // Use your favorite command line image converter program,
  8248. // for instance Image Magick. Just make sure the syntax can
  8249. // be written as below:
  8250. //
  8251. // C:\imconv source.ppm dest.jpg
  8252. //
  8253. if(format==ETC2PACKAGE_RGBA_NO_MIPMAPS||format==ETC2PACKAGE_RGBA1_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  8254. {
  8255. // Somewhere after version 6.7.1-2 of ImageMagick the following command gives the wrong result due to a bug.
  8256. // sprintf(str,"composite -compose CopyOpacity alphaout.pgm tmp.ppm %s\n",dstfile);
  8257. // Instead we read the file and write a tga.
  8258. printf("Converting destination file from .ppm/.pgm to %s with alpha\n",dstfile);
  8259. int rw, rh;
  8260. unsigned char *pixelsRGB;
  8261. unsigned char *pixelsA;
  8262. fReadPPM("tmp.ppm", rw, rh, pixelsRGB, 8);
  8263. fReadPGM("alphaout.pgm", rw, rh, pixelsA, 8);
  8264. fWriteTGAfromRGBandA(dstfile, rw, rh, pixelsRGB, pixelsA, true);
  8265. free(pixelsRGB);
  8266. free(pixelsA);
  8267. sprintf(str,""); // Nothing to execute.
  8268. }
  8269. else if(format==ETC2PACKAGE_R_NO_MIPMAPS)
  8270. {
  8271. sprintf(str,"imconv alphaout.pgm %s\n",dstfile);
  8272. printf("Converting destination file from .pgm to %s\n",dstfile);
  8273. }
  8274. else
  8275. {
  8276. sprintf(str,"imconv tmp.ppm %s\n",dstfile);
  8277. printf("Converting destination file from .ppm to %s\n",dstfile);
  8278. }
  8279. }
  8280. // Execute system call
  8281. system(str);
  8282. free(img);
  8283. if(alphaimg!=NULL)
  8284. free(alphaimg);
  8285. }
  8286. // Calculates the PSNR between two files
  8287. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  8288. double calculatePSNRfile(char *srcfile, uint8 *origimg, uint8* origalpha)
  8289. {
  8290. uint8 *alphaimg, *img;
  8291. int active_width, active_height;
  8292. uncompressFile(srcfile,img,alphaimg,active_width,active_height);
  8293. // calculate Mean Square Error (MSE)
  8294. double MSER=0,MSEG=0,MSEB=0,MSEA, PSNRR,PSNRG,PSNRA;
  8295. double MSE;
  8296. double wMSE;
  8297. double PSNR=0;
  8298. double wPSNR;
  8299. double err;
  8300. MSE = 0;
  8301. MSEA=0;
  8302. wMSE = 0;
  8303. int width=((active_width+3)/4)*4;
  8304. int height=((active_height+3)/4)*4;
  8305. int numpixels = 0;
  8306. for(int y=0;y<active_height;y++)
  8307. {
  8308. for(int x=0;x<active_width;x++)
  8309. {
  8310. if(format!=ETC2PACKAGE_R_NO_MIPMAPS&&format!=ETC2PACKAGE_RG_NO_MIPMAPS)
  8311. {
  8312. //we have regular color channels..
  8313. if((format != ETC2PACKAGE_RGBA1_NO_MIPMAPS && format != ETC2PACKAGE_sRGBA1_NO_MIPMAPS) || alphaimg[y*width + x] > 0)
  8314. {
  8315. err = img[y*active_width*3+x*3+0] - origimg[y*width*3+x*3+0];
  8316. MSE += ((err * err)/3.0);
  8317. wMSE += PERCEPTUAL_WEIGHT_R_SQUARED * (err*err);
  8318. err = img[y*active_width*3+x*3+1] - origimg[y*width*3+x*3+1];
  8319. MSE += ((err * err)/3.0);
  8320. wMSE += PERCEPTUAL_WEIGHT_G_SQUARED * (err*err);
  8321. err = img[y*active_width*3+x*3+2] - origimg[y*width*3+x*3+2];
  8322. MSE += ((err * err)/3.0);
  8323. wMSE += PERCEPTUAL_WEIGHT_B_SQUARED * (err*err);
  8324. numpixels++;
  8325. }
  8326. }
  8327. else if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
  8328. {
  8329. int rorig = (origimg[6*(y*width+x)+0]<<8)+origimg[6*(y*width+x)+1];
  8330. int rnew = ( img[6*(y*active_width+x)+0]<<8)+ img[6*(y*active_width+x)+1];
  8331. int gorig = (origimg[6*(y*width+x)+2]<<8)+origimg[6*(y*width+x)+3];
  8332. int gnew = ( img[6*(y*active_width+x)+2]<<8)+ img[6*(y*active_width+x)+3];
  8333. err=rorig-rnew;
  8334. MSER+=(err*err);
  8335. err=gorig-gnew;
  8336. MSEG+=(err*err);
  8337. }
  8338. else if(format==ETC2PACKAGE_R_NO_MIPMAPS)
  8339. {
  8340. int aorig = (((int)origalpha[2*(y*width+x)+0])<<8)+origalpha[2*(y*width+x)+1];
  8341. int anew = (((int)alphaimg[2*(y*active_width+x)+0])<<8)+alphaimg[2*(y*active_width+x)+1];
  8342. err=aorig-anew;
  8343. MSEA+=(err*err);
  8344. }
  8345. }
  8346. }
  8347. if(format == ETC2PACKAGE_RGBA1_NO_MIPMAPS || format == ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  8348. {
  8349. MSE = MSE / (1.0 * numpixels);
  8350. wMSE = wMSE / (1.0 * numpixels);
  8351. PSNR = 10*log((1.0*255*255)/MSE)/log(10.0);
  8352. wPSNR = 10*log((1.0*255*255)/wMSE)/log(10.0);
  8353. printf("PSNR only calculated on pixels where compressed alpha > 0\n");
  8354. printf("color PSNR: %lf\nweighted PSNR: %lf\n",PSNR,wPSNR);
  8355. }
  8356. else if(format!=ETC2PACKAGE_R_NO_MIPMAPS&&format!=ETC2PACKAGE_RG_NO_MIPMAPS)
  8357. {
  8358. MSE = MSE / (active_width * active_height);
  8359. wMSE = wMSE / (active_width * active_height);
  8360. PSNR = 10*log((1.0*255*255)/MSE)/log(10.0);
  8361. wPSNR = 10*log((1.0*255*255)/wMSE)/log(10.0);
  8362. if(format == ETC2PACKAGE_RGBA_NO_MIPMAPS || format == ETC2PACKAGE_sRGBA_NO_MIPMAPS)
  8363. printf("PSNR only calculated on RGB, not on alpha\n");
  8364. printf("color PSNR: %lf\nweighted PSNR: %lf\n",PSNR,wPSNR);
  8365. }
  8366. else if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
  8367. {
  8368. MSER = MSER / (active_width * active_height);
  8369. MSEG = MSEG / (active_width * active_height);
  8370. PSNRR = 10*log((1.0*65535*65535)/MSER)/log(10.0);
  8371. PSNRG = 10*log((1.0*65535*65535)/MSEG)/log(10.0);
  8372. printf("red PSNR: %lf\ngreen PSNR: %lf\n",PSNRR,PSNRG);
  8373. }
  8374. else if(format==ETC2PACKAGE_R_NO_MIPMAPS)
  8375. {
  8376. MSEA = MSEA / (active_width * active_height);
  8377. PSNRA = 10*log((1.0*65535.0*65535.0)/MSEA)/log(10.0);
  8378. printf("PSNR: %lf\n",PSNRA);
  8379. }
  8380. free(img);
  8381. return PSNR;
  8382. }*/
  8383. //// Exhaustive code starts here.
  8384. #if EXHAUSTIVE_CODE_ACTIVE
  8385. // Precomutes a table that is used when compressing a block exhaustively
  8386. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  8387. inline unsigned int precompute_3bittable_all_subblocksRG_withtest_perceptual1000(uint8 *block,uint8 *avg_color, unsigned int *precalc_err_UL_R, unsigned int *precalc_err_UR_R, unsigned int *precalc_err_LL_R, unsigned int *precalc_err_LR_R,unsigned int *precalc_err_UL_RG, unsigned int *precalc_err_UR_RG, unsigned int *precalc_err_LL_RG, unsigned int *precalc_err_LR_RG, unsigned int best_err)
  8388. {
  8389. int table;
  8390. int index;
  8391. int orig[3],approx[3][4];
  8392. int x;
  8393. int intensity_modifier;
  8394. const int *table_indices;
  8395. int good_enough_to_test;
  8396. unsigned int err[4];
  8397. unsigned int err_this_table_upper;
  8398. unsigned int err_this_table_lower;
  8399. unsigned int err_this_table_left;
  8400. unsigned int err_this_table_right;
  8401. // If the error in the red and green component is already larger than best_err for all 8 tables in
  8402. // all of upper, lower, left and right, this combination of red and green will never be used in
  8403. // the optimal color configuration. Therefore we can avoid testing all the blue colors for this
  8404. // combination.
  8405. good_enough_to_test = false;
  8406. for(table=0;table<8;table++) // try all the 8 tables.
  8407. {
  8408. table_indices = &compressParamsFast[table*4];
  8409. intensity_modifier = table_indices[0];
  8410. approx[1][0]=CLAMP(0, avg_color[1]+intensity_modifier,255);
  8411. intensity_modifier = table_indices[1];
  8412. approx[1][1]=CLAMP(0, avg_color[1]+intensity_modifier,255);
  8413. intensity_modifier = table_indices[2];
  8414. approx[1][2]=CLAMP(0, avg_color[1]+intensity_modifier,255);
  8415. intensity_modifier = table_indices[3];
  8416. approx[1][3]=CLAMP(0, avg_color[1]+intensity_modifier,255);
  8417. err_this_table_upper = 0;
  8418. err_this_table_lower = 0;
  8419. err_this_table_left = 0;
  8420. err_this_table_right = 0;
  8421. for(x=0; x<4; x++)
  8422. {
  8423. orig[0]=block[x*4];
  8424. orig[1]=block[x*4+1];
  8425. orig[2]=block[x*4+2];
  8426. for(index=0;index<4;index++)
  8427. {
  8428. err[index] = precalc_err_UL_R[table*4*4+x*4+index]
  8429. + PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000 * SQUARE(approx[1][index]-orig[1]);
  8430. precalc_err_UL_RG[table*4*4+x*4+index] = err[index];
  8431. }
  8432. if(err[0] > err[1])
  8433. err[0] = err[1];
  8434. if(err[2] > err[3])
  8435. err[2] = err[3];
  8436. if(err[0] > err[2])
  8437. err[0] = err[2];
  8438. err_this_table_upper+=err[0];
  8439. err_this_table_left+=err[0];
  8440. }
  8441. for(x=4; x<8; x++)
  8442. {
  8443. orig[0]=block[x*4];
  8444. orig[1]=block[x*4+1];
  8445. orig[2]=block[x*4+2];
  8446. for(index=0;index<4;index++)
  8447. {
  8448. err[index] = precalc_err_UR_R[table*4*4+(x-4)*4+index]
  8449. + PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000 * SQUARE(approx[1][index]-orig[1]);
  8450. precalc_err_UR_RG[table*4*4+(x-4)*4+index] = err[index];
  8451. }
  8452. if(err[0] > err[1])
  8453. err[0] = err[1];
  8454. if(err[2] > err[3])
  8455. err[2] = err[3];
  8456. if(err[0] > err[2])
  8457. err[0] = err[2];
  8458. err_this_table_upper+=err[0];
  8459. err_this_table_right+=err[0];
  8460. }
  8461. for(x=8; x<12; x++)
  8462. {
  8463. orig[0]=block[x*4];
  8464. orig[1]=block[x*4+1];
  8465. orig[2]=block[x*4+2];
  8466. for(index=0;index<4;index++)
  8467. {
  8468. err[index] = precalc_err_LL_R[table*4*4+(x-8)*4+index]
  8469. + PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000 * SQUARE(approx[1][index]-orig[1]);
  8470. precalc_err_LL_RG[table*4*4+(x-8)*4+index] = err[index];
  8471. }
  8472. if(err[0] > err[1])
  8473. err[0] = err[1];
  8474. if(err[2] > err[3])
  8475. err[2] = err[3];
  8476. if(err[0] > err[2])
  8477. err[0] = err[2];
  8478. err_this_table_lower+=err[0];
  8479. err_this_table_left+=err[0];
  8480. }
  8481. for(x=12; x<16; x++)
  8482. {
  8483. orig[0]=block[x*4];
  8484. orig[1]=block[x*4+1];
  8485. orig[2]=block[x*4+2];
  8486. for(index=0;index<4;index++)
  8487. {
  8488. err[index] = precalc_err_LR_R[table*4*4+(x-12)*4+index]
  8489. + PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000 * SQUARE(approx[1][index]-orig[1]);
  8490. precalc_err_LR_RG[table*4*4+(x-12)*4+index] = err[index];
  8491. }
  8492. if(err[0] > err[1])
  8493. err[0] = err[1];
  8494. if(err[2] > err[3])
  8495. err[2] = err[3];
  8496. if(err[0] > err[2])
  8497. err[0] = err[2];
  8498. err_this_table_lower+=err[0];
  8499. err_this_table_right+=err[0];
  8500. }
  8501. if(err_this_table_upper < best_err)
  8502. good_enough_to_test = true;
  8503. if(err_this_table_lower < best_err)
  8504. good_enough_to_test = true;
  8505. if(err_this_table_left < best_err)
  8506. good_enough_to_test = true;
  8507. if(err_this_table_right < best_err)
  8508. good_enough_to_test = true;
  8509. }
  8510. return good_enough_to_test;
  8511. }
  8512. #endif
  8513. #if EXHAUSTIVE_CODE_ACTIVE
  8514. // Precomutes a table that is used when compressing a block exhaustively
  8515. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  8516. inline int precompute_3bittable_all_subblocksRG_withtest(uint8 *block,uint8 *avg_color, unsigned int *precalc_err_UL_R, unsigned int *precalc_err_UR_R, unsigned int *precalc_err_LL_R, unsigned int *precalc_err_LR_R,unsigned int *precalc_err_UL_RG, unsigned int *precalc_err_UR_RG, unsigned int *precalc_err_LL_RG, unsigned int *precalc_err_LR_RG, unsigned int best_err)
  8517. {
  8518. int table;
  8519. int index;
  8520. int orig[3],approx[3][4];
  8521. int x;
  8522. int intensity_modifier;
  8523. const int *table_indices;
  8524. int good_enough_to_test;
  8525. unsigned int err[4];
  8526. unsigned int err_this_table_upper;
  8527. unsigned int err_this_table_lower;
  8528. unsigned int err_this_table_left;
  8529. unsigned int err_this_table_right;
  8530. // If the error in the red and green component is already larger than best_err for all 8 tables in
  8531. // all of upper, lower, left and right, this combination of red and green will never be used in
  8532. // the optimal color configuration. Therefore we can avoid testing all the blue colors for this
  8533. // combination.
  8534. good_enough_to_test = false;
  8535. for(table=0;table<8;table++) // try all the 8 tables.
  8536. {
  8537. table_indices = &compressParamsFast[table*4];
  8538. intensity_modifier = table_indices[0];
  8539. approx[1][0]=CLAMP(0, avg_color[1]+intensity_modifier,255);
  8540. intensity_modifier = table_indices[1];
  8541. approx[1][1]=CLAMP(0, avg_color[1]+intensity_modifier,255);
  8542. intensity_modifier = table_indices[2];
  8543. approx[1][2]=CLAMP(0, avg_color[1]+intensity_modifier,255);
  8544. intensity_modifier = table_indices[3];
  8545. approx[1][3]=CLAMP(0, avg_color[1]+intensity_modifier,255);
  8546. err_this_table_upper = 0;
  8547. err_this_table_lower = 0;
  8548. err_this_table_left = 0;
  8549. err_this_table_right = 0;
  8550. for(x=0; x<4; x++)
  8551. {
  8552. orig[0]=block[x*4];
  8553. orig[1]=block[x*4+1];
  8554. orig[2]=block[x*4+2];
  8555. for(index=0;index<4;index++)
  8556. {
  8557. err[index] = precalc_err_UL_R[table*4*4+x*4+index]+SQUARE(approx[1][index]-orig[1]);
  8558. precalc_err_UL_RG[table*4*4+x*4+index] = err[index];
  8559. }
  8560. if(err[0] > err[1])
  8561. err[0] = err[1];
  8562. if(err[2] > err[3])
  8563. err[2] = err[3];
  8564. if(err[0] > err[2])
  8565. err[0] = err[2];
  8566. err_this_table_upper+=err[0];
  8567. err_this_table_left+=err[0];
  8568. }
  8569. for(x=4; x<8; x++)
  8570. {
  8571. orig[0]=block[x*4];
  8572. orig[1]=block[x*4+1];
  8573. orig[2]=block[x*4+2];
  8574. for(index=0;index<4;index++)
  8575. {
  8576. err[index] = precalc_err_UR_R[table*4*4+(x-4)*4+index]+SQUARE(approx[1][index]-orig[1]);
  8577. precalc_err_UR_RG[table*4*4+(x-4)*4+index] = err[index];
  8578. }
  8579. if(err[0] > err[1])
  8580. err[0] = err[1];
  8581. if(err[2] > err[3])
  8582. err[2] = err[3];
  8583. if(err[0] > err[2])
  8584. err[0] = err[2];
  8585. err_this_table_upper+=err[0];
  8586. err_this_table_right+=err[0];
  8587. }
  8588. for(x=8; x<12; x++)
  8589. {
  8590. orig[0]=block[x*4];
  8591. orig[1]=block[x*4+1];
  8592. orig[2]=block[x*4+2];
  8593. for(index=0;index<4;index++)
  8594. {
  8595. err[index] = precalc_err_LL_R[table*4*4+(x-8)*4+index]+SQUARE(approx[1][index]-orig[1]);
  8596. precalc_err_LL_RG[table*4*4+(x-8)*4+index] = err[index];
  8597. }
  8598. if(err[0] > err[1])
  8599. err[0] = err[1];
  8600. if(err[2] > err[3])
  8601. err[2] = err[3];
  8602. if(err[0] > err[2])
  8603. err[0] = err[2];
  8604. err_this_table_lower+=err[0];
  8605. err_this_table_left+=err[0];
  8606. }
  8607. for(x=12; x<16; x++)
  8608. {
  8609. orig[0]=block[x*4];
  8610. orig[1]=block[x*4+1];
  8611. orig[2]=block[x*4+2];
  8612. for(index=0;index<4;index++)
  8613. {
  8614. err[index] = precalc_err_LR_R[table*4*4+(x-12)*4+index]+SQUARE(approx[1][index]-orig[1]);
  8615. precalc_err_LR_RG[table*4*4+(x-12)*4+index] = err[index];
  8616. }
  8617. if(err[0] > err[1])
  8618. err[0] = err[1];
  8619. if(err[2] > err[3])
  8620. err[2] = err[3];
  8621. if(err[0] > err[2])
  8622. err[0] = err[2];
  8623. err_this_table_lower+=err[0];
  8624. err_this_table_right+=err[0];
  8625. }
  8626. if(err_this_table_upper < best_err)
  8627. good_enough_to_test = true;
  8628. if(err_this_table_lower < best_err)
  8629. good_enough_to_test = true;
  8630. if(err_this_table_left < best_err)
  8631. good_enough_to_test = true;
  8632. if(err_this_table_right < best_err)
  8633. good_enough_to_test = true;
  8634. }
  8635. return good_enough_to_test;
  8636. }
  8637. #endif
  8638. #if EXHAUSTIVE_CODE_ACTIVE
  8639. // Precomutes a table that is used when compressing a block exhaustively
  8640. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  8641. inline unsigned int precompute_3bittable_all_subblocksR_with_test_perceptual1000(uint8 *block,uint8 *avg_color, unsigned int *precalc_err_UL_R, unsigned int *precalc_err_UR_R, unsigned int *precalc_err_LL_R, unsigned int *precalc_err_LR_R, unsigned int best_err)
  8642. {
  8643. int table;
  8644. int index;
  8645. int orig[3],approx[3][4];
  8646. int x;
  8647. int intensity_modifier;
  8648. const int *table_indices;
  8649. unsigned int err[4];
  8650. unsigned int err_this_table_upper;
  8651. unsigned int err_this_table_lower;
  8652. unsigned int err_this_table_left;
  8653. unsigned int err_this_table_right;
  8654. int good_enough_to_test;
  8655. good_enough_to_test = false;
  8656. for(table=0;table<8;table++) // try all the 8 tables.
  8657. {
  8658. err_this_table_upper = 0;
  8659. err_this_table_lower = 0;
  8660. err_this_table_left = 0;
  8661. err_this_table_right = 0;
  8662. table_indices = &compressParamsFast[table*4];
  8663. intensity_modifier = table_indices[0];
  8664. approx[0][0]=CLAMP(0, avg_color[0]+intensity_modifier,255);
  8665. intensity_modifier = table_indices[1];
  8666. approx[0][1]=CLAMP(0, avg_color[0]+intensity_modifier,255);
  8667. intensity_modifier = table_indices[2];
  8668. approx[0][2]=CLAMP(0, avg_color[0]+intensity_modifier,255);
  8669. intensity_modifier = table_indices[3];
  8670. approx[0][3]=CLAMP(0, avg_color[0]+intensity_modifier,255);
  8671. for(x=0; x<4; x++)
  8672. {
  8673. orig[0]=block[x*4];
  8674. orig[1]=block[x*4+1];
  8675. orig[2]=block[x*4+2];
  8676. for(index=0;index<4;index++)
  8677. {
  8678. err[index]=PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE(approx[0][index]-orig[0]);
  8679. precalc_err_UL_R[table*4*4+x*4+index]=err[index];
  8680. }
  8681. if(err[0] > err[1])
  8682. err[0] = err[1];
  8683. if(err[2] > err[3])
  8684. err[2] = err[3];
  8685. if(err[0] > err[2])
  8686. err[0] = err[2];
  8687. err_this_table_upper+=err[0];
  8688. err_this_table_left+=err[0];
  8689. }
  8690. for(x=4; x<8; x++)
  8691. {
  8692. orig[0]=block[x*4];
  8693. orig[1]=block[x*4+1];
  8694. orig[2]=block[x*4+2];
  8695. for(index=0;index<4;index++)
  8696. {
  8697. err[index]=PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE(approx[0][index]-orig[0]);
  8698. precalc_err_UR_R[table*4*4+(x-4)*4+index]=err[index];
  8699. }
  8700. if(err[0] > err[1])
  8701. err[0] = err[1];
  8702. if(err[2] > err[3])
  8703. err[2] = err[3];
  8704. if(err[0] > err[2])
  8705. err[0] = err[2];
  8706. err_this_table_upper+=err[0];
  8707. err_this_table_right+=err[0];
  8708. }
  8709. for(x=8; x<12; x++)
  8710. {
  8711. orig[0]=block[x*4];
  8712. orig[1]=block[x*4+1];
  8713. orig[2]=block[x*4+2];
  8714. for(index=0;index<4;index++)
  8715. {
  8716. err[index]=PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE(approx[0][index]-orig[0]);
  8717. precalc_err_LL_R[table*4*4+(x-8)*4+index]=err[index];
  8718. }
  8719. if(err[0] > err[1])
  8720. err[0] = err[1];
  8721. if(err[2] > err[3])
  8722. err[2] = err[3];
  8723. if(err[0] > err[2])
  8724. err[0] = err[2];
  8725. err_this_table_lower+=err[0];
  8726. err_this_table_left+=err[0];
  8727. }
  8728. for(x=12; x<16; x++)
  8729. {
  8730. orig[0]=block[x*4];
  8731. orig[1]=block[x*4+1];
  8732. orig[2]=block[x*4+2];
  8733. for(index=0;index<4;index++)
  8734. {
  8735. err[index]=PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE(approx[0][index]-orig[0]);
  8736. precalc_err_LR_R[table*4*4+(x-12)*4+index]=err[index];
  8737. }
  8738. if(err[0] > err[1])
  8739. err[0] = err[1];
  8740. if(err[2] > err[3])
  8741. err[2] = err[3];
  8742. if(err[0] > err[2])
  8743. err[0] = err[2];
  8744. err_this_table_lower+=err[0];
  8745. err_this_table_right+=err[0];
  8746. }
  8747. if(err_this_table_upper < best_err)
  8748. good_enough_to_test = true;
  8749. if(err_this_table_lower < best_err)
  8750. good_enough_to_test = true;
  8751. if(err_this_table_left < best_err)
  8752. good_enough_to_test = true;
  8753. if(err_this_table_right < best_err)
  8754. good_enough_to_test = true;
  8755. }
  8756. return good_enough_to_test;
  8757. }
  8758. #endif
  8759. #if EXHAUSTIVE_CODE_ACTIVE
  8760. // Precomutes a table that is used when compressing a block exhaustively
  8761. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  8762. inline int precompute_3bittable_all_subblocksR_with_test(uint8 *block,uint8 *avg_color, unsigned int *precalc_err_UL_R, unsigned int *precalc_err_UR_R, unsigned int *precalc_err_LL_R, unsigned int *precalc_err_LR_R, unsigned int best_err)
  8763. {
  8764. int table;
  8765. int index;
  8766. int orig[3],approx[3][4];
  8767. int x;
  8768. int intensity_modifier;
  8769. const int *table_indices;
  8770. unsigned int err[4];
  8771. unsigned int err_this_table_upper;
  8772. unsigned int err_this_table_lower;
  8773. unsigned int err_this_table_left;
  8774. unsigned int err_this_table_right;
  8775. int good_enough_to_test;
  8776. good_enough_to_test = false;
  8777. for(table=0;table<8;table++) // try all the 8 tables.
  8778. {
  8779. err_this_table_upper = 0;
  8780. err_this_table_lower = 0;
  8781. err_this_table_left = 0;
  8782. err_this_table_right = 0;
  8783. table_indices = &compressParamsFast[table*4];
  8784. intensity_modifier = table_indices[0];
  8785. approx[0][0]=CLAMP(0, avg_color[0]+intensity_modifier,255);
  8786. intensity_modifier = table_indices[1];
  8787. approx[0][1]=CLAMP(0, avg_color[0]+intensity_modifier,255);
  8788. intensity_modifier = table_indices[2];
  8789. approx[0][2]=CLAMP(0, avg_color[0]+intensity_modifier,255);
  8790. intensity_modifier = table_indices[3];
  8791. approx[0][3]=CLAMP(0, avg_color[0]+intensity_modifier,255);
  8792. for(x=0; x<4; x++)
  8793. {
  8794. orig[0]=block[x*4];
  8795. orig[1]=block[x*4+1];
  8796. orig[2]=block[x*4+2];
  8797. for(index=0;index<4;index++)
  8798. {
  8799. err[index]=SQUARE(approx[0][index]-orig[0]);
  8800. precalc_err_UL_R[table*4*4+x*4+index]=err[index];
  8801. }
  8802. if(err[0] > err[1])
  8803. err[0] = err[1];
  8804. if(err[2] > err[3])
  8805. err[2] = err[3];
  8806. if(err[0] > err[2])
  8807. err[0] = err[2];
  8808. err_this_table_upper+=err[0];
  8809. err_this_table_left+=err[0];
  8810. }
  8811. for(x=4; x<8; x++)
  8812. {
  8813. orig[0]=block[x*4];
  8814. orig[1]=block[x*4+1];
  8815. orig[2]=block[x*4+2];
  8816. for(index=0;index<4;index++)
  8817. {
  8818. err[index]=SQUARE(approx[0][index]-orig[0]);
  8819. precalc_err_UR_R[table*4*4+(x-4)*4+index]=err[index];
  8820. }
  8821. if(err[0] > err[1])
  8822. err[0] = err[1];
  8823. if(err[2] > err[3])
  8824. err[2] = err[3];
  8825. if(err[0] > err[2])
  8826. err[0] = err[2];
  8827. err_this_table_upper+=err[0];
  8828. err_this_table_right+=err[0];
  8829. }
  8830. for(x=8; x<12; x++)
  8831. {
  8832. orig[0]=block[x*4];
  8833. orig[1]=block[x*4+1];
  8834. orig[2]=block[x*4+2];
  8835. for(index=0;index<4;index++)
  8836. {
  8837. err[index]=SQUARE(approx[0][index]-orig[0]);
  8838. precalc_err_LL_R[table*4*4+(x-8)*4+index]=err[index];
  8839. }
  8840. if(err[0] > err[1])
  8841. err[0] = err[1];
  8842. if(err[2] > err[3])
  8843. err[2] = err[3];
  8844. if(err[0] > err[2])
  8845. err[0] = err[2];
  8846. err_this_table_lower+=err[0];
  8847. err_this_table_left+=err[0];
  8848. }
  8849. for(x=12; x<16; x++)
  8850. {
  8851. orig[0]=block[x*4];
  8852. orig[1]=block[x*4+1];
  8853. orig[2]=block[x*4+2];
  8854. for(index=0;index<4;index++)
  8855. {
  8856. err[index]=SQUARE(approx[0][index]-orig[0]);
  8857. precalc_err_LR_R[table*4*4+(x-12)*4+index]=err[index];
  8858. }
  8859. if(err[0] > err[1])
  8860. err[0] = err[1];
  8861. if(err[2] > err[3])
  8862. err[2] = err[3];
  8863. if(err[0] > err[2])
  8864. err[0] = err[2];
  8865. err_this_table_lower+=err[0];
  8866. err_this_table_right+=err[0];
  8867. }
  8868. if(err_this_table_upper < best_err)
  8869. good_enough_to_test = true;
  8870. if(err_this_table_lower < best_err)
  8871. good_enough_to_test = true;
  8872. if(err_this_table_left < best_err)
  8873. good_enough_to_test = true;
  8874. if(err_this_table_right < best_err)
  8875. good_enough_to_test = true;
  8876. }
  8877. return good_enough_to_test;
  8878. }
  8879. #endif
  8880. #if EXHAUSTIVE_CODE_ACTIVE
  8881. // Tries all index-tables, used when compressing a block exhaustively
  8882. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  8883. inline void tryalltables_3bittable_all_subblocks_using_precalc(uint8 *block_2x2,uint8 *color_quant1, unsigned int *precalc_err_UL_RG, unsigned int *precalc_err_UR_RG, unsigned int *precalc_err_LL_RG, unsigned int *precalc_err_LR_RG, unsigned int &err_upper, unsigned int &err_lower, unsigned int &err_left, unsigned int &err_right, unsigned int best_err)
  8884. {
  8885. unsigned int err_this_table_upper;
  8886. unsigned int err_this_table_lower;
  8887. unsigned int err_this_table_left;
  8888. unsigned int err_this_table_right;
  8889. int orig[3],approx[4];
  8890. int err[4];
  8891. err_upper = 3*255*255*16;
  8892. err_lower = 3*255*255*16;
  8893. err_left = 3*255*255*16;
  8894. err_right = 3*255*255*16;
  8895. #define ONE_PIXEL_UL(table_nbr,xx)\
  8896. orig[0]=block_2x2[xx*4];\
  8897. orig[1]=block_2x2[xx*4+1];\
  8898. orig[2]=block_2x2[xx*4+2];\
  8899. /* unrolled loop for(index=0;index<4;index++)*/\
  8900. err[0]=precalc_err_UL_RG[table_nbr*4*4+xx*4+0] + square_table[approx[0]-orig[2]];\
  8901. err[1]=precalc_err_UL_RG[table_nbr*4*4+xx*4+1] + square_table[approx[1]-orig[2]];\
  8902. err[2]=precalc_err_UL_RG[table_nbr*4*4+xx*4+2] + square_table[approx[2]-orig[2]];\
  8903. err[3]=precalc_err_UL_RG[table_nbr*4*4+xx*4+3] + square_table[approx[3]-orig[2]];\
  8904. /* end unrolled loop*/\
  8905. if(err[0] > err[1])\
  8906. err[0] = err[1];\
  8907. if(err[2] > err[3])\
  8908. err[2] = err[3];\
  8909. if(err[0] > err[2])\
  8910. err[0] = err[2];\
  8911. err_this_table_upper+=err[0];\
  8912. err_this_table_left+=err[0];\
  8913. #define ONE_PIXEL_UR(table_nbr,xx)\
  8914. orig[0]=block_2x2[xx*4];\
  8915. orig[1]=block_2x2[xx*4+1];\
  8916. orig[2]=block_2x2[xx*4+2];\
  8917. /* unrolled loop for(index=0;index<4;index++)*/\
  8918. err[0]=precalc_err_UR_RG[table_nbr*4*4+(xx-4)*4+0] + square_table[approx[0]-orig[2]];\
  8919. err[1]=precalc_err_UR_RG[table_nbr*4*4+(xx-4)*4+1] + square_table[approx[1]-orig[2]];\
  8920. err[2]=precalc_err_UR_RG[table_nbr*4*4+(xx-4)*4+2] + square_table[approx[2]-orig[2]];\
  8921. err[3]=precalc_err_UR_RG[table_nbr*4*4+(xx-4)*4+3] + square_table[approx[3]-orig[2]];\
  8922. /* end unrolled loop */\
  8923. if(err[0] > err[1])\
  8924. err[0] = err[1];\
  8925. if(err[2] > err[3])\
  8926. err[2] = err[3];\
  8927. if(err[0] > err[2])\
  8928. err[0] = err[2];\
  8929. err_this_table_upper+=err[0];\
  8930. err_this_table_right+=err[0];
  8931. #define ONE_PIXEL_LL(table_nbr,xx)\
  8932. orig[0]=block_2x2[xx*4];\
  8933. orig[1]=block_2x2[xx*4+1];\
  8934. orig[2]=block_2x2[xx*4+2];\
  8935. /* unrolled loop for(index=0;index<4;index++)*/\
  8936. err[0]=precalc_err_LL_RG[table_nbr*4*4+(xx-8)*4+0] + square_table[approx[0]-orig[2]];\
  8937. err[1]=precalc_err_LL_RG[table_nbr*4*4+(xx-8)*4+1] + square_table[approx[1]-orig[2]];\
  8938. err[2]=precalc_err_LL_RG[table_nbr*4*4+(xx-8)*4+2] + square_table[approx[2]-orig[2]];\
  8939. err[3]=precalc_err_LL_RG[table_nbr*4*4+(xx-8)*4+3] + square_table[approx[3]-orig[2]];\
  8940. /* end unrolled loop*/\
  8941. if(err[0] > err[1])\
  8942. err[0] = err[1];\
  8943. if(err[2] > err[3])\
  8944. err[2] = err[3];\
  8945. if(err[0] > err[2])\
  8946. err[0] = err[2];\
  8947. err_this_table_lower+=err[0];\
  8948. err_this_table_left+=err[0];\
  8949. #define ONE_PIXEL_LR(table_nbr,xx)\
  8950. orig[0]=block_2x2[xx*4];\
  8951. orig[1]=block_2x2[xx*4+1];\
  8952. orig[2]=block_2x2[xx*4+2];\
  8953. /* unrolled loop for(index=0;index<4;index++)*/\
  8954. err[0]=precalc_err_LR_RG[table_nbr*4*4+(xx-12)*4+0] + square_table[approx[0]-orig[2]];\
  8955. err[1]=precalc_err_LR_RG[table_nbr*4*4+(xx-12)*4+1] + square_table[approx[1]-orig[2]];\
  8956. err[2]=precalc_err_LR_RG[table_nbr*4*4+(xx-12)*4+2] + square_table[approx[2]-orig[2]];\
  8957. err[3]=precalc_err_LR_RG[table_nbr*4*4+(xx-12)*4+3] + square_table[approx[3]-orig[2]];\
  8958. /* end unrolled loop*/\
  8959. if(err[0] > err[1])\
  8960. err[0] = err[1];\
  8961. if(err[2] > err[3])\
  8962. err[2] = err[3];\
  8963. if(err[0] > err[2])\
  8964. err[0] = err[2];\
  8965. err_this_table_lower+=err[0];\
  8966. err_this_table_right+=err[0];\
  8967. #define ONE_TABLE_3(table_nbr)\
  8968. err_this_table_upper = 0;\
  8969. err_this_table_lower = 0;\
  8970. err_this_table_left = 0;\
  8971. err_this_table_right = 0;\
  8972. approx[0]=clamp_table_plus_255[color_quant1[2]+compressParamsFast[table_nbr*4+0]+255];\
  8973. approx[1]=clamp_table_plus_255[color_quant1[2]+compressParamsFast[table_nbr*4+1]+255];\
  8974. approx[2]=clamp_table_plus_255[color_quant1[2]+compressParamsFast[table_nbr*4+2]+255];\
  8975. approx[3]=clamp_table_plus_255[color_quant1[2]+compressParamsFast[table_nbr*4+3]+255];\
  8976. /* unroll loop for(xx=0; xx<4; xx++) */\
  8977. ONE_PIXEL_UL(table_nbr,0)\
  8978. ONE_PIXEL_UL(table_nbr,1)\
  8979. ONE_PIXEL_UL(table_nbr,2)\
  8980. ONE_PIXEL_UL(table_nbr,3)\
  8981. /* end unroll loop */\
  8982. /* unroll loop for(xx=4; xx<8; xx++) */\
  8983. ONE_PIXEL_LR(table_nbr,12)\
  8984. ONE_PIXEL_LR(table_nbr,13)\
  8985. ONE_PIXEL_LR(table_nbr,14)\
  8986. ONE_PIXEL_LR(table_nbr,15)\
  8987. /* end unroll loop */\
  8988. /* If error in the top left 2x2 pixel area is already larger than the best error, and */\
  8989. /* The same is true for the bottom right 2x2 pixel area, this combination of table and color */\
  8990. /* can never be part of an optimal solution and therefore we do not need to test the other */\
  8991. /* two 2x2 pixel areas */\
  8992. if((err_this_table_upper<best_err)||(err_this_table_lower<best_err))\
  8993. {\
  8994. /* unroll loop for(xx=4; xx<8; xx++) */\
  8995. ONE_PIXEL_UR(table_nbr,4)\
  8996. ONE_PIXEL_UR(table_nbr,5)\
  8997. ONE_PIXEL_UR(table_nbr,6)\
  8998. ONE_PIXEL_UR(table_nbr,7)\
  8999. /* end unroll loop */\
  9000. /* unroll loop for(xx=4; xx<8; xx++) */\
  9001. ONE_PIXEL_LL(table_nbr,8)\
  9002. ONE_PIXEL_LL(table_nbr,9)\
  9003. ONE_PIXEL_LL(table_nbr,10)\
  9004. ONE_PIXEL_LL(table_nbr,11)\
  9005. /* end unroll loop */\
  9006. if(err_this_table_upper<err_upper)\
  9007. err_upper = err_this_table_upper;\
  9008. if(err_this_table_lower<err_lower)\
  9009. err_lower = err_this_table_lower;\
  9010. if(err_this_table_left<err_left)\
  9011. err_left = err_this_table_left;\
  9012. if(err_this_table_right<err_right)\
  9013. err_right = err_this_table_right;\
  9014. }\
  9015. /*unroll loop for(table_nbr=0;table_nbr<8;table_nbr++)*/
  9016. ONE_TABLE_3(0);
  9017. ONE_TABLE_3(1);
  9018. ONE_TABLE_3(2);
  9019. ONE_TABLE_3(3);
  9020. ONE_TABLE_3(4);
  9021. ONE_TABLE_3(5);
  9022. ONE_TABLE_3(6);
  9023. ONE_TABLE_3(7);
  9024. /*end unroll loop*/
  9025. }
  9026. #endif
  9027. #if EXHAUSTIVE_CODE_ACTIVE
  9028. // Tries all index-tables, used when compressing a block exhaustively using perceptual error measure
  9029. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  9030. inline void tryalltables_3bittable_all_subblocks_using_precalc_perceptual1000(uint8 *block_2x2,uint8 *color_quant1, unsigned int *precalc_err_UL_RG, unsigned int *precalc_err_UR_RG, unsigned int *precalc_err_LL_RG, unsigned int *precalc_err_LR_RG, unsigned int &err_upper, unsigned int &err_lower, unsigned int &err_left, unsigned int &err_right, unsigned int best_err)
  9031. {
  9032. unsigned int err_this_table_upper;
  9033. unsigned int err_this_table_lower;
  9034. unsigned int err_this_table_left;
  9035. unsigned int err_this_table_right;
  9036. int orig[3],approx[4];
  9037. int err[4];
  9038. err_upper = MAXERR1000;
  9039. err_lower = MAXERR1000;
  9040. err_left = MAXERR1000;
  9041. err_right =MAXERR1000;
  9042. #define ONE_PIXEL_UL_PERCEP(table_nbr,xx)\
  9043. orig[0]=block_2x2[xx*4];\
  9044. orig[1]=block_2x2[xx*4+1];\
  9045. orig[2]=block_2x2[xx*4+2];\
  9046. /* unrolled loop for(index=0;index<4;index++)*/\
  9047. err[0]=precalc_err_UL_RG[table_nbr*4*4+xx*4+0] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[0]-orig[2]];\
  9048. err[1]=precalc_err_UL_RG[table_nbr*4*4+xx*4+1] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[1]-orig[2]];\
  9049. err[2]=precalc_err_UL_RG[table_nbr*4*4+xx*4+2] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[2]-orig[2]];\
  9050. err[3]=precalc_err_UL_RG[table_nbr*4*4+xx*4+3] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[3]-orig[2]];\
  9051. /* end unrolled loop*/\
  9052. if(err[0] > err[1])\
  9053. err[0] = err[1];\
  9054. if(err[2] > err[3])\
  9055. err[2] = err[3];\
  9056. if(err[0] > err[2])\
  9057. err[0] = err[2];\
  9058. err_this_table_upper+=err[0];\
  9059. err_this_table_left+=err[0];\
  9060. #define ONE_PIXEL_UR_PERCEP(table_nbr,xx)\
  9061. orig[0]=block_2x2[xx*4];\
  9062. orig[1]=block_2x2[xx*4+1];\
  9063. orig[2]=block_2x2[xx*4+2];\
  9064. /* unrolled loop for(index=0;index<4;index++)*/\
  9065. err[0]=precalc_err_UR_RG[table_nbr*4*4+(xx-4)*4+0] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[0]-orig[2]];\
  9066. err[1]=precalc_err_UR_RG[table_nbr*4*4+(xx-4)*4+1] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[1]-orig[2]];\
  9067. err[2]=precalc_err_UR_RG[table_nbr*4*4+(xx-4)*4+2] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[2]-orig[2]];\
  9068. err[3]=precalc_err_UR_RG[table_nbr*4*4+(xx-4)*4+3] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[3]-orig[2]];\
  9069. /* end unrolled loop */\
  9070. if(err[0] > err[1])\
  9071. err[0] = err[1];\
  9072. if(err[2] > err[3])\
  9073. err[2] = err[3];\
  9074. if(err[0] > err[2])\
  9075. err[0] = err[2];\
  9076. err_this_table_upper+=err[0];\
  9077. err_this_table_right+=err[0];
  9078. #define ONE_PIXEL_LL_PERCEP(table_nbr,xx)\
  9079. orig[0]=block_2x2[xx*4];\
  9080. orig[1]=block_2x2[xx*4+1];\
  9081. orig[2]=block_2x2[xx*4+2];\
  9082. /* unrolled loop for(index=0;index<4;index++)*/\
  9083. err[0]=precalc_err_LL_RG[table_nbr*4*4+(xx-8)*4+0] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[0]-orig[2]];\
  9084. err[1]=precalc_err_LL_RG[table_nbr*4*4+(xx-8)*4+1] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[1]-orig[2]];\
  9085. err[2]=precalc_err_LL_RG[table_nbr*4*4+(xx-8)*4+2] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[2]-orig[2]];\
  9086. err[3]=precalc_err_LL_RG[table_nbr*4*4+(xx-8)*4+3] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[3]-orig[2]];\
  9087. /* end unrolled loop*/\
  9088. if(err[0] > err[1])\
  9089. err[0] = err[1];\
  9090. if(err[2] > err[3])\
  9091. err[2] = err[3];\
  9092. if(err[0] > err[2])\
  9093. err[0] = err[2];\
  9094. err_this_table_lower+=err[0];\
  9095. err_this_table_left+=err[0];\
  9096. #define ONE_PIXEL_LR_PERCEP(table_nbr,xx)\
  9097. orig[0]=block_2x2[xx*4];\
  9098. orig[1]=block_2x2[xx*4+1];\
  9099. orig[2]=block_2x2[xx*4+2];\
  9100. /* unrolled loop for(index=0;index<4;index++)*/\
  9101. err[0]=precalc_err_LR_RG[table_nbr*4*4+(xx-12)*4+0] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[0]-orig[2]];\
  9102. err[1]=precalc_err_LR_RG[table_nbr*4*4+(xx-12)*4+1] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[1]-orig[2]];\
  9103. err[2]=precalc_err_LR_RG[table_nbr*4*4+(xx-12)*4+2] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[2]-orig[2]];\
  9104. err[3]=precalc_err_LR_RG[table_nbr*4*4+(xx-12)*4+3] + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[approx[3]-orig[2]];\
  9105. /* end unrolled loop*/\
  9106. if(err[0] > err[1])\
  9107. err[0] = err[1];\
  9108. if(err[2] > err[3])\
  9109. err[2] = err[3];\
  9110. if(err[0] > err[2])\
  9111. err[0] = err[2];\
  9112. err_this_table_lower+=err[0];\
  9113. err_this_table_right+=err[0];\
  9114. #define ONE_TABLE_3_PERCEP(table_nbr)\
  9115. err_this_table_upper = 0;\
  9116. err_this_table_lower = 0;\
  9117. err_this_table_left = 0;\
  9118. err_this_table_right = 0;\
  9119. approx[0]=clamp_table_plus_255[color_quant1[2]+compressParamsFast[table_nbr*4+0]+255];\
  9120. approx[1]=clamp_table_plus_255[color_quant1[2]+compressParamsFast[table_nbr*4+1]+255];\
  9121. approx[2]=clamp_table_plus_255[color_quant1[2]+compressParamsFast[table_nbr*4+2]+255];\
  9122. approx[3]=clamp_table_plus_255[color_quant1[2]+compressParamsFast[table_nbr*4+3]+255];\
  9123. /* unroll loop for(xx=0; xx<4; xx++) */\
  9124. ONE_PIXEL_UL_PERCEP(table_nbr,0)\
  9125. ONE_PIXEL_UL_PERCEP(table_nbr,1)\
  9126. ONE_PIXEL_UL_PERCEP(table_nbr,2)\
  9127. ONE_PIXEL_UL_PERCEP(table_nbr,3)\
  9128. /* end unroll loop */\
  9129. /* unroll loop for(xx=4; xx<8; xx++) */\
  9130. ONE_PIXEL_LR_PERCEP(table_nbr,12)\
  9131. ONE_PIXEL_LR_PERCEP(table_nbr,13)\
  9132. ONE_PIXEL_LR_PERCEP(table_nbr,14)\
  9133. ONE_PIXEL_LR_PERCEP(table_nbr,15)\
  9134. /* end unroll loop */\
  9135. /* If error in the top left 2x2 pixel area is already larger than the best error, and */\
  9136. /* The same is true for the bottom right 2x2 pixel area, this combination of table and color */\
  9137. /* can never be part of an optimal solution and therefore we do not need to test the other */\
  9138. /* two 2x2 pixel areas */\
  9139. if((err_this_table_upper<best_err)||(err_this_table_lower<best_err))\
  9140. {\
  9141. /* unroll loop for(xx=4; xx<8; xx++) */\
  9142. ONE_PIXEL_UR_PERCEP(table_nbr,4)\
  9143. ONE_PIXEL_UR_PERCEP(table_nbr,5)\
  9144. ONE_PIXEL_UR_PERCEP(table_nbr,6)\
  9145. ONE_PIXEL_UR_PERCEP(table_nbr,7)\
  9146. /* end unroll loop */\
  9147. /* unroll loop for(xx=4; xx<8; xx++) */\
  9148. ONE_PIXEL_LL_PERCEP(table_nbr,8)\
  9149. ONE_PIXEL_LL_PERCEP(table_nbr,9)\
  9150. ONE_PIXEL_LL_PERCEP(table_nbr,10)\
  9151. ONE_PIXEL_LL_PERCEP(table_nbr,11)\
  9152. /* end unroll loop */\
  9153. if(err_this_table_upper<err_upper)\
  9154. err_upper = err_this_table_upper;\
  9155. if(err_this_table_lower<err_lower)\
  9156. err_lower = err_this_table_lower;\
  9157. if(err_this_table_left<err_left)\
  9158. err_left = err_this_table_left;\
  9159. if(err_this_table_right<err_right)\
  9160. err_right = err_this_table_right;\
  9161. }\
  9162. /*unroll loop for(table_nbr=0;table_nbr<8;table_nbr++)*/
  9163. ONE_TABLE_3_PERCEP(0);
  9164. ONE_TABLE_3_PERCEP(1);
  9165. ONE_TABLE_3_PERCEP(2);
  9166. ONE_TABLE_3_PERCEP(3);
  9167. ONE_TABLE_3_PERCEP(4);
  9168. ONE_TABLE_3_PERCEP(5);
  9169. ONE_TABLE_3_PERCEP(6);
  9170. ONE_TABLE_3_PERCEP(7);
  9171. /*end unroll loop*/
  9172. }
  9173. #endif
  9174. #if EXHAUSTIVE_CODE_ACTIVE
  9175. // Compresses the individual mode exhaustively (perecptual error metric).
  9176. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  9177. unsigned int compressBlockIndividualExhaustivePerceptual(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2, unsigned int total_best_err)
  9178. {
  9179. unsigned int best_err_norm_diff = MAXERR1000;
  9180. unsigned int best_err_norm_444 = MAXERR1000;
  9181. unsigned int best_err_flip_diff = MAXERR1000;
  9182. unsigned int best_err_flip_444 = MAXERR1000;
  9183. uint8 color_quant1[3], color_quant2[3];
  9184. int enc_color1[3];
  9185. int best_enc_color1[3], best_enc_color2[3];
  9186. int min_error=MAXERR1000;
  9187. unsigned int best_pixel_indices1_MSB=0;
  9188. unsigned int best_pixel_indices1_LSB=0;
  9189. unsigned int best_pixel_indices2_MSB=0;
  9190. unsigned int best_pixel_indices2_LSB=0;
  9191. unsigned int pixel_indices1_MSB=0;
  9192. unsigned int pixel_indices1_LSB=0;
  9193. unsigned int pixel_indices2_MSB=0;
  9194. unsigned int err_upper, err_lower;
  9195. unsigned int err_left, err_right;
  9196. unsigned int pixel_indices2_LSB=0;
  9197. unsigned int best_err_upper = MAXERR1000;
  9198. unsigned int best_err_lower = MAXERR1000;
  9199. unsigned int best_err_left = MAXERR1000;
  9200. unsigned int best_err_right = MAXERR1000;
  9201. int best_upper_col[3];
  9202. int best_lower_col[3];
  9203. int best_left_col[3];
  9204. int best_right_col[3];
  9205. unsigned int table1=0, table2=0;
  9206. unsigned int best_table1=0, best_table2=0;
  9207. unsigned int precalc_err_UL_R[8*4*4];
  9208. unsigned int precalc_err_UR_R[8*4*4];
  9209. unsigned int precalc_err_LL_R[8*4*4];
  9210. unsigned int precalc_err_LR_R[8*4*4];
  9211. unsigned int precalc_err_UL_RG[8*4*4];
  9212. unsigned int precalc_err_UR_RG[8*4*4];
  9213. unsigned int precalc_err_LL_RG[8*4*4];
  9214. unsigned int precalc_err_LR_RG[8*4*4];
  9215. int diffbit;
  9216. uint8 block_2x2[4*4*4];
  9217. unsigned int best_err;
  9218. int best_flip;
  9219. int xx,yy,count = 0;
  9220. // Reshuffle pixels so that the top left 2x2 pixels arrive first, then the top right 2x2 pixels etc. Also put use 4 bytes per pixel to make it 32-word aligned.
  9221. for(xx = 0; xx<2; xx++)
  9222. {
  9223. for(yy=0; yy<2; yy++)
  9224. {
  9225. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  9226. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  9227. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  9228. block_2x2[(count)*4+3] = 0;
  9229. count++;
  9230. }
  9231. }
  9232. for(xx = 2; xx<4; xx++)
  9233. {
  9234. for(yy=0; yy<2; yy++)
  9235. {
  9236. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  9237. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  9238. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  9239. block_2x2[(count)*4+3] = 0;
  9240. count++;
  9241. }
  9242. }
  9243. for(xx = 0; xx<2; xx++)
  9244. {
  9245. for(yy=2; yy<4; yy++)
  9246. {
  9247. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  9248. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  9249. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  9250. block_2x2[(count)*4+3] = 0;
  9251. count++;
  9252. }
  9253. }
  9254. for(xx = 2; xx<4; xx++)
  9255. {
  9256. for(yy=2; yy<4; yy++)
  9257. {
  9258. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  9259. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  9260. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  9261. block_2x2[(count)*4+3] = 0;
  9262. count++;
  9263. }
  9264. }
  9265. unsigned int test1, test2;
  9266. best_err = (unsigned int)compressBlockOnlyIndividualAveragePerceptual1000(img, width, height, startx, starty, test1, test2, best_enc_color1, best_enc_color2, best_flip, best_err_upper, best_err_lower, best_err_left, best_err_right, best_upper_col, best_lower_col, best_left_col, best_right_col);
  9267. if(best_err < total_best_err)
  9268. total_best_err = best_err;
  9269. unsigned int tryblocks = 0;
  9270. unsigned int allblocks = 0;
  9271. int needtest;
  9272. for(enc_color1[0]=0; enc_color1[0]<16; enc_color1[0]++)
  9273. {
  9274. color_quant1[0] = enc_color1[0] << 4 | (enc_color1[0]);
  9275. if(precompute_3bittable_all_subblocksR_with_test_perceptual1000(block_2x2, color_quant1, precalc_err_UL_R, precalc_err_UR_R, precalc_err_LL_R, precalc_err_LR_R, total_best_err))
  9276. {
  9277. for(enc_color1[1]=0; enc_color1[1]<16; enc_color1[1]++)
  9278. {
  9279. color_quant1[1] = enc_color1[1] << 4 | (enc_color1[1]);
  9280. if(precompute_3bittable_all_subblocksRG_withtest_perceptual1000(block_2x2, color_quant1, precalc_err_UL_R, precalc_err_UR_R, precalc_err_LL_R, precalc_err_LR_R, precalc_err_UL_RG, precalc_err_UR_RG, precalc_err_LL_RG, precalc_err_LR_RG, total_best_err))
  9281. {
  9282. needtest = false;
  9283. for(enc_color1[2]=0; enc_color1[2]<16; enc_color1[2]++)
  9284. {
  9285. color_quant1[2] = enc_color1[2] << 4 | (enc_color1[2]);
  9286. tryalltables_3bittable_all_subblocks_using_precalc_perceptual1000(block_2x2, color_quant1, precalc_err_UL_RG, precalc_err_UR_RG, precalc_err_LL_RG, precalc_err_LR_RG, err_upper, err_lower, err_left, err_right, total_best_err);
  9287. if(err_upper<best_err_upper)
  9288. {
  9289. best_err_upper = err_upper;
  9290. best_upper_col[0] = enc_color1[0];
  9291. best_upper_col[1] = enc_color1[1];
  9292. best_upper_col[2] = enc_color1[2];
  9293. needtest = true;
  9294. }
  9295. if(err_lower<best_err_lower)
  9296. {
  9297. best_err_lower = err_lower;
  9298. best_lower_col[0] = enc_color1[0];
  9299. best_lower_col[1] = enc_color1[1];
  9300. best_lower_col[2] = enc_color1[2];
  9301. needtest=true;
  9302. }
  9303. if(err_left<best_err_left)
  9304. {
  9305. best_err_left = err_left;
  9306. best_left_col[0] = enc_color1[0];
  9307. best_left_col[1] = enc_color1[1];
  9308. best_left_col[2] = enc_color1[2];
  9309. needtest=true;
  9310. }
  9311. if(err_right<best_err_right)
  9312. {
  9313. best_err_right = err_right;
  9314. best_right_col[0] = enc_color1[0];
  9315. best_right_col[1] = enc_color1[1];
  9316. best_right_col[2] = enc_color1[2];
  9317. needtest = true;
  9318. }
  9319. }
  9320. if(needtest)
  9321. {
  9322. if(best_err_upper+best_err_lower < best_err_left+best_err_right)
  9323. {
  9324. best_err = best_err_upper+best_err_lower;
  9325. if(best_err < total_best_err)
  9326. total_best_err = best_err;
  9327. }
  9328. else
  9329. {
  9330. best_err = best_err_left+best_err_right;
  9331. if(best_err < total_best_err)
  9332. total_best_err = best_err;
  9333. }
  9334. }
  9335. }
  9336. }
  9337. }
  9338. }
  9339. if(best_err_upper+best_err_lower < best_err_left+best_err_right)
  9340. {
  9341. best_flip = 1;
  9342. best_enc_color1[0] = best_upper_col[0];
  9343. best_enc_color1[1] = best_upper_col[1];
  9344. best_enc_color1[2] = best_upper_col[2];
  9345. best_enc_color2[0] = best_lower_col[0];
  9346. best_enc_color2[1] = best_lower_col[1];
  9347. best_enc_color2[2] = best_lower_col[2];
  9348. best_err = best_err_upper+best_err_lower;
  9349. if(best_err < total_best_err)
  9350. total_best_err = best_err;
  9351. }
  9352. else
  9353. {
  9354. best_flip = 0;
  9355. best_enc_color1[0] = best_left_col[0];
  9356. best_enc_color1[1] = best_left_col[1];
  9357. best_enc_color1[2] = best_left_col[2];
  9358. best_enc_color2[0] = best_right_col[0];
  9359. best_enc_color2[1] = best_right_col[1];
  9360. best_enc_color2[2] = best_right_col[2];
  9361. best_err = best_err_left+best_err_right;
  9362. if(best_err < total_best_err)
  9363. total_best_err = best_err;
  9364. }
  9365. color_quant1[0] = best_enc_color1[0] << 4 | (best_enc_color1[0]);
  9366. color_quant1[1] = best_enc_color1[1] << 4 | (best_enc_color1[1]);
  9367. color_quant1[2] = best_enc_color1[2] << 4 | (best_enc_color1[2]);
  9368. if(best_flip == 0)
  9369. tryalltables_3bittable2x4percep1000(img,width,height,startx,starty,color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  9370. else
  9371. tryalltables_3bittable4x2percep1000(img,width,height,startx,starty,color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  9372. color_quant2[0] = best_enc_color2[0] << 4 | (best_enc_color2[0]);
  9373. color_quant2[1] = best_enc_color2[1] << 4 | (best_enc_color2[1]);
  9374. color_quant2[2] = best_enc_color2[2] << 4 | (best_enc_color2[2]);
  9375. if(best_flip == 0)
  9376. tryalltables_3bittable2x4percep1000(img,width,height,startx+2,starty,color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  9377. else
  9378. tryalltables_3bittable4x2percep1000(img,width,height,startx,starty+2,color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  9379. // ETC1_RGB8_OES:
  9380. //
  9381. // a) bit layout in bits 63 through 32 if diffbit = 0
  9382. //
  9383. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  9384. // ---------------------------------------------------------------------------------------------------
  9385. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  9386. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  9387. // ---------------------------------------------------------------------------------------------------
  9388. //
  9389. // b) bit layout in bits 63 through 32 if diffbit = 1
  9390. //
  9391. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  9392. // ---------------------------------------------------------------------------------------------------
  9393. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |diff|flip|
  9394. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
  9395. // ---------------------------------------------------------------------------------------------------
  9396. //
  9397. // c) bit layout in bits 31 through 0 (in both cases)
  9398. //
  9399. // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  9400. // --------------------------------------------------------------------------------------------------
  9401. // | most significant pixel index bits | least significant pixel index bits |
  9402. // | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a| p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
  9403. // --------------------------------------------------------------------------------------------------
  9404. diffbit = 1;
  9405. compressed1 = 0;
  9406. PUTBITSHIGH( compressed1, diffbit, 0, 33);
  9407. PUTBITSHIGH( compressed1, best_enc_color1[0], 4, 63);
  9408. PUTBITSHIGH( compressed1, best_enc_color1[1], 4, 55);
  9409. PUTBITSHIGH( compressed1, best_enc_color1[2], 4, 47);
  9410. PUTBITSHIGH( compressed1, best_enc_color2[0], 4, 59);
  9411. PUTBITSHIGH( compressed1, best_enc_color2[1], 4, 51);
  9412. PUTBITSHIGH( compressed1, best_enc_color2[2], 4, 43);
  9413. PUTBITSHIGH( compressed1, best_table1, 3, 39);
  9414. PUTBITSHIGH( compressed1, best_table2, 3, 36);
  9415. PUTBITSHIGH( compressed1, best_flip, 1, 32);
  9416. if(best_flip == 0)
  9417. {
  9418. compressed2 = 0;
  9419. PUTBITS( compressed2, (best_pixel_indices1_MSB ), 8, 23);
  9420. PUTBITS( compressed2, (best_pixel_indices2_MSB ), 8, 31);
  9421. PUTBITS( compressed2, (best_pixel_indices1_LSB ), 8, 7);
  9422. PUTBITS( compressed2, (best_pixel_indices2_LSB ), 8, 15);
  9423. }
  9424. else
  9425. {
  9426. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  9427. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  9428. compressed2 = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  9429. }
  9430. return best_err;
  9431. }
  9432. #endif
  9433. #if EXHAUSTIVE_CODE_ACTIVE
  9434. // Compresses the individual mode exhaustively.
  9435. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  9436. unsigned int compressBlockIndividualExhaustive(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2, unsigned int total_best_err)
  9437. {
  9438. unsigned int best_err_norm_diff = 255*255*16*3;
  9439. unsigned int best_err_norm_444 = 255*255*16*3;
  9440. unsigned int best_err_flip_diff = 255*255*16*3;
  9441. unsigned int best_err_flip_444 = 255*255*16*3;
  9442. uint8 color_quant1[3], color_quant2[3];
  9443. int enc_color1[3];
  9444. int best_enc_color1[3], best_enc_color2[3];
  9445. int min_error=255*255*8*3;
  9446. unsigned int best_pixel_indices1_MSB=0;
  9447. unsigned int best_pixel_indices1_LSB=0;
  9448. unsigned int best_pixel_indices2_MSB=0;
  9449. unsigned int best_pixel_indices2_LSB=0;
  9450. unsigned int pixel_indices1_MSB=0;
  9451. unsigned int pixel_indices1_LSB=0;
  9452. unsigned int pixel_indices2_MSB=0;
  9453. unsigned int err_upper, err_lower;
  9454. unsigned int err_left, err_right;
  9455. unsigned int pixel_indices2_LSB=0;
  9456. unsigned int best_err_upper = 255*255*16*3;
  9457. unsigned int best_err_lower = 255*255*16*3;
  9458. unsigned int best_err_left = 255*255*16*3;
  9459. unsigned int best_err_right = 255*255*16*3;
  9460. int best_upper_col[3];
  9461. int best_lower_col[3];
  9462. int best_left_col[3];
  9463. int best_right_col[3];
  9464. unsigned int table1=0, table2=0;
  9465. unsigned int best_table1=0, best_table2=0;
  9466. unsigned int precalc_err_UL_R[8*4*4];
  9467. unsigned int precalc_err_UR_R[8*4*4];
  9468. unsigned int precalc_err_LL_R[8*4*4];
  9469. unsigned int precalc_err_LR_R[8*4*4];
  9470. unsigned int precalc_err_UL_RG[8*4*4];
  9471. unsigned int precalc_err_UR_RG[8*4*4];
  9472. unsigned int precalc_err_LL_RG[8*4*4];
  9473. unsigned int precalc_err_LR_RG[8*4*4];
  9474. int diffbit;
  9475. uint8 block_2x2[4*4*4];
  9476. unsigned int best_err;
  9477. int best_flip;
  9478. int xx,yy,count = 0;
  9479. // Reshuffle pixels so that the top left 2x2 pixels arrive first, then the top right 2x2 pixels etc. Also put use 4 bytes per pixel to make it 32-word aligned.
  9480. for(xx = 0; xx<2; xx++)
  9481. {
  9482. for(yy=0; yy<2; yy++)
  9483. {
  9484. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  9485. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  9486. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  9487. block_2x2[(count)*4+3] = 0;
  9488. count++;
  9489. }
  9490. }
  9491. for(xx = 2; xx<4; xx++)
  9492. {
  9493. for(yy=0; yy<2; yy++)
  9494. {
  9495. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  9496. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  9497. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  9498. block_2x2[(count)*4+3] = 0;
  9499. count++;
  9500. }
  9501. }
  9502. for(xx = 0; xx<2; xx++)
  9503. {
  9504. for(yy=2; yy<4; yy++)
  9505. {
  9506. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  9507. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  9508. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  9509. block_2x2[(count)*4+3] = 0;
  9510. count++;
  9511. }
  9512. }
  9513. for(xx = 2; xx<4; xx++)
  9514. {
  9515. for(yy=2; yy<4; yy++)
  9516. {
  9517. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  9518. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  9519. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  9520. block_2x2[(count)*4+3] = 0;
  9521. count++;
  9522. }
  9523. }
  9524. unsigned int test1, test2;
  9525. best_err = (unsigned int)compressBlockOnlyIndividualAverage(img, width, height, startx, starty, test1, test2, best_enc_color1, best_enc_color2, best_flip, best_err_upper, best_err_lower, best_err_left, best_err_right, best_upper_col, best_lower_col, best_left_col, best_right_col);
  9526. if(best_err < total_best_err)
  9527. total_best_err = best_err;
  9528. unsigned int tryblocks = 0;
  9529. unsigned int allblocks = 0;
  9530. int needtest;
  9531. for(enc_color1[0]=0; enc_color1[0]<16; enc_color1[0]++)
  9532. {
  9533. color_quant1[0] = enc_color1[0] << 4 | (enc_color1[0]);
  9534. if(precompute_3bittable_all_subblocksR_with_test(block_2x2, color_quant1, precalc_err_UL_R, precalc_err_UR_R, precalc_err_LL_R, precalc_err_LR_R, total_best_err))
  9535. {
  9536. for(enc_color1[1]=0; enc_color1[1]<16; enc_color1[1]++)
  9537. {
  9538. color_quant1[1] = enc_color1[1] << 4 | (enc_color1[1]);
  9539. if(precompute_3bittable_all_subblocksRG_withtest(block_2x2, color_quant1, precalc_err_UL_R, precalc_err_UR_R, precalc_err_LL_R, precalc_err_LR_R, precalc_err_UL_RG, precalc_err_UR_RG, precalc_err_LL_RG, precalc_err_LR_RG, total_best_err))
  9540. {
  9541. needtest = false;
  9542. for(enc_color1[2]=0; enc_color1[2]<16; enc_color1[2]++)
  9543. {
  9544. color_quant1[2] = enc_color1[2] << 4 | (enc_color1[2]);
  9545. tryalltables_3bittable_all_subblocks_using_precalc(block_2x2, color_quant1, precalc_err_UL_RG, precalc_err_UR_RG, precalc_err_LL_RG, precalc_err_LR_RG, err_upper, err_lower, err_left, err_right, total_best_err);
  9546. if(err_upper<best_err_upper)
  9547. {
  9548. best_err_upper = err_upper;
  9549. best_upper_col[0] = enc_color1[0];
  9550. best_upper_col[1] = enc_color1[1];
  9551. best_upper_col[2] = enc_color1[2];
  9552. needtest = true;
  9553. }
  9554. if(err_lower<best_err_lower)
  9555. {
  9556. best_err_lower = err_lower;
  9557. best_lower_col[0] = enc_color1[0];
  9558. best_lower_col[1] = enc_color1[1];
  9559. best_lower_col[2] = enc_color1[2];
  9560. needtest=true;
  9561. }
  9562. if(err_left<best_err_left)
  9563. {
  9564. best_err_left = err_left;
  9565. best_left_col[0] = enc_color1[0];
  9566. best_left_col[1] = enc_color1[1];
  9567. best_left_col[2] = enc_color1[2];
  9568. needtest=true;
  9569. }
  9570. if(err_right<best_err_right)
  9571. {
  9572. best_err_right = err_right;
  9573. best_right_col[0] = enc_color1[0];
  9574. best_right_col[1] = enc_color1[1];
  9575. best_right_col[2] = enc_color1[2];
  9576. needtest = true;
  9577. }
  9578. }
  9579. if(needtest)
  9580. {
  9581. if(best_err_upper+best_err_lower < best_err_left+best_err_right)
  9582. {
  9583. best_err = best_err_upper+best_err_lower;
  9584. if(best_err < total_best_err)
  9585. total_best_err = best_err;
  9586. }
  9587. else
  9588. {
  9589. best_err = best_err_left+best_err_right;
  9590. if(best_err < total_best_err)
  9591. total_best_err = best_err;
  9592. }
  9593. }
  9594. }
  9595. }
  9596. }
  9597. }
  9598. if(best_err_upper+best_err_lower < best_err_left+best_err_right)
  9599. {
  9600. best_flip = 1;
  9601. best_enc_color1[0] = best_upper_col[0];
  9602. best_enc_color1[1] = best_upper_col[1];
  9603. best_enc_color1[2] = best_upper_col[2];
  9604. best_enc_color2[0] = best_lower_col[0];
  9605. best_enc_color2[1] = best_lower_col[1];
  9606. best_enc_color2[2] = best_lower_col[2];
  9607. best_err = best_err_upper+best_err_lower;
  9608. if(best_err < total_best_err)
  9609. total_best_err = best_err;
  9610. }
  9611. else
  9612. {
  9613. best_flip = 0;
  9614. best_enc_color1[0] = best_left_col[0];
  9615. best_enc_color1[1] = best_left_col[1];
  9616. best_enc_color1[2] = best_left_col[2];
  9617. best_enc_color2[0] = best_right_col[0];
  9618. best_enc_color2[1] = best_right_col[1];
  9619. best_enc_color2[2] = best_right_col[2];
  9620. best_err = best_err_left+best_err_right;
  9621. if(best_err < total_best_err)
  9622. total_best_err = best_err;
  9623. }
  9624. color_quant1[0] = best_enc_color1[0] << 4 | (best_enc_color1[0]);
  9625. color_quant1[1] = best_enc_color1[1] << 4 | (best_enc_color1[1]);
  9626. color_quant1[2] = best_enc_color1[2] << 4 | (best_enc_color1[2]);
  9627. if(best_flip == 0)
  9628. tryalltables_3bittable2x4(img,width,height,startx,starty,color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  9629. else
  9630. tryalltables_3bittable4x2(img,width,height,startx,starty,color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  9631. color_quant2[0] = best_enc_color2[0] << 4 | (best_enc_color2[0]);
  9632. color_quant2[1] = best_enc_color2[1] << 4 | (best_enc_color2[1]);
  9633. color_quant2[2] = best_enc_color2[2] << 4 | (best_enc_color2[2]);
  9634. if(best_flip == 0)
  9635. tryalltables_3bittable2x4(img,width,height,startx+2,starty,color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  9636. else
  9637. tryalltables_3bittable4x2(img,width,height,startx,starty+2,color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  9638. // ETC1_RGB8_OES:
  9639. //
  9640. // a) bit layout in bits 63 through 32 if diffbit = 0
  9641. //
  9642. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  9643. // ---------------------------------------------------------------------------------------------------
  9644. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  9645. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  9646. // ---------------------------------------------------------------------------------------------------
  9647. //
  9648. // b) bit layout in bits 63 through 32 if diffbit = 1
  9649. //
  9650. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  9651. // ---------------------------------------------------------------------------------------------------
  9652. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |diff|flip|
  9653. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
  9654. // ---------------------------------------------------------------------------------------------------
  9655. //
  9656. // c) bit layout in bits 31 through 0 (in both cases)
  9657. //
  9658. // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  9659. // --------------------------------------------------------------------------------------------------
  9660. // | most significant pixel index bits | least significant pixel index bits |
  9661. // | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a| p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
  9662. // --------------------------------------------------------------------------------------------------
  9663. diffbit = 1;
  9664. compressed1 = 0;
  9665. PUTBITSHIGH( compressed1, diffbit, 0, 33);
  9666. PUTBITSHIGH( compressed1, best_enc_color1[0], 4, 63);
  9667. PUTBITSHIGH( compressed1, best_enc_color1[1], 4, 55);
  9668. PUTBITSHIGH( compressed1, best_enc_color1[2], 4, 47);
  9669. PUTBITSHIGH( compressed1, best_enc_color2[0], 4, 59);
  9670. PUTBITSHIGH( compressed1, best_enc_color2[1], 4, 51);
  9671. PUTBITSHIGH( compressed1, best_enc_color2[2], 4, 43);
  9672. PUTBITSHIGH( compressed1, best_table1, 3, 39);
  9673. PUTBITSHIGH( compressed1, best_table2, 3, 36);
  9674. PUTBITSHIGH( compressed1, best_flip, 1, 32);
  9675. if(best_flip == 0)
  9676. {
  9677. compressed2 = 0;
  9678. PUTBITS( compressed2, (best_pixel_indices1_MSB ), 8, 23);
  9679. PUTBITS( compressed2, (best_pixel_indices2_MSB ), 8, 31);
  9680. PUTBITS( compressed2, (best_pixel_indices1_LSB ), 8, 7);
  9681. PUTBITS( compressed2, (best_pixel_indices2_LSB ), 8, 15);
  9682. }
  9683. else
  9684. {
  9685. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  9686. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  9687. compressed2 = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  9688. }
  9689. return best_err;
  9690. }
  9691. #endif
  9692. #if EXHAUSTIVE_CODE_ACTIVE
  9693. // Compresses the differential mode exhaustively (perecptual error metric).
  9694. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  9695. unsigned int compressBlockDifferentialExhaustivePerceptual(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2, unsigned int best_error_so_far)
  9696. {
  9697. unsigned int best_err_norm_diff = MAXERR1000;
  9698. unsigned int best_err_norm_444 = MAXERR1000;
  9699. unsigned int best_err_flip_diff = MAXERR1000;
  9700. unsigned int best_err_flip_444 = MAXERR1000;
  9701. uint8 color_quant1[3], color_quant2[3];
  9702. int enc_color1[3], enc_color2[3], diff[3];
  9703. int best_enc_color1[3], best_enc_color2[3];
  9704. signed char bytediff[3];
  9705. unsigned int best_pixel_indices1_MSB=0;
  9706. unsigned int best_pixel_indices1_LSB=0;
  9707. unsigned int best_pixel_indices2_MSB=0;
  9708. unsigned int best_pixel_indices2_LSB=0;
  9709. unsigned int pixel_indices1_MSB=0;
  9710. unsigned int pixel_indices1_LSB=0;
  9711. unsigned int pixel_indices2_MSB=0;
  9712. unsigned int *err_upper, *err_lower;
  9713. unsigned int *err_left, *err_right;
  9714. unsigned int pixel_indices2_LSB=0;
  9715. unsigned int table1=0, table2=0;
  9716. unsigned int best_table1=0, best_table2=0;
  9717. unsigned int precalc_err_UL_R[8*4*4];
  9718. unsigned int precalc_err_UR_R[8*4*4];
  9719. unsigned int precalc_err_LL_R[8*4*4];
  9720. unsigned int precalc_err_LR_R[8*4*4];
  9721. unsigned int precalc_err_UL_RG[8*4*4];
  9722. unsigned int precalc_err_UR_RG[8*4*4];
  9723. unsigned int precalc_err_LL_RG[8*4*4];
  9724. unsigned int precalc_err_LR_RG[8*4*4];
  9725. unsigned int best_error_using_diff_mode;
  9726. int diffbit;
  9727. uint8 block_2x2[4*4*4];
  9728. unsigned int error, error_lying, error_standing;
  9729. unsigned int *err_lower_adr;
  9730. int best_flip;
  9731. unsigned int *err_right_adr;
  9732. int xx,yy,count = 0;
  9733. // Reshuffle pixels so that the top left 2x2 pixels arrive first, then the top right 2x2 pixels etc. Also put use 4 bytes per pixel to make it 32-word aligned.
  9734. for(xx = 0; xx<2; xx++)
  9735. {
  9736. for(yy=0; yy<2; yy++)
  9737. {
  9738. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  9739. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  9740. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  9741. block_2x2[(count)*4+3] = 0;
  9742. count++;
  9743. }
  9744. }
  9745. for(xx = 2; xx<4; xx++)
  9746. {
  9747. for(yy=0; yy<2; yy++)
  9748. {
  9749. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  9750. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  9751. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  9752. block_2x2[(count)*4+3] = 0;
  9753. count++;
  9754. }
  9755. }
  9756. for(xx = 0; xx<2; xx++)
  9757. {
  9758. for(yy=2; yy<4; yy++)
  9759. {
  9760. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  9761. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  9762. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  9763. block_2x2[(count)*4+3] = 0;
  9764. count++;
  9765. }
  9766. }
  9767. for(xx = 2; xx<4; xx++)
  9768. {
  9769. for(yy=2; yy<4; yy++)
  9770. {
  9771. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  9772. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  9773. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  9774. block_2x2[(count)*4+3] = 0;
  9775. count++;
  9776. }
  9777. }
  9778. unsigned int test1, test2;
  9779. best_error_using_diff_mode = compressBlockOnlyDiffFlipAveragePerceptual1000(img, width, height, startx, starty, test1, test2);
  9780. if(best_error_using_diff_mode < best_error_so_far)
  9781. best_error_so_far = best_error_using_diff_mode;
  9782. // Decode the parameters so that we have a worst case color pair and a flip status
  9783. best_flip = test1 & 1;
  9784. best_enc_color1[0] = GETBITSHIGH( test1, 5, 63);
  9785. best_enc_color1[1] = GETBITSHIGH( test1, 5, 55);
  9786. best_enc_color1[2] = GETBITSHIGH( test1, 5, 47);
  9787. bytediff[0] = GETBITSHIGH( test1, 3, 58);
  9788. bytediff[1] = GETBITSHIGH( test1, 3, 50);
  9789. bytediff[2] = GETBITSHIGH( test1, 3, 42);
  9790. bytediff[0] = (bytediff[0] << 5);
  9791. bytediff[1] = (bytediff[1] << 5);
  9792. bytediff[2] = (bytediff[2] << 5);
  9793. bytediff[0] = bytediff[0] >> 5;
  9794. bytediff[1] = bytediff[1] >> 5;
  9795. bytediff[2] = bytediff[2] >> 5;
  9796. best_enc_color2[0]= best_enc_color1[0] + bytediff[0];
  9797. best_enc_color2[1]= best_enc_color1[1] + bytediff[1];
  9798. best_enc_color2[2]= best_enc_color1[2] + bytediff[2];
  9799. // allocate memory for errors:
  9800. err_upper = (unsigned int*) malloc(32*32*32*sizeof(unsigned int));
  9801. if(!err_upper){printf("Out of memory allocating \n");exit(1);}
  9802. err_lower = (unsigned int*) malloc(32*32*32*sizeof(unsigned int));
  9803. if(!err_lower){printf("Out of memory allocating \n");exit(1);}
  9804. err_left = (unsigned int*) malloc(32*32*32*sizeof(unsigned int));
  9805. if(!err_left){printf("Out of memory allocating \n");exit(1);}
  9806. err_right = (unsigned int*) malloc(32*32*32*sizeof(unsigned int));
  9807. if(!err_right){printf("Out of memory allocating \n");exit(1);}
  9808. int q;
  9809. // Calculate all errors
  9810. for(enc_color1[0]=0; enc_color1[0]<32; enc_color1[0]++)
  9811. {
  9812. color_quant1[0] = enc_color1[0] << 3 | (enc_color1[0] >> 2);
  9813. if(precompute_3bittable_all_subblocksR_with_test_perceptual1000(block_2x2, color_quant1, precalc_err_UL_R, precalc_err_UR_R, precalc_err_LL_R, precalc_err_LR_R, best_error_so_far))
  9814. {
  9815. for(enc_color1[1]=0; enc_color1[1]<32; enc_color1[1]++)
  9816. {
  9817. color_quant1[1] = enc_color1[1] << 3 | (enc_color1[1] >> 2);
  9818. if(precompute_3bittable_all_subblocksRG_withtest_perceptual1000(block_2x2, color_quant1, precalc_err_UL_R, precalc_err_UR_R, precalc_err_LL_R, precalc_err_LR_R, precalc_err_UL_RG, precalc_err_UR_RG, precalc_err_LL_RG, precalc_err_LR_RG, best_error_so_far))
  9819. {
  9820. for(enc_color1[2]=0; enc_color1[2]<32; enc_color1[2]++)
  9821. {
  9822. color_quant1[2] = enc_color1[2] << 3 | (enc_color1[2] >> 2);
  9823. tryalltables_3bittable_all_subblocks_using_precalc_perceptual1000(block_2x2, color_quant1, precalc_err_UL_RG, precalc_err_UR_RG, precalc_err_LL_RG, precalc_err_LR_RG, err_upper[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]], err_lower[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]], err_left[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]], err_right[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]], best_error_so_far);
  9824. }
  9825. }
  9826. else
  9827. {
  9828. for(q=0;q<32;q++)
  9829. {
  9830. err_upper[32*32*enc_color1[0]+32*enc_color1[1]+q] = MAXERR1000;
  9831. err_lower[32*32*enc_color1[0]+32*enc_color1[1]+q] = MAXERR1000;
  9832. err_left[32*32*enc_color1[0]+32*enc_color1[1]+q] = MAXERR1000;
  9833. err_right[32*32*enc_color1[0]+32*enc_color1[1]+q] = MAXERR1000;
  9834. }
  9835. }
  9836. }
  9837. }
  9838. else
  9839. {
  9840. for(q=0;q<32*32;q++)
  9841. {
  9842. err_upper[32*32*enc_color1[0]+q] = MAXERR1000;
  9843. err_lower[32*32*enc_color1[0]+q] = MAXERR1000;
  9844. err_left[32*32*enc_color1[0]+q] = MAXERR1000;
  9845. err_right[32*32*enc_color1[0]+q] = MAXERR1000;
  9846. }
  9847. }
  9848. }
  9849. for(enc_color1[0]=0; enc_color1[0]<32; enc_color1[0]++)
  9850. {
  9851. for(enc_color1[1]=0; enc_color1[1]<32; enc_color1[1]++)
  9852. {
  9853. for(enc_color1[2]=0; enc_color1[2]<4; enc_color1[2]++)
  9854. {
  9855. error_lying = err_upper[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]];
  9856. error_standing = err_left[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]];
  9857. if(error_lying < best_error_so_far || error_standing < best_error_so_far)
  9858. {
  9859. for(enc_color2[0]=JAS_MAX(0,enc_color1[0]-4); enc_color2[0]<JAS_MIN(enc_color1[0]+4,32); enc_color2[0]++)
  9860. {
  9861. for(enc_color2[1]=JAS_MAX(0,enc_color1[1]-4); enc_color2[1]<JAS_MIN(enc_color1[1]+4,32); enc_color2[1]++)
  9862. {
  9863. err_lower_adr = &err_lower[32*32*enc_color2[0]+32*enc_color2[1]];
  9864. err_right_adr = &err_right[32*32*enc_color2[0]+32*enc_color2[1]];
  9865. for(enc_color2[2]=JAS_MAX(0,enc_color1[2]-4); enc_color2[2]<JAS_MIN(enc_color1[2]+4,32); enc_color2[2]++)
  9866. {
  9867. error = error_lying+err_lower_adr[enc_color2[2]];
  9868. if(error<best_error_so_far)
  9869. {
  9870. best_flip = 1;
  9871. best_error_so_far = error;
  9872. best_error_using_diff_mode = error;
  9873. best_enc_color1[0] = enc_color1[0];
  9874. best_enc_color1[1] = enc_color1[1];
  9875. best_enc_color1[2] = enc_color1[2];
  9876. best_enc_color2[0] = enc_color2[0];
  9877. best_enc_color2[1] = enc_color2[1];
  9878. best_enc_color2[2] = enc_color2[2];
  9879. }
  9880. error = error_standing+err_right_adr[enc_color2[2]];
  9881. if(error<best_error_so_far)
  9882. {
  9883. best_flip = 0;
  9884. best_error_so_far = error;
  9885. best_error_using_diff_mode = error;
  9886. best_enc_color1[0] = enc_color1[0];
  9887. best_enc_color1[1] = enc_color1[1];
  9888. best_enc_color1[2] = enc_color1[2];
  9889. best_enc_color2[0] = enc_color2[0];
  9890. best_enc_color2[1] = enc_color2[1];
  9891. best_enc_color2[2] = enc_color2[2];
  9892. }
  9893. }
  9894. }
  9895. }
  9896. }
  9897. }
  9898. for(enc_color1[2]=4; enc_color1[2]<28; enc_color1[2]++)
  9899. {
  9900. error_lying = err_upper[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]];
  9901. error_standing = err_left[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]];
  9902. if(error_lying < best_error_so_far || error_standing < best_error_so_far)
  9903. {
  9904. for(enc_color2[0]=JAS_MAX(0,enc_color1[0]-4); enc_color2[0]<JAS_MIN(enc_color1[0]+4,32); enc_color2[0]++)
  9905. {
  9906. for(enc_color2[1]=JAS_MAX(0,enc_color1[1]-4); enc_color2[1]<JAS_MIN(enc_color1[1]+4,32); enc_color2[1]++)
  9907. {
  9908. err_lower_adr = &err_lower[32*32*enc_color2[0]+32*enc_color2[1]];
  9909. err_right_adr = &err_right[32*32*enc_color2[0]+32*enc_color2[1]];
  9910. // since enc_color[2] is between 4 and 29 we do not need to clamp the loop on the next line
  9911. for(enc_color2[2]=enc_color1[2]-4; enc_color2[2]<enc_color1[2]+4; enc_color2[2]++)
  9912. {
  9913. error = error_lying+err_lower_adr[enc_color2[2]];
  9914. if(error<best_error_so_far)
  9915. {
  9916. best_flip = 1;
  9917. best_error_so_far = error;
  9918. best_error_using_diff_mode = error;
  9919. best_enc_color1[0] = enc_color1[0];
  9920. best_enc_color1[1] = enc_color1[1];
  9921. best_enc_color1[2] = enc_color1[2];
  9922. best_enc_color2[0] = enc_color2[0];
  9923. best_enc_color2[1] = enc_color2[1];
  9924. best_enc_color2[2] = enc_color2[2];
  9925. }
  9926. error = error_standing+err_right_adr[enc_color2[2]];
  9927. if(error<best_error_so_far)
  9928. {
  9929. best_flip = 0;
  9930. best_error_so_far = error;
  9931. best_error_using_diff_mode = error;
  9932. best_enc_color1[0] = enc_color1[0];
  9933. best_enc_color1[1] = enc_color1[1];
  9934. best_enc_color1[2] = enc_color1[2];
  9935. best_enc_color2[0] = enc_color2[0];
  9936. best_enc_color2[1] = enc_color2[1];
  9937. best_enc_color2[2] = enc_color2[2];
  9938. }
  9939. }
  9940. }
  9941. }
  9942. }
  9943. }
  9944. for(enc_color1[2]=28; enc_color1[2]<32; enc_color1[2]++)
  9945. {
  9946. error_lying = err_upper[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]];
  9947. error_standing = err_left[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]];
  9948. if(error_lying < best_error_so_far || error_standing < best_error_so_far)
  9949. {
  9950. for(enc_color2[0]=JAS_MAX(0,enc_color1[0]-4); enc_color2[0]<JAS_MIN(enc_color1[0]+4,32); enc_color2[0]++)
  9951. {
  9952. for(enc_color2[1]=JAS_MAX(0,enc_color1[1]-4); enc_color2[1]<JAS_MIN(enc_color1[1]+4,32); enc_color2[1]++)
  9953. {
  9954. err_lower_adr = &err_lower[32*32*enc_color2[0]+32*enc_color2[1]];
  9955. err_right_adr = &err_right[32*32*enc_color2[0]+32*enc_color2[1]];
  9956. for(enc_color2[2]=JAS_MAX(0,enc_color1[2]-4); enc_color2[2]<JAS_MIN(enc_color1[2]+4,32); enc_color2[2]++)
  9957. {
  9958. error = error_lying+err_lower_adr[enc_color2[2]];
  9959. if(error<best_error_so_far)
  9960. {
  9961. best_flip = 1;
  9962. best_error_so_far = error;
  9963. best_error_using_diff_mode = error;
  9964. best_enc_color1[0] = enc_color1[0];
  9965. best_enc_color1[1] = enc_color1[1];
  9966. best_enc_color1[2] = enc_color1[2];
  9967. best_enc_color2[0] = enc_color2[0];
  9968. best_enc_color2[1] = enc_color2[1];
  9969. best_enc_color2[2] = enc_color2[2];
  9970. }
  9971. error = error_standing+err_right_adr[enc_color2[2]];
  9972. if(error<best_error_so_far)
  9973. {
  9974. best_flip = 0;
  9975. best_error_so_far = error;
  9976. best_error_using_diff_mode = error;
  9977. best_enc_color1[0] = enc_color1[0];
  9978. best_enc_color1[1] = enc_color1[1];
  9979. best_enc_color1[2] = enc_color1[2];
  9980. best_enc_color2[0] = enc_color2[0];
  9981. best_enc_color2[1] = enc_color2[1];
  9982. best_enc_color2[2] = enc_color2[2];
  9983. }
  9984. }
  9985. }
  9986. }
  9987. }
  9988. }
  9989. }
  9990. }
  9991. free(err_upper);
  9992. free(err_lower);
  9993. free(err_left);
  9994. free(err_right);
  9995. color_quant1[0] = best_enc_color1[0] << 3 | (best_enc_color1[0] >> 2);
  9996. color_quant1[1] = best_enc_color1[1] << 3 | (best_enc_color1[1] >> 2);
  9997. color_quant1[2] = best_enc_color1[2] << 3 | (best_enc_color1[2] >> 2);
  9998. if(best_flip == 0)
  9999. tryalltables_3bittable2x4percep1000(img,width,height,startx,starty,color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  10000. else
  10001. tryalltables_3bittable4x2percep1000(img,width,height,startx,starty,color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  10002. color_quant2[0] = best_enc_color2[0] << 3 | (best_enc_color2[0] >> 2);
  10003. color_quant2[1] = best_enc_color2[1] << 3 | (best_enc_color2[1] >> 2);
  10004. color_quant2[2] = best_enc_color2[2] << 3 | (best_enc_color2[2] >> 2);
  10005. if(best_flip == 0)
  10006. tryalltables_3bittable2x4percep1000(img,width,height,startx+2,starty,color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  10007. else
  10008. tryalltables_3bittable4x2percep1000(img,width,height,startx,starty+2,color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  10009. diff[0] = best_enc_color2[0]-best_enc_color1[0];
  10010. diff[1] = best_enc_color2[1]-best_enc_color1[1];
  10011. diff[2] = best_enc_color2[2]-best_enc_color1[2];
  10012. // ETC1_RGB8_OES:
  10013. //
  10014. // a) bit layout in bits 63 through 32 if diffbit = 0
  10015. //
  10016. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  10017. // ---------------------------------------------------------------------------------------------------
  10018. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  10019. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  10020. // ---------------------------------------------------------------------------------------------------
  10021. //
  10022. // b) bit layout in bits 63 through 32 if diffbit = 1
  10023. //
  10024. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  10025. // ---------------------------------------------------------------------------------------------------
  10026. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |diff|flip|
  10027. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
  10028. // ---------------------------------------------------------------------------------------------------
  10029. //
  10030. // c) bit layout in bits 31 through 0 (in both cases)
  10031. //
  10032. // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  10033. // --------------------------------------------------------------------------------------------------
  10034. // | most significant pixel index bits | least significant pixel index bits |
  10035. // | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a| p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
  10036. // --------------------------------------------------------------------------------------------------
  10037. diffbit = 1;
  10038. compressed1 = 0;
  10039. PUTBITSHIGH( compressed1, diffbit, 1, 33);
  10040. PUTBITSHIGH( compressed1, best_enc_color1[0], 5, 63);
  10041. PUTBITSHIGH( compressed1, best_enc_color1[1], 5, 55);
  10042. PUTBITSHIGH( compressed1, best_enc_color1[2], 5, 47);
  10043. PUTBITSHIGH( compressed1, diff[0], 3, 58);
  10044. PUTBITSHIGH( compressed1, diff[1], 3, 50);
  10045. PUTBITSHIGH( compressed1, diff[2], 3, 42);
  10046. PUTBITSHIGH( compressed1, best_table1, 3, 39);
  10047. PUTBITSHIGH( compressed1, best_table2, 3, 36);
  10048. PUTBITSHIGH( compressed1, best_flip, 1, 32);
  10049. if(best_flip == 0)
  10050. {
  10051. compressed2 = 0;
  10052. PUTBITS( compressed2, (best_pixel_indices1_MSB ), 8, 23);
  10053. PUTBITS( compressed2, (best_pixel_indices2_MSB ), 8, 31);
  10054. PUTBITS( compressed2, (best_pixel_indices1_LSB ), 8, 7);
  10055. PUTBITS( compressed2, (best_pixel_indices2_LSB ), 8, 15);
  10056. }
  10057. else
  10058. {
  10059. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  10060. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  10061. compressed2 = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  10062. }
  10063. return best_error_using_diff_mode;
  10064. }
  10065. #endif
  10066. #if EXHAUSTIVE_CODE_ACTIVE
  10067. // Compresses the differential mode exhaustively.
  10068. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  10069. unsigned int compressBlockDifferentialExhaustive(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2, unsigned int previous_best_err)
  10070. {
  10071. unsigned int best_err_norm_diff = 255*255*16*3;
  10072. unsigned int best_err_norm_444 = 255*255*16*3;
  10073. unsigned int best_err_flip_diff = 255*255*16*3;
  10074. unsigned int best_err_flip_444 = 255*255*16*3;
  10075. uint8 color_quant1[3], color_quant2[3];
  10076. int enc_color1[3], enc_color2[3], diff[3];
  10077. int best_enc_color1[3], best_enc_color2[3];
  10078. int min_error=255*255*8*3;
  10079. unsigned int best_pixel_indices1_MSB=0;
  10080. unsigned int best_pixel_indices1_LSB=0;
  10081. unsigned int best_pixel_indices2_MSB=0;
  10082. unsigned int best_pixel_indices2_LSB=0;
  10083. unsigned int pixel_indices1_MSB=0;
  10084. unsigned int pixel_indices1_LSB=0;
  10085. unsigned int pixel_indices2_MSB=0;
  10086. unsigned int *err_upper, *err_lower;
  10087. unsigned int *err_left, *err_right;
  10088. unsigned int pixel_indices2_LSB=0;
  10089. unsigned int table1=0, table2=0;
  10090. unsigned int best_table1=0, best_table2=0;
  10091. unsigned int precalc_err_UL_R[8*4*4];
  10092. unsigned int precalc_err_UR_R[8*4*4];
  10093. unsigned int precalc_err_LL_R[8*4*4];
  10094. unsigned int precalc_err_LR_R[8*4*4];
  10095. unsigned int precalc_err_UL_RG[8*4*4];
  10096. unsigned int precalc_err_UR_RG[8*4*4];
  10097. unsigned int precalc_err_LL_RG[8*4*4];
  10098. unsigned int precalc_err_LR_RG[8*4*4];
  10099. int diffbit;
  10100. uint8 block_2x2[4*4*4];
  10101. unsigned int error, error_lying, error_standing, best_err, total_best_err;
  10102. unsigned int *err_lower_adr;
  10103. int best_flip;
  10104. unsigned int *err_right_adr;
  10105. int xx,yy,count = 0;
  10106. // Reshuffle pixels so that the top left 2x2 pixels arrive first, then the top right 2x2 pixels etc. Also put use 4 bytes per pixel to make it 32-word aligned.
  10107. for(xx = 0; xx<2; xx++)
  10108. {
  10109. for(yy=0; yy<2; yy++)
  10110. {
  10111. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  10112. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  10113. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  10114. block_2x2[(count)*4+3] = 0;
  10115. count++;
  10116. }
  10117. }
  10118. for(xx = 2; xx<4; xx++)
  10119. {
  10120. for(yy=0; yy<2; yy++)
  10121. {
  10122. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  10123. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  10124. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  10125. block_2x2[(count)*4+3] = 0;
  10126. count++;
  10127. }
  10128. }
  10129. for(xx = 0; xx<2; xx++)
  10130. {
  10131. for(yy=2; yy<4; yy++)
  10132. {
  10133. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  10134. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  10135. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  10136. block_2x2[(count)*4+3] = 0;
  10137. count++;
  10138. }
  10139. }
  10140. for(xx = 2; xx<4; xx++)
  10141. {
  10142. for(yy=2; yy<4; yy++)
  10143. {
  10144. block_2x2[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  10145. block_2x2[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  10146. block_2x2[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  10147. block_2x2[(count)*4+3] = 0;
  10148. count++;
  10149. }
  10150. }
  10151. unsigned int test1, test2;
  10152. best_err = (unsigned int)compressBlockOnlyDiffFlipAverage(img, width, height, startx, starty, test1, test2, best_enc_color1, best_enc_color2, best_flip);
  10153. if(previous_best_err < best_err)
  10154. total_best_err = previous_best_err;
  10155. else
  10156. total_best_err = best_err;
  10157. // allocate memory for errors:
  10158. err_upper = (unsigned int*) malloc(32*32*32*sizeof(unsigned int));
  10159. if(!err_upper){printf("Out of memory allocating \n");exit(1);}
  10160. err_lower = (unsigned int*) malloc(32*32*32*sizeof(unsigned int));
  10161. if(!err_lower){printf("Out of memory allocating \n");exit(1);}
  10162. err_left = (unsigned int*) malloc(32*32*32*sizeof(unsigned int));
  10163. if(!err_left){printf("Out of memory allocating \n");exit(1);}
  10164. err_right = (unsigned int*) malloc(32*32*32*sizeof(unsigned int));
  10165. if(!err_right){printf("Out of memory allocating \n");exit(1);}
  10166. int q;
  10167. // Calculate all errors
  10168. for(enc_color1[0]=0; enc_color1[0]<32; enc_color1[0]++)
  10169. {
  10170. color_quant1[0] = enc_color1[0] << 3 | (enc_color1[0] >> 2);
  10171. if(precompute_3bittable_all_subblocksR_with_test(block_2x2, color_quant1, precalc_err_UL_R, precalc_err_UR_R, precalc_err_LL_R, precalc_err_LR_R, total_best_err))
  10172. {
  10173. for(enc_color1[1]=0; enc_color1[1]<32; enc_color1[1]++)
  10174. {
  10175. color_quant1[1] = enc_color1[1] << 3 | (enc_color1[1] >> 2);
  10176. if(precompute_3bittable_all_subblocksRG_withtest(block_2x2, color_quant1, precalc_err_UL_R, precalc_err_UR_R, precalc_err_LL_R, precalc_err_LR_R, precalc_err_UL_RG, precalc_err_UR_RG, precalc_err_LL_RG, precalc_err_LR_RG, total_best_err))
  10177. {
  10178. for(enc_color1[2]=0; enc_color1[2]<32; enc_color1[2]++)
  10179. {
  10180. color_quant1[2] = enc_color1[2] << 3 | (enc_color1[2] >> 2);
  10181. tryalltables_3bittable_all_subblocks_using_precalc(block_2x2, color_quant1, precalc_err_UL_RG, precalc_err_UR_RG, precalc_err_LL_RG, precalc_err_LR_RG, err_upper[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]], err_lower[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]], err_left[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]], err_right[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]], total_best_err);
  10182. }
  10183. }
  10184. else
  10185. {
  10186. for(q=0;q<32;q++)
  10187. {
  10188. err_upper[32*32*enc_color1[0]+32*enc_color1[1]+q] = 255*255*16*3;
  10189. err_lower[32*32*enc_color1[0]+32*enc_color1[1]+q] = 255*255*16*3;
  10190. err_left[32*32*enc_color1[0]+32*enc_color1[1]+q] = 255*255*16*3;
  10191. err_right[32*32*enc_color1[0]+32*enc_color1[1]+q] = 255*255*16*3;
  10192. }
  10193. }
  10194. }
  10195. }
  10196. else
  10197. {
  10198. for(q=0;q<32*32;q++)
  10199. {
  10200. err_upper[32*32*enc_color1[0]+q] = 255*255*16*3;
  10201. err_lower[32*32*enc_color1[0]+q] = 255*255*16*3;
  10202. err_left[32*32*enc_color1[0]+q] = 255*255*16*3;
  10203. err_right[32*32*enc_color1[0]+q] = 255*255*16*3;
  10204. }
  10205. }
  10206. }
  10207. for(enc_color1[0]=0; enc_color1[0]<32; enc_color1[0]++)
  10208. {
  10209. for(enc_color1[1]=0; enc_color1[1]<32; enc_color1[1]++)
  10210. {
  10211. for(enc_color1[2]=0; enc_color1[2]<4; enc_color1[2]++)
  10212. {
  10213. error_lying = err_upper[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]];
  10214. error_standing = err_left[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]];
  10215. if(error_lying < total_best_err || error_standing < total_best_err)
  10216. {
  10217. for(enc_color2[0]=JAS_MAX(0,enc_color1[0]-4); enc_color2[0]<JAS_MIN(enc_color1[0]+4,32); enc_color2[0]++)
  10218. {
  10219. for(enc_color2[1]=JAS_MAX(0,enc_color1[1]-4); enc_color2[1]<JAS_MIN(enc_color1[1]+4,32); enc_color2[1]++)
  10220. {
  10221. err_lower_adr = &err_lower[32*32*enc_color2[0]+32*enc_color2[1]];
  10222. err_right_adr = &err_right[32*32*enc_color2[0]+32*enc_color2[1]];
  10223. for(enc_color2[2]=JAS_MAX(0,enc_color1[2]-4); enc_color2[2]<JAS_MIN(enc_color1[2]+4,32); enc_color2[2]++)
  10224. {
  10225. error = error_lying+err_lower_adr[enc_color2[2]];
  10226. if(error<best_err)
  10227. {
  10228. best_flip = 1;
  10229. best_err = error;
  10230. best_enc_color1[0] = enc_color1[0];
  10231. best_enc_color1[1] = enc_color1[1];
  10232. best_enc_color1[2] = enc_color1[2];
  10233. best_enc_color2[0] = enc_color2[0];
  10234. best_enc_color2[1] = enc_color2[1];
  10235. best_enc_color2[2] = enc_color2[2];
  10236. }
  10237. error = error_standing+err_right_adr[enc_color2[2]];
  10238. if(error<best_err)
  10239. {
  10240. best_flip = 0;
  10241. best_err = error;
  10242. best_enc_color1[0] = enc_color1[0];
  10243. best_enc_color1[1] = enc_color1[1];
  10244. best_enc_color1[2] = enc_color1[2];
  10245. best_enc_color2[0] = enc_color2[0];
  10246. best_enc_color2[1] = enc_color2[1];
  10247. best_enc_color2[2] = enc_color2[2];
  10248. }
  10249. }
  10250. }
  10251. }
  10252. if(best_err < total_best_err)
  10253. total_best_err = best_err;
  10254. }
  10255. }
  10256. for(enc_color1[2]=4; enc_color1[2]<28; enc_color1[2]++)
  10257. {
  10258. error_lying = err_upper[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]];
  10259. error_standing = err_left[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]];
  10260. if(error_lying < total_best_err || error_standing < total_best_err)
  10261. {
  10262. for(enc_color2[0]=JAS_MAX(0,enc_color1[0]-4); enc_color2[0]<JAS_MIN(enc_color1[0]+4,32); enc_color2[0]++)
  10263. {
  10264. for(enc_color2[1]=JAS_MAX(0,enc_color1[1]-4); enc_color2[1]<JAS_MIN(enc_color1[1]+4,32); enc_color2[1]++)
  10265. {
  10266. err_lower_adr = &err_lower[32*32*enc_color2[0]+32*enc_color2[1]];
  10267. err_right_adr = &err_right[32*32*enc_color2[0]+32*enc_color2[1]];
  10268. // since enc_color[2] is between 4 and 29 we do not need to clamp the loop on the next line
  10269. for(enc_color2[2]=enc_color1[2]-4; enc_color2[2]<enc_color1[2]+4; enc_color2[2]++)
  10270. {
  10271. error = error_lying+err_lower_adr[enc_color2[2]];
  10272. if(error<best_err)
  10273. {
  10274. best_flip = 1;
  10275. best_err = error;
  10276. best_enc_color1[0] = enc_color1[0];
  10277. best_enc_color1[1] = enc_color1[1];
  10278. best_enc_color1[2] = enc_color1[2];
  10279. best_enc_color2[0] = enc_color2[0];
  10280. best_enc_color2[1] = enc_color2[1];
  10281. best_enc_color2[2] = enc_color2[2];
  10282. }
  10283. error = error_standing+err_right_adr[enc_color2[2]];
  10284. if(error<best_err)
  10285. {
  10286. best_flip = 0;
  10287. best_err = error;
  10288. best_enc_color1[0] = enc_color1[0];
  10289. best_enc_color1[1] = enc_color1[1];
  10290. best_enc_color1[2] = enc_color1[2];
  10291. best_enc_color2[0] = enc_color2[0];
  10292. best_enc_color2[1] = enc_color2[1];
  10293. best_enc_color2[2] = enc_color2[2];
  10294. }
  10295. }
  10296. }
  10297. }
  10298. if(best_err < total_best_err)
  10299. total_best_err = best_err;
  10300. }
  10301. }
  10302. for(enc_color1[2]=28; enc_color1[2]<32; enc_color1[2]++)
  10303. {
  10304. error_lying = err_upper[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]];
  10305. error_standing = err_left[32*32*enc_color1[0]+32*enc_color1[1]+enc_color1[2]];
  10306. if(error_lying < total_best_err || error_standing < total_best_err)
  10307. {
  10308. for(enc_color2[0]=JAS_MAX(0,enc_color1[0]-4); enc_color2[0]<JAS_MIN(enc_color1[0]+4,32); enc_color2[0]++)
  10309. {
  10310. for(enc_color2[1]=JAS_MAX(0,enc_color1[1]-4); enc_color2[1]<JAS_MIN(enc_color1[1]+4,32); enc_color2[1]++)
  10311. {
  10312. err_lower_adr = &err_lower[32*32*enc_color2[0]+32*enc_color2[1]];
  10313. err_right_adr = &err_right[32*32*enc_color2[0]+32*enc_color2[1]];
  10314. for(enc_color2[2]=JAS_MAX(0,enc_color1[2]-4); enc_color2[2]<JAS_MIN(enc_color1[2]+4,32); enc_color2[2]++)
  10315. {
  10316. error = error_lying+err_lower_adr[enc_color2[2]];
  10317. if(error<best_err)
  10318. {
  10319. best_flip = 1;
  10320. best_err = error;
  10321. best_enc_color1[0] = enc_color1[0];
  10322. best_enc_color1[1] = enc_color1[1];
  10323. best_enc_color1[2] = enc_color1[2];
  10324. best_enc_color2[0] = enc_color2[0];
  10325. best_enc_color2[1] = enc_color2[1];
  10326. best_enc_color2[2] = enc_color2[2];
  10327. }
  10328. error = error_standing+err_right_adr[enc_color2[2]];
  10329. if(error<best_err)
  10330. {
  10331. best_flip = 0;
  10332. best_err = error;
  10333. best_enc_color1[0] = enc_color1[0];
  10334. best_enc_color1[1] = enc_color1[1];
  10335. best_enc_color1[2] = enc_color1[2];
  10336. best_enc_color2[0] = enc_color2[0];
  10337. best_enc_color2[1] = enc_color2[1];
  10338. best_enc_color2[2] = enc_color2[2];
  10339. }
  10340. }
  10341. }
  10342. }
  10343. if(best_err < total_best_err)
  10344. total_best_err = best_err;
  10345. }
  10346. }
  10347. }
  10348. }
  10349. free(err_upper);
  10350. free(err_lower);
  10351. free(err_left);
  10352. free(err_right);
  10353. color_quant1[0] = best_enc_color1[0] << 3 | (best_enc_color1[0] >> 2);
  10354. color_quant1[1] = best_enc_color1[1] << 3 | (best_enc_color1[1] >> 2);
  10355. color_quant1[2] = best_enc_color1[2] << 3 | (best_enc_color1[2] >> 2);
  10356. if(best_flip == 0)
  10357. tryalltables_3bittable2x4(img,width,height,startx,starty,color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  10358. else
  10359. tryalltables_3bittable4x2(img,width,height,startx,starty,color_quant1,best_table1,best_pixel_indices1_MSB, best_pixel_indices1_LSB);
  10360. color_quant2[0] = best_enc_color2[0] << 3 | (best_enc_color2[0] >> 2);
  10361. color_quant2[1] = best_enc_color2[1] << 3 | (best_enc_color2[1] >> 2);
  10362. color_quant2[2] = best_enc_color2[2] << 3 | (best_enc_color2[2] >> 2);
  10363. if(best_flip == 0)
  10364. tryalltables_3bittable2x4(img,width,height,startx+2,starty,color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  10365. else
  10366. tryalltables_3bittable4x2(img,width,height,startx,starty+2,color_quant2,best_table2,best_pixel_indices2_MSB, best_pixel_indices2_LSB);
  10367. diff[0] = best_enc_color2[0]-best_enc_color1[0];
  10368. diff[1] = best_enc_color2[1]-best_enc_color1[1];
  10369. diff[2] = best_enc_color2[2]-best_enc_color1[2];
  10370. // ETC1_RGB8_OES:
  10371. //
  10372. // a) bit layout in bits 63 through 32 if diffbit = 0
  10373. //
  10374. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  10375. // ---------------------------------------------------------------------------------------------------
  10376. // | base col1 | base col2 | base col1 | base col2 | base col1 | base col2 | table | table |diff|flip|
  10377. // | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)| B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
  10378. // ---------------------------------------------------------------------------------------------------
  10379. //
  10380. // b) bit layout in bits 63 through 32 if diffbit = 1
  10381. //
  10382. // 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
  10383. // ---------------------------------------------------------------------------------------------------
  10384. // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |diff|flip|
  10385. // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
  10386. // ---------------------------------------------------------------------------------------------------
  10387. //
  10388. // c) bit layout in bits 31 through 0 (in both cases)
  10389. //
  10390. // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  10391. // --------------------------------------------------------------------------------------------------
  10392. // | most significant pixel index bits | least significant pixel index bits |
  10393. // | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a| p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
  10394. // --------------------------------------------------------------------------------------------------
  10395. diffbit = 1;
  10396. compressed1 = 0;
  10397. PUTBITSHIGH( compressed1, diffbit, 1, 33);
  10398. PUTBITSHIGH( compressed1, best_enc_color1[0], 5, 63);
  10399. PUTBITSHIGH( compressed1, best_enc_color1[1], 5, 55);
  10400. PUTBITSHIGH( compressed1, best_enc_color1[2], 5, 47);
  10401. PUTBITSHIGH( compressed1, diff[0], 3, 58);
  10402. PUTBITSHIGH( compressed1, diff[1], 3, 50);
  10403. PUTBITSHIGH( compressed1, diff[2], 3, 42);
  10404. PUTBITSHIGH( compressed1, best_table1, 3, 39);
  10405. PUTBITSHIGH( compressed1, best_table2, 3, 36);
  10406. PUTBITSHIGH( compressed1, best_flip, 1, 32);
  10407. if(best_flip == 0)
  10408. {
  10409. compressed2 = 0;
  10410. PUTBITS( compressed2, (best_pixel_indices1_MSB ), 8, 23);
  10411. PUTBITS( compressed2, (best_pixel_indices2_MSB ), 8, 31);
  10412. PUTBITS( compressed2, (best_pixel_indices1_LSB ), 8, 7);
  10413. PUTBITS( compressed2, (best_pixel_indices2_LSB ), 8, 15);
  10414. }
  10415. else
  10416. {
  10417. best_pixel_indices1_MSB |= (best_pixel_indices2_MSB << 2);
  10418. best_pixel_indices1_LSB |= (best_pixel_indices2_LSB << 2);
  10419. compressed2 = ((best_pixel_indices1_MSB & 0xffff) << 16) | (best_pixel_indices1_LSB & 0xffff);
  10420. }
  10421. return best_err;
  10422. }
  10423. #endif
  10424. #if EXHAUSTIVE_CODE_ACTIVE
  10425. // This function uses real exhaustive search for the planar mode.
  10426. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  10427. void compressBlockPlanar57ExhaustivePerceptual(uint8 *img, int width,int height,int startx,int starty, unsigned int &compressed57_1, unsigned int &compressed57_2, unsigned int best_error_sofar, unsigned int best_error_planar_red, unsigned int best_error_planar_green, unsigned int best_error_planar_blue)
  10428. {
  10429. int colorO_enc[3], colorH_enc[3], colorV_enc[3];
  10430. int best_colorO_enc[3], best_colorH_enc[3], best_colorV_enc[3];
  10431. unsigned int error;
  10432. unsigned int best_error;
  10433. unsigned int lowest_possible_error;
  10434. unsigned int best_error_red_sofar;
  10435. unsigned int best_error_green_sofar;
  10436. unsigned int best_error_blue_sofar;
  10437. unsigned int BBBtable[128*128];
  10438. unsigned int CCCtable[128*128];
  10439. uint8 block[4*4*4];
  10440. // Use 4 bytes per pixel to make it 32-word aligned.
  10441. int count = 0;
  10442. int xx, yy;
  10443. for(yy=0; yy<4; yy++)
  10444. {
  10445. for(xx = 0; xx<4; xx++)
  10446. {
  10447. block[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  10448. block[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  10449. block[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  10450. block[(count)*4+3] = 0;
  10451. count++;
  10452. }
  10453. }
  10454. // The task is to calculate the sum of the error over the entire area of the block.
  10455. //
  10456. // The block can be partitioned into: O A A A
  10457. // B D D C
  10458. // B D C D
  10459. // B C D D
  10460. // where the error in
  10461. // O only depends on colorO
  10462. // A only depends on colorO and colorH
  10463. // B only depends on colorO and colorV
  10464. // C only depends on colorH and colorV
  10465. // D depends on all three (colorO, colorH and colorV)
  10466. //
  10467. // Note that B can be precalculated for all combinations of colorO and colorV
  10468. // and the precalculated values can be used instead of calculating it in the inner loop.
  10469. // The same applies to C.
  10470. //
  10471. // In the code below, the squared error over O A A A is calculated and stored in lowest_possible_error
  10472. // Precalc BBB errors
  10473. for(colorO_enc[0] = 0; colorO_enc[0]<64; colorO_enc[0]++)
  10474. {
  10475. for(colorV_enc[0] = 0; colorV_enc[0]<64; colorV_enc[0]++)
  10476. {
  10477. BBBtable[colorO_enc[0]*64+colorV_enc[0]] = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*calcBBBred(block, colorO_enc[0], colorV_enc[0]);
  10478. }
  10479. }
  10480. // Precalc CCC errors
  10481. for(colorH_enc[0] = 0; colorH_enc[0]<64; colorH_enc[0]++)
  10482. {
  10483. for(colorV_enc[0] = 0; colorV_enc[0]<64; colorV_enc[0]++)
  10484. {
  10485. CCCtable[colorH_enc[0]*64+colorV_enc[0]] = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*calcCCCred(block, colorH_enc[0], colorV_enc[0]);
  10486. }
  10487. }
  10488. best_error = MAXERR1000;
  10489. best_error_red_sofar = JAS_MIN(best_error_planar_red, best_error_sofar);
  10490. for(colorO_enc[0] = 0; colorO_enc[0]<64; colorO_enc[0]++)
  10491. {
  10492. for(colorH_enc[0] = 0; colorH_enc[0]<64; colorH_enc[0]++)
  10493. {
  10494. lowest_possible_error = calcLowestPossibleRedOHperceptual(block, colorO_enc[0], colorH_enc[0], best_error_red_sofar);
  10495. if(lowest_possible_error <= best_error_red_sofar)
  10496. {
  10497. for(colorV_enc[0] = 0; colorV_enc[0]<64; colorV_enc[0]++)
  10498. {
  10499. error = calcErrorPlanarOnlyRedPerceptual(block, colorO_enc[0], colorH_enc[0], colorV_enc[0], lowest_possible_error, BBBtable[colorO_enc[0]*64+colorV_enc[0]], CCCtable[colorH_enc[0]*64+colorV_enc[0]], best_error_red_sofar);
  10500. if(error < best_error)
  10501. {
  10502. best_error = error;
  10503. best_colorO_enc[0] = colorO_enc[0];
  10504. best_colorH_enc[0] = colorH_enc[0];
  10505. best_colorV_enc[0] = colorV_enc[0];
  10506. }
  10507. }
  10508. }
  10509. }
  10510. }
  10511. if(best_error < best_error_planar_red)
  10512. best_error_planar_red = best_error;
  10513. if(best_error_planar_red > best_error_sofar)
  10514. {
  10515. // The red component in itself is already bigger than the previously best value ---- we can give up.
  10516. // use the dummy color black for all colors and report that the errors for the different color components are infinite
  10517. best_error_planar_green = MAXERR1000;
  10518. best_error_planar_blue = MAXERR1000;
  10519. compressed57_1 = 0;
  10520. compressed57_2 = 0;
  10521. return;
  10522. }
  10523. // The task is to calculate the sum of the error over the entire area of the block.
  10524. //
  10525. // The block can be partitioned into: O A A A
  10526. // B D D C
  10527. // B D C D
  10528. // B C D D
  10529. // where the error in
  10530. // O only depends on colorO
  10531. // A only depends on colorO and colorH
  10532. // B only depends on colorO and colorV
  10533. // C only depends on colorH and colorV
  10534. // D depends on all three (colorO, colorH and colorV)
  10535. //
  10536. // Note that B can be precalculated for all combinations of colorO and colorV
  10537. // and the precalculated values can be used instead of calculating it in the inner loop.
  10538. // The same applies to C.
  10539. //
  10540. // In the code below, the squared error over O A A A is calculated and store in lowest_possible_error
  10541. // Precalc BBB errors
  10542. for(colorO_enc[1] = 0; colorO_enc[1]<128; colorO_enc[1]++)
  10543. {
  10544. for(colorV_enc[1] = 0; colorV_enc[1]<128; colorV_enc[1]++)
  10545. {
  10546. BBBtable[colorO_enc[1]*128+colorV_enc[1]] = PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*calcBBBgreen(block, colorO_enc[1], colorV_enc[1]);
  10547. }
  10548. }
  10549. // Precalc CCC errors
  10550. for(colorH_enc[1] = 0; colorH_enc[1]<128; colorH_enc[1]++)
  10551. {
  10552. for(colorV_enc[1] = 0; colorV_enc[1]<128; colorV_enc[1]++)
  10553. {
  10554. CCCtable[colorH_enc[1]*128+colorV_enc[1]] = PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*calcCCCgreen(block, colorH_enc[1], colorV_enc[1]);
  10555. }
  10556. }
  10557. best_error = MAXERR1000;
  10558. best_error_green_sofar = JAS_MIN(best_error_planar_green, best_error_sofar);
  10559. for(colorO_enc[1] = 0; colorO_enc[1]<128; colorO_enc[1]++)
  10560. {
  10561. for(colorH_enc[1] = 0; colorH_enc[1]<128; colorH_enc[1]++)
  10562. {
  10563. lowest_possible_error = calcLowestPossibleGreenOHperceptual(block, colorO_enc[1], colorH_enc[1], best_error_green_sofar);
  10564. if(lowest_possible_error <= best_error_green_sofar)
  10565. {
  10566. for(colorV_enc[1] = 0; colorV_enc[1]<128; colorV_enc[1]++)
  10567. {
  10568. error = calcErrorPlanarOnlyGreenPerceptual(block, colorO_enc[1], colorH_enc[1], colorV_enc[1], lowest_possible_error, BBBtable[colorO_enc[1]*128+colorV_enc[1]], CCCtable[colorH_enc[1]*128+colorV_enc[1]], best_error_green_sofar);
  10569. if(error < best_error)
  10570. {
  10571. best_error = error;
  10572. best_colorO_enc[1] = colorO_enc[1];
  10573. best_colorH_enc[1] = colorH_enc[1];
  10574. best_colorV_enc[1] = colorV_enc[1];
  10575. }
  10576. }
  10577. }
  10578. }
  10579. }
  10580. if(best_error < best_error_planar_green)
  10581. best_error_planar_green = best_error;
  10582. if(best_error_planar_red + best_error_planar_green > best_error_sofar)
  10583. {
  10584. // The red component in itself is already bigger than the previously best value ---- we can give up.
  10585. // use the dummy color black for all colors and report that the errors for the different color components are infinite
  10586. best_error_planar_blue = MAXERR1000;
  10587. compressed57_1 = 0;
  10588. compressed57_2 = 0;
  10589. return;
  10590. }
  10591. // The task is to calculate the sum of the error over the entire area of the block.
  10592. //
  10593. // The block can be partitioned into: O A A A
  10594. // B D D C
  10595. // B D C D
  10596. // B C D D
  10597. // where the error in
  10598. // O only depends on colorO
  10599. // A only depends on colorO and colorH
  10600. // B only depends on colorO and colorV
  10601. // C only depends on colorH and colorV
  10602. // D depends on all three (colorO, colorH and colorV)
  10603. //
  10604. // Note that B can be precalculated for all combinations of colorO and colorV
  10605. // and the precalculated values can be used instead of calculating it in the inner loop.
  10606. // The same applies to C.
  10607. //
  10608. // In the code below, the squared error over O A A A is calculated and store in lowest_possible_error
  10609. // Precalc BBB errors
  10610. for(colorO_enc[2] = 0; colorO_enc[2]<64; colorO_enc[2]++)
  10611. {
  10612. for(colorV_enc[2] = 0; colorV_enc[2]<64; colorV_enc[2]++)
  10613. {
  10614. BBBtable[colorO_enc[2]*64+colorV_enc[2]] = calcBBBbluePerceptual(block, colorO_enc[2], colorV_enc[2]);
  10615. }
  10616. }
  10617. // Precalc CCC errors
  10618. for(colorH_enc[2] = 0; colorH_enc[2]<64; colorH_enc[2]++)
  10619. {
  10620. for(colorV_enc[2] = 0; colorV_enc[2]<64; colorV_enc[2]++)
  10621. {
  10622. CCCtable[colorH_enc[2]*64+colorV_enc[2]] = calcCCCbluePerceptual(block, colorH_enc[2], colorV_enc[2]);
  10623. }
  10624. }
  10625. best_error = MAXERR1000;
  10626. best_error_blue_sofar = JAS_MIN(best_error_planar_blue, best_error_sofar);
  10627. for(colorO_enc[2] = 0; colorO_enc[2]<64; colorO_enc[2]++)
  10628. {
  10629. for(colorH_enc[2] = 0; colorH_enc[2]<64; colorH_enc[2]++)
  10630. {
  10631. lowest_possible_error = calcLowestPossibleBlueOHperceptual(block, colorO_enc[2], colorH_enc[2], best_error_blue_sofar);
  10632. if(lowest_possible_error <= best_error_blue_sofar)
  10633. {
  10634. for(colorV_enc[2] = 0; colorV_enc[2]<64; colorV_enc[2]++)
  10635. {
  10636. error = calcErrorPlanarOnlyBluePerceptual(block, colorO_enc[2], colorH_enc[2], colorV_enc[2], lowest_possible_error, BBBtable[colorO_enc[2]*64+colorV_enc[2]], CCCtable[colorH_enc[2]*64+colorV_enc[2]], best_error_blue_sofar);
  10637. if(error < best_error)
  10638. {
  10639. best_error = error;
  10640. best_colorO_enc[2] = colorO_enc[2];
  10641. best_colorH_enc[2] = colorH_enc[2];
  10642. best_colorV_enc[2] = colorV_enc[2];
  10643. }
  10644. }
  10645. }
  10646. }
  10647. }
  10648. if(best_error < best_error_planar_blue)
  10649. best_error_planar_blue = best_error;
  10650. compressed57_1 = 0;
  10651. compressed57_2 = 0;
  10652. PUTBITSHIGH( compressed57_1, best_colorO_enc[0], 6, 63);
  10653. PUTBITSHIGH( compressed57_1, best_colorO_enc[1], 7, 57);
  10654. PUTBITSHIGH( compressed57_1, best_colorO_enc[2], 6, 50);
  10655. PUTBITSHIGH( compressed57_1, best_colorH_enc[0], 6, 44);
  10656. PUTBITSHIGH( compressed57_1, best_colorH_enc[1], 7, 38);
  10657. PUTBITS( compressed57_2, best_colorH_enc[2], 6, 31);
  10658. PUTBITS( compressed57_2, best_colorV_enc[0], 6, 25);
  10659. PUTBITS( compressed57_2, best_colorV_enc[1], 7, 19);
  10660. PUTBITS( compressed57_2, best_colorV_enc[2], 6, 12);
  10661. }
  10662. #endif
  10663. #if EXHAUSTIVE_CODE_ACTIVE
  10664. // This function uses real exhaustive search for the planar mode.
  10665. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  10666. void compressBlockPlanar57Exhaustive(uint8 *img, int width,int height,int startx,int starty, unsigned int &compressed57_1, unsigned int &compressed57_2, unsigned int best_error_sofar, unsigned int best_error_red, unsigned int best_error_green, unsigned int best_error_blue)
  10667. {
  10668. int colorO_enc[3], colorH_enc[3], colorV_enc[3];
  10669. int best_colorO_enc[3], best_colorH_enc[3], best_colorV_enc[3];
  10670. unsigned int error;
  10671. unsigned int best_error;
  10672. unsigned int lowest_possible_error;
  10673. unsigned int best_error_red_sofar;
  10674. unsigned int best_error_green_sofar;
  10675. unsigned int best_error_blue_sofar;
  10676. unsigned int BBBtable[128*128];
  10677. unsigned int CCCtable[128*128];
  10678. uint8 block[4*4*4];
  10679. // Use 4 bytes per pixel to make it 32-word aligned.
  10680. int count = 0;
  10681. int xx, yy;
  10682. for(yy=0; yy<4; yy++)
  10683. {
  10684. for(xx = 0; xx<4; xx++)
  10685. {
  10686. block[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  10687. block[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  10688. block[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  10689. block[(count)*4+3] = 0;
  10690. count++;
  10691. }
  10692. }
  10693. // The task is to calculate the sum of the error over the entire area of the block.
  10694. //
  10695. // The block can be partitioned into: O A A A
  10696. // B D D C
  10697. // B D C D
  10698. // B C D D
  10699. // where the error in
  10700. // O only depends on colorO
  10701. // A only depends on colorO and colorH
  10702. // B only depends on colorO and colorV
  10703. // C only depends on colorH and colorV
  10704. // D depends on all three (colorO, colorH and colorV)
  10705. //
  10706. // Note that B can be precalculated for all combinations of colorO and colorV
  10707. // and the precalculated values can be used instead of calculating it in the inner loop.
  10708. // The same applies to C.
  10709. //
  10710. // In the code below, the squared error over O A A A is calculated and store in lowest_possible_error
  10711. // Precalc BBB errors
  10712. for(colorO_enc[0] = 0; colorO_enc[0]<64; colorO_enc[0]++)
  10713. {
  10714. for(colorV_enc[0] = 0; colorV_enc[0]<64; colorV_enc[0]++)
  10715. {
  10716. BBBtable[colorO_enc[0]*64+colorV_enc[0]] = calcBBBred(block, colorO_enc[0], colorV_enc[0]);
  10717. }
  10718. }
  10719. // Precalc CCC errors
  10720. for(colorH_enc[0] = 0; colorH_enc[0]<64; colorH_enc[0]++)
  10721. {
  10722. for(colorV_enc[0] = 0; colorV_enc[0]<64; colorV_enc[0]++)
  10723. {
  10724. CCCtable[colorH_enc[0]*64+colorV_enc[0]] = calcCCCred(block, colorH_enc[0], colorV_enc[0]);
  10725. }
  10726. }
  10727. best_error = MAXERR1000;
  10728. best_error_red_sofar = JAS_MIN(best_error_red, best_error_sofar);
  10729. for(colorO_enc[0] = 0; colorO_enc[0]<64; colorO_enc[0]++)
  10730. {
  10731. for(colorH_enc[0] = 0; colorH_enc[0]<64; colorH_enc[0]++)
  10732. {
  10733. lowest_possible_error = calcLowestPossibleRedOH(block, colorO_enc[0], colorH_enc[0], best_error_red_sofar);
  10734. if(lowest_possible_error <= best_error_red_sofar)
  10735. {
  10736. for(colorV_enc[0] = 0; colorV_enc[0]<64; colorV_enc[0]++)
  10737. {
  10738. error = calcErrorPlanarOnlyRed(block, colorO_enc[0], colorH_enc[0], colorV_enc[0], lowest_possible_error, BBBtable[colorO_enc[0]*64+colorV_enc[0]], CCCtable[colorH_enc[0]*64+colorV_enc[0]], best_error_red_sofar);
  10739. if(error < best_error)
  10740. {
  10741. best_error = error;
  10742. best_colorO_enc[0] = colorO_enc[0];
  10743. best_colorH_enc[0] = colorH_enc[0];
  10744. best_colorV_enc[0] = colorV_enc[0];
  10745. }
  10746. }
  10747. }
  10748. }
  10749. }
  10750. // The task is to calculate the sum of the error over the entire area of the block.
  10751. //
  10752. // The block can be partitioned into: O A A A
  10753. // B D D C
  10754. // B D C D
  10755. // B C D D
  10756. // where the error in
  10757. // O only depends on colorO
  10758. // A only depends on colorO and colorH
  10759. // B only depends on colorO and colorV
  10760. // C only depends on colorH and colorV
  10761. // D depends on all three (colorO, colorH and colorV)
  10762. //
  10763. // Note that B can be precalculated for all combinations of colorO and colorV
  10764. // and the precalculated values can be used instead of calculating it in the inner loop.
  10765. // The same applies to C.
  10766. //
  10767. // In the code below, the squared error over O A A A is calculated and store in lowest_possible_error
  10768. // Precalc BBB errors
  10769. for(colorO_enc[1] = 0; colorO_enc[1]<128; colorO_enc[1]++)
  10770. {
  10771. for(colorV_enc[1] = 0; colorV_enc[1]<128; colorV_enc[1]++)
  10772. {
  10773. BBBtable[colorO_enc[1]*128+colorV_enc[1]] = calcBBBgreen(block, colorO_enc[1], colorV_enc[1]);
  10774. }
  10775. }
  10776. // Precalc CCC errors
  10777. for(colorH_enc[1] = 0; colorH_enc[1]<128; colorH_enc[1]++)
  10778. {
  10779. for(colorV_enc[1] = 0; colorV_enc[1]<128; colorV_enc[1]++)
  10780. {
  10781. CCCtable[colorH_enc[1]*128+colorV_enc[1]] = calcCCCgreen(block, colorH_enc[1], colorV_enc[1]);
  10782. }
  10783. }
  10784. best_error = MAXERR1000;
  10785. best_error_green_sofar = JAS_MIN(best_error_green, best_error_sofar);
  10786. for(colorO_enc[1] = 0; colorO_enc[1]<128; colorO_enc[1]++)
  10787. {
  10788. for(colorH_enc[1] = 0; colorH_enc[1]<128; colorH_enc[1]++)
  10789. {
  10790. lowest_possible_error = calcLowestPossibleGreenOH(block, colorO_enc[1], colorH_enc[1], best_error_green_sofar);
  10791. if(lowest_possible_error <= best_error_green_sofar)
  10792. {
  10793. for(colorV_enc[1] = 0; colorV_enc[1]<128; colorV_enc[1]++)
  10794. {
  10795. error = calcErrorPlanarOnlyGreen(block, colorO_enc[1], colorH_enc[1], colorV_enc[1], lowest_possible_error, BBBtable[colorO_enc[1]*128+colorV_enc[1]], CCCtable[colorH_enc[1]*128+colorV_enc[1]], best_error_green_sofar);
  10796. if(error < best_error)
  10797. {
  10798. best_error = error;
  10799. best_colorO_enc[1] = colorO_enc[1];
  10800. best_colorH_enc[1] = colorH_enc[1];
  10801. best_colorV_enc[1] = colorV_enc[1];
  10802. }
  10803. }
  10804. }
  10805. }
  10806. }
  10807. // The task is to calculate the sum of the error over the entire area of the block.
  10808. //
  10809. // The block can be partitioned into: O A A A
  10810. // B D D C
  10811. // B D C D
  10812. // B C D D
  10813. // where the error in
  10814. // O only depends on colorO
  10815. // A only depends on colorO and colorH
  10816. // B only depends on colorO and colorV
  10817. // C only depends on colorH and colorV
  10818. // D depends on all three (colorO, colorH and colorV)
  10819. //
  10820. // Note that B can be precalculated for all combinations of colorO and colorV
  10821. // and the precalculated values can be used instead of calculating it in the inner loop.
  10822. // The same applies to C.
  10823. //
  10824. // In the code below, the squared error over O A A A is calculated and store in lowest_possible_error
  10825. // Precalc BBB errors
  10826. for(colorO_enc[2] = 0; colorO_enc[2]<64; colorO_enc[2]++)
  10827. {
  10828. for(colorV_enc[2] = 0; colorV_enc[2]<64; colorV_enc[2]++)
  10829. {
  10830. BBBtable[colorO_enc[2]*64+colorV_enc[2]] = calcBBBblue(block, colorO_enc[2], colorV_enc[2]);
  10831. }
  10832. }
  10833. // Precalc CCC errors
  10834. for(colorH_enc[2] = 0; colorH_enc[2]<64; colorH_enc[2]++)
  10835. {
  10836. for(colorV_enc[2] = 0; colorV_enc[2]<64; colorV_enc[2]++)
  10837. {
  10838. CCCtable[colorH_enc[2]*64+colorV_enc[2]] = calcCCCblue(block, colorH_enc[2], colorV_enc[2]);
  10839. }
  10840. }
  10841. best_error = MAXERR1000;
  10842. best_error_blue_sofar = JAS_MIN(best_error_blue, best_error_sofar);
  10843. for(colorO_enc[2] = 0; colorO_enc[2]<64; colorO_enc[2]++)
  10844. {
  10845. for(colorH_enc[2] = 0; colorH_enc[2]<64; colorH_enc[2]++)
  10846. {
  10847. lowest_possible_error = calcLowestPossibleBlueOH(block, colorO_enc[2], colorH_enc[2], best_error_blue_sofar);
  10848. if(lowest_possible_error <= best_error_blue_sofar)
  10849. {
  10850. for(colorV_enc[2] = 0; colorV_enc[2]<64; colorV_enc[2]++)
  10851. {
  10852. error = calcErrorPlanarOnlyBlue(block, colorO_enc[2], colorH_enc[2], colorV_enc[2], lowest_possible_error, BBBtable[colorO_enc[2]*64+colorV_enc[2]], CCCtable[colorH_enc[2]*64+colorV_enc[2]], best_error_blue_sofar);
  10853. if(error < best_error)
  10854. {
  10855. best_error = error;
  10856. best_colorO_enc[2] = colorO_enc[2];
  10857. best_colorH_enc[2] = colorH_enc[2];
  10858. best_colorV_enc[2] = colorV_enc[2];
  10859. }
  10860. }
  10861. }
  10862. }
  10863. }
  10864. compressed57_1 = 0;
  10865. compressed57_2 = 0;
  10866. PUTBITSHIGH( compressed57_1, best_colorO_enc[0], 6, 63);
  10867. PUTBITSHIGH( compressed57_1, best_colorO_enc[1], 7, 57);
  10868. PUTBITSHIGH( compressed57_1, best_colorO_enc[2], 6, 50);
  10869. PUTBITSHIGH( compressed57_1, best_colorH_enc[0], 6, 44);
  10870. PUTBITSHIGH( compressed57_1, best_colorH_enc[1], 7, 38);
  10871. PUTBITS( compressed57_2, best_colorH_enc[2], 6, 31);
  10872. PUTBITS( compressed57_2, best_colorV_enc[0], 6, 25);
  10873. PUTBITS( compressed57_2, best_colorV_enc[1], 7, 19);
  10874. PUTBITS( compressed57_2, best_colorV_enc[2], 6, 12);
  10875. }
  10876. #endif
  10877. #if EXHAUSTIVE_CODE_ACTIVE
  10878. // Precalculates a table used in exhaustive compression of the T-mode.
  10879. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  10880. void precalcError59T_col0_Rpercep1000(uint8* block, int colorRGB444_packed, unsigned int *precalc_err_col0_R)
  10881. {
  10882. unsigned int block_error = 0,
  10883. best_block_error = MAXERR1000,
  10884. pixel_error,
  10885. best_pixel_error;
  10886. int diff;
  10887. uint8 color;
  10888. uint8 possible_colors[3];
  10889. color = ((colorRGB444_packed >> 8) & 0xf)*17;
  10890. // Test all distances
  10891. for (uint8 d = 0; d < 8; d++)
  10892. {
  10893. possible_colors[0] = CLAMP(0,color - table59T[d],255);
  10894. possible_colors[1] = CLAMP(0,color,255);
  10895. possible_colors[2] = CLAMP(0,color + table59T[d],255);
  10896. // Loop block
  10897. for (int x = 0; x < 16; x++)
  10898. {
  10899. best_pixel_error = MAXERR1000;
  10900. // Loop possible block colors
  10901. for (uint8 c = 0; c < 3; c++)
  10902. {
  10903. diff = block[4*x + R] - CLAMP(0,possible_colors[c],255);
  10904. pixel_error = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE(diff);
  10905. // Choose best error
  10906. if (pixel_error < best_pixel_error)
  10907. best_pixel_error = pixel_error;
  10908. }
  10909. precalc_err_col0_R[((colorRGB444_packed>>8)*8 + d)*16 + x] = (unsigned int) best_pixel_error;
  10910. }
  10911. }
  10912. }
  10913. #endif
  10914. #if EXHAUSTIVE_CODE_ACTIVE
  10915. // Precalculates a table used in exhaustive compression of the T-mode.
  10916. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  10917. void precalcError59T_col0_R(uint8* block, int colorRGB444_packed, unsigned int *precalc_err_col0_R)
  10918. {
  10919. unsigned int block_error = 0,
  10920. best_block_error = MAXIMUM_ERROR,
  10921. pixel_error,
  10922. best_pixel_error;
  10923. int diff;
  10924. uint8 color;
  10925. uint8 possible_colors[3];
  10926. color = ((colorRGB444_packed >> 8) & 0xf)*17;
  10927. // Test all distances
  10928. for (uint8 d = 0; d < 8; d++)
  10929. {
  10930. possible_colors[0] = CLAMP(0,color - table59T[d],255);
  10931. possible_colors[1] = CLAMP(0,color,255);
  10932. possible_colors[2] = CLAMP(0,color + table59T[d],255);
  10933. // Loop block
  10934. for (int x = 0; x < 16; x++)
  10935. {
  10936. best_pixel_error = MAXIMUM_ERROR;
  10937. // Loop possible block colors
  10938. for (uint8 c = 0; c < 3; c++)
  10939. {
  10940. diff = block[4*x + R] - CLAMP(0,possible_colors[c],255);
  10941. pixel_error = SQUARE(diff);
  10942. // Choose best error
  10943. if (pixel_error < best_pixel_error)
  10944. best_pixel_error = pixel_error;
  10945. }
  10946. precalc_err_col0_R[((colorRGB444_packed>>8)*8 + d)*16 + x] = (unsigned int) best_pixel_error;
  10947. }
  10948. }
  10949. }
  10950. #endif
  10951. #if EXHAUSTIVE_CODE_ACTIVE
  10952. // Precalculates a table used in exhaustive compression of the T-mode.
  10953. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  10954. void precalcError59T_col0_RGpercep1000(uint8* block, int colorRGB444_packed, unsigned int *precalc_err_col0_RG)
  10955. {
  10956. unsigned int block_error = 0,
  10957. best_block_error = MAXERR1000,
  10958. pixel_error,
  10959. best_pixel_error;
  10960. int diff[3];
  10961. uint8 color[3];
  10962. uint8 possible_colors[3][2];
  10963. color[R] = ((colorRGB444_packed >> 8) & 0xf)*17;
  10964. color[G] = ((colorRGB444_packed >> 4) & 0xf)*17;
  10965. // Test all distances
  10966. for (uint8 d = 0; d < 8; d++)
  10967. {
  10968. possible_colors[0][R] = CLAMP(0,color[R] - table59T[d],255);
  10969. possible_colors[0][G] = CLAMP(0,color[G] - table59T[d],255);
  10970. possible_colors[1][R] = CLAMP(0,color[R],255);
  10971. possible_colors[1][G] = CLAMP(0,color[G],255);
  10972. possible_colors[2][R] = CLAMP(0,color[R] + table59T[d],255);
  10973. possible_colors[2][G] = CLAMP(0,color[G] + table59T[d],255);
  10974. // Loop block
  10975. for (int x = 0; x < 16; x++)
  10976. {
  10977. best_pixel_error = MAXERR1000;
  10978. // Loop possible block colors
  10979. for (uint8 c = 0; c < 3; c++)
  10980. {
  10981. diff[R] = block[4*x + R] - CLAMP(0,possible_colors[c][R],255);
  10982. diff[G] = block[4*x + G] - CLAMP(0,possible_colors[c][G],255);
  10983. pixel_error = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE(diff[R]) + PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*SQUARE(diff[G]);
  10984. // Choose best error
  10985. if (pixel_error < best_pixel_error)
  10986. best_pixel_error = pixel_error;
  10987. }
  10988. precalc_err_col0_RG[((colorRGB444_packed>>4)*8 + d)*16 + x] = (unsigned int) best_pixel_error;
  10989. }
  10990. }
  10991. }
  10992. #endif
  10993. #if EXHAUSTIVE_CODE_ACTIVE
  10994. // Precalculates a table used in exhaustive compression of the T-mode.
  10995. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  10996. void precalcError59T_col0_RG(uint8* block, int colorRGB444_packed, unsigned int *precalc_err_col0_RG)
  10997. {
  10998. unsigned int block_error = 0,
  10999. best_block_error = MAXIMUM_ERROR,
  11000. pixel_error,
  11001. best_pixel_error;
  11002. int diff[3];
  11003. uint8 color[3];
  11004. uint8 possible_colors[3][2];
  11005. color[R] = ((colorRGB444_packed >> 8) & 0xf)*17;
  11006. color[G] = ((colorRGB444_packed >> 4) & 0xf)*17;
  11007. // Test all distances
  11008. for (uint8 d = 0; d < 8; d++)
  11009. {
  11010. possible_colors[0][R] = CLAMP(0,color[R] - table59T[d],255);
  11011. possible_colors[0][G] = CLAMP(0,color[G] - table59T[d],255);
  11012. possible_colors[1][R] = CLAMP(0,color[R],255);
  11013. possible_colors[1][G] = CLAMP(0,color[G],255);
  11014. possible_colors[2][R] = CLAMP(0,color[R] + table59T[d],255);
  11015. possible_colors[2][G] = CLAMP(0,color[G] + table59T[d],255);
  11016. // Loop block
  11017. for (int x = 0; x < 16; x++)
  11018. {
  11019. best_pixel_error = MAXIMUM_ERROR;
  11020. // Loop possible block colors
  11021. for (uint8 c = 0; c < 3; c++)
  11022. {
  11023. diff[R] = block[4*x + R] - CLAMP(0,possible_colors[c][R],255);
  11024. diff[G] = block[4*x + G] - CLAMP(0,possible_colors[c][G],255);
  11025. pixel_error = SQUARE(diff[R]) + SQUARE(diff[G]);
  11026. // Choose best error
  11027. if (pixel_error < best_pixel_error)
  11028. best_pixel_error = pixel_error;
  11029. }
  11030. precalc_err_col0_RG[((colorRGB444_packed>>4)*8 + d)*16 + x] = (unsigned int) best_pixel_error;
  11031. }
  11032. }
  11033. }
  11034. #endif
  11035. #if EXHAUSTIVE_CODE_ACTIVE
  11036. // Precalculates a table used in exhaustive compression of the T-mode.
  11037. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  11038. void precalcError59T_col1_Rpercep1000(uint8* block, int colorRGB444_packed, unsigned int *precalc_err_col1_R)
  11039. {
  11040. unsigned int pixel_error;
  11041. int diff;
  11042. uint8 color;
  11043. color = ((colorRGB444_packed >> 8) & 0xf)*17;
  11044. // Loop block
  11045. for (int x = 0; x < 16; x++)
  11046. {
  11047. diff = block[4*x + R] - color;
  11048. pixel_error = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE(diff);
  11049. precalc_err_col1_R[((colorRGB444_packed>>8))*16 + x] = (unsigned int) pixel_error;
  11050. }
  11051. }
  11052. #endif
  11053. #if EXHAUSTIVE_CODE_ACTIVE
  11054. /**
  11055. * Calculate the error for the block at position (startx,starty)
  11056. * The parameters needed for reconstruction is calculated as well
  11057. *
  11058. * In the 59T bit mode, we only have pattern T.
  11059. */
  11060. void precalcError59T_col1_R(uint8* block, int colorRGB444_packed, unsigned int *precalc_err_col1_R)
  11061. {
  11062. unsigned int pixel_error;
  11063. int diff;
  11064. uint8 color;
  11065. color = ((colorRGB444_packed >> 8) & 0xf)*17;
  11066. // Loop block
  11067. for (int x = 0; x < 16; x++)
  11068. {
  11069. diff = block[4*x + R] - color;
  11070. pixel_error = SQUARE(diff);
  11071. precalc_err_col1_R[((colorRGB444_packed>>8))*16 + x] = (unsigned int) pixel_error;
  11072. }
  11073. }
  11074. #endif
  11075. #if EXHAUSTIVE_CODE_ACTIVE
  11076. // Precalculates a table used in exhaustive compression of the T-mode.
  11077. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  11078. void precalcError59T_col1_RGpercep1000(uint8* block, int colorRGB444_packed, unsigned int *precalc_err_col1_RG)
  11079. {
  11080. unsigned int pixel_error;
  11081. int diff[3];
  11082. uint8 color[2];
  11083. color[R] = ((colorRGB444_packed >> 8) & 0xf)*17;
  11084. color[G] = ((colorRGB444_packed >> 4) & 0xf)*17;
  11085. // Loop block
  11086. for (int x = 0; x < 16; x++)
  11087. {
  11088. diff[R] = block[4*x + R] - color[R];
  11089. diff[G] = block[4*x + G] - color[G];
  11090. pixel_error = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE(diff[R]) + PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*SQUARE(diff[G]);
  11091. precalc_err_col1_RG[((colorRGB444_packed>>4))*16 + x] = (unsigned int) pixel_error;
  11092. }
  11093. }
  11094. #endif
  11095. #if EXHAUSTIVE_CODE_ACTIVE
  11096. // Precalculates a table used in exhaustive compression of the T-mode.
  11097. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  11098. void precalcError59T_col1_RG(uint8* block, int colorRGB444_packed, unsigned int *precalc_err_col1_RG)
  11099. {
  11100. unsigned int pixel_error;
  11101. int diff[3];
  11102. uint8 color[2];
  11103. color[R] = ((colorRGB444_packed >> 8) & 0xf)*17;
  11104. color[G] = ((colorRGB444_packed >> 4) & 0xf)*17;
  11105. // Loop block
  11106. for (int x = 0; x < 16; x++)
  11107. {
  11108. diff[R] = block[4*x + R] - color[R];
  11109. diff[G] = block[4*x + G] - color[G];
  11110. pixel_error = SQUARE(diff[R]) + SQUARE(diff[G]);
  11111. precalc_err_col1_RG[((colorRGB444_packed>>4))*16 + x] = (unsigned int) pixel_error;
  11112. }
  11113. }
  11114. #endif
  11115. #if EXHAUSTIVE_CODE_ACTIVE
  11116. // Precalculates a table used in exhaustive compression of the T-mode.
  11117. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  11118. void precalcError59T_col0_RGBpercep1000(uint8* block, int colorRGB444_packed, unsigned int *precalc_err_col0_RGB)
  11119. {
  11120. unsigned int block_error = 0,
  11121. best_block_error = MAXERR1000,
  11122. pixel_error,
  11123. best_pixel_error;
  11124. uint8 color[3];
  11125. int possible_colors[3][3];
  11126. unsigned int *precalc_err_col0_RGB_adr;
  11127. #define ONEPOINT59RGB_PERCEP(xval) \
  11128. /* Loop possible block colors */\
  11129. /* unroll loop for (uint8 c = 0; c < 3; c++) */\
  11130. {\
  11131. best_pixel_error = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*square_table[block[4*xval + R] - possible_colors[0][R]]\
  11132. + PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*square_table[block[4*xval + G] - possible_colors[0][G]] \
  11133. + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[block[4*xval + B] - possible_colors[0][B]];\
  11134. pixel_error = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*square_table[block[4*xval + R] - possible_colors[1][R]]\
  11135. + PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*square_table[block[4*xval + G] - possible_colors[1][G]]\
  11136. + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[block[4*xval + B] - possible_colors[1][B]];\
  11137. if (pixel_error < best_pixel_error)\
  11138. best_pixel_error = pixel_error;\
  11139. pixel_error = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*square_table[block[4*xval + R] - possible_colors[2][R]]\
  11140. + PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*square_table[block[4*xval + G] - possible_colors[2][G]]\
  11141. + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[block[4*xval + B] - possible_colors[2][B]];\
  11142. if (pixel_error < best_pixel_error)\
  11143. best_pixel_error = pixel_error;\
  11144. }\
  11145. precalc_err_col0_RGB_adr[xval] = (unsigned int) best_pixel_error;\
  11146. #define ONETABLE59RGB_PERCEP(dval) \
  11147. possible_colors[0][R] = clamp_table[color[R] - table59T[dval]+255]-255;\
  11148. possible_colors[0][G] = clamp_table[color[G] - table59T[dval]+255]-255;\
  11149. possible_colors[0][B] = clamp_table[color[B] - table59T[dval]+255]-255;\
  11150. possible_colors[1][R] = color[R]-255;\
  11151. possible_colors[1][G] = color[G]-255;\
  11152. possible_colors[1][B] = color[B]-255;\
  11153. possible_colors[2][R] = clamp_table[color[R] + table59T[dval]+255]-255;\
  11154. possible_colors[2][G] = clamp_table[color[G] + table59T[dval]+255]-255;\
  11155. possible_colors[2][B] = clamp_table[color[B] + table59T[dval]+255]-255;\
  11156. precalc_err_col0_RGB_adr = &precalc_err_col0_RGB[(colorRGB444_packed*8 + dval)*16];\
  11157. /* Loop block */\
  11158. /* unroll loop for (int x = 0; x < 16; x++) */\
  11159. {\
  11160. ONEPOINT59RGB_PERCEP(0)\
  11161. ONEPOINT59RGB_PERCEP(1)\
  11162. ONEPOINT59RGB_PERCEP(2)\
  11163. ONEPOINT59RGB_PERCEP(3)\
  11164. ONEPOINT59RGB_PERCEP(4)\
  11165. ONEPOINT59RGB_PERCEP(5)\
  11166. ONEPOINT59RGB_PERCEP(6)\
  11167. ONEPOINT59RGB_PERCEP(7)\
  11168. ONEPOINT59RGB_PERCEP(8)\
  11169. ONEPOINT59RGB_PERCEP(9)\
  11170. ONEPOINT59RGB_PERCEP(10)\
  11171. ONEPOINT59RGB_PERCEP(11)\
  11172. ONEPOINT59RGB_PERCEP(12)\
  11173. ONEPOINT59RGB_PERCEP(13)\
  11174. ONEPOINT59RGB_PERCEP(14)\
  11175. ONEPOINT59RGB_PERCEP(15)\
  11176. }\
  11177. color[R] = (((colorRGB444_packed >> 8) ) << 4) | ((colorRGB444_packed >> 8) ) ;
  11178. color[G] = (((colorRGB444_packed >> 4) & 0xf) << 4) | ((colorRGB444_packed >> 4) & 0xf) ;
  11179. color[B] = (((colorRGB444_packed) & 0xf) << 4) | ((colorRGB444_packed) & 0xf) ;
  11180. /* Test all distances */
  11181. /* unroll loop for (uint8 d = 0; d < 8; ++d) */
  11182. {
  11183. ONETABLE59RGB_PERCEP(0)
  11184. ONETABLE59RGB_PERCEP(1)
  11185. ONETABLE59RGB_PERCEP(2)
  11186. ONETABLE59RGB_PERCEP(3)
  11187. ONETABLE59RGB_PERCEP(4)
  11188. ONETABLE59RGB_PERCEP(5)
  11189. ONETABLE59RGB_PERCEP(6)
  11190. ONETABLE59RGB_PERCEP(7)
  11191. }
  11192. }
  11193. #endif
  11194. #if EXHAUSTIVE_CODE_ACTIVE
  11195. // Precalculates a table used in exhaustive compression of the T-mode.
  11196. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  11197. void precalcError59T_col0_RGB(uint8* block, int colorRGB444_packed, unsigned int *precalc_err_col0_RGB)
  11198. {
  11199. unsigned int block_error = 0,
  11200. best_block_error = MAXIMUM_ERROR,
  11201. pixel_error,
  11202. best_pixel_error;
  11203. uint8 color[3];
  11204. int possible_colors[3][3];
  11205. unsigned int *precalc_err_col0_RGB_adr;
  11206. #define ONEPOINT59RGB(xval) \
  11207. /* Loop possible block colors */\
  11208. /* unroll loop for (uint8 c = 0; c < 3; c++) */\
  11209. {\
  11210. best_pixel_error = square_table[block[4*xval + R] - possible_colors[0][R]]\
  11211. + square_table[block[4*xval + G] - possible_colors[0][G]] \
  11212. + square_table[block[4*xval + B] - possible_colors[0][B]];\
  11213. pixel_error = square_table[block[4*xval + R] - possible_colors[1][R]]\
  11214. + square_table[block[4*xval + G] - possible_colors[1][G]]\
  11215. + square_table[block[4*xval + B] - possible_colors[1][B]];\
  11216. if (pixel_error < best_pixel_error)\
  11217. best_pixel_error = pixel_error;\
  11218. pixel_error = square_table[block[4*xval + R] - possible_colors[2][R]]\
  11219. + square_table[block[4*xval + G] - possible_colors[2][G]]\
  11220. + square_table[block[4*xval + B] - possible_colors[2][B]];\
  11221. if (pixel_error < best_pixel_error)\
  11222. best_pixel_error = pixel_error;\
  11223. }\
  11224. precalc_err_col0_RGB_adr[xval] = (unsigned int) best_pixel_error;\
  11225. #define ONETABLE59RGB(dval) \
  11226. possible_colors[0][R] = clamp_table[color[R] - table59T[dval]+255]-255;\
  11227. possible_colors[0][G] = clamp_table[color[G] - table59T[dval]+255]-255;\
  11228. possible_colors[0][B] = clamp_table[color[B] - table59T[dval]+255]-255;\
  11229. possible_colors[1][R] = color[R]-255;\
  11230. possible_colors[1][G] = color[G]-255;\
  11231. possible_colors[1][B] = color[B]-255;\
  11232. possible_colors[2][R] = clamp_table[color[R] + table59T[dval]+255]-255;\
  11233. possible_colors[2][G] = clamp_table[color[G] + table59T[dval]+255]-255;\
  11234. possible_colors[2][B] = clamp_table[color[B] + table59T[dval]+255]-255;\
  11235. precalc_err_col0_RGB_adr = &precalc_err_col0_RGB[(colorRGB444_packed*8 + dval)*16];\
  11236. /* Loop block */\
  11237. /* unroll loop for (int x = 0; x < 16; x++) */\
  11238. {\
  11239. ONEPOINT59RGB(0)\
  11240. ONEPOINT59RGB(1)\
  11241. ONEPOINT59RGB(2)\
  11242. ONEPOINT59RGB(3)\
  11243. ONEPOINT59RGB(4)\
  11244. ONEPOINT59RGB(5)\
  11245. ONEPOINT59RGB(6)\
  11246. ONEPOINT59RGB(7)\
  11247. ONEPOINT59RGB(8)\
  11248. ONEPOINT59RGB(9)\
  11249. ONEPOINT59RGB(10)\
  11250. ONEPOINT59RGB(11)\
  11251. ONEPOINT59RGB(12)\
  11252. ONEPOINT59RGB(13)\
  11253. ONEPOINT59RGB(14)\
  11254. ONEPOINT59RGB(15)\
  11255. }\
  11256. color[R] = (((colorRGB444_packed >> 8) ) << 4) | ((colorRGB444_packed >> 8) ) ;
  11257. color[G] = (((colorRGB444_packed >> 4) & 0xf) << 4) | ((colorRGB444_packed >> 4) & 0xf) ;
  11258. color[B] = (((colorRGB444_packed) & 0xf) << 4) | ((colorRGB444_packed) & 0xf) ;
  11259. /* Test all distances */
  11260. /* unroll loop for (uint8 d = 0; d < 8; ++d) */
  11261. {
  11262. ONETABLE59RGB(0)
  11263. ONETABLE59RGB(1)
  11264. ONETABLE59RGB(2)
  11265. ONETABLE59RGB(3)
  11266. ONETABLE59RGB(4)
  11267. ONETABLE59RGB(5)
  11268. ONETABLE59RGB(6)
  11269. ONETABLE59RGB(7)
  11270. }
  11271. }
  11272. #endif
  11273. #if EXHAUSTIVE_CODE_ACTIVE
  11274. // Precalculates a table used in exhaustive compression of the T-mode.
  11275. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  11276. void precalcError59T_col1_RGBpercep1000(uint8* block, int colorRGB444_packed, unsigned int *precalc_err_col1_RGB)
  11277. {
  11278. unsigned int pixel_error;
  11279. int diff[3];
  11280. uint8 colorRGB[3];
  11281. colorRGB[0] = ((colorRGB444_packed >> 8) & 0xf)*17;
  11282. colorRGB[1] = ((colorRGB444_packed >> 4) & 0xf)*17;
  11283. colorRGB[2] = ((colorRGB444_packed >> 0) & 0xf)*17;
  11284. // Loop block
  11285. for (int x = 0; x < 16; x++)
  11286. {
  11287. diff[R] = block[4*x + R] - colorRGB[R];
  11288. diff[G] = block[4*x + G] - colorRGB[G];
  11289. diff[B] = block[4*x + B] - colorRGB[B];
  11290. pixel_error = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE(diff[R]) + PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*SQUARE(diff[G]) + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*SQUARE(diff[B]);
  11291. precalc_err_col1_RGB[(colorRGB444_packed)*16 + x] = (unsigned int) pixel_error;
  11292. }
  11293. }
  11294. #endif
  11295. #if EXHAUSTIVE_CODE_ACTIVE
  11296. // Precalculates a table used in exhaustive compression of the T-mode.
  11297. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  11298. void precalcError59T_col1_RGB(uint8* block, int colorRGB444_packed, unsigned int *precalc_err_col1_RGB)
  11299. {
  11300. unsigned int pixel_error;
  11301. int diff[3];
  11302. uint8 colorRGB[3];
  11303. colorRGB[0] = ((colorRGB444_packed >> 8) & 0xf)*17;
  11304. colorRGB[1] = ((colorRGB444_packed >> 4) & 0xf)*17;
  11305. colorRGB[2] = ((colorRGB444_packed >> 0) & 0xf)*17;
  11306. // Loop block
  11307. for (int x = 0; x < 16; x++)
  11308. {
  11309. diff[R] = block[4*x + R] - colorRGB[R];
  11310. diff[G] = block[4*x + G] - colorRGB[G];
  11311. diff[B] = block[4*x + B] - colorRGB[B];
  11312. pixel_error = SQUARE(diff[R]) + SQUARE(diff[G]) + SQUARE(diff[B]);
  11313. precalc_err_col1_RGB[(colorRGB444_packed)*16 + x] = (unsigned int) pixel_error;
  11314. }
  11315. }
  11316. #endif
  11317. #if EXHAUSTIVE_CODE_ACTIVE
  11318. // Calculate a minimal error for the T-mode when compressing exhaustively.
  11319. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  11320. unsigned int calculateError59TusingPrecalcRperceptual1000(uint8* block, int *colorsRGB444_packed, unsigned int *precalc_err_col0_R, unsigned int *precalc_err_col1_R, unsigned int best_error_so_far)
  11321. {
  11322. unsigned int block_error = 0,
  11323. best_block_error = MAXERR1000;
  11324. unsigned int *pixel_error_col0_base_adr;
  11325. unsigned int *pixel_error_col0_adr, *pixel_error_col1_adr;
  11326. #define FIRSTCHOICE59R_PERCEP\
  11327. if(*pixel_error_col0_adr < *pixel_error_col1_adr)\
  11328. block_error = *pixel_error_col0_adr;\
  11329. else\
  11330. block_error = *pixel_error_col1_adr;\
  11331. #define CHOICE59R_PERCEP(xval)\
  11332. if(pixel_error_col0_adr[xval] < pixel_error_col1_adr[xval])\
  11333. block_error += pixel_error_col0_adr[xval];\
  11334. else\
  11335. block_error += pixel_error_col1_adr[xval];\
  11336. #define ONETABLE59R_PERCEP(dval) \
  11337. pixel_error_col0_adr = &pixel_error_col0_base_adr[dval*16];\
  11338. /* unroll loop for(int x = 0; block_error < best_error_so_far && x<16; x++) */\
  11339. {\
  11340. FIRSTCHOICE59R_PERCEP\
  11341. if( block_error < best_error_so_far)\
  11342. {\
  11343. CHOICE59R_PERCEP(1)\
  11344. if( block_error < best_error_so_far)\
  11345. {\
  11346. CHOICE59R_PERCEP(2)\
  11347. CHOICE59R_PERCEP(3)\
  11348. if( block_error < best_error_so_far)\
  11349. {\
  11350. CHOICE59R_PERCEP(4)\
  11351. CHOICE59R_PERCEP(5)\
  11352. if( block_error < best_error_so_far)\
  11353. {\
  11354. CHOICE59R_PERCEP(6)\
  11355. CHOICE59R_PERCEP(7)\
  11356. if( block_error < best_error_so_far)\
  11357. {\
  11358. CHOICE59R_PERCEP(8)\
  11359. CHOICE59R_PERCEP(9)\
  11360. if( block_error < best_error_so_far)\
  11361. {\
  11362. CHOICE59R_PERCEP(10)\
  11363. CHOICE59R_PERCEP(11)\
  11364. if( block_error < best_error_so_far)\
  11365. {\
  11366. CHOICE59R_PERCEP(12)\
  11367. CHOICE59R_PERCEP(13)\
  11368. if( block_error < best_error_so_far)\
  11369. {\
  11370. CHOICE59R_PERCEP(14)\
  11371. CHOICE59R_PERCEP(15)\
  11372. }\
  11373. }\
  11374. }\
  11375. }\
  11376. }\
  11377. }\
  11378. }\
  11379. }\
  11380. }\
  11381. if (block_error < best_block_error)\
  11382. best_block_error = block_error;\
  11383. pixel_error_col0_base_adr = &precalc_err_col0_R[((colorsRGB444_packed[0]>>8)*8)*16];
  11384. pixel_error_col1_adr = &precalc_err_col1_R[((colorsRGB444_packed[1]>>8))*16];
  11385. // Test all distances
  11386. /* unroll loop for (uint8 d = 0; d < 8; d++) */
  11387. {
  11388. ONETABLE59R_PERCEP(0)
  11389. ONETABLE59R_PERCEP(1)
  11390. ONETABLE59R_PERCEP(2)
  11391. ONETABLE59R_PERCEP(3)
  11392. ONETABLE59R_PERCEP(4)
  11393. ONETABLE59R_PERCEP(5)
  11394. ONETABLE59R_PERCEP(6)
  11395. ONETABLE59R_PERCEP(7)
  11396. }
  11397. return best_block_error;
  11398. }
  11399. #endif
  11400. #if EXHAUSTIVE_CODE_ACTIVE
  11401. // Calculate a minimal error for the T-mode when compressing exhaustively.
  11402. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  11403. unsigned int calculateError59TusingPrecalcR(uint8* block, int *colorsRGB444_packed, unsigned int *precalc_err_col0_R, unsigned int *precalc_err_col1_R, unsigned int best_error_so_far)
  11404. {
  11405. unsigned int block_error = 0,
  11406. best_block_error = MAXIMUM_ERROR;
  11407. unsigned int *pixel_error_col0_base_adr;
  11408. unsigned int *pixel_error_col0_adr, *pixel_error_col1_adr;
  11409. #define FIRSTCHOICE59R\
  11410. if(*pixel_error_col0_adr < *pixel_error_col1_adr)\
  11411. block_error = *pixel_error_col0_adr;\
  11412. else\
  11413. block_error = *pixel_error_col1_adr;\
  11414. #define CHOICE59R(xval)\
  11415. if(pixel_error_col0_adr[xval] < pixel_error_col1_adr[xval])\
  11416. block_error += pixel_error_col0_adr[xval];\
  11417. else\
  11418. block_error += pixel_error_col1_adr[xval];\
  11419. #define ONETABLE59R(dval) \
  11420. pixel_error_col0_adr = &pixel_error_col0_base_adr[dval*16];\
  11421. /* unroll loop for(int x = 0; block_error < best_error_so_far && x<16; x++) */\
  11422. {\
  11423. FIRSTCHOICE59R\
  11424. if( block_error < best_error_so_far)\
  11425. {\
  11426. CHOICE59R(1)\
  11427. if( block_error < best_error_so_far)\
  11428. {\
  11429. CHOICE59R(2)\
  11430. CHOICE59R(3)\
  11431. if( block_error < best_error_so_far)\
  11432. {\
  11433. CHOICE59R(4)\
  11434. CHOICE59R(5)\
  11435. if( block_error < best_error_so_far)\
  11436. {\
  11437. CHOICE59R(6)\
  11438. CHOICE59R(7)\
  11439. if( block_error < best_error_so_far)\
  11440. {\
  11441. CHOICE59R(8)\
  11442. CHOICE59R(9)\
  11443. if( block_error < best_error_so_far)\
  11444. {\
  11445. CHOICE59R(10)\
  11446. CHOICE59R(11)\
  11447. if( block_error < best_error_so_far)\
  11448. {\
  11449. CHOICE59R(12)\
  11450. CHOICE59R(13)\
  11451. if( block_error < best_error_so_far)\
  11452. {\
  11453. CHOICE59R(14)\
  11454. CHOICE59R(15)\
  11455. }\
  11456. }\
  11457. }\
  11458. }\
  11459. }\
  11460. }\
  11461. }\
  11462. }\
  11463. }\
  11464. if (block_error < best_block_error)\
  11465. best_block_error = block_error;\
  11466. pixel_error_col0_base_adr = &precalc_err_col0_R[((colorsRGB444_packed[0]>>8)*8)*16];
  11467. pixel_error_col1_adr = &precalc_err_col1_R[((colorsRGB444_packed[1]>>8))*16];
  11468. // Test all distances
  11469. /* unroll loop for (uint8 d = 0; d < 8; d++) */
  11470. {
  11471. ONETABLE59R(0)
  11472. ONETABLE59R(1)
  11473. ONETABLE59R(2)
  11474. ONETABLE59R(3)
  11475. ONETABLE59R(4)
  11476. ONETABLE59R(5)
  11477. ONETABLE59R(6)
  11478. ONETABLE59R(7)
  11479. }
  11480. return best_block_error;
  11481. }
  11482. #endif
  11483. #if EXHAUSTIVE_CODE_ACTIVE
  11484. // Calculate a minimal error for the T-mode when compressing exhaustively.
  11485. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  11486. unsigned int calculateError59TusingPrecalcRGperceptual1000(uint8* block, int *colorsRGB444_packed, unsigned int *precalc_err_col0_RG, unsigned int *precalc_err_col1_RG, unsigned int best_error_so_far)
  11487. {
  11488. unsigned int block_error = 0,
  11489. best_block_error = MAXERR1000;
  11490. unsigned int *pixel_error_col0_adr, *pixel_error_col1_adr;
  11491. unsigned int *pixel_error_col0_base_adr;
  11492. #define FIRSTCHOICE59RG_PERCEP \
  11493. if(*pixel_error_col0_adr < *pixel_error_col1_adr)\
  11494. block_error = *pixel_error_col0_adr;\
  11495. else\
  11496. block_error = *pixel_error_col1_adr;\
  11497. #define CHOICE59RG_PERCEP(xval) \
  11498. if(pixel_error_col0_adr[xval] < pixel_error_col1_adr[xval])\
  11499. block_error += pixel_error_col0_adr[xval];\
  11500. else\
  11501. block_error += pixel_error_col1_adr[xval];\
  11502. #define ONETABLE59RG_PERCEP(dval)\
  11503. pixel_error_col0_adr = &pixel_error_col0_base_adr[dval*16];\
  11504. /* unroll loop for(int x = 0; block_error < best_error_so_far && x<16; x++) */\
  11505. {\
  11506. FIRSTCHOICE59RG_PERCEP\
  11507. if( block_error < best_error_so_far)\
  11508. {\
  11509. CHOICE59RG_PERCEP(1)\
  11510. if( block_error < best_error_so_far)\
  11511. {\
  11512. CHOICE59RG_PERCEP(2)\
  11513. CHOICE59RG_PERCEP(3)\
  11514. if( block_error < best_error_so_far)\
  11515. {\
  11516. CHOICE59RG_PERCEP(4)\
  11517. CHOICE59RG_PERCEP(5)\
  11518. if( block_error < best_error_so_far)\
  11519. {\
  11520. CHOICE59RG_PERCEP(6)\
  11521. CHOICE59RG_PERCEP(7)\
  11522. if( block_error < best_error_so_far)\
  11523. {\
  11524. CHOICE59RG_PERCEP(8)\
  11525. CHOICE59RG_PERCEP(9)\
  11526. if( block_error < best_error_so_far)\
  11527. {\
  11528. CHOICE59RG_PERCEP(10)\
  11529. CHOICE59RG_PERCEP(11)\
  11530. if( block_error < best_error_so_far)\
  11531. {\
  11532. CHOICE59RG_PERCEP(12)\
  11533. CHOICE59RG_PERCEP(13)\
  11534. if( block_error < best_error_so_far)\
  11535. {\
  11536. CHOICE59RG_PERCEP(14)\
  11537. CHOICE59RG_PERCEP(15)\
  11538. }\
  11539. }\
  11540. }\
  11541. }\
  11542. }\
  11543. }\
  11544. }\
  11545. }\
  11546. }\
  11547. if (block_error < best_block_error)\
  11548. best_block_error = block_error;\
  11549. pixel_error_col0_base_adr = &precalc_err_col0_RG[((colorsRGB444_packed[0]>>4)*8)*16];
  11550. pixel_error_col1_adr = &precalc_err_col1_RG[((colorsRGB444_packed[1]>>4))*16];
  11551. // Test all distances
  11552. /* unroll loop for (uint8 d = 0; d < 8; d++) */
  11553. {
  11554. ONETABLE59RG_PERCEP(0)
  11555. ONETABLE59RG_PERCEP(1)
  11556. ONETABLE59RG_PERCEP(2)
  11557. ONETABLE59RG_PERCEP(3)
  11558. ONETABLE59RG_PERCEP(4)
  11559. ONETABLE59RG_PERCEP(5)
  11560. ONETABLE59RG_PERCEP(6)
  11561. ONETABLE59RG_PERCEP(7)
  11562. }
  11563. return best_block_error;
  11564. }
  11565. #endif
  11566. #if EXHAUSTIVE_CODE_ACTIVE
  11567. // Calculate a minimal error for the T-mode when compressing exhaustively.
  11568. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  11569. unsigned int calculateError59TusingPrecalcRG(uint8* block, int *colorsRGB444_packed, unsigned int *precalc_err_col0_RG, unsigned int *precalc_err_col1_RG, unsigned int best_error_so_far)
  11570. {
  11571. unsigned int block_error = 0,
  11572. best_block_error = MAXIMUM_ERROR;
  11573. unsigned int *pixel_error_col0_adr, *pixel_error_col1_adr;
  11574. unsigned int *pixel_error_col0_base_adr;
  11575. #define FIRSTCHOICE59RG \
  11576. if(*pixel_error_col0_adr < *pixel_error_col1_adr)\
  11577. block_error = *pixel_error_col0_adr;\
  11578. else\
  11579. block_error = *pixel_error_col1_adr;\
  11580. #define CHOICE59RG(xval) \
  11581. if(pixel_error_col0_adr[xval] < pixel_error_col1_adr[xval])\
  11582. block_error += pixel_error_col0_adr[xval];\
  11583. else\
  11584. block_error += pixel_error_col1_adr[xval];\
  11585. #define ONETABLE59RG(dval)\
  11586. pixel_error_col0_adr = &pixel_error_col0_base_adr[dval*16];\
  11587. /* unroll loop for(int x = 0; block_error < best_error_so_far && x<16; x++) */\
  11588. {\
  11589. FIRSTCHOICE59RG\
  11590. if( block_error < best_error_so_far)\
  11591. {\
  11592. CHOICE59RG(1)\
  11593. if( block_error < best_error_so_far)\
  11594. {\
  11595. CHOICE59RG(2)\
  11596. CHOICE59RG(3)\
  11597. if( block_error < best_error_so_far)\
  11598. {\
  11599. CHOICE59RG(4)\
  11600. CHOICE59RG(5)\
  11601. if( block_error < best_error_so_far)\
  11602. {\
  11603. CHOICE59RG(6)\
  11604. CHOICE59RG(7)\
  11605. if( block_error < best_error_so_far)\
  11606. {\
  11607. CHOICE59RG(8)\
  11608. CHOICE59RG(9)\
  11609. if( block_error < best_error_so_far)\
  11610. {\
  11611. CHOICE59RG(10)\
  11612. CHOICE59RG(11)\
  11613. if( block_error < best_error_so_far)\
  11614. {\
  11615. CHOICE59RG(12)\
  11616. CHOICE59RG(13)\
  11617. if( block_error < best_error_so_far)\
  11618. {\
  11619. CHOICE59RG(14)\
  11620. CHOICE59RG(15)\
  11621. }\
  11622. }\
  11623. }\
  11624. }\
  11625. }\
  11626. }\
  11627. }\
  11628. }\
  11629. }\
  11630. if (block_error < best_block_error)\
  11631. best_block_error = block_error;\
  11632. pixel_error_col0_base_adr = &precalc_err_col0_RG[((colorsRGB444_packed[0]>>4)*8)*16];
  11633. pixel_error_col1_adr = &precalc_err_col1_RG[((colorsRGB444_packed[1]>>4))*16];
  11634. // Test all distances
  11635. /* unroll loop for (uint8 d = 0; d < 8; d++) */
  11636. {
  11637. ONETABLE59RG(0)
  11638. ONETABLE59RG(1)
  11639. ONETABLE59RG(2)
  11640. ONETABLE59RG(3)
  11641. ONETABLE59RG(4)
  11642. ONETABLE59RG(5)
  11643. ONETABLE59RG(6)
  11644. ONETABLE59RG(7)
  11645. }
  11646. return best_block_error;
  11647. }
  11648. #endif
  11649. #if EXHAUSTIVE_CODE_ACTIVE
  11650. // Calculate a minimal error for the T-mode when compressing exhaustively.
  11651. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  11652. unsigned int calculateError59TusingPrecalcRGBperceptual1000(uint8* block, int *colorsRGB444_packed, unsigned int *precalc_err_col0_RGB, unsigned int *precalc_err_col1_RGB, unsigned int best_error_so_far)
  11653. {
  11654. unsigned int block_error = 0,
  11655. best_block_error = MAXERR1000;
  11656. unsigned int *pixel_error_col0_adr, *pixel_error_col1_adr;
  11657. unsigned int *pixel_error_col0_base_adr;
  11658. #define FIRSTCHOICE59_PERCEP \
  11659. if(*pixel_error_col0_adr < *pixel_error_col1_adr)\
  11660. block_error = *pixel_error_col0_adr;\
  11661. else\
  11662. block_error = *pixel_error_col1_adr;\
  11663. #define CHOICE59_PERCEP(xval) \
  11664. if(pixel_error_col0_adr[xval] < pixel_error_col1_adr[xval])\
  11665. block_error += pixel_error_col0_adr[xval];\
  11666. else\
  11667. block_error += pixel_error_col1_adr[xval];\
  11668. #define ONETABLE59T_PERCEP(dval)\
  11669. pixel_error_col0_adr = &pixel_error_col0_base_adr[dval*16];\
  11670. /* unroll for(int x = 0; block_error < best_error_so_far && x<16; x++) */\
  11671. {\
  11672. FIRSTCHOICE59_PERCEP\
  11673. if( block_error < best_error_so_far)\
  11674. {\
  11675. CHOICE59_PERCEP(1)\
  11676. if( block_error < best_error_so_far)\
  11677. {\
  11678. CHOICE59_PERCEP(2)\
  11679. CHOICE59_PERCEP(3)\
  11680. if( block_error < best_error_so_far)\
  11681. {\
  11682. CHOICE59_PERCEP(4)\
  11683. CHOICE59_PERCEP(5)\
  11684. if( block_error < best_error_so_far)\
  11685. {\
  11686. CHOICE59_PERCEP(6)\
  11687. CHOICE59_PERCEP(7)\
  11688. if( block_error < best_error_so_far)\
  11689. {\
  11690. CHOICE59_PERCEP(8)\
  11691. CHOICE59_PERCEP(9)\
  11692. if( block_error < best_error_so_far)\
  11693. {\
  11694. CHOICE59_PERCEP(10)\
  11695. CHOICE59_PERCEP(11)\
  11696. if( block_error < best_error_so_far)\
  11697. {\
  11698. CHOICE59_PERCEP(12)\
  11699. CHOICE59_PERCEP(13)\
  11700. if( block_error < best_error_so_far)\
  11701. {\
  11702. CHOICE59_PERCEP(14)\
  11703. CHOICE59_PERCEP(15)\
  11704. }\
  11705. }\
  11706. }\
  11707. }\
  11708. }\
  11709. }\
  11710. }\
  11711. }\
  11712. }\
  11713. if (block_error < best_block_error)\
  11714. best_block_error = block_error;\
  11715. pixel_error_col1_adr = &precalc_err_col1_RGB[(colorsRGB444_packed[1])*16];
  11716. pixel_error_col0_base_adr = &precalc_err_col0_RGB[(colorsRGB444_packed[0]*8)*16];
  11717. // Test all distances
  11718. /* unroll loop for (uint8 d = 0; d < 8; d++)*/
  11719. {
  11720. ONETABLE59T_PERCEP(0)
  11721. ONETABLE59T_PERCEP(1)
  11722. ONETABLE59T_PERCEP(2)
  11723. ONETABLE59T_PERCEP(3)
  11724. ONETABLE59T_PERCEP(4)
  11725. ONETABLE59T_PERCEP(5)
  11726. ONETABLE59T_PERCEP(6)
  11727. ONETABLE59T_PERCEP(7)
  11728. }
  11729. return best_block_error;
  11730. }
  11731. #endif
  11732. #if EXHAUSTIVE_CODE_ACTIVE
  11733. // Calculate a minimal error for the T-mode when compressing exhaustively.
  11734. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  11735. unsigned int calculateError59TusingPrecalcRGB(uint8* block, int *colorsRGB444_packed, unsigned int *precalc_err_col0_RGB, unsigned int *precalc_err_col1_RGB, unsigned int best_error_so_far)
  11736. {
  11737. unsigned int block_error = 0,
  11738. best_block_error = MAXIMUM_ERROR;
  11739. unsigned int *pixel_error_col0_adr, *pixel_error_col1_adr;
  11740. unsigned int *pixel_error_col0_base_adr;
  11741. #define FIRSTCHOICE59 \
  11742. if(*pixel_error_col0_adr < *pixel_error_col1_adr)\
  11743. block_error = *pixel_error_col0_adr;\
  11744. else\
  11745. block_error = *pixel_error_col1_adr;\
  11746. #define CHOICE59(xval) \
  11747. if(pixel_error_col0_adr[xval] < pixel_error_col1_adr[xval])\
  11748. block_error += pixel_error_col0_adr[xval];\
  11749. else\
  11750. block_error += pixel_error_col1_adr[xval];\
  11751. #define ONETABLE59T(dval)\
  11752. pixel_error_col0_adr = &pixel_error_col0_base_adr[dval*16];\
  11753. /* unroll for(int x = 0; block_error < best_error_so_far && x<16; x++) */\
  11754. {\
  11755. FIRSTCHOICE59\
  11756. if( block_error < best_error_so_far)\
  11757. {\
  11758. CHOICE59(1)\
  11759. if( block_error < best_error_so_far)\
  11760. {\
  11761. CHOICE59(2)\
  11762. CHOICE59(3)\
  11763. if( block_error < best_error_so_far)\
  11764. {\
  11765. CHOICE59(4)\
  11766. CHOICE59(5)\
  11767. if( block_error < best_error_so_far)\
  11768. {\
  11769. CHOICE59(6)\
  11770. CHOICE59(7)\
  11771. if( block_error < best_error_so_far)\
  11772. {\
  11773. CHOICE59(8)\
  11774. CHOICE59(9)\
  11775. if( block_error < best_error_so_far)\
  11776. {\
  11777. CHOICE59(10)\
  11778. CHOICE59(11)\
  11779. if( block_error < best_error_so_far)\
  11780. {\
  11781. CHOICE59(12)\
  11782. CHOICE59(13)\
  11783. if( block_error < best_error_so_far)\
  11784. {\
  11785. CHOICE59(14)\
  11786. CHOICE59(15)\
  11787. }\
  11788. }\
  11789. }\
  11790. }\
  11791. }\
  11792. }\
  11793. }\
  11794. }\
  11795. }\
  11796. if (block_error < best_block_error)\
  11797. best_block_error = block_error;\
  11798. pixel_error_col1_adr = &precalc_err_col1_RGB[(colorsRGB444_packed[1])*16];
  11799. pixel_error_col0_base_adr = &precalc_err_col0_RGB[(colorsRGB444_packed[0]*8)*16];
  11800. // Test all distances
  11801. /* unroll loop for (uint8 d = 0; d < 8; d++)*/
  11802. {
  11803. ONETABLE59T(0)
  11804. ONETABLE59T(1)
  11805. ONETABLE59T(2)
  11806. ONETABLE59T(3)
  11807. ONETABLE59T(4)
  11808. ONETABLE59T(5)
  11809. ONETABLE59T(6)
  11810. ONETABLE59T(7)
  11811. }
  11812. return best_block_error;
  11813. }
  11814. #endif
  11815. #if EXHAUSTIVE_CODE_ACTIVE
  11816. // The below code should compress the block to 59 bits.
  11817. // This is supposed to match the first of the three modes in TWOTIMER.
  11818. //
  11819. //|63 62 61 60 59|58 57 56 55|54 53 52 51|50 49 48 47|46 45 44 43|42 41 40 39|38 37 36 35|34 33 32|
  11820. //|----empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|--dist--|
  11821. //
  11822. //|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  11823. //|----------------------------------------index bits---------------------------------------------|
  11824. //
  11825. // Note that this method might not return the best possible compression for the T-mode. It will only do so if the best possible T-representation
  11826. // is less than best_error_so_far. To guarantee that the best possible T-representation is found, the function should be called using
  11827. // best_error_so_far = 255*255*3*16, which is the maximum error for a block.
  11828. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  11829. unsigned int compressBlockTHUMB59TExhaustivePerceptual(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2, unsigned int best_error_so_far)
  11830. {
  11831. uint8 colorsRGB444[2][3];
  11832. unsigned int pixel_indices;
  11833. uint8 distance;
  11834. uint8 block[4*4*4];
  11835. unsigned int *precalc_err_col0_RGB;
  11836. unsigned int *precalc_err_col1_RGB;
  11837. unsigned int *precalc_err_col0_RG;
  11838. unsigned int *precalc_err_col1_RG;
  11839. unsigned int *precalc_err_col0_R;
  11840. unsigned int *precalc_err_col1_R;
  11841. int colorRGB444_packed;
  11842. int colorsRGB444_packed[2];
  11843. int best_colorsRGB444_packed[2];
  11844. unsigned int best_error_using_Tmode;
  11845. // First compress block quickly to a resonable quality so that we can
  11846. // rule out all blocks that are of worse quality than that.
  11847. best_error_using_Tmode = (unsigned int) compressBlockTHUMB59TFastestOnlyColorPerceptual1000(img, width, height, startx, starty, best_colorsRGB444_packed);
  11848. if(best_error_using_Tmode < best_error_so_far)
  11849. best_error_so_far = best_error_using_Tmode;
  11850. // Color numbering is reversed between the above function and the precalc functions below; swap colors.
  11851. int temp = best_colorsRGB444_packed[0];
  11852. best_colorsRGB444_packed[0] = best_colorsRGB444_packed[1];
  11853. best_colorsRGB444_packed[1] = temp;
  11854. int xx,yy,count = 0;
  11855. // Use 4 bytes per pixel to make it 32-word aligned.
  11856. for(xx = 0; xx<4; xx++)
  11857. {
  11858. for(yy=0; yy<4; yy++)
  11859. {
  11860. block[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  11861. block[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  11862. block[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  11863. block[(count)*4+3] = 0;
  11864. count++;
  11865. }
  11866. }
  11867. // Precalculate error for color 0 (which produces the upper half of the T)
  11868. precalc_err_col0_RGB = (unsigned int*) malloc(4096*8*16*sizeof(unsigned int));
  11869. if(!precalc_err_col0_RGB){printf("Out of memory allocating \n");exit(1);}
  11870. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed++)
  11871. {
  11872. precalcError59T_col0_RGBpercep1000(block, colorRGB444_packed, precalc_err_col0_RGB);
  11873. }
  11874. // Precalculate error for color 1 (which produces the lower half of the T -- the lone color)
  11875. precalc_err_col1_RGB = (unsigned int*) malloc(4096*16*sizeof(unsigned int));
  11876. if(!precalc_err_col1_RGB){printf("Out of memory allocating \n");exit(1);}
  11877. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed++)
  11878. {
  11879. precalcError59T_col1_RGBpercep1000(block, colorRGB444_packed, precalc_err_col1_RGB);
  11880. }
  11881. precalc_err_col0_RG = (unsigned int*) malloc(16*16*8*16*sizeof(unsigned int));
  11882. if(!precalc_err_col0_RG){printf("Out of memory allocating \n");exit(1);}
  11883. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed+=16)
  11884. {
  11885. precalcError59T_col0_RGpercep1000(block, colorRGB444_packed, precalc_err_col0_RG);
  11886. }
  11887. precalc_err_col1_RG = (unsigned int*) malloc(16*16*16*sizeof(unsigned int));
  11888. if(!precalc_err_col1_RG){printf("Out of memory allocating \n");exit(1);}
  11889. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed+=16)
  11890. {
  11891. precalcError59T_col1_RGpercep1000(block, colorRGB444_packed, precalc_err_col1_RG);
  11892. }
  11893. precalc_err_col0_R = (unsigned int*) malloc(16*8*16*sizeof(unsigned int));
  11894. if(!precalc_err_col0_R){printf("Out of memory allocating \n");exit(1);}
  11895. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed+=16*16)
  11896. {
  11897. precalcError59T_col0_Rpercep1000(block, colorRGB444_packed, precalc_err_col0_R);
  11898. }
  11899. precalc_err_col1_R = (unsigned int*) malloc(16*16*sizeof(unsigned int));
  11900. if(!precalc_err_col1_R){printf("Out of memory allocating \n");exit(1);}
  11901. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed+=16*16)
  11902. {
  11903. precalcError59T_col1_Rpercep1000(block, colorRGB444_packed, precalc_err_col1_R);
  11904. }
  11905. unsigned int error;
  11906. unsigned int avoided = 0;
  11907. unsigned int notavoided = 0;
  11908. for(colorsRGB444[0][0] = 0; colorsRGB444[0][0] < 16; colorsRGB444[0][0]++)
  11909. {
  11910. for(colorsRGB444[1][0] = 0; colorsRGB444[1][0] < 16; colorsRGB444[1][0]++)
  11911. {
  11912. colorsRGB444_packed[0] = (colorsRGB444[0][0] << 8);
  11913. colorsRGB444_packed[1] = (colorsRGB444[1][0] << 8);
  11914. error = calculateError59TusingPrecalcRperceptual1000(block, colorsRGB444_packed, precalc_err_col0_R, precalc_err_col1_R, best_error_so_far);
  11915. if(error < best_error_so_far)
  11916. {
  11917. notavoided = notavoided + 1;
  11918. for(colorsRGB444[0][1] = 0; colorsRGB444[0][1] < 16; colorsRGB444[0][1]++)
  11919. {
  11920. colorsRGB444_packed[0] = (colorsRGB444[0][0] << 8) + (colorsRGB444[0][1] <<4);
  11921. for(colorsRGB444[1][1] = 0; colorsRGB444[1][1] < 16; colorsRGB444[1][1]++)
  11922. {
  11923. colorsRGB444_packed[1] = (colorsRGB444[1][0] << 8) + (colorsRGB444[1][1] <<4);
  11924. error = calculateError59TusingPrecalcRGperceptual1000(block, colorsRGB444_packed, precalc_err_col0_RG, precalc_err_col1_RG, best_error_so_far);
  11925. if(error < best_error_so_far)
  11926. {
  11927. for(colorsRGB444[0][2] = 0; colorsRGB444[0][2] < 16; colorsRGB444[0][2]++)
  11928. {
  11929. colorsRGB444_packed[0] = (colorsRGB444[0][0] << 8) + (colorsRGB444[0][1] <<4) + colorsRGB444[0][2];
  11930. for(colorsRGB444[1][2] = 0; colorsRGB444[1][2] < 16; colorsRGB444[1][2]++)
  11931. {
  11932. colorsRGB444_packed[1] = (colorsRGB444[1][0] << 8) + (colorsRGB444[1][1] <<4) + colorsRGB444[1][2];
  11933. error = calculateError59TusingPrecalcRGBperceptual1000(block, colorsRGB444_packed, precalc_err_col0_RGB, precalc_err_col1_RGB, best_error_so_far);
  11934. if(error < best_error_so_far)
  11935. {
  11936. best_error_so_far = error;
  11937. best_error_using_Tmode = error;
  11938. best_colorsRGB444_packed[0] = colorsRGB444_packed[0];
  11939. best_colorsRGB444_packed[1] = colorsRGB444_packed[1];
  11940. }
  11941. }
  11942. }
  11943. }
  11944. }
  11945. }
  11946. }
  11947. }
  11948. }
  11949. free(precalc_err_col0_RGB);
  11950. free(precalc_err_col1_RGB);
  11951. free(precalc_err_col0_RG);
  11952. free(precalc_err_col1_RG);
  11953. free(precalc_err_col0_R);
  11954. free(precalc_err_col1_R);
  11955. // We have got the two best colors. Now find the best distance and pixel indices.
  11956. // Color numbering are reversed between precalc and noSwap
  11957. colorsRGB444[0][0] = (best_colorsRGB444_packed[1] >> 8) & 0xf;
  11958. colorsRGB444[0][1] = (best_colorsRGB444_packed[1] >> 4) & 0xf;
  11959. colorsRGB444[0][2] = (best_colorsRGB444_packed[1] >> 0) & 0xf;
  11960. colorsRGB444[1][0] = (best_colorsRGB444_packed[0] >> 8) & 0xf;
  11961. colorsRGB444[1][1] = (best_colorsRGB444_packed[0] >> 4) & 0xf;
  11962. colorsRGB444[1][2] = (best_colorsRGB444_packed[0] >> 0) & 0xf;
  11963. calculateError59TnoSwapPerceptual1000(img, width, startx, starty, colorsRGB444, distance, pixel_indices);
  11964. // Put the compress params into the compression block
  11965. packBlock59T(colorsRGB444, distance, pixel_indices, compressed1, compressed2);
  11966. return best_error_using_Tmode;
  11967. }
  11968. #endif
  11969. #if EXHAUSTIVE_CODE_ACTIVE
  11970. // The below code should compress the block to 59 bits.
  11971. // This is supposed to match the first of the three modes in TWOTIMER.
  11972. //
  11973. //|63 62 61 60 59|58 57 56 55|54 53 52 51|50 49 48 47|46 45 44 43|42 41 40 39|38 37 36 35|34 33 32|
  11974. //|----empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|--dist--|
  11975. //
  11976. //|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  11977. //|----------------------------------------index bits---------------------------------------------|
  11978. //
  11979. // Note that this method might not return the best possible compression for the T-mode. It will only do so if the best possible T-representation
  11980. // is less than best_error_so_far. To guarantee that the best possible T-representation is found, the function should be called using
  11981. // best_error_so_far = 255*255*3*16, which is the maximum error for a block.
  11982. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  11983. unsigned int compressBlockTHUMB59TExhaustive(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2, unsigned int best_error_so_far)
  11984. {
  11985. uint8 colorsRGB444[2][3];
  11986. unsigned int pixel_indices;
  11987. uint8 distance;
  11988. uint8 block[4*4*4];
  11989. unsigned int *precalc_err_col0_RGB;
  11990. unsigned int *precalc_err_col1_RGB;
  11991. unsigned int *precalc_err_col0_RG;
  11992. unsigned int *precalc_err_col1_RG;
  11993. unsigned int *precalc_err_col0_R;
  11994. unsigned int *precalc_err_col1_R;
  11995. int colorRGB444_packed;
  11996. int colorsRGB444_packed[2];
  11997. int best_colorsRGB444_packed[2];
  11998. unsigned int best_error_using_Tmode;
  11999. // First compress block quickly to a resonable quality so that we can
  12000. // rule out all blocks that are of worse quality than that.
  12001. best_error_using_Tmode = (unsigned int) compressBlockTHUMB59TFastestOnlyColor(img, width, height, startx, starty, best_colorsRGB444_packed);
  12002. if(best_error_using_Tmode < best_error_so_far)
  12003. best_error_so_far = best_error_using_Tmode;
  12004. // Colors numbering is reversed between the above function and the precalc below:
  12005. int temp = best_colorsRGB444_packed[0];
  12006. best_colorsRGB444_packed[0] = best_colorsRGB444_packed[1];
  12007. best_colorsRGB444_packed[1] = temp;
  12008. int xx,yy,count = 0;
  12009. // Use 4 bytes per pixel to make it 32-word aligned.
  12010. for(xx = 0; xx<4; xx++)
  12011. {
  12012. for(yy=0; yy<4; yy++)
  12013. {
  12014. block[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  12015. block[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  12016. block[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  12017. block[(count)*4+3] = 0;
  12018. count++;
  12019. }
  12020. }
  12021. // Precalculate error for color 0 (which produces the upper half of the T)
  12022. precalc_err_col0_RGB = (unsigned int*) malloc(4096*8*16*sizeof(unsigned int));
  12023. if(!precalc_err_col0_RGB){printf("Out of memory allocating \n");exit(1);}
  12024. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed++)
  12025. {
  12026. precalcError59T_col0_RGB(block, colorRGB444_packed, precalc_err_col0_RGB);
  12027. }
  12028. // Precalculate error for color 1 (which produces the lower half of the T -- the lone color)
  12029. precalc_err_col1_RGB = (unsigned int*) malloc(4096*16*sizeof(unsigned int));
  12030. if(!precalc_err_col1_RGB){printf("Out of memory allocating \n");exit(1);}
  12031. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed++)
  12032. {
  12033. precalcError59T_col1_RGB(block, colorRGB444_packed, precalc_err_col1_RGB);
  12034. }
  12035. precalc_err_col0_RG = (unsigned int*) malloc(16*16*8*16*sizeof(unsigned int));
  12036. if(!precalc_err_col0_RG){printf("Out of memory allocating \n");exit(1);}
  12037. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed+=16)
  12038. {
  12039. precalcError59T_col0_RG(block, colorRGB444_packed, precalc_err_col0_RG);
  12040. }
  12041. precalc_err_col1_RG = (unsigned int*) malloc(16*16*16*sizeof(unsigned int));
  12042. if(!precalc_err_col1_RG){printf("Out of memory allocating \n");exit(1);}
  12043. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed+=16)
  12044. {
  12045. precalcError59T_col1_RG(block, colorRGB444_packed, precalc_err_col1_RG);
  12046. }
  12047. precalc_err_col0_R = (unsigned int*) malloc(16*8*16*sizeof(unsigned int));
  12048. if(!precalc_err_col0_R){printf("Out of memory allocating \n");exit(1);}
  12049. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed+=16*16)
  12050. {
  12051. precalcError59T_col0_R(block, colorRGB444_packed, precalc_err_col0_R);
  12052. }
  12053. precalc_err_col1_R = (unsigned int*) malloc(16*16*sizeof(unsigned int));
  12054. if(!precalc_err_col1_R){printf("Out of memory allocating \n");exit(1);}
  12055. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed+=16*16)
  12056. {
  12057. precalcError59T_col1_R(block, colorRGB444_packed, precalc_err_col1_R);
  12058. }
  12059. unsigned int error;
  12060. unsigned int avoided = 0;
  12061. unsigned int notavoided = 0;
  12062. for(colorsRGB444[0][0] = 0; colorsRGB444[0][0] < 16; colorsRGB444[0][0]++)
  12063. {
  12064. for(colorsRGB444[1][0] = 0; colorsRGB444[1][0] < 16; colorsRGB444[1][0]++)
  12065. {
  12066. colorsRGB444_packed[0] = (colorsRGB444[0][0] << 8);
  12067. colorsRGB444_packed[1] = (colorsRGB444[1][0] << 8);
  12068. error = calculateError59TusingPrecalcR(block, colorsRGB444_packed, precalc_err_col0_R, precalc_err_col1_R, best_error_so_far);
  12069. if(error < best_error_so_far)
  12070. {
  12071. notavoided = notavoided + 1;
  12072. for(colorsRGB444[0][1] = 0; colorsRGB444[0][1] < 16; colorsRGB444[0][1]++)
  12073. {
  12074. colorsRGB444_packed[0] = (colorsRGB444[0][0] << 8) + (colorsRGB444[0][1] <<4);
  12075. for(colorsRGB444[1][1] = 0; colorsRGB444[1][1] < 16; colorsRGB444[1][1]++)
  12076. {
  12077. colorsRGB444_packed[1] = (colorsRGB444[1][0] << 8) + (colorsRGB444[1][1] <<4);
  12078. error = calculateError59TusingPrecalcRG(block, colorsRGB444_packed, precalc_err_col0_RG, precalc_err_col1_RG, best_error_so_far);
  12079. if(error < best_error_so_far)
  12080. {
  12081. for(colorsRGB444[0][2] = 0; colorsRGB444[0][2] < 16; colorsRGB444[0][2]++)
  12082. {
  12083. colorsRGB444_packed[0] = (colorsRGB444[0][0] << 8) + (colorsRGB444[0][1] <<4) + colorsRGB444[0][2];
  12084. for(colorsRGB444[1][2] = 0; colorsRGB444[1][2] < 16; colorsRGB444[1][2]++)
  12085. {
  12086. colorsRGB444_packed[1] = (colorsRGB444[1][0] << 8) + (colorsRGB444[1][1] <<4) + colorsRGB444[1][2];
  12087. error = calculateError59TusingPrecalcRGB(block, colorsRGB444_packed, precalc_err_col0_RGB, precalc_err_col1_RGB, best_error_so_far);
  12088. if(error < best_error_so_far)
  12089. {
  12090. best_error_so_far = error;
  12091. best_error_using_Tmode = error;
  12092. best_colorsRGB444_packed[0] = colorsRGB444_packed[0];
  12093. best_colorsRGB444_packed[1] = colorsRGB444_packed[1];
  12094. }
  12095. }
  12096. }
  12097. }
  12098. }
  12099. }
  12100. }
  12101. }
  12102. }
  12103. free(precalc_err_col0_RGB);
  12104. free(precalc_err_col1_RGB);
  12105. free(precalc_err_col0_RG);
  12106. free(precalc_err_col1_RG);
  12107. free(precalc_err_col0_R);
  12108. free(precalc_err_col1_R);
  12109. // We have got the two best colors. Now find the best distance and pixel indices.
  12110. // Color numbering are reversed between precalc and noSwap
  12111. colorsRGB444[0][0] = (best_colorsRGB444_packed[1] >> 8) & 0xf;
  12112. colorsRGB444[0][1] = (best_colorsRGB444_packed[1] >> 4) & 0xf;
  12113. colorsRGB444[0][2] = (best_colorsRGB444_packed[1] >> 0) & 0xf;
  12114. colorsRGB444[1][0] = (best_colorsRGB444_packed[0] >> 8) & 0xf;
  12115. colorsRGB444[1][1] = (best_colorsRGB444_packed[0] >> 4) & 0xf;
  12116. colorsRGB444[1][2] = (best_colorsRGB444_packed[0] >> 0) & 0xf;
  12117. calculateError59TnoSwap(img, width, startx, starty, colorsRGB444, distance, pixel_indices);
  12118. // Put the compress params into the compression block
  12119. packBlock59T(colorsRGB444, distance, pixel_indices, compressed1, compressed2);
  12120. return best_error_using_Tmode;
  12121. }
  12122. #endif
  12123. #if EXHAUSTIVE_CODE_ACTIVE
  12124. // Precalculates tables used in the exhaustive compression of the H-mode.
  12125. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  12126. void precalcErrorR_58Hperceptual1000(uint8* srcimg, int width, int startx, int starty, uint8 (colorsRGB444)[2][3],int colorRGB444_packed, unsigned int *precalc_errR)
  12127. {
  12128. unsigned int block_error = 0,
  12129. best_block_error = MAXERR1000,
  12130. pixel_error,
  12131. best_pixel_error;
  12132. int diff[3];
  12133. unsigned int pixel_colors;
  12134. uint8 possible_colors[2][3];
  12135. uint8 colors[2][3];
  12136. decompressColor(R_BITS58H, G_BITS58H, B_BITS58H, colorsRGB444, colors);
  12137. // Test all distances
  12138. for (uint8 d = 0; d < BINPOW(TABLE_BITS_58H); ++d)
  12139. {
  12140. possible_colors[0][R] = CLAMP(0,colors[0][R] - table58H[d],255);
  12141. possible_colors[1][R] = CLAMP(0,colors[0][R] + table58H[d],255);
  12142. block_error = 0;
  12143. pixel_colors = 0;
  12144. // Loop block
  12145. for (size_t y = 0; y < BLOCKHEIGHT; ++y)
  12146. {
  12147. for (size_t x = 0; x < BLOCKWIDTH; ++x)
  12148. {
  12149. best_pixel_error = MAXERR1000;
  12150. // Loop possible block colors
  12151. for (uint8 c = 0; c < 2; ++c)
  12152. {
  12153. diff[R] = srcimg[3*((starty+y)*width+startx+x)+R] - CLAMP(0,possible_colors[c][R],255);
  12154. pixel_error = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE(diff[R]);
  12155. // Choose best error
  12156. if (pixel_error < best_pixel_error)
  12157. {
  12158. best_pixel_error = pixel_error;
  12159. }
  12160. }
  12161. precalc_errR[((colorRGB444_packed>>8)*8 + d)*16 + (y*4)+x] = (unsigned int) best_pixel_error;
  12162. }
  12163. }
  12164. }
  12165. }
  12166. #endif
  12167. #if EXHAUSTIVE_CODE_ACTIVE
  12168. // Precalculates tables used in the exhaustive compression of the H-mode.
  12169. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  12170. void precalcErrorR_58H(uint8* srcimg, int width, int startx, int starty, uint8 (colorsRGB444)[2][3],int colorRGB444_packed, unsigned int *precalc_errR)
  12171. {
  12172. double block_error = 0,
  12173. best_block_error = MAXIMUM_ERROR,
  12174. pixel_error,
  12175. best_pixel_error;
  12176. int diff[3];
  12177. unsigned int pixel_colors;
  12178. uint8 possible_colors[2][3];
  12179. uint8 colors[2][3];
  12180. decompressColor(R_BITS58H, G_BITS58H, B_BITS58H, colorsRGB444, colors);
  12181. // Test all distances
  12182. for (uint8 d = 0; d < BINPOW(TABLE_BITS_58H); ++d)
  12183. {
  12184. possible_colors[0][R] = CLAMP(0,colors[0][R] - table58H[d],255);
  12185. possible_colors[1][R] = CLAMP(0,colors[0][R] + table58H[d],255);
  12186. block_error = 0;
  12187. pixel_colors = 0;
  12188. // Loop block
  12189. for (size_t y = 0; y < BLOCKHEIGHT; ++y)
  12190. {
  12191. for (size_t x = 0; x < BLOCKWIDTH; ++x)
  12192. {
  12193. best_pixel_error = MAXIMUM_ERROR;
  12194. // Loop possible block colors
  12195. for (uint8 c = 0; c < 2; ++c)
  12196. {
  12197. diff[R] = srcimg[3*((starty+y)*width+startx+x)+R] - CLAMP(0,possible_colors[c][R],255);
  12198. pixel_error = weight[R]*SQUARE(diff[R]);
  12199. // Choose best error
  12200. if (pixel_error < best_pixel_error)
  12201. {
  12202. best_pixel_error = pixel_error;
  12203. }
  12204. }
  12205. precalc_errR[((colorRGB444_packed>>8)*8 + d)*16 + (y*4)+x] = (unsigned int) best_pixel_error;
  12206. }
  12207. }
  12208. }
  12209. }
  12210. #endif
  12211. #if EXHAUSTIVE_CODE_ACTIVE
  12212. // Precalculates tables used in the exhaustive compression of the H-mode.
  12213. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  12214. void precalcErrorRG_58Hperceptual1000(uint8* srcimg, int width, int startx, int starty, uint8 (colorsRGB444)[2][3],int colorRGB444_packed, unsigned int *precalc_errRG)
  12215. {
  12216. unsigned int block_error = 0,
  12217. best_block_error = MAXERR1000,
  12218. pixel_error,
  12219. best_pixel_error;
  12220. int diff[3];
  12221. unsigned int pixel_colors;
  12222. uint8 possible_colors[2][3];
  12223. uint8 colors[2][3];
  12224. decompressColor(R_BITS58H, G_BITS58H, B_BITS58H, colorsRGB444, colors);
  12225. // Test all distances
  12226. for (uint8 d = 0; d < BINPOW(TABLE_BITS_58H); ++d)
  12227. {
  12228. possible_colors[0][R] = CLAMP(0,colors[0][R] - table58H[d],255);
  12229. possible_colors[0][G] = CLAMP(0,colors[0][G] - table58H[d],255);
  12230. possible_colors[1][R] = CLAMP(0,colors[0][R] + table58H[d],255);
  12231. possible_colors[1][G] = CLAMP(0,colors[0][G] + table58H[d],255);
  12232. block_error = 0;
  12233. pixel_colors = 0;
  12234. // Loop block
  12235. for (size_t y = 0; y < BLOCKHEIGHT; ++y)
  12236. {
  12237. for (size_t x = 0; x < BLOCKWIDTH; ++x)
  12238. {
  12239. best_pixel_error = MAXERR1000;
  12240. // Loop possible block colors
  12241. for (uint8 c = 0; c < 2; ++c)
  12242. {
  12243. diff[R] = srcimg[3*((starty+y)*width+startx+x)+R] - CLAMP(0,possible_colors[c][R],255);
  12244. diff[G] = srcimg[3*((starty+y)*width+startx+x)+G] - CLAMP(0,possible_colors[c][G],255);
  12245. pixel_error = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*SQUARE(diff[R]) +
  12246. PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*SQUARE(diff[G]);
  12247. // Choose best error
  12248. if (pixel_error < best_pixel_error)
  12249. {
  12250. best_pixel_error = pixel_error;
  12251. }
  12252. }
  12253. precalc_errRG[((colorRGB444_packed>>4)*8 + d)*16 + (y*4)+x] = (unsigned int) best_pixel_error;
  12254. }
  12255. }
  12256. }
  12257. }
  12258. #endif
  12259. #if EXHAUSTIVE_CODE_ACTIVE
  12260. // Precalculates tables used in the exhaustive compression of the H-mode.
  12261. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  12262. void precalcErrorRG_58H(uint8* srcimg, int width, int startx, int starty, uint8 (colorsRGB444)[2][3],int colorRGB444_packed, unsigned int *precalc_errRG)
  12263. {
  12264. double block_error = 0,
  12265. best_block_error = MAXIMUM_ERROR,
  12266. pixel_error,
  12267. best_pixel_error;
  12268. int diff[3];
  12269. unsigned int pixel_colors;
  12270. uint8 possible_colors[2][3];
  12271. uint8 colors[2][3];
  12272. decompressColor(R_BITS58H, G_BITS58H, B_BITS58H, colorsRGB444, colors);
  12273. // Test all distances
  12274. for (uint8 d = 0; d < BINPOW(TABLE_BITS_58H); ++d)
  12275. {
  12276. possible_colors[0][R] = CLAMP(0,colors[0][R] - table58H[d],255);
  12277. possible_colors[0][G] = CLAMP(0,colors[0][G] - table58H[d],255);
  12278. possible_colors[1][R] = CLAMP(0,colors[0][R] + table58H[d],255);
  12279. possible_colors[1][G] = CLAMP(0,colors[0][G] + table58H[d],255);
  12280. block_error = 0;
  12281. pixel_colors = 0;
  12282. // Loop block
  12283. for (size_t y = 0; y < BLOCKHEIGHT; ++y)
  12284. {
  12285. for (size_t x = 0; x < BLOCKWIDTH; ++x)
  12286. {
  12287. best_pixel_error = MAXIMUM_ERROR;
  12288. // Loop possible block colors
  12289. for (uint8 c = 0; c < 2; ++c)
  12290. {
  12291. diff[R] = srcimg[3*((starty+y)*width+startx+x)+R] - CLAMP(0,possible_colors[c][R],255);
  12292. diff[G] = srcimg[3*((starty+y)*width+startx+x)+G] - CLAMP(0,possible_colors[c][G],255);
  12293. pixel_error = weight[R]*SQUARE(diff[R]) +
  12294. weight[G]*SQUARE(diff[G]);
  12295. // Choose best error
  12296. if (pixel_error < best_pixel_error)
  12297. {
  12298. best_pixel_error = pixel_error;
  12299. }
  12300. }
  12301. precalc_errRG[((colorRGB444_packed>>4)*8 + d)*16 + (y*4)+x] = (unsigned int) best_pixel_error;
  12302. }
  12303. }
  12304. }
  12305. }
  12306. #endif
  12307. #if EXHAUSTIVE_CODE_ACTIVE
  12308. // Precalculates a table used in the exhaustive compression of the H-mode.
  12309. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  12310. void precalcError58Hperceptual1000(uint8* block, uint8 (colorsRGB444)[2][3],int colorRGB444_packed, unsigned int *precalc_err)
  12311. {
  12312. unsigned int pixel_error,
  12313. best_pixel_error;
  12314. int possible_colors[2][3];
  12315. uint8 colors[2][3];
  12316. unsigned int *precalc_err_tab;
  12317. int red_original;
  12318. int green_original;
  12319. int blue_original;
  12320. #define PRECALC_ONE_58H_PERCEP(qvalue)\
  12321. red_original = block[qvalue*4];\
  12322. green_original = block[qvalue*4+1];\
  12323. blue_original = block[qvalue*4+2];\
  12324. /* unroll loop for (color = 0; color< 2; color++) */\
  12325. best_pixel_error = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*square_table[(possible_colors[0][R] - red_original)] \
  12326. + PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*square_table[(possible_colors[0][G] - green_original)]\
  12327. + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[(possible_colors[0][B] - blue_original)];\
  12328. pixel_error = PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000*square_table[(possible_colors[1][R] - red_original)]\
  12329. + PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000*square_table[(possible_colors[1][G] - green_original)]\
  12330. + PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000*square_table[(possible_colors[1][B] - blue_original)];\
  12331. if (pixel_error < best_pixel_error)\
  12332. best_pixel_error = pixel_error;\
  12333. /* end unroll loop */\
  12334. precalc_err_tab[qvalue] = best_pixel_error;\
  12335. #define PRECALC_ONE_TABLE_58H_PERCEP(dvalue)\
  12336. precalc_err_tab = &precalc_err[((colorRGB444_packed*8)+dvalue)*16];\
  12337. possible_colors[0][R] = CLAMP_LEFT_ZERO(colors[0][R] - table58H[dvalue])+255;\
  12338. possible_colors[0][G] = CLAMP_LEFT_ZERO(colors[0][G] - table58H[dvalue])+255;\
  12339. possible_colors[0][B] = CLAMP_LEFT_ZERO(colors[0][B] - table58H[dvalue])+255;\
  12340. possible_colors[1][R] = CLAMP_RIGHT_255(colors[0][R] + table58H[dvalue])+255;\
  12341. possible_colors[1][G] = CLAMP_RIGHT_255(colors[0][G] + table58H[dvalue])+255;\
  12342. possible_colors[1][B] = CLAMP_RIGHT_255(colors[0][B] + table58H[dvalue])+255;\
  12343. /* unrolled loop for(q = 0; q<16; q++)*/\
  12344. PRECALC_ONE_58H_PERCEP(0)\
  12345. PRECALC_ONE_58H_PERCEP(1)\
  12346. PRECALC_ONE_58H_PERCEP(2)\
  12347. PRECALC_ONE_58H_PERCEP(3)\
  12348. PRECALC_ONE_58H_PERCEP(4)\
  12349. PRECALC_ONE_58H_PERCEP(5)\
  12350. PRECALC_ONE_58H_PERCEP(6)\
  12351. PRECALC_ONE_58H_PERCEP(7)\
  12352. PRECALC_ONE_58H_PERCEP(8)\
  12353. PRECALC_ONE_58H_PERCEP(9)\
  12354. PRECALC_ONE_58H_PERCEP(10)\
  12355. PRECALC_ONE_58H_PERCEP(11)\
  12356. PRECALC_ONE_58H_PERCEP(12)\
  12357. PRECALC_ONE_58H_PERCEP(13)\
  12358. PRECALC_ONE_58H_PERCEP(14)\
  12359. PRECALC_ONE_58H_PERCEP(15)\
  12360. /* end unroll loop */\
  12361. colors[0][R] = (colorsRGB444[0][R] << 4) | colorsRGB444[0][R];
  12362. colors[0][G] = (colorsRGB444[0][G] << 4) | colorsRGB444[0][G];
  12363. colors[0][B] = (colorsRGB444[0][B] << 4) | colorsRGB444[0][B];
  12364. // Test all distances
  12365. /* unroll loop for (uint8 d = 0; d < 8; ++d) */
  12366. PRECALC_ONE_TABLE_58H_PERCEP(0)
  12367. PRECALC_ONE_TABLE_58H_PERCEP(1)
  12368. PRECALC_ONE_TABLE_58H_PERCEP(2)
  12369. PRECALC_ONE_TABLE_58H_PERCEP(3)
  12370. PRECALC_ONE_TABLE_58H_PERCEP(4)
  12371. PRECALC_ONE_TABLE_58H_PERCEP(5)
  12372. PRECALC_ONE_TABLE_58H_PERCEP(6)
  12373. PRECALC_ONE_TABLE_58H_PERCEP(7)
  12374. /* end unroll loop */
  12375. }
  12376. #endif
  12377. #if EXHAUSTIVE_CODE_ACTIVE
  12378. // Precalculates a table used in the exhaustive compression of the H-mode.
  12379. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  12380. void precalcError58H(uint8* block, uint8 (colorsRGB444)[2][3],int colorRGB444_packed, unsigned int *precalc_err)
  12381. {
  12382. unsigned int pixel_error,
  12383. best_pixel_error;
  12384. int possible_colors[2][3];
  12385. uint8 colors[2][3];
  12386. unsigned int *precalc_err_tab;
  12387. int red_original;
  12388. int green_original;
  12389. int blue_original;
  12390. #define PRECALC_ONE_58H(qvalue)\
  12391. red_original = block[qvalue*4];\
  12392. green_original = block[qvalue*4+1];\
  12393. blue_original = block[qvalue*4+2];\
  12394. /* unroll loop for (color = 0; color< 2; color++) */\
  12395. best_pixel_error = square_table[(possible_colors[0][R] - red_original)] + square_table[(possible_colors[0][G] - green_original)] + square_table[(possible_colors[0][B] - blue_original)];\
  12396. pixel_error = square_table[(possible_colors[1][R] - red_original)] + square_table[(possible_colors[1][G] - green_original)] + square_table[(possible_colors[1][B] - blue_original)];\
  12397. if (pixel_error < best_pixel_error)\
  12398. best_pixel_error = pixel_error;\
  12399. /* end unroll loop */\
  12400. precalc_err_tab[qvalue] = best_pixel_error;\
  12401. #define PRECALC_ONE_TABLE_58H(dvalue)\
  12402. precalc_err_tab = &precalc_err[((colorRGB444_packed*8)+dvalue)*16];\
  12403. possible_colors[0][R] = CLAMP_LEFT_ZERO(colors[0][R] - table58H[dvalue])+255;\
  12404. possible_colors[0][G] = CLAMP_LEFT_ZERO(colors[0][G] - table58H[dvalue])+255;\
  12405. possible_colors[0][B] = CLAMP_LEFT_ZERO(colors[0][B] - table58H[dvalue])+255;\
  12406. possible_colors[1][R] = CLAMP_RIGHT_255(colors[0][R] + table58H[dvalue])+255;\
  12407. possible_colors[1][G] = CLAMP_RIGHT_255(colors[0][G] + table58H[dvalue])+255;\
  12408. possible_colors[1][B] = CLAMP_RIGHT_255(colors[0][B] + table58H[dvalue])+255;\
  12409. /* unrolled loop for(q = 0; q<16; q++)*/\
  12410. PRECALC_ONE_58H(0)\
  12411. PRECALC_ONE_58H(1)\
  12412. PRECALC_ONE_58H(2)\
  12413. PRECALC_ONE_58H(3)\
  12414. PRECALC_ONE_58H(4)\
  12415. PRECALC_ONE_58H(5)\
  12416. PRECALC_ONE_58H(6)\
  12417. PRECALC_ONE_58H(7)\
  12418. PRECALC_ONE_58H(8)\
  12419. PRECALC_ONE_58H(9)\
  12420. PRECALC_ONE_58H(10)\
  12421. PRECALC_ONE_58H(11)\
  12422. PRECALC_ONE_58H(12)\
  12423. PRECALC_ONE_58H(13)\
  12424. PRECALC_ONE_58H(14)\
  12425. PRECALC_ONE_58H(15)\
  12426. /* end unroll loop */\
  12427. colors[0][R] = (colorsRGB444[0][R] << 4) | colorsRGB444[0][R];
  12428. colors[0][G] = (colorsRGB444[0][G] << 4) | colorsRGB444[0][G];
  12429. colors[0][B] = (colorsRGB444[0][B] << 4) | colorsRGB444[0][B];
  12430. // Test all distances
  12431. /* unroll loop for (uint8 d = 0; d < 8; ++d) */
  12432. PRECALC_ONE_TABLE_58H(0)
  12433. PRECALC_ONE_TABLE_58H(1)
  12434. PRECALC_ONE_TABLE_58H(2)
  12435. PRECALC_ONE_TABLE_58H(3)
  12436. PRECALC_ONE_TABLE_58H(4)
  12437. PRECALC_ONE_TABLE_58H(5)
  12438. PRECALC_ONE_TABLE_58H(6)
  12439. PRECALC_ONE_TABLE_58H(7)
  12440. /* end unroll loop */
  12441. }
  12442. #endif
  12443. #if EXHAUSTIVE_CODE_ACTIVE
  12444. // Calculate a minimum error for the H-mode when doing exhaustive compression.
  12445. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  12446. unsigned int calculateErrorFromPrecalcR58Hperceptual1000(int *colorsRGB444_packed, unsigned int *precalc_errR, unsigned int best_err_so_far)
  12447. {
  12448. unsigned int block_error = 0;
  12449. unsigned int best_block_error = MAXERR1000;
  12450. unsigned int *precalc_col1, *precalc_col2;
  12451. unsigned int *precalc_col1tab, *precalc_col2tab;
  12452. precalc_col1 = &precalc_errR[(colorsRGB444_packed[0]>>8)*8*16];
  12453. precalc_col2 = &precalc_errR[(colorsRGB444_packed[1]>>8)*8*16];
  12454. #define CHOICE_R58H_PERCEP(value)\
  12455. if(precalc_col1tab[value] < precalc_col2tab[value])\
  12456. block_error += precalc_col1tab[value];\
  12457. else\
  12458. block_error += precalc_col2tab[value];\
  12459. // Test all distances
  12460. for (uint8 d = 0; d < 8; ++d)
  12461. {
  12462. block_error = 0;
  12463. precalc_col1tab = &precalc_col1[d*16];
  12464. precalc_col2tab = &precalc_col2[d*16];
  12465. // Loop block
  12466. /* unroll loop for(q = 0; q<16 && block_error < best_err_so_far; q++) */
  12467. CHOICE_R58H_PERCEP(0)
  12468. if( block_error < best_err_so_far )
  12469. {
  12470. CHOICE_R58H_PERCEP(1)
  12471. if( block_error < best_err_so_far )
  12472. {
  12473. CHOICE_R58H_PERCEP(2)
  12474. if( block_error < best_err_so_far )
  12475. {
  12476. CHOICE_R58H_PERCEP(3)
  12477. if( block_error < best_err_so_far )
  12478. {
  12479. CHOICE_R58H_PERCEP(4)
  12480. if( block_error < best_err_so_far )
  12481. {
  12482. CHOICE_R58H_PERCEP(5)
  12483. if( block_error < best_err_so_far )
  12484. {
  12485. CHOICE_R58H_PERCEP(6)
  12486. if( block_error < best_err_so_far )
  12487. {
  12488. CHOICE_R58H_PERCEP(7)
  12489. if( block_error < best_err_so_far )
  12490. {
  12491. CHOICE_R58H_PERCEP(8)
  12492. if( block_error < best_err_so_far )
  12493. {
  12494. CHOICE_R58H_PERCEP(9)
  12495. if( block_error < best_err_so_far )
  12496. {
  12497. CHOICE_R58H_PERCEP(10)
  12498. if( block_error < best_err_so_far )
  12499. {
  12500. CHOICE_R58H_PERCEP(11)
  12501. if( block_error < best_err_so_far )
  12502. {
  12503. CHOICE_R58H_PERCEP(12)
  12504. if( block_error < best_err_so_far )
  12505. {
  12506. CHOICE_R58H_PERCEP(13)
  12507. if( block_error < best_err_so_far )
  12508. {
  12509. CHOICE_R58H_PERCEP(14)
  12510. if( block_error < best_err_so_far )
  12511. {
  12512. CHOICE_R58H_PERCEP(15)
  12513. }
  12514. }
  12515. }
  12516. }
  12517. }
  12518. }
  12519. }
  12520. }
  12521. }
  12522. }
  12523. }
  12524. }
  12525. }
  12526. }
  12527. }
  12528. /* end unroll loop */
  12529. if (block_error < best_block_error)
  12530. best_block_error = block_error;
  12531. }
  12532. return best_block_error;
  12533. }
  12534. #endif
  12535. #if EXHAUSTIVE_CODE_ACTIVE
  12536. // Calculate a minimum error for the H-mode when doing exhaustive compression.
  12537. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  12538. unsigned int calculateErrorFromPrecalcR58H(int *colorsRGB444_packed, unsigned int *precalc_errR, unsigned int best_err_so_far)
  12539. {
  12540. unsigned int block_error = 0;
  12541. unsigned int best_block_error = MAXIMUM_ERROR;
  12542. unsigned int *precalc_col1, *precalc_col2;
  12543. unsigned int *precalc_col1tab, *precalc_col2tab;
  12544. precalc_col1 = &precalc_errR[(colorsRGB444_packed[0]>>8)*8*16];
  12545. precalc_col2 = &precalc_errR[(colorsRGB444_packed[1]>>8)*8*16];
  12546. #define CHOICE_R58H(value)\
  12547. if(precalc_col1tab[value] < precalc_col2tab[value])\
  12548. block_error += precalc_col1tab[value];\
  12549. else\
  12550. block_error += precalc_col2tab[value];\
  12551. // Test all distances
  12552. for (uint8 d = 0; d < 8; ++d)
  12553. {
  12554. block_error = 0;
  12555. precalc_col1tab = &precalc_col1[d*16];
  12556. precalc_col2tab = &precalc_col2[d*16];
  12557. // Loop block
  12558. /* unroll loop for(q = 0; q<16 && block_error < best_err_so_far; q++) */
  12559. CHOICE_R58H(0)
  12560. if( block_error < best_err_so_far )
  12561. {
  12562. CHOICE_R58H(1)
  12563. if( block_error < best_err_so_far )
  12564. {
  12565. CHOICE_R58H(2)
  12566. if( block_error < best_err_so_far )
  12567. {
  12568. CHOICE_R58H(3)
  12569. if( block_error < best_err_so_far )
  12570. {
  12571. CHOICE_R58H(4)
  12572. if( block_error < best_err_so_far )
  12573. {
  12574. CHOICE_R58H(5)
  12575. if( block_error < best_err_so_far )
  12576. {
  12577. CHOICE_R58H(6)
  12578. if( block_error < best_err_so_far )
  12579. {
  12580. CHOICE_R58H(7)
  12581. if( block_error < best_err_so_far )
  12582. {
  12583. CHOICE_R58H(8)
  12584. if( block_error < best_err_so_far )
  12585. {
  12586. CHOICE_R58H(9)
  12587. if( block_error < best_err_so_far )
  12588. {
  12589. CHOICE_R58H(10)
  12590. if( block_error < best_err_so_far )
  12591. {
  12592. CHOICE_R58H(11)
  12593. if( block_error < best_err_so_far )
  12594. {
  12595. CHOICE_R58H(12)
  12596. if( block_error < best_err_so_far )
  12597. {
  12598. CHOICE_R58H(13)
  12599. if( block_error < best_err_so_far )
  12600. {
  12601. CHOICE_R58H(14)
  12602. if( block_error < best_err_so_far )
  12603. {
  12604. CHOICE_R58H(15)
  12605. }
  12606. }
  12607. }
  12608. }
  12609. }
  12610. }
  12611. }
  12612. }
  12613. }
  12614. }
  12615. }
  12616. }
  12617. }
  12618. }
  12619. }
  12620. /* end unroll loop */
  12621. if (block_error < best_block_error)
  12622. best_block_error = block_error;
  12623. }
  12624. return best_block_error;
  12625. }
  12626. #endif
  12627. #if EXHAUSTIVE_CODE_ACTIVE
  12628. // Calculate a minimum error for the H-mode when doing exhaustive compression.
  12629. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  12630. unsigned int calculateErrorFromPrecalcRG58Hperceptual1000(int *colorsRGB444_packed, unsigned int *precalc_errRG, unsigned int best_err_so_far)
  12631. {
  12632. unsigned int block_error = 0;
  12633. unsigned int best_block_error = MAXIMUM_ERROR;
  12634. unsigned int *precalc_col1, *precalc_col2;
  12635. unsigned int *precalc_col1tab, *precalc_col2tab;
  12636. precalc_col1 = &precalc_errRG[(colorsRGB444_packed[0]>>4)*8*16];
  12637. precalc_col2 = &precalc_errRG[(colorsRGB444_packed[1]>>4)*8*16];
  12638. #define CHOICE_RG58H_PERCEP(value)\
  12639. if(precalc_col1tab[value] < precalc_col2tab[value])\
  12640. block_error += precalc_col1tab[value];\
  12641. else\
  12642. block_error += precalc_col2tab[value];\
  12643. // Test all distances
  12644. for (uint8 d = 0; d < 8; ++d)
  12645. {
  12646. block_error = 0;
  12647. precalc_col1tab = &precalc_col1[d*16];
  12648. precalc_col2tab = &precalc_col2[d*16];
  12649. // Loop block
  12650. /* unroll loop for(q = 0; q<16 && block_error < best_err_so_far; q++) */
  12651. CHOICE_RG58H_PERCEP(0)
  12652. if( block_error < best_err_so_far )
  12653. {
  12654. CHOICE_RG58H_PERCEP(1)
  12655. if( block_error < best_err_so_far )
  12656. {
  12657. CHOICE_RG58H_PERCEP(2)
  12658. if( block_error < best_err_so_far )
  12659. {
  12660. CHOICE_RG58H_PERCEP(3)
  12661. if( block_error < best_err_so_far )
  12662. {
  12663. CHOICE_RG58H_PERCEP(4)
  12664. if( block_error < best_err_so_far )
  12665. {
  12666. CHOICE_RG58H_PERCEP(5)
  12667. if( block_error < best_err_so_far )
  12668. {
  12669. CHOICE_RG58H_PERCEP(6)
  12670. if( block_error < best_err_so_far )
  12671. {
  12672. CHOICE_RG58H_PERCEP(7)
  12673. if( block_error < best_err_so_far )
  12674. {
  12675. CHOICE_RG58H_PERCEP(8)
  12676. if( block_error < best_err_so_far )
  12677. {
  12678. CHOICE_RG58H_PERCEP(9)
  12679. if( block_error < best_err_so_far )
  12680. {
  12681. CHOICE_RG58H_PERCEP(10)
  12682. if( block_error < best_err_so_far )
  12683. {
  12684. CHOICE_RG58H_PERCEP(11)
  12685. if( block_error < best_err_so_far )
  12686. {
  12687. CHOICE_RG58H_PERCEP(12)
  12688. if( block_error < best_err_so_far )
  12689. {
  12690. CHOICE_RG58H_PERCEP(13)
  12691. if( block_error < best_err_so_far )
  12692. {
  12693. CHOICE_RG58H_PERCEP(14)
  12694. if( block_error < best_err_so_far )
  12695. {
  12696. CHOICE_RG58H_PERCEP(15)
  12697. }
  12698. }
  12699. }
  12700. }
  12701. }
  12702. }
  12703. }
  12704. }
  12705. }
  12706. }
  12707. }
  12708. }
  12709. }
  12710. }
  12711. }
  12712. /* end unroll loop */
  12713. if (block_error < best_block_error)
  12714. best_block_error = block_error;
  12715. }
  12716. return best_block_error;
  12717. }
  12718. #endif
  12719. #if EXHAUSTIVE_CODE_ACTIVE
  12720. // Calculate a minimum error for the H-mode when doing exhaustive compression.
  12721. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  12722. unsigned int calculateErrorFromPrecalcRG58H(int *colorsRGB444_packed, unsigned int *precalc_errRG, unsigned int best_err_so_far)
  12723. {
  12724. unsigned int block_error = 0;
  12725. unsigned int best_block_error = MAXIMUM_ERROR;
  12726. unsigned int *precalc_col1, *precalc_col2;
  12727. unsigned int *precalc_col1tab, *precalc_col2tab;
  12728. precalc_col1 = &precalc_errRG[(colorsRGB444_packed[0]>>4)*8*16];
  12729. precalc_col2 = &precalc_errRG[(colorsRGB444_packed[1]>>4)*8*16];
  12730. #define CHOICE_RG58H(value)\
  12731. if(precalc_col1tab[value] < precalc_col2tab[value])\
  12732. block_error += precalc_col1tab[value];\
  12733. else\
  12734. block_error += precalc_col2tab[value];\
  12735. // Test all distances
  12736. for (uint8 d = 0; d < 8; ++d)
  12737. {
  12738. block_error = 0;
  12739. precalc_col1tab = &precalc_col1[d*16];
  12740. precalc_col2tab = &precalc_col2[d*16];
  12741. // Loop block
  12742. /* unroll loop for(q = 0; q<16 && block_error < best_err_so_far; q++) */
  12743. CHOICE_RG58H(0)
  12744. if( block_error < best_err_so_far )
  12745. {
  12746. CHOICE_RG58H(1)
  12747. if( block_error < best_err_so_far )
  12748. {
  12749. CHOICE_RG58H(2)
  12750. if( block_error < best_err_so_far )
  12751. {
  12752. CHOICE_RG58H(3)
  12753. if( block_error < best_err_so_far )
  12754. {
  12755. CHOICE_RG58H(4)
  12756. if( block_error < best_err_so_far )
  12757. {
  12758. CHOICE_RG58H(5)
  12759. if( block_error < best_err_so_far )
  12760. {
  12761. CHOICE_RG58H(6)
  12762. if( block_error < best_err_so_far )
  12763. {
  12764. CHOICE_RG58H(7)
  12765. if( block_error < best_err_so_far )
  12766. {
  12767. CHOICE_RG58H(8)
  12768. if( block_error < best_err_so_far )
  12769. {
  12770. CHOICE_RG58H(9)
  12771. if( block_error < best_err_so_far )
  12772. {
  12773. CHOICE_RG58H(10)
  12774. if( block_error < best_err_so_far )
  12775. {
  12776. CHOICE_RG58H(11)
  12777. if( block_error < best_err_so_far )
  12778. {
  12779. CHOICE_RG58H(12)
  12780. if( block_error < best_err_so_far )
  12781. {
  12782. CHOICE_RG58H(13)
  12783. if( block_error < best_err_so_far )
  12784. {
  12785. CHOICE_RG58H(14)
  12786. if( block_error < best_err_so_far )
  12787. {
  12788. CHOICE_RG58H(15)
  12789. }
  12790. }
  12791. }
  12792. }
  12793. }
  12794. }
  12795. }
  12796. }
  12797. }
  12798. }
  12799. }
  12800. }
  12801. }
  12802. }
  12803. }
  12804. /* end unroll loop */
  12805. if (block_error < best_block_error)
  12806. best_block_error = block_error;
  12807. }
  12808. return best_block_error;
  12809. }
  12810. #endif
  12811. #if EXHAUSTIVE_CODE_ACTIVE
  12812. // Calculate a minimum error for the H-mode when doing exhaustive compression.
  12813. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  12814. unsigned int calculateErrorFromPrecalc58Hperceptual1000(int *colorsRGB444_packed, unsigned int *precalc_err, unsigned int total_best_err)
  12815. {
  12816. unsigned int block_error;\
  12817. unsigned int *precalc_col1, *precalc_col2;\
  12818. unsigned int *precalc_col1tab, *precalc_col2tab;\
  12819. unsigned int error;
  12820. #define FIRSTCHOICE_RGB58H_PERCEP(value)\
  12821. if(precalc_col1tab[value] < precalc_col2tab[value])\
  12822. block_error = precalc_col1tab[value];\
  12823. else\
  12824. block_error = precalc_col2tab[value];\
  12825. #define CHOICE_RGB58H_PERCEP(value)\
  12826. if(precalc_col1tab[value] < precalc_col2tab[value])\
  12827. block_error += precalc_col1tab[value];\
  12828. else\
  12829. block_error += precalc_col2tab[value];\
  12830. #define ONETABLE_RGB58H_PERCEP(distance)\
  12831. precalc_col1tab = &precalc_col1[distance*16];\
  12832. precalc_col2tab = &precalc_col2[distance*16];\
  12833. /* unroll loop for(q = 0; q<16 && block_error < total_best_err; q++) */\
  12834. FIRSTCHOICE_RGB58H_PERCEP(0)\
  12835. if( block_error < total_best_err)\
  12836. {\
  12837. CHOICE_RGB58H_PERCEP(1)\
  12838. if( block_error < total_best_err)\
  12839. {\
  12840. CHOICE_RGB58H_PERCEP(2)\
  12841. CHOICE_RGB58H_PERCEP(3)\
  12842. if( block_error < total_best_err)\
  12843. {\
  12844. CHOICE_RGB58H_PERCEP(4)\
  12845. CHOICE_RGB58H_PERCEP(5)\
  12846. if( block_error < total_best_err)\
  12847. {\
  12848. CHOICE_RGB58H_PERCEP(6)\
  12849. CHOICE_RGB58H_PERCEP(7)\
  12850. if( block_error < total_best_err)\
  12851. {\
  12852. CHOICE_RGB58H_PERCEP(8)\
  12853. CHOICE_RGB58H_PERCEP(9)\
  12854. if( block_error < total_best_err)\
  12855. {\
  12856. CHOICE_RGB58H_PERCEP(10)\
  12857. CHOICE_RGB58H_PERCEP(11)\
  12858. if( block_error < total_best_err)\
  12859. {\
  12860. CHOICE_RGB58H_PERCEP(12)\
  12861. CHOICE_RGB58H_PERCEP(13)\
  12862. if( block_error < total_best_err)\
  12863. {\
  12864. CHOICE_RGB58H_PERCEP(14)\
  12865. CHOICE_RGB58H_PERCEP(15)\
  12866. }\
  12867. }\
  12868. }\
  12869. }\
  12870. }\
  12871. }\
  12872. }\
  12873. }\
  12874. /* end unroll loop */\
  12875. if (block_error < error)\
  12876. error = block_error;\
  12877. #define CALCULATE_ERROR_FROM_PRECALC_RGB58H_PERCEP\
  12878. error = MAXERR1000;\
  12879. precalc_col1 = &precalc_err[colorsRGB444_packed[0]*8*16];\
  12880. precalc_col2 = &precalc_err[colorsRGB444_packed[1]*8*16];\
  12881. /* Test all distances*/\
  12882. /* unroll loop for (uint8 d = 0; d < 8; ++d) */\
  12883. ONETABLE_RGB58H_PERCEP(0)\
  12884. ONETABLE_RGB58H_PERCEP(1)\
  12885. ONETABLE_RGB58H_PERCEP(2)\
  12886. ONETABLE_RGB58H_PERCEP(3)\
  12887. ONETABLE_RGB58H_PERCEP(4)\
  12888. ONETABLE_RGB58H_PERCEP(5)\
  12889. ONETABLE_RGB58H_PERCEP(6)\
  12890. ONETABLE_RGB58H_PERCEP(7)\
  12891. /* end unroll loop */\
  12892. CALCULATE_ERROR_FROM_PRECALC_RGB58H_PERCEP
  12893. return error;\
  12894. }
  12895. #endif
  12896. #if EXHAUSTIVE_CODE_ACTIVE
  12897. // Calculate a minimum error for the H-mode when doing exhaustive compression.
  12898. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  12899. unsigned int calculateErrorFromPrecalc58H(int *colorsRGB444_packed, unsigned int *precalc_err, unsigned int total_best_err)
  12900. {
  12901. unsigned int block_error;\
  12902. unsigned int *precalc_col1, *precalc_col2;\
  12903. unsigned int *precalc_col1tab, *precalc_col2tab;\
  12904. unsigned int error;
  12905. #define FIRSTCHOICE_RGB58H(value)\
  12906. if(precalc_col1tab[value] < precalc_col2tab[value])\
  12907. block_error = precalc_col1tab[value];\
  12908. else\
  12909. block_error = precalc_col2tab[value];\
  12910. #define CHOICE_RGB58H(value)\
  12911. if(precalc_col1tab[value] < precalc_col2tab[value])\
  12912. block_error += precalc_col1tab[value];\
  12913. else\
  12914. block_error += precalc_col2tab[value];\
  12915. #define ONETABLE_RGB58H(distance)\
  12916. precalc_col1tab = &precalc_col1[distance*16];\
  12917. precalc_col2tab = &precalc_col2[distance*16];\
  12918. /* unroll loop for(q = 0; q<16 && block_error < total_best_err; q++) */\
  12919. FIRSTCHOICE_RGB58H(0)\
  12920. if( block_error < total_best_err)\
  12921. {\
  12922. CHOICE_RGB58H(1)\
  12923. if( block_error < total_best_err)\
  12924. {\
  12925. CHOICE_RGB58H(2)\
  12926. CHOICE_RGB58H(3)\
  12927. if( block_error < total_best_err)\
  12928. {\
  12929. CHOICE_RGB58H(4)\
  12930. CHOICE_RGB58H(5)\
  12931. if( block_error < total_best_err)\
  12932. {\
  12933. CHOICE_RGB58H(6)\
  12934. CHOICE_RGB58H(7)\
  12935. if( block_error < total_best_err)\
  12936. {\
  12937. CHOICE_RGB58H(8)\
  12938. CHOICE_RGB58H(9)\
  12939. if( block_error < total_best_err)\
  12940. {\
  12941. CHOICE_RGB58H(10)\
  12942. CHOICE_RGB58H(11)\
  12943. if( block_error < total_best_err)\
  12944. {\
  12945. CHOICE_RGB58H(12)\
  12946. CHOICE_RGB58H(13)\
  12947. if( block_error < total_best_err)\
  12948. {\
  12949. CHOICE_RGB58H(14)\
  12950. CHOICE_RGB58H(15)\
  12951. }\
  12952. }\
  12953. }\
  12954. }\
  12955. }\
  12956. }\
  12957. }\
  12958. }\
  12959. /* end unroll loop */\
  12960. if (block_error < error)\
  12961. error = block_error;\
  12962. #define CALCULATE_ERROR_FROM_PRECALC_RGB58H\
  12963. error = MAXIMUM_ERROR;\
  12964. precalc_col1 = &precalc_err[colorsRGB444_packed[0]*8*16];\
  12965. precalc_col2 = &precalc_err[colorsRGB444_packed[1]*8*16];\
  12966. /* Test all distances*/\
  12967. /* unroll loop for (uint8 d = 0; d < 8; ++d) */\
  12968. ONETABLE_RGB58H(0)\
  12969. ONETABLE_RGB58H(1)\
  12970. ONETABLE_RGB58H(2)\
  12971. ONETABLE_RGB58H(3)\
  12972. ONETABLE_RGB58H(4)\
  12973. ONETABLE_RGB58H(5)\
  12974. ONETABLE_RGB58H(6)\
  12975. ONETABLE_RGB58H(7)\
  12976. /* end unroll loop */\
  12977. CALCULATE_ERROR_FROM_PRECALC_RGB58H
  12978. return error;\
  12979. }
  12980. #endif
  12981. #if EXHAUSTIVE_CODE_ACTIVE
  12982. // The below code should compress the block to 58 bits.
  12983. // This is supposed to match the first of the three modes in TWOTIMER.
  12984. // The bit layout is thought to be:
  12985. //
  12986. //|63 62 61 60 59 58|57 56 55 54|53 52 51 50|49 48 47 46|45 44 43 42|41 40 39 38|37 36 35 34|33 32|
  12987. //|-------empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|d2 d1|
  12988. //
  12989. //|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  12990. //|----------------------------------------index bits---------------------------------------------|
  12991. //
  12992. // The distance d is three bits, d2 (MSB), d1 and d0 (LSB). d0 is not stored explicitly.
  12993. // Instead if the 12-bit word red0,green0,blue0 < red1,green1,blue1, d0 is assumed to be 0.
  12994. // Else, it is assumed to be 1.
  12995. // The below code should compress the block to 58 bits.
  12996. // This is supposed to match the first of the three modes in TWOTIMER.
  12997. // The bit layout is thought to be:
  12998. //
  12999. //|63 62 61 60 59 58|57 56 55 54|53 52 51 50|49 48 47 46|45 44 43 42|41 40 39 38|37 36 35 34|33 32|
  13000. //|-------empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|d2 d1|
  13001. //
  13002. //|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  13003. //|----------------------------------------index bits---------------------------------------------|
  13004. //
  13005. // The distance d is three bits, d2 (MSB), d1 and d0 (LSB). d0 is not stored explicitly.
  13006. // Instead if the 12-bit word red0,green0,blue0 < red1,green1,blue1, d0 is assumed to be 0.
  13007. // Else, it is assumed to be 1.
  13008. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  13009. unsigned int compressBlockTHUMB58HExhaustivePerceptual(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2, unsigned int best_error_so_far)
  13010. {
  13011. unsigned int best_error_using_Hmode;
  13012. uint8 best_colorsRGB444[2][3];
  13013. unsigned int best_pixel_indices;
  13014. uint8 best_distance;
  13015. unsigned int error;
  13016. uint8 colorsRGB444[2][3];
  13017. int colorsRGB444_packed[2];
  13018. int best_colorsRGB444_packed[2];
  13019. int colorRGB444_packed;
  13020. unsigned int pixel_indices;
  13021. uint8 distance;
  13022. unsigned int *precalc_err; // smallest error per color, table and pixel
  13023. unsigned int *precalc_err_RG; // smallest pixel error for an entire table
  13024. unsigned int *precalc_err_R; // smallest pixel error for an entire table
  13025. uint8 block[4*4*4];
  13026. best_error_using_Hmode = MAXERR1000;
  13027. precalc_err = (unsigned int*) malloc(4096*8*16*sizeof(unsigned int));
  13028. if(!precalc_err){printf("Out of memory allocating \n");exit(1);}
  13029. precalc_err_RG = (unsigned int*) malloc(16*16*8*16*sizeof(unsigned int));
  13030. if(!precalc_err_RG){printf("Out of memory allocating \n");exit(1);}
  13031. precalc_err_R = (unsigned int*) malloc(16*8*16*sizeof(unsigned int));
  13032. if(!precalc_err_R){printf("Out of memory allocating \n");exit(1);}
  13033. unsigned int test1, test2;
  13034. best_error_using_Hmode = (unsigned int)compressBlockTHUMB58HFastestPerceptual1000(img,width, height, startx, starty, test1, test2);
  13035. best_colorsRGB444_packed[0] = 0;
  13036. best_colorsRGB444_packed[0] = GETBITSHIGH(test1, 12, 57);
  13037. best_colorsRGB444_packed[1] = 0;
  13038. best_colorsRGB444_packed[1] = GETBITSHIGH(test1, 12, 45);
  13039. if(best_error_using_Hmode < best_error_so_far)
  13040. best_error_so_far = best_error_using_Hmode;
  13041. int xx,yy,count = 0;
  13042. // Use 4 bytes per pixel to make it 32-word aligned.
  13043. for(xx = 0; xx<4; xx++)
  13044. {
  13045. for(yy=0; yy<4; yy++)
  13046. {
  13047. block[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  13048. block[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  13049. block[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  13050. block[(count)*4+3] = 0;
  13051. count++;
  13052. }
  13053. }
  13054. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed++)
  13055. {
  13056. colorsRGB444[0][0] = (colorRGB444_packed >> 8) & 0xf;
  13057. colorsRGB444[0][1] = (colorRGB444_packed >> 4) & 0xf;
  13058. colorsRGB444[0][2] = (colorRGB444_packed) & 0xf;
  13059. precalcError58Hperceptual1000(block, colorsRGB444, colorRGB444_packed, precalc_err);
  13060. }
  13061. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed+=16)
  13062. {
  13063. colorsRGB444[0][0] = (colorRGB444_packed >> 8) & 0xf;
  13064. colorsRGB444[0][1] = (colorRGB444_packed >> 4) & 0xf;
  13065. colorsRGB444[0][2] = (colorRGB444_packed) & 0xf;
  13066. precalcErrorRG_58Hperceptual1000(img, width, startx, starty, colorsRGB444, colorRGB444_packed, precalc_err_RG);
  13067. }
  13068. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed+=16*16)
  13069. {
  13070. colorsRGB444[0][0] = (colorRGB444_packed >> 8) & 0xf;
  13071. colorsRGB444[0][1] = (colorRGB444_packed >> 4) & 0xf;
  13072. colorsRGB444[0][2] = (colorRGB444_packed) & 0xf;
  13073. precalcErrorR_58Hperceptual1000(img, width, startx, starty, colorsRGB444, colorRGB444_packed, precalc_err_R);
  13074. }
  13075. int trycols = 0;
  13076. int allcols = 0;
  13077. for( colorsRGB444[0][0] = 0; colorsRGB444[0][0] <16; colorsRGB444[0][0]++)
  13078. {
  13079. colorsRGB444_packed[0] = colorsRGB444[0][0]*256;
  13080. for( colorsRGB444[1][0] = 0; colorsRGB444[1][0] <16; colorsRGB444[1][0]++)
  13081. {
  13082. colorsRGB444_packed[1] = colorsRGB444[1][0]*256;
  13083. if(colorsRGB444_packed[0] <= colorsRGB444_packed[1])
  13084. {
  13085. error = calculateErrorFromPrecalcR58Hperceptual1000(colorsRGB444_packed, precalc_err_R, best_error_so_far);
  13086. if(error < best_error_so_far)
  13087. {
  13088. for( colorsRGB444[0][1] = 0; colorsRGB444[0][1] <16; colorsRGB444[0][1]++)
  13089. {
  13090. colorsRGB444_packed[0] = colorsRGB444[0][0]*256 + colorsRGB444[0][1]*16;
  13091. for( colorsRGB444[1][1] = 0; colorsRGB444[1][1] <16; colorsRGB444[1][1]++)
  13092. {
  13093. colorsRGB444_packed[1] = colorsRGB444[1][0]*256 + colorsRGB444[1][1]*16;
  13094. if(colorsRGB444_packed[0] <= colorsRGB444_packed[1])
  13095. {
  13096. error = calculateErrorFromPrecalcRG58Hperceptual1000(colorsRGB444_packed, precalc_err_RG, best_error_so_far);
  13097. if(error < best_error_so_far)
  13098. {
  13099. for( colorsRGB444[0][2] = 0; colorsRGB444[0][2] <16; colorsRGB444[0][2]++)
  13100. {
  13101. colorsRGB444_packed[0] = colorsRGB444[0][0]*256 + colorsRGB444[0][1]*16 + colorsRGB444[0][2];
  13102. for( colorsRGB444[1][2] = 0; colorsRGB444[1][2] <16; colorsRGB444[1][2]++)
  13103. {
  13104. colorsRGB444_packed[1] = colorsRGB444[1][0]*256 + colorsRGB444[1][1]*16 + colorsRGB444[1][2];
  13105. if(colorsRGB444_packed[0] < colorsRGB444_packed[1])
  13106. {
  13107. error = calculateErrorFromPrecalc58Hperceptual1000(colorsRGB444_packed, precalc_err, best_error_so_far);
  13108. if(error < best_error_so_far)
  13109. {
  13110. best_error_so_far = error;
  13111. best_error_using_Hmode = error;
  13112. best_colorsRGB444_packed[0] = colorsRGB444_packed[0];
  13113. best_colorsRGB444_packed[1] = colorsRGB444_packed[1];
  13114. }
  13115. }
  13116. }
  13117. }
  13118. }
  13119. }
  13120. }
  13121. }
  13122. }
  13123. }
  13124. }
  13125. }
  13126. best_colorsRGB444[0][0] = (best_colorsRGB444_packed[0] >> 8) & 0xf;
  13127. best_colorsRGB444[0][1] = (best_colorsRGB444_packed[0] >> 4) & 0xf;
  13128. best_colorsRGB444[0][2] = (best_colorsRGB444_packed[0]) & 0xf;
  13129. best_colorsRGB444[1][0] = (best_colorsRGB444_packed[1] >> 8) & 0xf;
  13130. best_colorsRGB444[1][1] = (best_colorsRGB444_packed[1] >> 4) & 0xf;
  13131. best_colorsRGB444[1][2] = (best_colorsRGB444_packed[1]) & 0xf;
  13132. free(precalc_err);
  13133. free(precalc_err_RG);
  13134. free(precalc_err_R);
  13135. error = (unsigned int) calculateErrorAndCompress58Hperceptual1000(img, width, startx, starty, best_colorsRGB444, distance, pixel_indices);
  13136. best_distance = distance;
  13137. best_pixel_indices = pixel_indices;
  13138. // | col0 >= col1 col0 < col1
  13139. //------------------------------------------------------
  13140. // (dist & 1) = 1 | no need to swap | need to swap
  13141. // |-----------------+----------------
  13142. // (dist & 1) = 0 | need to swap | no need to swap
  13143. //
  13144. // This can be done with an xor test.
  13145. best_colorsRGB444_packed[0] = (best_colorsRGB444[0][R] << 8) + (best_colorsRGB444[0][G] << 4) + best_colorsRGB444[0][B];
  13146. best_colorsRGB444_packed[1] = (best_colorsRGB444[1][R] << 8) + (best_colorsRGB444[1][G] << 4) + best_colorsRGB444[1][B];
  13147. if( (best_colorsRGB444_packed[0] >= best_colorsRGB444_packed[1]) ^ ((best_distance & 1)==1) )
  13148. {
  13149. swapColors(best_colorsRGB444);
  13150. // Reshuffle pixel indices to to exchange C1 with C3, and C2 with C4
  13151. best_pixel_indices = (0x55555555 & best_pixel_indices) | (0xaaaaaaaa & (~best_pixel_indices));
  13152. }
  13153. // Put the compress params into the compression block
  13154. compressed1 = 0;
  13155. PUTBITSHIGH( compressed1, best_colorsRGB444[0][R], 4, 57);
  13156. PUTBITSHIGH( compressed1, best_colorsRGB444[0][G], 4, 53);
  13157. PUTBITSHIGH( compressed1, best_colorsRGB444[0][B], 4, 49);
  13158. PUTBITSHIGH( compressed1, best_colorsRGB444[1][R], 4, 45);
  13159. PUTBITSHIGH( compressed1, best_colorsRGB444[1][G], 4, 41);
  13160. PUTBITSHIGH( compressed1, best_colorsRGB444[1][B], 4, 37);
  13161. PUTBITSHIGH( compressed1, (best_distance >> 1), 2, 33);
  13162. best_pixel_indices=indexConversion(best_pixel_indices);
  13163. compressed2 = 0;
  13164. PUTBITS( compressed2, best_pixel_indices, 32, 31);
  13165. return best_error_using_Hmode;
  13166. }
  13167. #endif
  13168. #if EXHAUSTIVE_CODE_ACTIVE
  13169. // The below code should compress the block to 58 bits.
  13170. // This is supposed to match the first of the three modes in TWOTIMER.
  13171. // The bit layout is thought to be:
  13172. //
  13173. //|63 62 61 60 59 58|57 56 55 54|53 52 51 50|49 48 47 46|45 44 43 42|41 40 39 38|37 36 35 34|33 32|
  13174. //|-------empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|d2 d1|
  13175. //
  13176. //|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  13177. //|----------------------------------------index bits---------------------------------------------|
  13178. //
  13179. // The distance d is three bits, d2 (MSB), d1 and d0 (LSB). d0 is not stored explicitly.
  13180. // Instead if the 12-bit word red0,green0,blue0 < red1,green1,blue1, d0 is assumed to be 0.
  13181. // Else, it is assumed to be 1.
  13182. // The below code should compress the block to 58 bits.
  13183. // This is supposed to match the first of the three modes in TWOTIMER.
  13184. // The bit layout is thought to be:
  13185. //
  13186. //|63 62 61 60 59 58|57 56 55 54|53 52 51 50|49 48 47 46|45 44 43 42|41 40 39 38|37 36 35 34|33 32|
  13187. //|-------empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|d2 d1|
  13188. //
  13189. //|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
  13190. //|----------------------------------------index bits---------------------------------------------|
  13191. //
  13192. // The distance d is three bits, d2 (MSB), d1 and d0 (LSB). d0 is not stored explicitly.
  13193. // Instead if the 12-bit word red0,green0,blue0 < red1,green1,blue1, d0 is assumed to be 0.
  13194. // Else, it is assumed to be 1.
  13195. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  13196. unsigned int compressBlockTHUMB58HExhaustive(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2, unsigned int best_error_so_far)
  13197. {
  13198. unsigned int best_error_using_Hmode;
  13199. uint8 best_colorsRGB444[2][3];
  13200. unsigned int best_pixel_indices;
  13201. uint8 best_distance;
  13202. unsigned int error;
  13203. uint8 colorsRGB444[2][3];
  13204. int colorsRGB444_packed[2];
  13205. int best_colorsRGB444_packed[2];
  13206. int colorRGB444_packed;
  13207. unsigned int pixel_indices;
  13208. uint8 distance;
  13209. unsigned int *precalc_err; // smallest error per color, table and pixel
  13210. unsigned int *precalc_err_RG; // smallest pixel error for an entire table
  13211. unsigned int *precalc_err_R; // smallest pixel error for an entire table
  13212. uint8 block[4*4*4];
  13213. best_error_using_Hmode = MAXIMUM_ERROR;
  13214. precalc_err = (unsigned int*) malloc(4096*8*16*sizeof(unsigned int));
  13215. if(!precalc_err){printf("Out of memory allocating \n");exit(1);}
  13216. precalc_err_RG = (unsigned int*) malloc(16*16*8*16*sizeof(unsigned int));
  13217. if(!precalc_err_RG){printf("Out of memory allocating \n");exit(1);}
  13218. precalc_err_R = (unsigned int*) malloc(16*8*16*sizeof(unsigned int));
  13219. if(!precalc_err_R){printf("Out of memory allocating \n");exit(1);}
  13220. unsigned int test1, test2;
  13221. best_error_using_Hmode = (unsigned int)compressBlockTHUMB58HFastest(img,width, height, startx, starty, test1, test2);
  13222. best_colorsRGB444_packed[0] = 0;
  13223. best_colorsRGB444_packed[0] = GETBITSHIGH(test1, 12, 57);
  13224. best_colorsRGB444_packed[1] = 0;
  13225. best_colorsRGB444_packed[1] = GETBITSHIGH(test1, 12, 45);
  13226. if(best_error_using_Hmode < best_error_so_far)
  13227. best_error_so_far = best_error_using_Hmode;
  13228. int xx,yy,count = 0;
  13229. // Reshuffle pixels so that the top left 2x2 pixels arrive first, then the top right 2x2 pixels etc. Also put use 4 bytes per pixel to make it 32-word aligned.
  13230. for(xx = 0; xx<4; xx++)
  13231. {
  13232. for(yy=0; yy<4; yy++)
  13233. {
  13234. block[(count)*4] = img[((starty+yy)*width+(startx+xx))*3];
  13235. block[(count)*4+1] = img[((starty+yy)*width+(startx+xx))*3+1];
  13236. block[(count)*4+2] = img[((starty+yy)*width+(startx+xx))*3+2];
  13237. block[(count)*4+3] = 0;
  13238. count++;
  13239. }
  13240. }
  13241. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed++)
  13242. {
  13243. colorsRGB444[0][0] = (colorRGB444_packed >> 8) & 0xf;
  13244. colorsRGB444[0][1] = (colorRGB444_packed >> 4) & 0xf;
  13245. colorsRGB444[0][2] = (colorRGB444_packed) & 0xf;
  13246. precalcError58H(block, colorsRGB444, colorRGB444_packed, precalc_err);
  13247. }
  13248. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed+=16)
  13249. {
  13250. colorsRGB444[0][0] = (colorRGB444_packed >> 8) & 0xf;
  13251. colorsRGB444[0][1] = (colorRGB444_packed >> 4) & 0xf;
  13252. colorsRGB444[0][2] = (colorRGB444_packed) & 0xf;
  13253. precalcErrorRG_58H(img, width, startx, starty, colorsRGB444, colorRGB444_packed, precalc_err_RG);
  13254. }
  13255. for( colorRGB444_packed = 0; colorRGB444_packed<16*16*16; colorRGB444_packed+=16*16)
  13256. {
  13257. colorsRGB444[0][0] = (colorRGB444_packed >> 8) & 0xf;
  13258. colorsRGB444[0][1] = (colorRGB444_packed >> 4) & 0xf;
  13259. colorsRGB444[0][2] = (colorRGB444_packed) & 0xf;
  13260. precalcErrorR_58H(img, width, startx, starty, colorsRGB444, colorRGB444_packed, precalc_err_R);
  13261. }
  13262. int trycols = 0;
  13263. int allcols = 0;
  13264. for( colorsRGB444[0][0] = 0; colorsRGB444[0][0] <16; colorsRGB444[0][0]++)
  13265. {
  13266. colorsRGB444_packed[0] = colorsRGB444[0][0]*256;
  13267. for( colorsRGB444[1][0] = 0; colorsRGB444[1][0] <16; colorsRGB444[1][0]++)
  13268. {
  13269. colorsRGB444_packed[1] = colorsRGB444[1][0]*256;
  13270. if(colorsRGB444_packed[0] <= colorsRGB444_packed[1])
  13271. {
  13272. error = calculateErrorFromPrecalcR58H(colorsRGB444_packed, precalc_err_R, best_error_so_far);
  13273. if(error < best_error_so_far)
  13274. {
  13275. for( colorsRGB444[0][1] = 0; colorsRGB444[0][1] <16; colorsRGB444[0][1]++)
  13276. {
  13277. colorsRGB444_packed[0] = colorsRGB444[0][0]*256 + colorsRGB444[0][1]*16;
  13278. for( colorsRGB444[1][1] = 0; colorsRGB444[1][1] <16; colorsRGB444[1][1]++)
  13279. {
  13280. colorsRGB444_packed[1] = colorsRGB444[1][0]*256 + colorsRGB444[1][1]*16;
  13281. if(colorsRGB444_packed[0] <= colorsRGB444_packed[1])
  13282. {
  13283. error = calculateErrorFromPrecalcRG58H(colorsRGB444_packed, precalc_err_RG, best_error_so_far);
  13284. if(error < best_error_so_far)
  13285. {
  13286. for( colorsRGB444[0][2] = 0; colorsRGB444[0][2] <16; colorsRGB444[0][2]++)
  13287. {
  13288. colorsRGB444_packed[0] = colorsRGB444[0][0]*256 + colorsRGB444[0][1]*16 + colorsRGB444[0][2];
  13289. for( colorsRGB444[1][2] = 0; colorsRGB444[1][2] <16; colorsRGB444[1][2]++)
  13290. {
  13291. colorsRGB444_packed[1] = colorsRGB444[1][0]*256 + colorsRGB444[1][1]*16 + colorsRGB444[1][2];
  13292. if(colorsRGB444_packed[0] < colorsRGB444_packed[1])
  13293. {
  13294. error = calculateErrorFromPrecalc58H(colorsRGB444_packed, precalc_err, best_error_so_far);
  13295. if(error < best_error_so_far)
  13296. {
  13297. best_error_so_far = error;
  13298. best_error_using_Hmode = error;
  13299. best_colorsRGB444_packed[0] = colorsRGB444_packed[0];
  13300. best_colorsRGB444_packed[1] = colorsRGB444_packed[1];
  13301. }
  13302. }
  13303. }
  13304. }
  13305. }
  13306. }
  13307. }
  13308. }
  13309. }
  13310. }
  13311. }
  13312. }
  13313. best_colorsRGB444[0][0] = (best_colorsRGB444_packed[0] >> 8) & 0xf;
  13314. best_colorsRGB444[0][1] = (best_colorsRGB444_packed[0] >> 4) & 0xf;
  13315. best_colorsRGB444[0][2] = (best_colorsRGB444_packed[0]) & 0xf;
  13316. best_colorsRGB444[1][0] = (best_colorsRGB444_packed[1] >> 8) & 0xf;
  13317. best_colorsRGB444[1][1] = (best_colorsRGB444_packed[1] >> 4) & 0xf;
  13318. best_colorsRGB444[1][2] = (best_colorsRGB444_packed[1]) & 0xf;
  13319. free(precalc_err);
  13320. free(precalc_err_RG);
  13321. free(precalc_err_R);
  13322. error = (unsigned int) calculateErrorAndCompress58H(img, width, startx, starty, best_colorsRGB444, distance, pixel_indices);
  13323. best_distance = distance;
  13324. best_pixel_indices = pixel_indices;
  13325. // | col0 >= col1 col0 < col1
  13326. //------------------------------------------------------
  13327. // (dist & 1) = 1 | no need to swap | need to swap
  13328. // |-----------------+----------------
  13329. // (dist & 1) = 0 | need to swap | no need to swap
  13330. //
  13331. // This can be done with an xor test.
  13332. best_colorsRGB444_packed[0] = (best_colorsRGB444[0][R] << 8) + (best_colorsRGB444[0][G] << 4) + best_colorsRGB444[0][B];
  13333. best_colorsRGB444_packed[1] = (best_colorsRGB444[1][R] << 8) + (best_colorsRGB444[1][G] << 4) + best_colorsRGB444[1][B];
  13334. if( (best_colorsRGB444_packed[0] >= best_colorsRGB444_packed[1]) ^ ((best_distance & 1)==1) )
  13335. {
  13336. swapColors(best_colorsRGB444);
  13337. // Reshuffle pixel indices to to exchange C1 with C3, and C2 with C4
  13338. best_pixel_indices = (0x55555555 & best_pixel_indices) | (0xaaaaaaaa & (~best_pixel_indices));
  13339. }
  13340. // Put the compress params into the compression block
  13341. compressed1 = 0;
  13342. PUTBITSHIGH( compressed1, best_colorsRGB444[0][R], 4, 57);
  13343. PUTBITSHIGH( compressed1, best_colorsRGB444[0][G], 4, 53);
  13344. PUTBITSHIGH( compressed1, best_colorsRGB444[0][B], 4, 49);
  13345. PUTBITSHIGH( compressed1, best_colorsRGB444[1][R], 4, 45);
  13346. PUTBITSHIGH( compressed1, best_colorsRGB444[1][G], 4, 41);
  13347. PUTBITSHIGH( compressed1, best_colorsRGB444[1][B], 4, 37);
  13348. PUTBITSHIGH( compressed1, (best_distance >> 1), 2, 33);
  13349. best_pixel_indices=indexConversion(best_pixel_indices);
  13350. compressed2 = 0;
  13351. PUTBITS( compressed2, best_pixel_indices, 32, 31);
  13352. return best_error_using_Hmode;
  13353. }
  13354. #endif
  13355. #if EXHAUSTIVE_CODE_ACTIVE
  13356. // Compress a block exhaustively for the ETC1 codec.
  13357. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  13358. void compressBlockETC1Exhaustive(uint8 *img, uint8 *imgdec,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  13359. {
  13360. unsigned int error_currently_best;
  13361. unsigned int etc1_differential_word1;
  13362. unsigned int etc1_differential_word2;
  13363. unsigned int error_etc1_differential;
  13364. unsigned int etc1_individual_word1;
  13365. unsigned int etc1_individual_word2;
  13366. unsigned int error_etc1_individual;
  13367. unsigned int error_best;
  13368. signed char best_char;
  13369. int best_mode;
  13370. error_currently_best = 255*255*16*3;
  13371. // First pass -- quickly find a low error so that we can later cull away a lot of
  13372. // calculations later that are guaranteed to be higher than that error.
  13373. unsigned int error_etc1;
  13374. unsigned int etc1_word1;
  13375. unsigned int etc1_word2;
  13376. error_etc1 = (unsigned int) compressBlockDiffFlipFast(img, imgdec, width, height, startx, starty, etc1_word1, etc1_word2);
  13377. if(error_etc1 < error_currently_best)
  13378. error_currently_best = error_etc1;
  13379. error_etc1_individual = compressBlockIndividualExhaustive(img, width, height, startx, starty, etc1_individual_word1, etc1_individual_word2, error_currently_best);
  13380. if(error_etc1_individual < error_currently_best)
  13381. error_currently_best = error_etc1_individual;
  13382. error_etc1_differential = compressBlockDifferentialExhaustive(img, width, height, startx, starty, etc1_differential_word1, etc1_differential_word2, error_currently_best);
  13383. if(error_etc1_differential < error_currently_best)
  13384. error_currently_best = error_etc1_differential;
  13385. error_best = error_etc1_differential;
  13386. compressed1 = etc1_differential_word1;
  13387. compressed2 = etc1_differential_word2;
  13388. best_char = '.';
  13389. best_mode = MODE_ETC1;
  13390. if(error_etc1_individual < error_best)
  13391. {
  13392. compressed1 = etc1_individual_word1;
  13393. compressed2 = etc1_individual_word2;
  13394. best_char = ',';
  13395. error_best = error_etc1_individual;
  13396. best_mode = MODE_ETC1;
  13397. }
  13398. if(error_etc1 < error_best)
  13399. {
  13400. compressed1 = etc1_word1;
  13401. compressed2 = etc1_word2;
  13402. best_char = '.';
  13403. error_best = error_etc1;
  13404. best_mode = MODE_ETC1;
  13405. }
  13406. }
  13407. #endif
  13408. #if EXHAUSTIVE_CODE_ACTIVE
  13409. // Compress a block exhaustively for the ETC1 codec using perceptual error measure.
  13410. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  13411. void compressBlockETC1ExhaustivePerceptual(uint8 *img, uint8 *imgdec,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  13412. {
  13413. unsigned int error_currently_best;
  13414. unsigned int etc1_differential_word1;
  13415. unsigned int etc1_differential_word2;
  13416. unsigned int error_etc1_differential;
  13417. unsigned int etc1_individual_word1;
  13418. unsigned int etc1_individual_word2;
  13419. unsigned int error_etc1_individual;
  13420. unsigned int error_best;
  13421. signed char best_char;
  13422. int best_mode;
  13423. error_currently_best = 255*255*16*1000;
  13424. // First pass -- quickly find a low error so that we can later cull away a lot of
  13425. // calculations later that are guaranteed to be higher than that error.
  13426. unsigned int error_etc1;
  13427. unsigned int etc1_word1;
  13428. unsigned int etc1_word2;
  13429. compressBlockDiffFlipFastPerceptual(img, imgdec, width, height, startx, starty, etc1_word1, etc1_word2);
  13430. decompressBlockDiffFlip(etc1_word1, etc1_word2, imgdec, width, height, startx, starty);
  13431. error_etc1 = 1000*calcBlockPerceptualErrorRGB(img, imgdec, width, height, startx, starty);
  13432. if(error_etc1 < error_currently_best)
  13433. error_currently_best = error_etc1;
  13434. // Second pass --- now find the lowest error, but only if it is lower than error_currently_best
  13435. error_etc1_differential = compressBlockDifferentialExhaustivePerceptual(img, width, height, startx, starty, etc1_differential_word1, etc1_differential_word2, error_currently_best);
  13436. if(error_etc1_differential < error_currently_best)
  13437. error_currently_best = error_etc1_differential;
  13438. error_etc1_individual = compressBlockIndividualExhaustivePerceptual(img, width, height, startx, starty, etc1_individual_word1, etc1_individual_word2, error_currently_best);
  13439. if(error_etc1_individual < error_currently_best)
  13440. error_currently_best = error_etc1_individual;
  13441. // Now find the best error.
  13442. error_best = error_etc1;
  13443. compressed1 = etc1_word1;
  13444. compressed2 = etc1_word2;
  13445. best_char = '.';
  13446. best_mode = MODE_ETC1;
  13447. if(error_etc1_differential < error_best)
  13448. {
  13449. error_best = error_etc1_differential;
  13450. compressed1 = etc1_differential_word1;
  13451. compressed2 = etc1_differential_word2;
  13452. best_char = '.';
  13453. best_mode = MODE_ETC1;
  13454. }
  13455. if(error_etc1_individual < error_best)
  13456. {
  13457. compressed1 = etc1_individual_word1;
  13458. compressed2 = etc1_individual_word2;
  13459. best_char = ',';
  13460. error_best = error_etc1_individual;
  13461. best_mode = MODE_ETC1;
  13462. }
  13463. }
  13464. #endif
  13465. #if EXHAUSTIVE_CODE_ACTIVE
  13466. // Compress a block exhaustively for the ETC2 RGB codec using perceptual error measure.
  13467. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  13468. void compressBlockETC2ExhaustivePerceptual(uint8 *img, uint8 *imgdec,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  13469. {
  13470. unsigned int error_currently_best;
  13471. unsigned int etc1_differential_word1;
  13472. unsigned int etc1_differential_word2;
  13473. unsigned int error_etc1_differential;
  13474. unsigned int etc1_individual_word1;
  13475. unsigned int etc1_individual_word2;
  13476. unsigned int error_etc1_individual;
  13477. unsigned int planar57_word1;
  13478. unsigned int planar57_word2;
  13479. unsigned int planar_word1;
  13480. unsigned int planar_word2;
  13481. double error_planar;
  13482. unsigned int error_planar_red, error_planar_green, error_planar_blue;
  13483. unsigned int thumbH58_word1;
  13484. unsigned int thumbH58_word2;
  13485. unsigned int thumbH_word1;
  13486. unsigned int thumbH_word2;
  13487. unsigned int error_thumbH;
  13488. unsigned int thumbT59_word1;
  13489. unsigned int thumbT59_word2;
  13490. unsigned int thumbT_word1;
  13491. unsigned int thumbT_word2;
  13492. unsigned int error_thumbT;
  13493. unsigned int error_best;
  13494. signed char best_char;
  13495. int best_mode;
  13496. error_currently_best = 255*255*16*1000;
  13497. // First pass -- quickly find a low error so that we can later cull away a lot of
  13498. // calculations later that are guaranteed to be higher than that error.
  13499. unsigned int error_etc1;
  13500. unsigned int etc1_word1;
  13501. unsigned int etc1_word2;
  13502. compressBlockDiffFlipFastPerceptual(img, imgdec, width, height, startx, starty, etc1_word1, etc1_word2);
  13503. decompressBlockDiffFlip(etc1_word1, etc1_word2, imgdec, width, height, startx, starty);
  13504. error_etc1 = 1000*calcBlockPerceptualErrorRGB(img, imgdec, width, height, startx, starty);
  13505. if(error_etc1 < error_currently_best)
  13506. error_currently_best = error_etc1;
  13507. // The planar mode treats every channel independently and should not be affected by the weights in the error measure.
  13508. // We can hence use the nonperceptual version of the encoder also to find the best perceptual description of the block.
  13509. compressBlockPlanar57(img, width, height, startx, starty, planar57_word1, planar57_word2);
  13510. decompressBlockPlanar57errorPerComponent(planar57_word1, planar57_word2, imgdec, width, height, startx, starty, img, error_planar_red, error_planar_green, error_planar_blue);
  13511. error_planar = 1000*calcBlockPerceptualErrorRGB(img, imgdec, width, height, startx, starty);
  13512. stuff57bits(planar57_word1, planar57_word2, planar_word1, planar_word2);
  13513. if(error_planar < error_currently_best)
  13514. error_currently_best = (unsigned int) error_planar;
  13515. error_thumbT = (unsigned int) compressBlockTHUMB59TFastestPerceptual1000(img,width, height, startx, starty, thumbT59_word1, thumbT59_word2);
  13516. stuff59bits(thumbT59_word1, thumbT59_word2, thumbT_word1, thumbT_word2);
  13517. if(error_thumbT < error_currently_best)
  13518. error_currently_best = error_thumbT;
  13519. error_thumbH = (unsigned int) compressBlockTHUMB58HFastestPerceptual1000(img,width,height,startx, starty, thumbH58_word1, thumbH58_word2);
  13520. stuff58bits(thumbH58_word1, thumbH58_word2, thumbH_word1, thumbH_word2);
  13521. if(error_thumbH < error_currently_best)
  13522. error_currently_best = error_thumbH;
  13523. // Second pass --- now find the lowest error, but only if it is lower than error_currently_best
  13524. // Correct the individual errors for the different planes so that they sum to 1000 instead of 1.
  13525. error_planar_red *=PERCEPTUAL_WEIGHT_R_SQUARED_TIMES1000;
  13526. error_planar_green *=PERCEPTUAL_WEIGHT_G_SQUARED_TIMES1000;
  13527. error_planar_blue *=PERCEPTUAL_WEIGHT_B_SQUARED_TIMES1000;
  13528. compressBlockPlanar57ExhaustivePerceptual(img, width, height, startx, starty, planar57_word1, planar57_word2, error_currently_best, error_planar_red, error_planar_green, error_planar_blue);
  13529. decompressBlockPlanar57(planar57_word1, planar57_word2, imgdec, width, height, startx, starty);
  13530. error_planar = 1000*calcBlockPerceptualErrorRGB(img, imgdec, width, height, startx, starty);
  13531. stuff57bits(planar57_word1, planar57_word2, planar_word1, planar_word2);
  13532. if(error_planar < error_currently_best)
  13533. error_currently_best = (unsigned int) error_planar;
  13534. error_etc1_differential = compressBlockDifferentialExhaustivePerceptual(img, width, height, startx, starty, etc1_differential_word1, etc1_differential_word2, error_currently_best);
  13535. if(error_etc1_differential < error_currently_best)
  13536. error_currently_best = error_etc1_differential;
  13537. error_etc1_individual = compressBlockIndividualExhaustivePerceptual(img, width, height, startx, starty, etc1_individual_word1, etc1_individual_word2, error_currently_best);
  13538. if(error_etc1_individual < error_currently_best)
  13539. error_currently_best = error_etc1_individual;
  13540. error_thumbH = compressBlockTHUMB58HExhaustivePerceptual(img,width,height,startx, starty, thumbH58_word1, thumbH58_word2, error_currently_best);
  13541. stuff58bits(thumbH58_word1, thumbH58_word2, thumbH_word1, thumbH_word2);
  13542. if( error_thumbH < error_currently_best)
  13543. error_currently_best = error_thumbH;
  13544. error_thumbT = compressBlockTHUMB59TExhaustivePerceptual(img,width, height, startx, starty, thumbT59_word1, thumbT59_word2, error_currently_best);
  13545. stuff59bits(thumbT59_word1, thumbT59_word2, thumbT_word1, thumbT_word2);
  13546. if(error_thumbT < error_currently_best)
  13547. error_currently_best = error_thumbT;
  13548. // Now find the best error.
  13549. error_best = error_etc1;
  13550. compressed1 = etc1_word1;
  13551. compressed2 = etc1_word2;
  13552. best_char = '.';
  13553. best_mode = MODE_ETC1;
  13554. if(error_etc1_differential < error_best)
  13555. {
  13556. error_best = error_etc1_differential;
  13557. compressed1 = etc1_differential_word1;
  13558. compressed2 = etc1_differential_word2;
  13559. best_char = '.';
  13560. best_mode = MODE_ETC1;
  13561. }
  13562. if(error_etc1_individual < error_best)
  13563. {
  13564. compressed1 = etc1_individual_word1;
  13565. compressed2 = etc1_individual_word2;
  13566. best_char = ',';
  13567. error_best = error_etc1_individual;
  13568. best_mode = MODE_ETC1;
  13569. }
  13570. if(error_planar < error_best)
  13571. {
  13572. compressed1 = planar_word1;
  13573. compressed2 = planar_word2;
  13574. best_char = 'p';
  13575. error_best = (unsigned int) error_planar;
  13576. best_mode = MODE_PLANAR;
  13577. }
  13578. if(error_thumbH < error_best)
  13579. {
  13580. compressed1 = thumbH_word1;
  13581. compressed2 = thumbH_word2;
  13582. best_char = 'H';
  13583. error_best = error_thumbH;
  13584. best_mode = MODE_THUMB_H;
  13585. }
  13586. if(error_thumbT < error_best)
  13587. {
  13588. compressed1 = thumbT_word1;
  13589. compressed2 = thumbT_word2;
  13590. best_char = 'T';
  13591. error_best = error_thumbT;
  13592. best_mode = MODE_THUMB_T;
  13593. }
  13594. }
  13595. #endif
  13596. #if EXHAUSTIVE_CODE_ACTIVE
  13597. // Compress a block exhaustively for the ETC2 RGB codec.
  13598. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  13599. void compressBlockETC2Exhaustive(uint8 *img, uint8 *imgdec,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2)
  13600. {
  13601. unsigned int error_currently_best;
  13602. unsigned int etc1_differential_word1;
  13603. unsigned int etc1_differential_word2;
  13604. unsigned int error_etc1_differential;
  13605. unsigned int etc1_individual_word1;
  13606. unsigned int etc1_individual_word2;
  13607. unsigned int error_etc1_individual;
  13608. unsigned int planar57_word1;
  13609. unsigned int planar57_word2;
  13610. unsigned int planar_word1;
  13611. unsigned int planar_word2;
  13612. double error_planar;
  13613. unsigned int error_planar_red;
  13614. unsigned int error_planar_green;
  13615. unsigned int error_planar_blue;
  13616. unsigned int thumbH58_word1;
  13617. unsigned int thumbH58_word2;
  13618. unsigned int thumbH_word1;
  13619. unsigned int thumbH_word2;
  13620. unsigned int error_thumbH;
  13621. unsigned int thumbT59_word1;
  13622. unsigned int thumbT59_word2;
  13623. unsigned int thumbT_word1;
  13624. unsigned int thumbT_word2;
  13625. unsigned int error_thumbT;
  13626. unsigned int error_best;
  13627. signed char best_char;
  13628. int best_mode;
  13629. error_currently_best = 255*255*16*3;
  13630. // First pass -- quickly find a low error so that we can later cull away a lot of
  13631. // calculations later that are guaranteed to be higher than that error.
  13632. unsigned int error_etc1;
  13633. unsigned int etc1_word1;
  13634. unsigned int etc1_word2;
  13635. error_etc1 = (unsigned int) compressBlockDiffFlipFast(img, imgdec, width, height, startx, starty, etc1_word1, etc1_word2);
  13636. if(error_etc1 < error_currently_best)
  13637. error_currently_best = error_etc1;
  13638. compressBlockPlanar57(img, width, height, startx, starty, planar57_word1, planar57_word2);
  13639. decompressBlockPlanar57errorPerComponent(planar57_word1, planar57_word2, imgdec, width, height, startx, starty, img, error_planar_red, error_planar_green, error_planar_blue);
  13640. error_planar = calcBlockErrorRGB(img, imgdec, width, height, startx, starty);
  13641. stuff57bits(planar57_word1, planar57_word2, planar_word1, planar_word2);
  13642. if(error_planar < error_currently_best)
  13643. error_currently_best = (unsigned int) error_planar;
  13644. error_thumbT = (unsigned int) compressBlockTHUMB59TFastest(img,width, height, startx, starty, thumbT59_word1, thumbT59_word2);
  13645. stuff59bits(thumbT59_word1, thumbT59_word2, thumbT_word1, thumbT_word2);
  13646. if(error_thumbT < error_currently_best)
  13647. error_currently_best = error_thumbT;
  13648. error_thumbH = (unsigned int) compressBlockTHUMB58HFastest(img,width,height,startx, starty, thumbH58_word1, thumbH58_word2);
  13649. stuff58bits(thumbH58_word1, thumbH58_word2, thumbH_word1, thumbH_word2);
  13650. if(error_thumbH < error_currently_best)
  13651. error_currently_best = error_thumbH;
  13652. // Second pass --- now find the lowest error, but only if it is lower than error_currently_best
  13653. error_etc1_differential = compressBlockDifferentialExhaustive(img, width, height, startx, starty, etc1_differential_word1, etc1_differential_word2, error_currently_best);
  13654. if(error_etc1_differential < error_currently_best)
  13655. error_currently_best = error_etc1_differential;
  13656. compressBlockPlanar57Exhaustive(img, width, height, startx, starty, planar57_word1, planar57_word2, error_currently_best, error_planar_red, error_planar_green, error_planar_blue);
  13657. decompressBlockPlanar57(planar57_word1, planar57_word2, imgdec, width, height, startx, starty);
  13658. error_planar = calcBlockErrorRGB(img, imgdec, width, height, startx, starty);
  13659. stuff57bits(planar57_word1, planar57_word2, planar_word1, planar_word2);
  13660. if(error_planar < error_currently_best)
  13661. error_currently_best = (unsigned int) error_planar;
  13662. error_etc1_individual = compressBlockIndividualExhaustive(img, width, height, startx, starty, etc1_individual_word1, etc1_individual_word2, error_currently_best);
  13663. if(error_etc1_individual < error_currently_best)
  13664. error_currently_best = error_etc1_individual;
  13665. error_thumbH = compressBlockTHUMB58HExhaustive(img,width,height,startx, starty, thumbH58_word1, thumbH58_word2, error_currently_best);
  13666. if( error_thumbH < error_currently_best)
  13667. error_currently_best = error_thumbH;
  13668. stuff58bits(thumbH58_word1, thumbH58_word2, thumbH_word1, thumbH_word2);
  13669. error_thumbT = compressBlockTHUMB59TExhaustive(img,width, height, startx, starty, thumbT59_word1, thumbT59_word2, error_currently_best);
  13670. if(error_thumbT < error_currently_best)
  13671. error_currently_best = error_thumbT;
  13672. stuff59bits(thumbT59_word1, thumbT59_word2, thumbT_word1, thumbT_word2);
  13673. error_best = 255*255*3*16;
  13674. // Now find the best error.
  13675. error_best = error_etc1;
  13676. compressed1 = etc1_word1;
  13677. compressed2 = etc1_word2;
  13678. best_char = '.';
  13679. best_mode = MODE_ETC1;
  13680. if(error_etc1_differential < error_best)
  13681. {
  13682. error_best = error_etc1_differential;
  13683. compressed1 = etc1_differential_word1;
  13684. compressed2 = etc1_differential_word2;
  13685. best_char = '.';
  13686. best_mode = MODE_ETC1;
  13687. }
  13688. if(error_etc1_individual < error_best)
  13689. {
  13690. compressed1 = etc1_individual_word1;
  13691. compressed2 = etc1_individual_word2;
  13692. best_char = ',';
  13693. error_best = error_etc1_individual;
  13694. best_mode = MODE_ETC1;
  13695. }
  13696. if(error_planar < error_best)
  13697. {
  13698. compressed1 = planar_word1;
  13699. compressed2 = planar_word2;
  13700. best_char = 'p';
  13701. error_best = (unsigned int) error_planar;
  13702. best_mode = MODE_PLANAR;
  13703. }
  13704. if(error_thumbH < error_best)
  13705. {
  13706. compressed1 = thumbH_word1;
  13707. compressed2 = thumbH_word2;
  13708. best_char = 'H';
  13709. error_best = error_thumbH;
  13710. best_mode = MODE_THUMB_H;
  13711. }
  13712. if(error_thumbT < error_best)
  13713. {
  13714. compressed1 = thumbT_word1;
  13715. compressed2 = thumbT_word2;
  13716. best_char = 'T';
  13717. error_best = error_thumbT;
  13718. best_mode = MODE_THUMB_T;
  13719. }
  13720. }
  13721. #endif
  13722. //// Exhaustive code ends here.
  13723. // Compress an image file.
  13724. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  13725. /*void compressImageFile(uint8 *img, uint8 *alphaimg,int width,int height,char *dstfile, int expandedwidth, int expandedheight)
  13726. {
  13727. FILE *f;
  13728. int x,y,w,h;
  13729. unsigned int block1, block2;
  13730. unsigned short wi, hi;
  13731. unsigned char magic[4];
  13732. unsigned char version[2];
  13733. unsigned short texture_type=format;
  13734. uint8 *imgdec;
  13735. uint8* alphaimg2;
  13736. imgdec = (unsigned char*) malloc(expandedwidth*expandedheight*3);
  13737. if(!imgdec)
  13738. {
  13739. printf("Could not allocate decompression buffer --- exiting\n");
  13740. }
  13741. magic[0] = 'P'; magic[1] = 'K'; magic[2] = 'M'; magic[3] = ' ';
  13742. if(codec==CODEC_ETC2)
  13743. {
  13744. version[0] = '2'; version[1] = '0';
  13745. }
  13746. else
  13747. {
  13748. version[0] = '1'; version[1] = '0';
  13749. }
  13750. if(f=fopen(dstfile,"wb"))
  13751. {
  13752. w=expandedwidth/4; w*=4;
  13753. h=expandedheight/4; h*=4;
  13754. wi = w;
  13755. hi = h;
  13756. if(ktxFile)
  13757. {
  13758. //.ktx file: KTX header followed by compressed binary data.
  13759. KTX_header header;
  13760. //identifier
  13761. for(int i=0; i<12; i++)
  13762. {
  13763. header.identifier[i]=ktx_identifier[i];
  13764. }
  13765. //endianess int.. if this comes out reversed, all of the other ints will too.
  13766. header.endianness=KTX_ENDIAN_REF;
  13767. //these values are always 0/1 for compressed textures.
  13768. header.glType=0;
  13769. header.glTypeSize=1;
  13770. header.glFormat=0;
  13771. header.pixelWidth=width;
  13772. header.pixelHeight=height;
  13773. header.pixelDepth=0;
  13774. //we only support single non-mipmapped non-cubemap textures..
  13775. header.numberOfArrayElements=0;
  13776. header.numberOfFaces=1;
  13777. header.numberOfMipmapLevels=1;
  13778. //and no metadata..
  13779. header.bytesOfKeyValueData=0;
  13780. int halfbytes=1;
  13781. //header.glInternalFormat=?
  13782. //header.glBaseInternalFormat=?
  13783. if(format==ETC2PACKAGE_R_NO_MIPMAPS)
  13784. {
  13785. header.glBaseInternalFormat=GL_R;
  13786. if(formatSigned)
  13787. header.glInternalFormat=GL_COMPRESSED_SIGNED_R11_EAC;
  13788. else
  13789. header.glInternalFormat=GL_COMPRESSED_R11_EAC;
  13790. }
  13791. else if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
  13792. {
  13793. halfbytes=2;
  13794. header.glBaseInternalFormat=GL_RG;
  13795. if(formatSigned)
  13796. header.glInternalFormat=GL_COMPRESSED_SIGNED_RG11_EAC;
  13797. else
  13798. header.glInternalFormat=GL_COMPRESSED_RG11_EAC;
  13799. }
  13800. else if(format==ETC2PACKAGE_RGB_NO_MIPMAPS)
  13801. {
  13802. header.glBaseInternalFormat=GL_RGB;
  13803. header.glInternalFormat=GL_COMPRESSED_RGB8_ETC2;
  13804. }
  13805. else if(format==ETC2PACKAGE_sRGB_NO_MIPMAPS)
  13806. {
  13807. header.glBaseInternalFormat=GL_SRGB;
  13808. header.glInternalFormat=GL_COMPRESSED_SRGB8_ETC2;
  13809. }
  13810. else if(format==ETC2PACKAGE_RGBA_NO_MIPMAPS)
  13811. {
  13812. halfbytes=2;
  13813. header.glBaseInternalFormat=GL_RGBA;
  13814. header.glInternalFormat=GL_COMPRESSED_RGBA8_ETC2_EAC;
  13815. }
  13816. else if(format==ETC2PACKAGE_sRGBA_NO_MIPMAPS)
  13817. {
  13818. halfbytes=2;
  13819. header.glBaseInternalFormat=GL_SRGB8_ALPHA8;
  13820. header.glInternalFormat=GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
  13821. }
  13822. else if(format==ETC2PACKAGE_RGBA1_NO_MIPMAPS)
  13823. {
  13824. header.glBaseInternalFormat=GL_RGBA;
  13825. header.glInternalFormat=GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
  13826. }
  13827. else if(format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  13828. {
  13829. header.glBaseInternalFormat=GL_SRGB8_ALPHA8;
  13830. header.glInternalFormat=GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
  13831. }
  13832. else if(format==ETC1_RGB_NO_MIPMAPS)
  13833. {
  13834. header.glBaseInternalFormat=GL_RGB;
  13835. header.glInternalFormat=GL_ETC1_RGB8_OES;
  13836. }
  13837. else
  13838. {
  13839. printf("internal error: bad format!\n");
  13840. exit(1);
  13841. }
  13842. //write header
  13843. fwrite(&header,sizeof(KTX_header),1,f);
  13844. //write size of compressed data.. which depend on the expanded size..
  13845. unsigned int imagesize=(w*h*halfbytes)/2;
  13846. fwrite(&imagesize,sizeof(int),1,f);
  13847. }
  13848. else
  13849. {
  13850. //.pkm file, contains small header..
  13851. // Write magic number
  13852. fwrite(&magic[0], sizeof(unsigned char), 1, f);
  13853. fwrite(&magic[1], sizeof(unsigned char), 1, f);
  13854. fwrite(&magic[2], sizeof(unsigned char), 1, f);
  13855. fwrite(&magic[3], sizeof(unsigned char), 1, f);
  13856. // Write version
  13857. fwrite(&version[0], sizeof(unsigned char), 1, f);
  13858. fwrite(&version[1], sizeof(unsigned char), 1, f);
  13859. // Write texture type
  13860. if(texture_type==ETC2PACKAGE_RG_NO_MIPMAPS&&formatSigned)
  13861. {
  13862. unsigned short temp = ETC2PACKAGE_RG_SIGNED_NO_MIPMAPS;
  13863. write_big_endian_2byte_word(&temp,f);
  13864. }
  13865. else if(texture_type==ETC2PACKAGE_R_NO_MIPMAPS&&formatSigned)
  13866. {
  13867. unsigned short temp = ETC2PACKAGE_R_SIGNED_NO_MIPMAPS;
  13868. write_big_endian_2byte_word(&temp,f);
  13869. }
  13870. else
  13871. write_big_endian_2byte_word(&texture_type, f);
  13872. // Write binary header: the width and height as unsigned 16-bit words
  13873. write_big_endian_2byte_word(&wi, f);
  13874. write_big_endian_2byte_word(&hi, f);
  13875. // Also write the active pixels. For instance, if we want to compress
  13876. // a 128 x 129 image, we have to extend it to 128 x 132 pixels.
  13877. // Then the wi and hi written above will be 128 and 132, but the
  13878. // additional information that we write below will be 128 and 129,
  13879. // to indicate that it is only the top 129 lines of data in the
  13880. // decompressed image that will be valid data, and the rest will
  13881. // be just garbage.
  13882. unsigned short activew, activeh;
  13883. activew = width;
  13884. activeh = height;
  13885. write_big_endian_2byte_word(&activew, f);
  13886. write_big_endian_2byte_word(&activeh, f);
  13887. }
  13888. int totblocks = expandedheight/4 * expandedwidth/4;
  13889. int countblocks = 0;
  13890. double percentageblocks=-1.0;
  13891. double oldpercentageblocks;
  13892. if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
  13893. {
  13894. //extract data from red and green channel into two alpha channels.
  13895. //note that the image will be 16-bit per channel in this case.
  13896. alphaimg= (unsigned char*)malloc(expandedwidth*expandedheight*2);
  13897. alphaimg2=(unsigned char*)malloc(expandedwidth*expandedheight*2);
  13898. setupAlphaTableAndValtab();
  13899. if(!alphaimg||!alphaimg2)
  13900. {
  13901. printf("failed allocating space for alpha buffers!\n");
  13902. exit(1);
  13903. }
  13904. for(y=0;y<expandedheight;y++)
  13905. {
  13906. for(x=0;x<expandedwidth;x++)
  13907. {
  13908. alphaimg[2*(y*expandedwidth+x)]=img[6*(y*expandedwidth+x)];
  13909. alphaimg[2*(y*expandedwidth+x)+1]=img[6*(y*expandedwidth+x)+1];
  13910. alphaimg2[2*(y*expandedwidth+x)]=img[6*(y*expandedwidth+x)+2];
  13911. alphaimg2[2*(y*expandedwidth+x)+1]=img[6*(y*expandedwidth+x)+3];
  13912. }
  13913. }
  13914. }
  13915. for(y=0;y<expandedheight/4;y++)
  13916. {
  13917. for(x=0;x<expandedwidth/4;x++)
  13918. {
  13919. countblocks++;
  13920. oldpercentageblocks = percentageblocks;
  13921. percentageblocks = 100.0*countblocks/(1.0*totblocks);
  13922. //compress color channels
  13923. if(codec==CODEC_ETC)
  13924. {
  13925. if(metric==METRIC_NONPERCEPTUAL)
  13926. {
  13927. if(speed==SPEED_FAST)
  13928. compressBlockDiffFlipFast(img, imgdec, expandedwidth, expandedheight, 4*x, 4*y, block1, block2);
  13929. else
  13930. #if EXHAUSTIVE_CODE_ACTIVE
  13931. compressBlockETC1Exhaustive(img, imgdec, expandedwidth, expandedheight, 4*x, 4*y, block1, block2);
  13932. #else
  13933. printf("Not implemented in this version\n");
  13934. #endif
  13935. }
  13936. else
  13937. {
  13938. if(speed==SPEED_FAST)
  13939. compressBlockDiffFlipFastPerceptual(img, imgdec, expandedwidth, expandedheight, 4*x, 4*y, block1, block2);
  13940. else
  13941. #if EXHAUSTIVE_CODE_ACTIVE
  13942. compressBlockETC1ExhaustivePerceptual(img, imgdec, expandedwidth, expandedheight, 4*x, 4*y, block1, block2);
  13943. #else
  13944. printf("Not implemented in this version\n");
  13945. #endif
  13946. }
  13947. }
  13948. else
  13949. {
  13950. if(format==ETC2PACKAGE_R_NO_MIPMAPS||format==ETC2PACKAGE_RG_NO_MIPMAPS)
  13951. {
  13952. //don't compress color
  13953. }
  13954. else if(format==ETC2PACKAGE_RGBA1_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  13955. {
  13956. //this is only available for fast/nonperceptual
  13957. if(speed == SPEED_SLOW && first_time_message)
  13958. {
  13959. printf("Slow codec not implemented for RGBA1 --- using fast codec instead.\n");
  13960. first_time_message = false;
  13961. }
  13962. compressBlockETC2Fast(img, alphaimg,imgdec, expandedwidth, expandedheight, 4*x, 4*y, block1, block2);
  13963. }
  13964. else if(metric==METRIC_NONPERCEPTUAL)
  13965. {
  13966. if(speed==SPEED_FAST)
  13967. compressBlockETC2Fast(img, alphaimg,imgdec, expandedwidth, expandedheight, 4*x, 4*y, block1, block2);
  13968. else
  13969. #if EXHAUSTIVE_CODE_ACTIVE
  13970. compressBlockETC2Exhaustive(img, imgdec, expandedwidth, expandedheight, 4*x, 4*y, block1, block2);
  13971. #else
  13972. printf("Not implemented in this version\n");
  13973. #endif
  13974. }
  13975. else
  13976. {
  13977. if(speed==SPEED_FAST)
  13978. compressBlockETC2FastPerceptual(img, imgdec, expandedwidth, expandedheight, 4*x, 4*y, block1, block2);
  13979. else
  13980. #if EXHAUSTIVE_CODE_ACTIVE
  13981. compressBlockETC2ExhaustivePerceptual(img, imgdec, expandedwidth, expandedheight, 4*x, 4*y, block1, block2);
  13982. #else
  13983. printf("Not implemented in this version\n");
  13984. #endif
  13985. }
  13986. }
  13987. //compression of alpha channel in case of 4-bit alpha. Uses 8-bit alpha channel as input, and has 8-bit precision.
  13988. if(format==ETC2PACKAGE_RGBA_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA_NO_MIPMAPS)
  13989. {
  13990. uint8 alphadata[8];
  13991. if(speed==SPEED_SLOW)
  13992. compressBlockAlphaSlow(alphaimg,4*x,4*y,expandedwidth,expandedheight,alphadata);
  13993. else
  13994. compressBlockAlphaFast(alphaimg,4*x,4*y,expandedwidth,expandedheight,alphadata);
  13995. //write the 8 bytes of alphadata into f.
  13996. fwrite(alphadata,1,8,f);
  13997. }
  13998. //store compressed color channels
  13999. if(format!=ETC2PACKAGE_R_NO_MIPMAPS&&format!=ETC2PACKAGE_RG_NO_MIPMAPS)
  14000. {
  14001. write_big_endian_4byte_word(&block1, f);
  14002. write_big_endian_4byte_word(&block2, f);
  14003. }
  14004. //1-channel or 2-channel alpha compression: uses 16-bit data as input, and has 11-bit precision
  14005. if(format==ETC2PACKAGE_R_NO_MIPMAPS||format==ETC2PACKAGE_RG_NO_MIPMAPS)
  14006. {
  14007. uint8 alphadata[8];
  14008. compressBlockAlpha16(alphaimg,4*x,4*y,expandedwidth,expandedheight,alphadata);
  14009. fwrite(alphadata,1,8,f);
  14010. }
  14011. //compression of second alpha channel in RG-compression
  14012. if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
  14013. {
  14014. uint8 alphadata[8];
  14015. compressBlockAlpha16(alphaimg2,4*x,4*y,expandedwidth,expandedheight,alphadata);
  14016. fwrite(alphadata,1,8,f);
  14017. }
  14018. #if 1
  14019. if(verbose)
  14020. {
  14021. if(speed==SPEED_FAST)
  14022. {
  14023. if( ((int)(percentageblocks) != (int)(oldpercentageblocks) ) || percentageblocks == 100.0)
  14024. printf("Compressed %d of %d blocks, %.0f%% finished.\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", countblocks, totblocks, 100.0*countblocks/(1.0*totblocks));
  14025. }
  14026. else
  14027. printf("Compressed %d of %d blocks, %.0f%% finished.\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", countblocks, totblocks, 100.0*countblocks/(1.0*totblocks));
  14028. }
  14029. #endif
  14030. }
  14031. }
  14032. printf("\n");
  14033. fclose(f);
  14034. printf("Saved file <%s>.\n",dstfile);
  14035. }
  14036. }
  14037. // Compress an file.
  14038. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  14039. void compressFile(char *srcfile,char *dstfile)
  14040. {
  14041. uint8 *srcimg;
  14042. int width,height;
  14043. int extendedwidth, extendedheight;
  14044. struct _timeb tstruct;
  14045. int tstart;
  14046. int tstop;
  14047. // 0: compress from .any to .pkm with SPEED_FAST, METRIC_NONPERCEPTUAL, ETC
  14048. // 1: compress from .any to .pkm with SPEED_MEDIUM, METRIC_NONPERCEPTUAL, ETC
  14049. // 2: compress from .any to .pkm with SPEED_SLOW, METRIC_NONPERCEPTUAL, ETC
  14050. // 3: compress from .any to .pkm with SPEED_FAST, METRIC_PERCEPTUAL, ETC
  14051. // 4: compress from .any to .pkm with SPEED_MEDIUM, METRIC_PERCEPTUAL, ETC
  14052. // 5: compress from .any to .pkm with SPEED_SLOW, METRIC_PERCEPTUAL, ETC
  14053. // 6: decompress from .pkm to .any
  14054. // 7: calculate PSNR between .any and .any
  14055. // 8: compress from .any to .pkm with SPEED_FAST, METRIC_NONPERCEPTUAL, ETC2
  14056. // 9: compress from .any to .pkm with SPEED_MEDIUM, METRIC_NONPERCEPTUAL, ETC2
  14057. //10: compress from .any to .pkm with SPEED_SLOW, METRIC_NONPERCEPTUAL, ETC2
  14058. //11: compress from .any to .pkm with SPEED_FAST, METRIC_PERCEPTUAL, ETC2
  14059. //12: compress from .any to .pkm with SPEED_MEDIUM, METRIC_PERCEPTUAL, ETC2
  14060. //13: compress from .any to .pkm with SPEED_SLOW, METRIC_PERCEPTUAL, ETC2
  14061. printf("\n");
  14062. if(codec==CODEC_ETC)
  14063. printf("ETC codec, ");
  14064. else
  14065. printf("ETC2 codec, ");
  14066. if(speed==SPEED_FAST)
  14067. printf("using FAST compression mode and ");
  14068. else if(speed==SPEED_MEDIUM)
  14069. printf("using MEDIUM compression mode and ");
  14070. else
  14071. printf("using SLOW compression mode and ");
  14072. if(metric==METRIC_PERCEPTUAL)
  14073. printf("PERCEPTUAL error metric, ");
  14074. else
  14075. printf("NONPERCEPTUAL error metric, ");
  14076. if(format==ETC2PACKAGE_RGBA_NO_MIPMAPS)
  14077. printf("in RGBA format");
  14078. else if(format==ETC2PACKAGE_sRGBA_NO_MIPMAPS)
  14079. printf("in sRGBA format");
  14080. else if(format==ETC2PACKAGE_RGBA1_NO_MIPMAPS)
  14081. printf("in RGB + punch-through alpha format");
  14082. else if(format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  14083. printf("in sRGB + punch-through alpha format");
  14084. else if(format==ETC2PACKAGE_R_NO_MIPMAPS)
  14085. printf("in R format");
  14086. else if(format==ETC2PACKAGE_RGB_NO_MIPMAPS||format==ETC1_RGB_NO_MIPMAPS)
  14087. printf("in RGB format");
  14088. else if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
  14089. printf("in RG format");
  14090. else
  14091. printf("in OTHER format");
  14092. printf("\n");
  14093. if(readCompressParams())
  14094. {
  14095. if(format==ETC2PACKAGE_R_NO_MIPMAPS||readSrcFile(srcfile,srcimg,width,height,extendedwidth, extendedheight))
  14096. {
  14097. //make sure that alphasrcimg contains the alpha channel or is null here, and pass it to compressimagefile
  14098. uint8* alphaimg=NULL;
  14099. if(format==ETC2PACKAGE_RGBA_NO_MIPMAPS||format==ETC2PACKAGE_RGBA1_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
  14100. {
  14101. char str[300];
  14102. //printf("reading alpha channel....");
  14103. sprintf(str,"imconv %s -alpha extract alpha.pgm\n",srcfile);
  14104. system(str);
  14105. readAlpha(alphaimg,width,height,extendedwidth,extendedheight);
  14106. printf("ok!\n");
  14107. setupAlphaTableAndValtab();
  14108. }
  14109. else if(format==ETC2PACKAGE_R_NO_MIPMAPS)
  14110. {
  14111. char str[300];
  14112. sprintf(str,"imconv %s alpha.pgm\n",srcfile);
  14113. system(str);
  14114. readAlpha(alphaimg,width,height,extendedwidth,extendedheight);
  14115. printf("read alpha ok, size is %d,%d (%d,%d)",width,height,extendedwidth,extendedheight);
  14116. setupAlphaTableAndValtab();
  14117. }
  14118. printf("Compressing...\n");
  14119. tstart=time(NULL);
  14120. _ftime( &tstruct );
  14121. tstart=tstart*1000+tstruct.millitm;
  14122. compressImageFile(srcimg,alphaimg,width,height,dstfile,extendedwidth, extendedheight);
  14123. tstop = time(NULL);
  14124. _ftime( &tstruct );
  14125. tstop = tstop*1000+tstruct.millitm;
  14126. printf( "It took %u milliseconds to compress:\n", tstop - tstart);
  14127. calculatePSNRfile(dstfile,srcimg,alphaimg);
  14128. }
  14129. }
  14130. }
  14131. // Calculates the PSNR between two files.
  14132. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  14133. double calculatePSNRTwoFiles(char *srcfile1,char *srcfile2)
  14134. {
  14135. uint8 *srcimg1;
  14136. uint8 *srcimg2;
  14137. int width1, height1;
  14138. int width2, height2;
  14139. double PSNR;
  14140. double perceptually_weighted_PSNR;
  14141. if(readSrcFileNoExpand(srcfile1,srcimg1,width1,height1))
  14142. {
  14143. if(readSrcFileNoExpand(srcfile2,srcimg2,width2,height2))
  14144. {
  14145. if((width1 == width2) && (height1 == height2))
  14146. {
  14147. PSNR = calculatePSNR(srcimg1, srcimg2, width1, height1);
  14148. printf("%f\n",PSNR);
  14149. perceptually_weighted_PSNR = calculateWeightedPSNR(srcimg1, srcimg2, width1, height1, 0.299, 0.587, 0.114);
  14150. }
  14151. else
  14152. {
  14153. printf("\n Width and height do no not match for image: width, height = (%d, %d) and (%d, %d)\n",width1,height1, width2, height2);
  14154. }
  14155. }
  14156. else
  14157. {
  14158. printf("Couldn't open file %s.\n",srcfile2);
  14159. }
  14160. }
  14161. else
  14162. {
  14163. printf("Couldn't open file %s.\n",srcfile1);
  14164. }
  14165. return PSNR;
  14166. }
  14167. // Main function
  14168. // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
  14169. int main(int argc,char *argv[])
  14170. {
  14171. if(argc==3 || argc==4 || argc == 5 || argc == 7 || argc == 9 || argc == 11 || argc == 13)
  14172. {
  14173. // The source file is always the second last one.
  14174. char srcfile[200];
  14175. char dstfile[200];
  14176. readArguments(argc,argv,srcfile,dstfile);
  14177. int q = find_pos_of_extension(srcfile);
  14178. int q2 = find_pos_of_extension(dstfile);
  14179. if(!fileExist(srcfile))
  14180. {
  14181. printf("Error: file <%s> does not exist.\n",srcfile);
  14182. exit(0);
  14183. }
  14184. if(mode==MODE_UNCOMPRESS)
  14185. {
  14186. printf("Decompressing .pkm/.ktx file ...\n");
  14187. uint8* alphaimg=NULL, *img;
  14188. int w, h;
  14189. uncompressFile(srcfile,img,alphaimg,w,h);
  14190. writeOutputFile(dstfile,img,alphaimg,w,h);
  14191. }
  14192. else if(mode==MODE_PSNR)
  14193. {
  14194. calculatePSNRTwoFiles(srcfile,dstfile);
  14195. }
  14196. else
  14197. {
  14198. compressFile(srcfile, dstfile);
  14199. }
  14200. }
  14201. else
  14202. {
  14203. printf("ETCPACK v2.74 For ETC and ETC2\n");
  14204. printf("Compresses and decompresses images using the Ericsson Texture Compression (ETC) version 1.0 and 2.0.\n\nUsage: etcpack srcfile dstfile\n\n");
  14205. printf(" -s {fast|slow} Compression speed. Slow = exhaustive \n");
  14206. printf(" search for optimal quality\n");
  14207. printf(" (default: fast)\n");
  14208. printf(" -e {perceptual|nonperceptual} Error metric: Perceptual (nicest) or \n");
  14209. printf(" nonperceptual (highest PSNR)\n");
  14210. printf(" (default: perceptual)\n");
  14211. printf(" -c {etc1|etc2} Codec: etc1 (most compatible) or \n");
  14212. printf(" etc2 (highest quality)\n");
  14213. printf(" (default: etc2)\n");
  14214. printf(" -f {R|R_signed|RG|RG_signed| Format: one, two, three or four \n");
  14215. printf(" RGB|RGBA1|RGBA8| channels, and 1 or 8 bits for alpha\n");
  14216. printf(" sRGB|sRGBA1|sRGBA8|} RGB or sRGB.\n");
  14217. printf(" (1 equals punchthrough)\n");
  14218. printf(" (default: RGB)\n");
  14219. printf(" -v {on|off} Detailed progress info. (default on)\n");
  14220. printf(" \n");
  14221. printf("Examples: \n");
  14222. printf(" etcpack img.ppm img.pkm Compresses img.ppm to img.pkm in\n");
  14223. printf(" ETC2 RGB format\n");
  14224. printf(" etcpack img.ppm img.ktx Compresses img.ppm to img.ktx in\n");
  14225. printf(" ETC2 RGB format\n");
  14226. printf(" etcpack img.pkm img_copy.ppm Decompresses img.pkm to img_copy.ppm\n");
  14227. printf(" etcpack -s slow img.ppm img.pkm Compress using the slow mode.\n");
  14228. printf(" etcpack -p orig.ppm copy.ppm Calculate PSNR between orig and copy\n");
  14229. printf(" etcpack -f RGBA8 img.tga img.pkm Compresses img.tga to img.pkm, using \n");
  14230. printf(" etc2 + alpha.\n");
  14231. printf(" etcpack -f RG img.ppm img.pkm Compresses red and green channels of\n");
  14232. printf(" img.ppm\n");
  14233. }
  14234. return 0;
  14235. }
  14236. */