| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842 |
- /**
-
- @~English
- @page licensing Licensing
-
- @section etcdec etcdec.cxx License
-
- etcdec.cxx is made available under the terms and conditions of the following
- License Agreement.
- Software License Agreement
- PLEASE REVIEW THE FOLLOWING TERMS AND CONDITIONS PRIOR TO USING THE
- ERICSSON TEXTURE COMPRESSION CODEC SOFTWARE (THE "SOFTWARE"). THE USE
- OF THE SOFTWARE IS SUBJECT TO THE TERMS AND CONDITIONS OF THE
- FOLLOWING SOFTWARE LICENSE AGREEMENT (THE "SLA"). IF YOU DO NOT ACCEPT
- SUCH TERMS AND CONDITIONS YOU MAY NOT USE THE SOFTWARE.
- Subject to the terms and conditions of the SLA, the licensee of the
- Software (the "Licensee") hereby, receives a non-exclusive,
- non-transferable, limited, free-of-charge, perpetual and worldwide
- license, to copy, use, distribute and modify the Software, but only
- for the purpose of developing, manufacturing, selling, using and
- distributing products including the Software in binary form, which
- products are used for compression and/or decompression according to
- the Khronos standard specifications OpenGL, OpenGL ES and
- WebGL. Notwithstanding anything of the above, Licensee may distribute
- [etcdec.cxx] in source code form provided (i) it is in unmodified
- form; and (ii) it is included in software owned by Licensee.
- If Licensee institutes, or threatens to institute, patent litigation
- against Ericsson or Ericsson's affiliates for using the Software for
- developing, having developed, manufacturing, having manufactured,
- selling, offer for sale, importing, using, leasing, operating,
- repairing and/or distributing products (i) within the scope of the
- Khronos framework; or (ii) using software or other intellectual
- property rights owned by Ericsson or its affiliates and provided under
- the Khronos framework, Ericsson shall have the right to terminate this
- SLA with immediate effect. Moreover, if Licensee institutes, or
- threatens to institute, patent litigation against any other licensee
- of the Software for using the Software in products within the scope of
- the Khronos framework, Ericsson shall have the right to terminate this
- SLA with immediate effect. However, should Licensee institute, or
- threaten to institute, patent litigation against any other licensee of
- the Software based on such other licensee's use of any other software
- together with the Software, then Ericsson shall have no right to
- terminate this SLA.
- This SLA does not transfer to Licensee any ownership to any Ericsson
- or third party intellectual property rights. All rights not expressly
- granted by Ericsson under this SLA are hereby expressly
- reserved. Furthermore, nothing in this SLA shall be construed as a
- right to use or sell products in a manner which conveys or purports to
- convey whether explicitly, by principles of implied license, or
- otherwise, any rights to any third party, under any patent of Ericsson
- or of Ericsson's affiliates covering or relating to any combination of
- the Software with any other software or product (not licensed
- hereunder) where the right applies specifically to the combination and
- not to the software or product itself.
- THE SOFTWARE IS PROVIDED "AS IS". ERICSSON MAKES NO REPRESENTATIONS OF
- ANY KIND, EXTENDS NO WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
- EXPRESS, IMPLIED OR STATUTORY; INCLUDING, BUT NOT LIMITED TO, EXPRESS,
- IMPLIED OR STATUTORY WARRANTIES OR CONDITIONS OF TITLE,
- MERCHANTABILITY, SATISFACTORY QUALITY, SUITABILITY, AND FITNESS FOR A
- PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
- OF THE SOFTWARE IS WITH THE LICENSEE. SHOULD THE SOFTWARE PROVE
- DEFECTIVE, THE LICENSEE ASSUMES THE COST OF ALL NECESSARY SERVICING,
- REPAIR OR CORRECTION. ERICSSON MAKES NO WARRANTY THAT THE MANUFACTURE,
- SALE, OFFERING FOR SALE, DISTRIBUTION, LEASE, USE OR IMPORTATION UNDER
- THE SLA WILL BE FREE FROM INFRINGEMENT OF PATENTS, COPYRIGHTS OR OTHER
- INTELLECTUAL PROPERTY RIGHTS OF OTHERS, AND THE VALIDITY OF THE
- LICENSE AND THE SLA ARE SUBJECT TO LICENSEE'S SOLE RESPONSIBILITY TO
- MAKE SUCH DETERMINATION AND ACQUIRE SUCH LICENSES AS MAY BE NECESSARY
- WITH RESPECT TO PATENTS, COPYRIGHT AND OTHER INTELLECTUAL PROPERTY OF
- THIRD PARTIES.
- THE LICENSEE ACKNOWLEDGES AND ACCEPTS THAT THE SOFTWARE (I) IS NOT
- LICENSED FOR; (II) IS NOT DESIGNED FOR OR INTENDED FOR; AND (III) MAY
- NOT BE USED FOR; ANY MISSION CRITICAL APPLICATIONS SUCH AS, BUT NOT
- LIMITED TO OPERATION OF NUCLEAR OR HEALTHCARE COMPUTER SYSTEMS AND/OR
- NETWORKS, AIRCRAFT OR TRAIN CONTROL AND/OR COMMUNICATION SYSTEMS OR
- ANY OTHER COMPUTER SYSTEMS AND/OR NETWORKS OR CONTROL AND/OR
- COMMUNICATION SYSTEMS ALL IN WHICH CASE THE FAILURE OF THE SOFTWARE
- COULD LEAD TO DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL, MATERIAL OR
- ENVIRONMENTAL DAMAGE. LICENSEE'S RIGHTS UNDER THIS LICENSE WILL
- TERMINATE AUTOMATICALLY AND IMMEDIATELY WITHOUT NOTICE IF LICENSEE
- FAILS TO COMPLY WITH THIS PARAGRAPH.
- IN NO EVENT SHALL ERICSSON BE LIABLE FOR ANY DAMAGES WHATSOEVER,
- INCLUDING BUT NOT LIMITED TO PERSONAL INJURY, ANY GENERAL, SPECIAL,
- INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN
- CONNECTION WITH THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING
- BUT NOT LIMITED TO LOSS OF PROFITS, BUSINESS INTERUPTIONS, OR ANY
- OTHER COMMERCIAL DAMAGES OR LOSSES, LOSS OF DATA OR DATA BEING
- RENDERED INACCURATE OR LOSSES SUSTAINED BY THE LICENSEE OR THIRD
- PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER
- SOFTWARE) REGARDLESS OF THE THEORY OF LIABILITY (CONTRACT, TORT, OR
- OTHERWISE), EVEN IF THE LICENSEE OR ANY OTHER PARTY HAS BEEN ADVISED
- OF THE POSSIBILITY OF SUCH DAMAGES.
- Licensee acknowledges that "ERICSSON ///" is the corporate trademark
- of Telefonaktiebolaget LM Ericsson and that both "Ericsson" and the
- figure "///" are important features of the trade names of
- Telefonaktiebolaget LM Ericsson. Nothing contained in these terms and
- conditions shall be deemed to grant Licensee any right, title or
- interest in the word "Ericsson" or the figure "///". No delay or
- omission by Ericsson to exercise any right or power shall impair any
- such right or power to be construed to be a waiver thereof. Consent by
- Ericsson to, or waiver of, a breach by the Licensee shall not
- constitute consent to, waiver of, or excuse for any other different or
- subsequent breach.
- This SLA shall be governed by the substantive law of Sweden. Any
- dispute, controversy or claim arising out of or in connection with
- this SLA, or the breach, termination or invalidity thereof, shall be
- submitted to the exclusive jurisdiction of the Swedish Courts.
- */
- //// etcpack v2.74
- ////
- //// NO WARRANTY
- ////
- //// BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE THE PROGRAM IS PROVIDED
- //// "AS IS". ERICSSON MAKES NO REPRESENTATIONS OF ANY KIND, EXTENDS NO
- //// WARRANTIES OR CONDITIONS OF ANY KIND; EITHER EXPRESS, IMPLIED OR
- //// STATUTORY; INCLUDING, BUT NOT LIMITED TO, EXPRESS, IMPLIED OR
- //// STATUTORY WARRANTIES OR CONDITIONS OF TITLE, MERCHANTABILITY,
- //// SATISFACTORY QUALITY, SUITABILITY AND FITNESS FOR A PARTICULAR
- //// PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
- //// PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
- //// THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. ERICSSON
- //// MAKES NO WARRANTY THAT THE MANUFACTURE, SALE, OFFERING FOR SALE,
- //// DISTRIBUTION, LEASE, USE OR IMPORTATION UNDER THE LICENSE WILL BE FREE
- //// FROM INFRINGEMENT OF PATENTS, COPYRIGHTS OR OTHER INTELLECTUAL
- //// PROPERTY RIGHTS OF OTHERS, AND THE VALIDITY OF THE LICENSE IS SUBJECT
- //// TO YOUR SOLE RESPONSIBILITY TO MAKE SUCH DETERMINATION AND ACQUIRE
- //// SUCH LICENSES AS MAY BE NECESSARY WITH RESPECT TO PATENTS, COPYRIGHT
- //// AND OTHER INTELLECTUAL PROPERTY OF THIRD PARTIES.
- ////
- //// FOR THE AVOIDANCE OF DOUBT THE PROGRAM (I) IS NOT LICENSED FOR; (II)
- //// IS NOT DESIGNED FOR OR INTENDED FOR; AND (III) MAY NOT BE USED FOR;
- //// ANY MISSION CRITICAL APPLICATIONS SUCH AS, BUT NOT LIMITED TO
- //// OPERATION OF NUCLEAR OR HEALTHCARE COMPUTER SYSTEMS AND/OR NETWORKS,
- //// AIRCRAFT OR TRAIN CONTROL AND/OR COMMUNICATION SYSTEMS OR ANY OTHER
- //// COMPUTER SYSTEMS AND/OR NETWORKS OR CONTROL AND/OR COMMUNICATION
- //// SYSTEMS ALL IN WHICH CASE THE FAILURE OF THE PROGRAM COULD LEAD TO
- //// DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL, MATERIAL OR ENVIRONMENTAL
- //// DAMAGE. YOUR RIGHTS UNDER THIS LICENSE WILL TERMINATE AUTOMATICALLY
- //// AND IMMEDIATELY WITHOUT NOTICE IF YOU FAIL TO COMPLY WITH THIS
- //// PARAGRAPH.
- ////
- //// IN NO EVENT WILL ERICSSON, BE LIABLE FOR ANY DAMAGES WHATSOEVER,
- //// INCLUDING BUT NOT LIMITED TO PERSONAL INJURY, ANY GENERAL, SPECIAL,
- //// INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN
- //// CONNECTION WITH THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
- //// NOT LIMITED TO LOSS OF PROFITS, BUSINESS INTERUPTIONS, OR ANY OTHER
- //// COMMERCIAL DAMAGES OR LOSSES, LOSS OF DATA OR DATA BEING RENDERED
- //// INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
- //// THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) REGARDLESS OF THE
- //// THEORY OF LIABILITY (CONTRACT, TORT OR OTHERWISE), EVEN IF SUCH HOLDER
- //// OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- ////
- //// (C) Ericsson AB 2005-2013. All Rights Reserved.
- ////
- #include <stdio.h>
- #include <stdlib.h>
- // Typedefs
- typedef unsigned char uint8;
- typedef unsigned short uint16;
- typedef short int16;
- // Macros to help with bit extraction/insertion
- #define SHIFT(size,startpos) ((startpos)-(size)+1)
- #define MASK(size, startpos) (((2<<(size-1))-1) << SHIFT(size,startpos))
- #define PUTBITS( dest, data, size, startpos) dest = ((dest & ~MASK(size, startpos)) | ((data << SHIFT(size, startpos)) & MASK(size,startpos)))
- #define SHIFTHIGH(size, startpos) (((startpos)-32)-(size)+1)
- #define MASKHIGH(size, startpos) (((1<<(size))-1) << SHIFTHIGH(size,startpos))
- #define PUTBITSHIGH(dest, data, size, startpos) dest = ((dest & ~MASKHIGH(size, startpos)) | ((data << SHIFTHIGH(size, startpos)) & MASKHIGH(size,startpos)))
- #define GETBITS(source, size, startpos) (( (source) >> ((startpos)-(size)+1) ) & ((1<<(size)) -1))
- #define GETBITSHIGH(source, size, startpos) (( (source) >> (((startpos)-32)-(size)+1) ) & ((1<<(size)) -1))
- #ifndef PGMOUT
- #define PGMOUT 1
- #endif
- // Thumb macros and definitions
- #define R_BITS59T 4
- #define G_BITS59T 4
- #define B_BITS59T 4
- #define R_BITS58H 4
- #define G_BITS58H 4
- #define B_BITS58H 4
- #define MAXIMUM_ERROR (255*255*16*1000)
- #define R 0
- #define G 1
- #define B 2
- #define BLOCKHEIGHT 4
- #define BLOCKWIDTH 4
- #define BINPOW(power) (1<<(power))
- #define TABLE_BITS_59T 3
- #define TABLE_BITS_58H 3
- // Helper Macros
- #define CLAMP(ll,x,ul) (((x)<(ll)) ? (ll) : (((x)>(ul)) ? (ul) : (x)))
- #define JAS_ROUND(x) (((x) < 0.0 ) ? ((int)((x)-0.5)) : ((int)((x)+0.5)))
- #define RED_CHANNEL(img,width,x,y,channels) img[channels*(y*width+x)+0]
- #define GREEN_CHANNEL(img,width,x,y,channels) img[channels*(y*width+x)+1]
- #define BLUE_CHANNEL(img,width,x,y,channels) img[channels*(y*width+x)+2]
- #define ALPHA_CHANNEL(img,width,x,y,channels) img[channels*(y*width+x)+3]
- // Global tables
- static uint8 table59T[8] = {3,6,11,16,23,32,41,64}; // 3-bit table for the 59 bit T-mode
- static uint8 table58H[8] = {3,6,11,16,23,32,41,64}; // 3-bit table for the 58 bit H-mode
- static int compressParams[16][4] = {{-8, -2, 2, 8}, {-8, -2, 2, 8}, {-17, -5, 5, 17}, {-17, -5, 5, 17}, {-29, -9, 9, 29}, {-29, -9, 9, 29}, {-42, -13, 13, 42}, {-42, -13, 13, 42}, {-60, -18, 18, 60}, {-60, -18, 18, 60}, {-80, -24, 24, 80}, {-80, -24, 24, 80}, {-106, -33, 33, 106}, {-106, -33, 33, 106}, {-183, -47, 47, 183}, {-183, -47, 47, 183}};
- static int unscramble[4] = {2, 3, 1, 0};
- int alphaTableInitialized = 0;
- int alphaTable[256][8];
- int alphaBase[16][4] = {
- {-15,-9,-6,-3},
- {-13,-10,-7,-3},
- {-13,-8,-5,-2},
- {-13,-6,-4,-2},
- {-12,-8,-6,-3},
- {-11,-9,-7,-3},
- {-11,-8,-7,-4},
- {-11,-8,-5,-3},
- { -10,-8,-6,-2},
- { -10,-8,-5,-2},
- { -10,-8,-4,-2},
- { -10,-7,-5,-2},
- { -10,-7,-4,-3},
- { -10,-3,-2, -1},
- { -9,-8,-6,-4},
- { -9,-7,-5,-3}
- };
- // Global variables
- int formatSigned = 0;
- // Enums
- enum{PATTERN_H = 0,
- PATTERN_T = 1};
- // Code used to create the valtab
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void setupAlphaTable()
- {
- if(alphaTableInitialized)
- return;
- alphaTableInitialized = 1;
- //read table used for alpha compression
- int buf;
- for(int i = 16; i<32; i++)
- {
- for(int j=0; j<8; j++)
- {
- buf=alphaBase[i-16][3-j%4];
- if(j<4)
- alphaTable[i][j]=buf;
- else
- alphaTable[i][j]=(-buf-1);
- }
- }
-
- //beyond the first 16 values, the rest of the table is implicit.. so calculate that!
- for(int i=0; i<256; i++)
- {
- //fill remaining slots in table with multiples of the first ones.
- int mul = i/16;
- int old = 16+i%16;
- for(int j = 0; j<8; j++)
- {
- alphaTable[i][j]=alphaTable[old][j]*mul;
- //note: we don't do clamping here, though we could, because we'll be clamped afterwards anyway.
- }
- }
- }
- // Read a word in big endian style
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void read_big_endian_2byte_word(unsigned short *blockadr, FILE *f)
- {
- uint8 bytes[2];
- unsigned short block;
- fread(&bytes[0], 1, 1, f);
- fread(&bytes[1], 1, 1, f);
- block = 0;
- block |= bytes[0];
- block = block << 8;
- block |= bytes[1];
- blockadr[0] = block;
- }
- // Read a word in big endian style
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void read_big_endian_4byte_word(unsigned int *blockadr, FILE *f)
- {
- uint8 bytes[4];
- unsigned int block;
- fread(&bytes[0], 1, 1, f);
- fread(&bytes[1], 1, 1, f);
- fread(&bytes[2], 1, 1, f);
- fread(&bytes[3], 1, 1, f);
- block = 0;
- block |= bytes[0];
- block = block << 8;
- block |= bytes[1];
- block = block << 8;
- block |= bytes[2];
- block = block << 8;
- block |= bytes[3];
- blockadr[0] = block;
- }
- // The format stores the bits for the three extra modes in a roundabout way to be able to
- // fit them without increasing the bit rate. This function converts them into something
- // that is easier to work with.
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void unstuff57bits(unsigned int planar_word1, unsigned int planar_word2, unsigned int &planar57_word1, unsigned int &planar57_word2)
- {
- // Get bits from twotimer configuration for 57 bits
- //
- // Go to this bit layout:
- //
- // 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
- // -----------------------------------------------------------------------------------------------
- // |R0 |G01G02 |B01B02 ;B03 |RH1 |RH2|GH |
- // -----------------------------------------------------------------------------------------------
- //
- // 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
- // -----------------------------------------------------------------------------------------------
- // |BH |RV |GV |BV | not used |
- // -----------------------------------------------------------------------------------------------
- //
- // From this:
- //
- // 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
- // ------------------------------------------------------------------------------------------------
- // |//|R0 |G01|/|G02 |B01|/ // //|B02 |//|B03 |RH1 |df|RH2|
- // ------------------------------------------------------------------------------------------------
- //
- // 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
- // -----------------------------------------------------------------------------------------------
- // |GH |BH |RV |GV |BV |
- // -----------------------------------------------------------------------------------------------
- //
- // 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
- // ---------------------------------------------------------------------------------------------------
- // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |diff|flip|
- // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
- // ---------------------------------------------------------------------------------------------------
- uint8 RO, GO1, GO2, BO1, BO2, BO3, RH1, RH2, GH, BH, RV, GV, BV;
- RO = GETBITSHIGH( planar_word1, 6, 62);
- GO1 = GETBITSHIGH( planar_word1, 1, 56);
- GO2 = GETBITSHIGH( planar_word1, 6, 54);
- BO1 = GETBITSHIGH( planar_word1, 1, 48);
- BO2 = GETBITSHIGH( planar_word1, 2, 44);
- BO3 = GETBITSHIGH( planar_word1, 3, 41);
- RH1 = GETBITSHIGH( planar_word1, 5, 38);
- RH2 = GETBITSHIGH( planar_word1, 1, 32);
- GH = GETBITS( planar_word2, 7, 31);
- BH = GETBITS( planar_word2, 6, 24);
- RV = GETBITS( planar_word2, 6, 18);
- GV = GETBITS( planar_word2, 7, 12);
- BV = GETBITS( planar_word2, 6, 5);
- planar57_word1 = 0; planar57_word2 = 0;
- PUTBITSHIGH( planar57_word1, RO, 6, 63);
- PUTBITSHIGH( planar57_word1, GO1, 1, 57);
- PUTBITSHIGH( planar57_word1, GO2, 6, 56);
- PUTBITSHIGH( planar57_word1, BO1, 1, 50);
- PUTBITSHIGH( planar57_word1, BO2, 2, 49);
- PUTBITSHIGH( planar57_word1, BO3, 3, 47);
- PUTBITSHIGH( planar57_word1, RH1, 5, 44);
- PUTBITSHIGH( planar57_word1, RH2, 1, 39);
- PUTBITSHIGH( planar57_word1, GH, 7, 38);
- PUTBITS( planar57_word2, BH, 6, 31);
- PUTBITS( planar57_word2, RV, 6, 25);
- PUTBITS( planar57_word2, GV, 7, 19);
- PUTBITS( planar57_word2, BV, 6, 12);
- }
- // The format stores the bits for the three extra modes in a roundabout way to be able to
- // fit them without increasing the bit rate. This function converts them into something
- // that is easier to work with.
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void unstuff58bits(unsigned int thumbH_word1, unsigned int thumbH_word2, unsigned int &thumbH58_word1, unsigned int &thumbH58_word2)
- {
- // Go to this layout:
- //
- // |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 |
- // |-------empty-----|part0---------------|part1|part2------------------------------------------|part3|
- //
- // from this:
- //
- // 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
- // --------------------------------------------------------------------------------------------------|
- // |//|part0 |// // //|part1|//|part2 |df|part3|
- // --------------------------------------------------------------------------------------------------|
- unsigned int part0, part1, part2, part3;
- // move parts
- part0 = GETBITSHIGH( thumbH_word1, 7, 62);
- part1 = GETBITSHIGH( thumbH_word1, 2, 52);
- part2 = GETBITSHIGH( thumbH_word1,16, 49);
- part3 = GETBITSHIGH( thumbH_word1, 1, 32);
- thumbH58_word1 = 0;
- PUTBITSHIGH( thumbH58_word1, part0, 7, 57);
- PUTBITSHIGH( thumbH58_word1, part1, 2, 50);
- PUTBITSHIGH( thumbH58_word1, part2, 16, 48);
- PUTBITSHIGH( thumbH58_word1, part3, 1, 32);
- thumbH58_word2 = thumbH_word2;
- }
- // The format stores the bits for the three extra modes in a roundabout way to be able to
- // fit them without increasing the bit rate. This function converts them into something
- // that is easier to work with.
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void unstuff59bits(unsigned int thumbT_word1, unsigned int thumbT_word2, unsigned int &thumbT59_word1, unsigned int &thumbT59_word2)
- {
- // Get bits from twotimer configuration 59 bits.
- //
- // Go to this bit layout:
- //
- // |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|
- // |----empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|--dist--|
- //
- // |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|
- // |----------------------------------------index bits---------------------------------------------|
- //
- //
- // From this:
- //
- // 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
- // -----------------------------------------------------------------------------------------------
- // |// // //|R0a |//|R0b |G0 |B0 |R1 |G1 |B1 |da |df|db|
- // -----------------------------------------------------------------------------------------------
- //
- // |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|
- // |----------------------------------------index bits---------------------------------------------|
- //
- // 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
- // -----------------------------------------------------------------------------------------------
- // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |df|fp|
- // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bt|bt|
- // ------------------------------------------------------------------------------------------------
- uint8 R0a;
- // Fix middle part
- thumbT59_word1 = thumbT_word1 >> 1;
- // Fix db (lowest bit of d)
- PUTBITSHIGH( thumbT59_word1, thumbT_word1, 1, 32);
- // Fix R0a (top two bits of R0)
- R0a = GETBITSHIGH( thumbT_word1, 2, 60);
- PUTBITSHIGH( thumbT59_word1, R0a, 2, 58);
- // Zero top part (not needed)
- PUTBITSHIGH( thumbT59_word1, 0, 5, 63);
- thumbT59_word2 = thumbT_word2;
- }
- // The color bits are expanded to the full color
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void decompressColor(int R_B, int G_B, int B_B, uint8 (colors_RGB444)[2][3], uint8 (colors)[2][3])
- {
- // The color should be retrieved as:
- //
- // c = round(255/(r_bits^2-1))*comp_color
- //
- // This is similar to bit replication
- //
- // Note -- this code only work for bit replication from 4 bits and up --- 3 bits needs
- // two copy operations.
- colors[0][R] = (colors_RGB444[0][R] << (8 - R_B)) | (colors_RGB444[0][R] >> (R_B - (8-R_B)) );
- colors[0][G] = (colors_RGB444[0][G] << (8 - G_B)) | (colors_RGB444[0][G] >> (G_B - (8-G_B)) );
- colors[0][B] = (colors_RGB444[0][B] << (8 - B_B)) | (colors_RGB444[0][B] >> (B_B - (8-B_B)) );
- colors[1][R] = (colors_RGB444[1][R] << (8 - R_B)) | (colors_RGB444[1][R] >> (R_B - (8-R_B)) );
- colors[1][G] = (colors_RGB444[1][G] << (8 - G_B)) | (colors_RGB444[1][G] >> (G_B - (8-G_B)) );
- colors[1][B] = (colors_RGB444[1][B] << (8 - B_B)) | (colors_RGB444[1][B] >> (B_B - (8-B_B)) );
- }
- void calculatePaintColors59T(uint8 d, uint8 p, uint8 (colors)[2][3], uint8 (possible_colors)[4][3])
- {
- //////////////////////////////////////////////
- //
- // C3 C1 C4----C1---C2
- // | | |
- // | | |
- // |-------| |
- // | | |
- // | | |
- // C4 C2 C3
- //
- //////////////////////////////////////////////
- // C4
- possible_colors[3][R] = CLAMP(0,colors[1][R] - table59T[d],255);
- possible_colors[3][G] = CLAMP(0,colors[1][G] - table59T[d],255);
- possible_colors[3][B] = CLAMP(0,colors[1][B] - table59T[d],255);
-
- if (p == PATTERN_T)
- {
- // C3
- possible_colors[0][R] = colors[0][R];
- possible_colors[0][G] = colors[0][G];
- possible_colors[0][B] = colors[0][B];
- // C2
- possible_colors[1][R] = CLAMP(0,colors[1][R] + table59T[d],255);
- possible_colors[1][G] = CLAMP(0,colors[1][G] + table59T[d],255);
- possible_colors[1][B] = CLAMP(0,colors[1][B] + table59T[d],255);
- // C1
- possible_colors[2][R] = colors[1][R];
- possible_colors[2][G] = colors[1][G];
- possible_colors[2][B] = colors[1][B];
- }
- else
- {
- printf("Invalid pattern. Terminating");
- exit(1);
- }
- }
- // Decompress a T-mode block (simple packing)
- // Simple 59T packing:
- //|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|
- //|----empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|--dist--|
- //
- //|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|
- //|----------------------------------------index bits---------------------------------------------|
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void decompressBlockTHUMB59Tc(unsigned int block_part1, unsigned int block_part2, uint8 *img,int width,int height,int startx,int starty, int channels)
- {
- uint8 colorsRGB444[2][3];
- uint8 colors[2][3];
- uint8 paint_colors[4][3];
- uint8 distance;
- uint8 block_mask[4][4];
- // First decode left part of block.
- colorsRGB444[0][R]= GETBITSHIGH(block_part1, 4, 58);
- colorsRGB444[0][G]= GETBITSHIGH(block_part1, 4, 54);
- colorsRGB444[0][B]= GETBITSHIGH(block_part1, 4, 50);
- colorsRGB444[1][R]= GETBITSHIGH(block_part1, 4, 46);
- colorsRGB444[1][G]= GETBITSHIGH(block_part1, 4, 42);
- colorsRGB444[1][B]= GETBITSHIGH(block_part1, 4, 38);
- distance = GETBITSHIGH(block_part1, TABLE_BITS_59T, 34);
- // Extend the two colors to RGB888
- decompressColor(R_BITS59T, G_BITS59T, B_BITS59T, colorsRGB444, colors);
- calculatePaintColors59T(distance, PATTERN_T, colors, paint_colors);
-
- // Choose one of the four paint colors for each texel
- for (uint8 x = 0; x < BLOCKWIDTH; ++x)
- {
- for (uint8 y = 0; y < BLOCKHEIGHT; ++y)
- {
- //block_mask[x][y] = GETBITS(block_part2,2,31-(y*4+x)*2);
- block_mask[x][y] = GETBITS(block_part2,1,(y+x*4)+16)<<1;
- block_mask[x][y] |= GETBITS(block_part2,1,(y+x*4));
- img[channels*((starty+y)*width+startx+x)+R] =
- CLAMP(0,paint_colors[block_mask[x][y]][R],255); // RED
- img[channels*((starty+y)*width+startx+x)+G] =
- CLAMP(0,paint_colors[block_mask[x][y]][G],255); // GREEN
- img[channels*((starty+y)*width+startx+x)+B] =
- CLAMP(0,paint_colors[block_mask[x][y]][B],255); // BLUE
- }
- }
- }
- void decompressBlockTHUMB59T(unsigned int block_part1, unsigned int block_part2, uint8 *img, int width, int height, int startx, int starty)
- {
- decompressBlockTHUMB59Tc(block_part1, block_part2, img, width, height, startx, starty, 3);
- }
- // Calculate the paint colors from the block colors
- // using a distance d and one of the H- or T-patterns.
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void calculatePaintColors58H(uint8 d, uint8 p, uint8 (colors)[2][3], uint8 (possible_colors)[4][3])
- {
-
- //////////////////////////////////////////////
- //
- // C3 C1 C4----C1---C2
- // | | |
- // | | |
- // |-------| |
- // | | |
- // | | |
- // C4 C2 C3
- //
- //////////////////////////////////////////////
- // C4
- possible_colors[3][R] = CLAMP(0,colors[1][R] - table58H[d],255);
- possible_colors[3][G] = CLAMP(0,colors[1][G] - table58H[d],255);
- possible_colors[3][B] = CLAMP(0,colors[1][B] - table58H[d],255);
-
- if (p == PATTERN_H)
- {
- // C1
- possible_colors[0][R] = CLAMP(0,colors[0][R] + table58H[d],255);
- possible_colors[0][G] = CLAMP(0,colors[0][G] + table58H[d],255);
- possible_colors[0][B] = CLAMP(0,colors[0][B] + table58H[d],255);
- // C2
- possible_colors[1][R] = CLAMP(0,colors[0][R] - table58H[d],255);
- possible_colors[1][G] = CLAMP(0,colors[0][G] - table58H[d],255);
- possible_colors[1][B] = CLAMP(0,colors[0][B] - table58H[d],255);
- // C3
- possible_colors[2][R] = CLAMP(0,colors[1][R] + table58H[d],255);
- possible_colors[2][G] = CLAMP(0,colors[1][G] + table58H[d],255);
- possible_colors[2][B] = CLAMP(0,colors[1][B] + table58H[d],255);
- }
- else
- {
- printf("Invalid pattern. Terminating");
- exit(1);
- }
- }
- // Decompress an H-mode block
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void decompressBlockTHUMB58Hc(unsigned int block_part1, unsigned int block_part2, uint8 *img, int width, int height, int startx, int starty, int channels)
- {
- unsigned int col0, col1;
- uint8 colors[2][3];
- uint8 colorsRGB444[2][3];
- uint8 paint_colors[4][3];
- uint8 distance;
- uint8 block_mask[4][4];
-
- // First decode left part of block.
- colorsRGB444[0][R]= GETBITSHIGH(block_part1, 4, 57);
- colorsRGB444[0][G]= GETBITSHIGH(block_part1, 4, 53);
- colorsRGB444[0][B]= GETBITSHIGH(block_part1, 4, 49);
- colorsRGB444[1][R]= GETBITSHIGH(block_part1, 4, 45);
- colorsRGB444[1][G]= GETBITSHIGH(block_part1, 4, 41);
- colorsRGB444[1][B]= GETBITSHIGH(block_part1, 4, 37);
- distance = 0;
- distance = (GETBITSHIGH(block_part1, 2, 33)) << 1;
- col0 = GETBITSHIGH(block_part1, 12, 57);
- col1 = GETBITSHIGH(block_part1, 12, 45);
- if(col0 >= col1)
- {
- distance |= 1;
- }
- // Extend the two colors to RGB888
- decompressColor(R_BITS58H, G_BITS58H, B_BITS58H, colorsRGB444, colors);
-
- calculatePaintColors58H(distance, PATTERN_H, colors, paint_colors);
-
- // Choose one of the four paint colors for each texel
- for (uint8 x = 0; x < BLOCKWIDTH; ++x)
- {
- for (uint8 y = 0; y < BLOCKHEIGHT; ++y)
- {
- //block_mask[x][y] = GETBITS(block_part2,2,31-(y*4+x)*2);
- block_mask[x][y] = GETBITS(block_part2,1,(y+x*4)+16)<<1;
- block_mask[x][y] |= GETBITS(block_part2,1,(y+x*4));
- img[channels*((starty+y)*width+startx+x)+R] =
- CLAMP(0,paint_colors[block_mask[x][y]][R],255); // RED
- img[channels*((starty+y)*width+startx+x)+G] =
- CLAMP(0,paint_colors[block_mask[x][y]][G],255); // GREEN
- img[channels*((starty+y)*width+startx+x)+B] =
- CLAMP(0,paint_colors[block_mask[x][y]][B],255); // BLUE
- }
- }
- }
- void decompressBlockTHUMB58H(unsigned int block_part1, unsigned int block_part2, uint8 *img, int width, int height, int startx, int starty)
- {
- decompressBlockTHUMB58Hc(block_part1, block_part2, img, width, height, startx, starty, 3);
- }
- // Decompress the planar mode.
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void decompressBlockPlanar57c(unsigned int compressed57_1, unsigned int compressed57_2, uint8 *img, int width, int height, int startx, int starty, int channels)
- {
- uint8 colorO[3], colorH[3], colorV[3];
- colorO[0] = GETBITSHIGH( compressed57_1, 6, 63);
- colorO[1] = GETBITSHIGH( compressed57_1, 7, 57);
- colorO[2] = GETBITSHIGH( compressed57_1, 6, 50);
- colorH[0] = GETBITSHIGH( compressed57_1, 6, 44);
- colorH[1] = GETBITSHIGH( compressed57_1, 7, 38);
- colorH[2] = GETBITS( compressed57_2, 6, 31);
- colorV[0] = GETBITS( compressed57_2, 6, 25);
- colorV[1] = GETBITS( compressed57_2, 7, 19);
- colorV[2] = GETBITS( compressed57_2, 6, 12);
- colorO[0] = (colorO[0] << 2) | (colorO[0] >> 4);
- colorO[1] = (colorO[1] << 1) | (colorO[1] >> 6);
- colorO[2] = (colorO[2] << 2) | (colorO[2] >> 4);
- colorH[0] = (colorH[0] << 2) | (colorH[0] >> 4);
- colorH[1] = (colorH[1] << 1) | (colorH[1] >> 6);
- colorH[2] = (colorH[2] << 2) | (colorH[2] >> 4);
- colorV[0] = (colorV[0] << 2) | (colorV[0] >> 4);
- colorV[1] = (colorV[1] << 1) | (colorV[1] >> 6);
- colorV[2] = (colorV[2] << 2) | (colorV[2] >> 4);
- int xx, yy;
- for( xx=0; xx<4; xx++)
- {
- for( yy=0; yy<4; yy++)
- {
- img[channels*width*(starty+yy) + channels*(startx+xx) + 0] = CLAMP(0, ((xx*(colorH[0]-colorO[0]) + yy*(colorV[0]-colorO[0]) + 4*colorO[0] + 2) >> 2),255);
- img[channels*width*(starty+yy) + channels*(startx+xx) + 1] = CLAMP(0, ((xx*(colorH[1]-colorO[1]) + yy*(colorV[1]-colorO[1]) + 4*colorO[1] + 2) >> 2),255);
- img[channels*width*(starty+yy) + channels*(startx+xx) + 2] = CLAMP(0, ((xx*(colorH[2]-colorO[2]) + yy*(colorV[2]-colorO[2]) + 4*colorO[2] + 2) >> 2),255);
- //Equivalent method
- /*img[channels*width*(starty+yy) + channels*(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);
- img[channels*width*(starty+yy) + channels*(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);
- img[channels*width*(starty+yy) + channels*(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);*/
-
- }
- }
- }
- void decompressBlockPlanar57(unsigned int compressed57_1, unsigned int compressed57_2, uint8 *img, int width, int height, int startx, int starty)
- {
- decompressBlockPlanar57c(compressed57_1, compressed57_2, img, width, height, startx, starty, 3);
- }
- // Decompress an ETC1 block (or ETC2 using individual or differential mode).
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void decompressBlockDiffFlipC(unsigned int block_part1, unsigned int block_part2, uint8 *img, int width, int height, int startx, int starty, int channels)
- {
- uint8 avg_color[3], enc_color1[3], enc_color2[3];
- signed char diff[3];
- int table;
- int index,shift;
- int r,g,b;
- int diffbit;
- int flipbit;
- diffbit = (GETBITSHIGH(block_part1, 1, 33));
- flipbit = (GETBITSHIGH(block_part1, 1, 32));
- if( !diffbit )
- {
- // We have diffbit = 0.
- // First decode left part of block.
- avg_color[0]= GETBITSHIGH(block_part1, 4, 63);
- avg_color[1]= GETBITSHIGH(block_part1, 4, 55);
- avg_color[2]= GETBITSHIGH(block_part1, 4, 47);
- // Here, we should really multiply by 17 instead of 16. This can
- // be done by just copying the four lower bits to the upper ones
- // while keeping the lower bits.
- avg_color[0] |= (avg_color[0] <<4);
- avg_color[1] |= (avg_color[1] <<4);
- avg_color[2] |= (avg_color[2] <<4);
- table = GETBITSHIGH(block_part1, 3, 39) << 1;
- unsigned int pixel_indices_MSB, pixel_indices_LSB;
-
- pixel_indices_MSB = GETBITS(block_part2, 16, 31);
- pixel_indices_LSB = GETBITS(block_part2, 16, 15);
- if( (flipbit) == 0 )
- {
- // We should not flip
- shift = 0;
- for(int x=startx; x<startx+2; x++)
- {
- for(int y=starty; y<starty+4; y++)
- {
- index = ((pixel_indices_MSB >> shift) & 1) << 1;
- index |= ((pixel_indices_LSB >> shift) & 1);
- shift++;
- index=unscramble[index];
- r=RED_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
- }
- }
- }
- else
- {
- // We should flip
- shift = 0;
- for(int x=startx; x<startx+4; x++)
- {
- for(int y=starty; y<starty+2; y++)
- {
- index = ((pixel_indices_MSB >> shift) & 1) << 1;
- index |= ((pixel_indices_LSB >> shift) & 1);
- shift++;
- index=unscramble[index];
- r=RED_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
- }
- shift+=2;
- }
- }
- // Now decode other part of block.
- avg_color[0]= GETBITSHIGH(block_part1, 4, 59);
- avg_color[1]= GETBITSHIGH(block_part1, 4, 51);
- avg_color[2]= GETBITSHIGH(block_part1, 4, 43);
- // Here, we should really multiply by 17 instead of 16. This can
- // be done by just copying the four lower bits to the upper ones
- // while keeping the lower bits.
- avg_color[0] |= (avg_color[0] <<4);
- avg_color[1] |= (avg_color[1] <<4);
- avg_color[2] |= (avg_color[2] <<4);
- table = GETBITSHIGH(block_part1, 3, 36) << 1;
- pixel_indices_MSB = GETBITS(block_part2, 16, 31);
- pixel_indices_LSB = GETBITS(block_part2, 16, 15);
- if( (flipbit) == 0 )
- {
- // We should not flip
- shift=8;
- for(int x=startx+2; x<startx+4; x++)
- {
- for(int y=starty; y<starty+4; y++)
- {
- index = ((pixel_indices_MSB >> shift) & 1) << 1;
- index |= ((pixel_indices_LSB >> shift) & 1);
- shift++;
- index=unscramble[index];
- r=RED_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
- }
- }
- }
- else
- {
- // We should flip
- shift=2;
- for(int x=startx; x<startx+4; x++)
- {
- for(int y=starty+2; y<starty+4; y++)
- {
- index = ((pixel_indices_MSB >> shift) & 1) << 1;
- index |= ((pixel_indices_LSB >> shift) & 1);
- shift++;
- index=unscramble[index];
- r=RED_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
- }
- shift += 2;
- }
- }
- }
- else
- {
- // We have diffbit = 1.
- // 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
- // ---------------------------------------------------------------------------------------------------
- // | base col1 | dcol 2 | base col1 | dcol 2 | base col 1 | dcol 2 | table | table |diff|flip|
- // | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
- // ---------------------------------------------------------------------------------------------------
- //
- //
- // c) bit layout in bits 31 through 0 (in both cases)
- //
- // 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
- // --------------------------------------------------------------------------------------------------
- // | most significant pixel index bits | least significant pixel index bits |
- // | 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 |
- // --------------------------------------------------------------------------------------------------
- // First decode left part of block.
- enc_color1[0]= GETBITSHIGH(block_part1, 5, 63);
- enc_color1[1]= GETBITSHIGH(block_part1, 5, 55);
- enc_color1[2]= GETBITSHIGH(block_part1, 5, 47);
- // Expand from 5 to 8 bits
- avg_color[0] = (enc_color1[0] <<3) | (enc_color1[0] >> 2);
- avg_color[1] = (enc_color1[1] <<3) | (enc_color1[1] >> 2);
- avg_color[2] = (enc_color1[2] <<3) | (enc_color1[2] >> 2);
- table = GETBITSHIGH(block_part1, 3, 39) << 1;
- unsigned int pixel_indices_MSB, pixel_indices_LSB;
-
- pixel_indices_MSB = GETBITS(block_part2, 16, 31);
- pixel_indices_LSB = GETBITS(block_part2, 16, 15);
- if( (flipbit) == 0 )
- {
- // We should not flip
- shift = 0;
- for(int x=startx; x<startx+2; x++)
- {
- for(int y=starty; y<starty+4; y++)
- {
- index = ((pixel_indices_MSB >> shift) & 1) << 1;
- index |= ((pixel_indices_LSB >> shift) & 1);
- shift++;
- index=unscramble[index];
- r=RED_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
- }
- }
- }
- else
- {
- // We should flip
- shift = 0;
- for(int x=startx; x<startx+4; x++)
- {
- for(int y=starty; y<starty+2; y++)
- {
- index = ((pixel_indices_MSB >> shift) & 1) << 1;
- index |= ((pixel_indices_LSB >> shift) & 1);
- shift++;
- index=unscramble[index];
- r=RED_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
- }
- shift+=2;
- }
- }
- // Now decode right part of block.
- diff[0]= GETBITSHIGH(block_part1, 3, 58);
- diff[1]= GETBITSHIGH(block_part1, 3, 50);
- diff[2]= GETBITSHIGH(block_part1, 3, 42);
- // Extend sign bit to entire byte.
- diff[0] = (diff[0] << 5);
- diff[1] = (diff[1] << 5);
- diff[2] = (diff[2] << 5);
- diff[0] = diff[0] >> 5;
- diff[1] = diff[1] >> 5;
- diff[2] = diff[2] >> 5;
- // Calculale second color
- enc_color2[0]= enc_color1[0] + diff[0];
- enc_color2[1]= enc_color1[1] + diff[1];
- enc_color2[2]= enc_color1[2] + diff[2];
- // Expand from 5 to 8 bits
- avg_color[0] = (enc_color2[0] <<3) | (enc_color2[0] >> 2);
- avg_color[1] = (enc_color2[1] <<3) | (enc_color2[1] >> 2);
- avg_color[2] = (enc_color2[2] <<3) | (enc_color2[2] >> 2);
- table = GETBITSHIGH(block_part1, 3, 36) << 1;
- pixel_indices_MSB = GETBITS(block_part2, 16, 31);
- pixel_indices_LSB = GETBITS(block_part2, 16, 15);
- if( (flipbit) == 0 )
- {
- // We should not flip
- shift=8;
- for(int x=startx+2; x<startx+4; x++)
- {
- for(int y=starty; y<starty+4; y++)
- {
- index = ((pixel_indices_MSB >> shift) & 1) << 1;
- index |= ((pixel_indices_LSB >> shift) & 1);
- shift++;
- index=unscramble[index];
- r=RED_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
- }
- }
- }
- else
- {
- // We should flip
- shift=2;
- for(int x=startx; x<startx+4; x++)
- {
- for(int y=starty+2; y<starty+4; y++)
- {
- index = ((pixel_indices_MSB >> shift) & 1) << 1;
- index |= ((pixel_indices_LSB >> shift) & 1);
- shift++;
- index=unscramble[index];
- r=RED_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
- }
- shift += 2;
- }
- }
- }
- }
- void decompressBlockDiffFlip(unsigned int block_part1, unsigned int block_part2, uint8 *img, int width, int height, int startx, int starty)
- {
- decompressBlockDiffFlipC(block_part1, block_part2, img, width, height, startx, starty, 3);
- }
- // Decompress an ETC2 RGB block
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void decompressBlockETC2c(unsigned int block_part1, unsigned int block_part2, uint8 *img, int width, int height, int startx, int starty, int channels)
- {
- int diffbit;
- signed char color1[3];
- signed char diff[3];
- signed char red, green, blue;
- diffbit = (GETBITSHIGH(block_part1, 1, 33));
- if( diffbit )
- {
- // We have diffbit = 1;
- // Base color
- color1[0]= GETBITSHIGH(block_part1, 5, 63);
- color1[1]= GETBITSHIGH(block_part1, 5, 55);
- color1[2]= GETBITSHIGH(block_part1, 5, 47);
- // Diff color
- diff[0]= GETBITSHIGH(block_part1, 3, 58);
- diff[1]= GETBITSHIGH(block_part1, 3, 50);
- diff[2]= GETBITSHIGH(block_part1, 3, 42);
- // Extend sign bit to entire byte.
- diff[0] = (diff[0] << 5);
- diff[1] = (diff[1] << 5);
- diff[2] = (diff[2] << 5);
- diff[0] = diff[0] >> 5;
- diff[1] = diff[1] >> 5;
- diff[2] = diff[2] >> 5;
- red = color1[0] + diff[0];
- green = color1[1] + diff[1];
- blue = color1[2] + diff[2];
- if(red < 0 || red > 31)
- {
- unsigned int block59_part1, block59_part2;
- unstuff59bits(block_part1, block_part2, block59_part1, block59_part2);
- decompressBlockTHUMB59Tc(block59_part1, block59_part2, img, width, height, startx, starty, channels);
- }
- else if (green < 0 || green > 31)
- {
- unsigned int block58_part1, block58_part2;
- unstuff58bits(block_part1, block_part2, block58_part1, block58_part2);
- decompressBlockTHUMB58Hc(block58_part1, block58_part2, img, width, height, startx, starty, channels);
- }
- else if(blue < 0 || blue > 31)
- {
- unsigned int block57_part1, block57_part2;
- unstuff57bits(block_part1, block_part2, block57_part1, block57_part2);
- decompressBlockPlanar57c(block57_part1, block57_part2, img, width, height, startx, starty, channels);
- }
- else
- {
- decompressBlockDiffFlipC(block_part1, block_part2, img, width, height, startx, starty, channels);
- }
- }
- else
- {
- // We have diffbit = 0;
- decompressBlockDiffFlipC(block_part1, block_part2, img, width, height, startx, starty, channels);
- }
- }
- void decompressBlockETC2(unsigned int block_part1, unsigned int block_part2, uint8 *img, int width, int height, int startx, int starty)
- {
- decompressBlockETC2c(block_part1, block_part2, img, width, height, startx, starty, 3);
- }
- // Decompress an ETC2 block with punchthrough alpha
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void decompressBlockDifferentialWithAlphaC(unsigned int block_part1, unsigned int block_part2, uint8* img, uint8* alpha, int width, int height, int startx, int starty, int channelsRGB)
- {
-
- uint8 avg_color[3], enc_color1[3], enc_color2[3];
- signed char diff[3];
- int table;
- int index,shift;
- int r,g,b;
- int diffbit;
- int flipbit;
- int channelsA;
- if(channelsRGB == 3)
- {
- // We will decode the alpha data to a separate memory area.
- channelsA = 1;
- }
- else
- {
- // We will decode the RGB data and the alpha data to the same memory area,
- // interleaved as RGBA.
- channelsA = 4;
- alpha = &img[0+3];
- }
- //the diffbit now encodes whether or not the entire alpha channel is 255.
- diffbit = (GETBITSHIGH(block_part1, 1, 33));
- flipbit = (GETBITSHIGH(block_part1, 1, 32));
- // First decode left part of block.
- enc_color1[0]= GETBITSHIGH(block_part1, 5, 63);
- enc_color1[1]= GETBITSHIGH(block_part1, 5, 55);
- enc_color1[2]= GETBITSHIGH(block_part1, 5, 47);
- // Expand from 5 to 8 bits
- avg_color[0] = (enc_color1[0] <<3) | (enc_color1[0] >> 2);
- avg_color[1] = (enc_color1[1] <<3) | (enc_color1[1] >> 2);
- avg_color[2] = (enc_color1[2] <<3) | (enc_color1[2] >> 2);
- table = GETBITSHIGH(block_part1, 3, 39) << 1;
- unsigned int pixel_indices_MSB, pixel_indices_LSB;
-
- pixel_indices_MSB = GETBITS(block_part2, 16, 31);
- pixel_indices_LSB = GETBITS(block_part2, 16, 15);
- if( (flipbit) == 0 )
- {
- // We should not flip
- shift = 0;
- for(int x=startx; x<startx+2; x++)
- {
- for(int y=starty; y<starty+4; y++)
- {
- index = ((pixel_indices_MSB >> shift) & 1) << 1;
- index |= ((pixel_indices_LSB >> shift) & 1);
- shift++;
- index=unscramble[index];
- int mod = compressParams[table][index];
- if(diffbit==0&&(index==1||index==2))
- {
- mod=0;
- }
-
- r=RED_CHANNEL(img,width,x,y,channelsRGB) =CLAMP(0,avg_color[0]+mod,255);
- g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=CLAMP(0,avg_color[1]+mod,255);
- b=BLUE_CHANNEL(img,width,x,y,channelsRGB) =CLAMP(0,avg_color[2]+mod,255);
- if(diffbit==0&&index==1)
- {
- alpha[(y*width+x)*channelsA]=0;
- r=RED_CHANNEL(img,width,x,y,channelsRGB)=0;
- g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=0;
- b=BLUE_CHANNEL(img,width,x,y,channelsRGB)=0;
- }
- else
- {
- alpha[(y*width+x)*channelsA]=255;
- }
- }
- }
- }
- else
- {
- // We should flip
- shift = 0;
- for(int x=startx; x<startx+4; x++)
- {
- for(int y=starty; y<starty+2; y++)
- {
- index = ((pixel_indices_MSB >> shift) & 1) << 1;
- index |= ((pixel_indices_LSB >> shift) & 1);
- shift++;
- index=unscramble[index];
- int mod = compressParams[table][index];
- if(diffbit==0&&(index==1||index==2))
- {
- mod=0;
- }
- r=RED_CHANNEL(img,width,x,y,channelsRGB) =CLAMP(0,avg_color[0]+mod,255);
- g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=CLAMP(0,avg_color[1]+mod,255);
- b=BLUE_CHANNEL(img,width,x,y,channelsRGB) =CLAMP(0,avg_color[2]+mod,255);
- if(diffbit==0&&index==1)
- {
- alpha[(y*width+x)*channelsA]=0;
- r=RED_CHANNEL(img,width,x,y,channelsRGB)=0;
- g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=0;
- b=BLUE_CHANNEL(img,width,x,y,channelsRGB)=0;
- }
- else
- {
- alpha[(y*width+x)*channelsA]=255;
- }
- }
- shift+=2;
- }
- }
- // Now decode right part of block.
- diff[0]= GETBITSHIGH(block_part1, 3, 58);
- diff[1]= GETBITSHIGH(block_part1, 3, 50);
- diff[2]= GETBITSHIGH(block_part1, 3, 42);
- // Extend sign bit to entire byte.
- diff[0] = (diff[0] << 5);
- diff[1] = (diff[1] << 5);
- diff[2] = (diff[2] << 5);
- diff[0] = diff[0] >> 5;
- diff[1] = diff[1] >> 5;
- diff[2] = diff[2] >> 5;
- // Calculate second color
- enc_color2[0]= enc_color1[0] + diff[0];
- enc_color2[1]= enc_color1[1] + diff[1];
- enc_color2[2]= enc_color1[2] + diff[2];
- // Expand from 5 to 8 bits
- avg_color[0] = (enc_color2[0] <<3) | (enc_color2[0] >> 2);
- avg_color[1] = (enc_color2[1] <<3) | (enc_color2[1] >> 2);
- avg_color[2] = (enc_color2[2] <<3) | (enc_color2[2] >> 2);
- table = GETBITSHIGH(block_part1, 3, 36) << 1;
- pixel_indices_MSB = GETBITS(block_part2, 16, 31);
- pixel_indices_LSB = GETBITS(block_part2, 16, 15);
- if( (flipbit) == 0 )
- {
- // We should not flip
- shift=8;
- for(int x=startx+2; x<startx+4; x++)
- {
- for(int y=starty; y<starty+4; y++)
- {
- index = ((pixel_indices_MSB >> shift) & 1) << 1;
- index |= ((pixel_indices_LSB >> shift) & 1);
- shift++;
- index=unscramble[index];
- int mod = compressParams[table][index];
- if(diffbit==0&&(index==1||index==2))
- {
- mod=0;
- }
-
- r=RED_CHANNEL(img,width,x,y,channelsRGB) =CLAMP(0,avg_color[0]+mod,255);
- g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=CLAMP(0,avg_color[1]+mod,255);
- b=BLUE_CHANNEL(img,width,x,y,channelsRGB) =CLAMP(0,avg_color[2]+mod,255);
- if(diffbit==0&&index==1)
- {
- alpha[(y*width+x)*channelsA]=0;
- r=RED_CHANNEL(img,width,x,y,channelsRGB)=0;
- g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=0;
- b=BLUE_CHANNEL(img,width,x,y,channelsRGB)=0;
- }
- else
- {
- alpha[(y*width+x)*channelsA]=255;
- }
- }
- }
- }
- else
- {
- // We should flip
- shift=2;
- for(int x=startx; x<startx+4; x++)
- {
- for(int y=starty+2; y<starty+4; y++)
- {
- index = ((pixel_indices_MSB >> shift) & 1) << 1;
- index |= ((pixel_indices_LSB >> shift) & 1);
- shift++;
- index=unscramble[index];
- int mod = compressParams[table][index];
- if(diffbit==0&&(index==1||index==2))
- {
- mod=0;
- }
-
- r=RED_CHANNEL(img,width,x,y,channelsRGB) =CLAMP(0,avg_color[0]+mod,255);
- g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=CLAMP(0,avg_color[1]+mod,255);
- b=BLUE_CHANNEL(img,width,x,y,channelsRGB) =CLAMP(0,avg_color[2]+mod,255);
- if(diffbit==0&&index==1)
- {
- alpha[(y*width+x)*channelsA]=0;
- r=RED_CHANNEL(img,width,x,y,channelsRGB)=0;
- g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=0;
- b=BLUE_CHANNEL(img,width,x,y,channelsRGB)=0;
- }
- else
- {
- alpha[(y*width+x)*channelsA]=255;
- }
- }
- shift += 2;
- }
- }
- }
- void decompressBlockDifferentialWithAlpha(unsigned int block_part1, unsigned int block_part2, uint8* img, uint8* alpha, int width, int height, int startx, int starty)
- {
- decompressBlockDifferentialWithAlphaC(block_part1, block_part2, img, alpha, width, height, startx, starty, 3);
- }
- // similar to regular decompression, but alpha channel is set to 0 if pixel index is 2, otherwise 255.
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void decompressBlockTHUMB59TAlphaC(unsigned int block_part1, unsigned int block_part2, uint8 *img, uint8* alpha, int width, int height, int startx, int starty, int channelsRGB)
- {
- uint8 colorsRGB444[2][3];
- uint8 colors[2][3];
- uint8 paint_colors[4][3];
- uint8 distance;
- uint8 block_mask[4][4];
- int channelsA;
- if(channelsRGB == 3)
- {
- // We will decode the alpha data to a separate memory area.
- channelsA = 1;
- }
- else
- {
- // We will decode the RGB data and the alpha data to the same memory area,
- // interleaved as RGBA.
- channelsA = 4;
- alpha = &img[0+3];
- }
- // First decode left part of block.
- colorsRGB444[0][R]= GETBITSHIGH(block_part1, 4, 58);
- colorsRGB444[0][G]= GETBITSHIGH(block_part1, 4, 54);
- colorsRGB444[0][B]= GETBITSHIGH(block_part1, 4, 50);
- colorsRGB444[1][R]= GETBITSHIGH(block_part1, 4, 46);
- colorsRGB444[1][G]= GETBITSHIGH(block_part1, 4, 42);
- colorsRGB444[1][B]= GETBITSHIGH(block_part1, 4, 38);
- distance = GETBITSHIGH(block_part1, TABLE_BITS_59T, 34);
- // Extend the two colors to RGB888
- decompressColor(R_BITS59T, G_BITS59T, B_BITS59T, colorsRGB444, colors);
- calculatePaintColors59T(distance, PATTERN_T, colors, paint_colors);
-
- // Choose one of the four paint colors for each texel
- for (uint8 x = 0; x < BLOCKWIDTH; ++x)
- {
- for (uint8 y = 0; y < BLOCKHEIGHT; ++y)
- {
- //block_mask[x][y] = GETBITS(block_part2,2,31-(y*4+x)*2);
- block_mask[x][y] = GETBITS(block_part2,1,(y+x*4)+16)<<1;
- block_mask[x][y] |= GETBITS(block_part2,1,(y+x*4));
- img[channelsRGB*((starty+y)*width+startx+x)+R] =
- CLAMP(0,paint_colors[block_mask[x][y]][R],255); // RED
- img[channelsRGB*((starty+y)*width+startx+x)+G] =
- CLAMP(0,paint_colors[block_mask[x][y]][G],255); // GREEN
- img[channelsRGB*((starty+y)*width+startx+x)+B] =
- CLAMP(0,paint_colors[block_mask[x][y]][B],255); // BLUE
- if(block_mask[x][y]==2)
- {
- alpha[channelsA*(x+startx+(y+starty)*width)]=0;
- img[channelsRGB*((starty+y)*width+startx+x)+R] =0;
- img[channelsRGB*((starty+y)*width+startx+x)+G] =0;
- img[channelsRGB*((starty+y)*width+startx+x)+B] =0;
- }
- else
- alpha[channelsA*(x+startx+(y+starty)*width)]=255;
- }
- }
- }
- void decompressBlockTHUMB59TAlpha(unsigned int block_part1, unsigned int block_part2, uint8 *img, uint8* alpha, int width, int height, int startx, int starty)
- {
- decompressBlockTHUMB59TAlphaC(block_part1, block_part2, img, alpha, width, height, startx, starty, 3);
- }
- // Decompress an H-mode block with alpha
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void decompressBlockTHUMB58HAlphaC(unsigned int block_part1, unsigned int block_part2, uint8 *img, uint8* alpha, int width, int height, int startx, int starty, int channelsRGB)
- {
- unsigned int col0, col1;
- uint8 colors[2][3];
- uint8 colorsRGB444[2][3];
- uint8 paint_colors[4][3];
- uint8 distance;
- uint8 block_mask[4][4];
- int channelsA;
- if(channelsRGB == 3)
- {
- // We will decode the alpha data to a separate memory area.
- channelsA = 1;
- }
- else
- {
- // We will decode the RGB data and the alpha data to the same memory area,
- // interleaved as RGBA.
- channelsA = 4;
- alpha = &img[0+3];
- }
- // First decode left part of block.
- colorsRGB444[0][R]= GETBITSHIGH(block_part1, 4, 57);
- colorsRGB444[0][G]= GETBITSHIGH(block_part1, 4, 53);
- colorsRGB444[0][B]= GETBITSHIGH(block_part1, 4, 49);
- colorsRGB444[1][R]= GETBITSHIGH(block_part1, 4, 45);
- colorsRGB444[1][G]= GETBITSHIGH(block_part1, 4, 41);
- colorsRGB444[1][B]= GETBITSHIGH(block_part1, 4, 37);
- distance = 0;
- distance = (GETBITSHIGH(block_part1, 2, 33)) << 1;
- col0 = GETBITSHIGH(block_part1, 12, 57);
- col1 = GETBITSHIGH(block_part1, 12, 45);
- if(col0 >= col1)
- {
- distance |= 1;
- }
- // Extend the two colors to RGB888
- decompressColor(R_BITS58H, G_BITS58H, B_BITS58H, colorsRGB444, colors);
-
- calculatePaintColors58H(distance, PATTERN_H, colors, paint_colors);
-
- // Choose one of the four paint colors for each texel
- for (uint8 x = 0; x < BLOCKWIDTH; ++x)
- {
- for (uint8 y = 0; y < BLOCKHEIGHT; ++y)
- {
- //block_mask[x][y] = GETBITS(block_part2,2,31-(y*4+x)*2);
- block_mask[x][y] = GETBITS(block_part2,1,(y+x*4)+16)<<1;
- block_mask[x][y] |= GETBITS(block_part2,1,(y+x*4));
- img[channelsRGB*((starty+y)*width+startx+x)+R] =
- CLAMP(0,paint_colors[block_mask[x][y]][R],255); // RED
- img[channelsRGB*((starty+y)*width+startx+x)+G] =
- CLAMP(0,paint_colors[block_mask[x][y]][G],255); // GREEN
- img[channelsRGB*((starty+y)*width+startx+x)+B] =
- CLAMP(0,paint_colors[block_mask[x][y]][B],255); // BLUE
-
- if(block_mask[x][y]==2)
- {
- alpha[channelsA*(x+startx+(y+starty)*width)]=0;
- img[channelsRGB*((starty+y)*width+startx+x)+R] =0;
- img[channelsRGB*((starty+y)*width+startx+x)+G] =0;
- img[channelsRGB*((starty+y)*width+startx+x)+B] =0;
- }
- else
- alpha[channelsA*(x+startx+(y+starty)*width)]=255;
- }
- }
- }
- void decompressBlockTHUMB58HAlpha(unsigned int block_part1, unsigned int block_part2, uint8 *img, uint8* alpha, int width, int height, int startx, int starty)
- {
- decompressBlockTHUMB58HAlphaC(block_part1, block_part2, img, alpha, width, height, startx, starty, 3);
- }
- // Decompression function for ETC2_RGBA1 format.
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void decompressBlockETC21BitAlphaC(unsigned int block_part1, unsigned int block_part2, uint8 *img, uint8* alphaimg, int width, int height, int startx, int starty, int channelsRGB)
- {
- int diffbit;
- signed char color1[3];
- signed char diff[3];
- signed char red, green, blue;
- int channelsA;
- if(channelsRGB == 3)
- {
- // We will decode the alpha data to a separate memory area.
- channelsA = 1;
- }
- else
- {
- // We will decode the RGB data and the alpha data to the same memory area,
- // interleaved as RGBA.
- channelsA = 4;
- alphaimg = &img[0+3];
- }
- diffbit = (GETBITSHIGH(block_part1, 1, 33));
- if( diffbit )
- {
- // We have diffbit = 1, meaning no transparent pixels. regular decompression.
- // Base color
- color1[0]= GETBITSHIGH(block_part1, 5, 63);
- color1[1]= GETBITSHIGH(block_part1, 5, 55);
- color1[2]= GETBITSHIGH(block_part1, 5, 47);
- // Diff color
- diff[0]= GETBITSHIGH(block_part1, 3, 58);
- diff[1]= GETBITSHIGH(block_part1, 3, 50);
- diff[2]= GETBITSHIGH(block_part1, 3, 42);
- // Extend sign bit to entire byte.
- diff[0] = (diff[0] << 5);
- diff[1] = (diff[1] << 5);
- diff[2] = (diff[2] << 5);
- diff[0] = diff[0] >> 5;
- diff[1] = diff[1] >> 5;
- diff[2] = diff[2] >> 5;
- red = color1[0] + diff[0];
- green = color1[1] + diff[1];
- blue = color1[2] + diff[2];
- if(red < 0 || red > 31)
- {
- unsigned int block59_part1, block59_part2;
- unstuff59bits(block_part1, block_part2, block59_part1, block59_part2);
- decompressBlockTHUMB59Tc(block59_part1, block59_part2, img, width, height, startx, starty, channelsRGB);
- }
- else if (green < 0 || green > 31)
- {
- unsigned int block58_part1, block58_part2;
- unstuff58bits(block_part1, block_part2, block58_part1, block58_part2);
- decompressBlockTHUMB58Hc(block58_part1, block58_part2, img, width, height, startx, starty, channelsRGB);
- }
- else if(blue < 0 || blue > 31)
- {
- unsigned int block57_part1, block57_part2;
- unstuff57bits(block_part1, block_part2, block57_part1, block57_part2);
- decompressBlockPlanar57c(block57_part1, block57_part2, img, width, height, startx, starty, channelsRGB);
- }
- else
- {
- decompressBlockDifferentialWithAlphaC(block_part1, block_part2, img, alphaimg, width, height, startx, starty, channelsRGB);
- }
- for(int x=startx; x<startx+4; x++)
- {
- for(int y=starty; y<starty+4; y++)
- {
- alphaimg[channelsA*(x+y*width)]=255;
- }
- }
- }
- else
- {
- // We have diffbit = 0, transparent pixels. Only T-, H- or regular diff-mode possible.
-
- // Base color
- color1[0]= GETBITSHIGH(block_part1, 5, 63);
- color1[1]= GETBITSHIGH(block_part1, 5, 55);
- color1[2]= GETBITSHIGH(block_part1, 5, 47);
- // Diff color
- diff[0]= GETBITSHIGH(block_part1, 3, 58);
- diff[1]= GETBITSHIGH(block_part1, 3, 50);
- diff[2]= GETBITSHIGH(block_part1, 3, 42);
- // Extend sign bit to entire byte.
- diff[0] = (diff[0] << 5);
- diff[1] = (diff[1] << 5);
- diff[2] = (diff[2] << 5);
- diff[0] = diff[0] >> 5;
- diff[1] = diff[1] >> 5;
- diff[2] = diff[2] >> 5;
- red = color1[0] + diff[0];
- green = color1[1] + diff[1];
- blue = color1[2] + diff[2];
- if(red < 0 || red > 31)
- {
- unsigned int block59_part1, block59_part2;
- unstuff59bits(block_part1, block_part2, block59_part1, block59_part2);
- decompressBlockTHUMB59TAlphaC(block59_part1, block59_part2, img, alphaimg, width, height, startx, starty, channelsRGB);
- }
- else if(green < 0 || green > 31)
- {
- unsigned int block58_part1, block58_part2;
- unstuff58bits(block_part1, block_part2, block58_part1, block58_part2);
- decompressBlockTHUMB58HAlphaC(block58_part1, block58_part2, img, alphaimg, width, height, startx, starty, channelsRGB);
- }
- else if(blue < 0 || blue > 31)
- {
- unsigned int block57_part1, block57_part2;
- unstuff57bits(block_part1, block_part2, block57_part1, block57_part2);
- decompressBlockPlanar57c(block57_part1, block57_part2, img, width, height, startx, starty, channelsRGB);
- for(int x=startx; x<startx+4; x++)
- {
- for(int y=starty; y<starty+4; y++)
- {
- alphaimg[channelsA*(x+y*width)]=255;
- }
- }
- }
- else
- decompressBlockDifferentialWithAlphaC(block_part1, block_part2, img,alphaimg, width, height, startx, starty, channelsRGB);
- }
- }
- void decompressBlockETC21BitAlpha(unsigned int block_part1, unsigned int block_part2, uint8 *img, uint8* alphaimg, int width, int height, int startx, int starty)
- {
- decompressBlockETC21BitAlphaC(block_part1, block_part2, img, alphaimg, width, height, startx, starty, 3);
- }
- //
- // Utility functions used for alpha compression
- //
- // bit number frompos is extracted from input, and moved to bit number topos in the return value.
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- uint8 getbit(uint8 input, int frompos, int topos)
- {
- uint8 output=0;
- if(frompos>topos)
- return ((1<<frompos)&input)>>(frompos-topos);
- return ((1<<frompos)&input)<<(topos-frompos);
- }
- // takes as input a value, returns the value clamped to the interval [0,255].
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- int clamp(int val)
- {
- if(val<0)
- val=0;
- if(val>255)
- val=255;
- return val;
- }
- // Decodes tha alpha component in a block coded with GL_COMPRESSED_RGBA8_ETC2_EAC.
- // Note that this decoding is slightly different from that of GL_COMPRESSED_R11_EAC.
- // However, a hardware decoder can share gates between the two formats as explained
- // in the specification under GL_COMPRESSED_R11_EAC.
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void decompressBlockAlphaC(uint8* data, uint8* img, int width, int height, int ix, int iy, int channels)
- {
- int alpha = data[0];
- int table = data[1];
-
- int bit=0;
- int byte=2;
- //extract an alpha value for each pixel.
- for(int x=0; x<4; x++)
- {
- for(int y=0; y<4; y++)
- {
- //Extract table index
- int index=0;
- for(int bitpos=0; bitpos<3; bitpos++)
- {
- index|=getbit(data[byte],7-bit,2-bitpos);
- bit++;
- if(bit>7)
- {
- bit=0;
- byte++;
- }
- }
- img[(ix+x+(iy+y)*width)*channels]=clamp(alpha +alphaTable[table][index]);
- }
- }
- }
- void decompressBlockAlpha(uint8* data, uint8* img, int width, int height, int ix, int iy)
- {
- decompressBlockAlphaC(data, img, width, height, ix, iy, 1);
- }
- // Does decompression and then immediately converts from 11 bit signed to a 16-bit format.
- //
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- int16 get16bits11signed(int base, int table, int mul, int index)
- {
- int elevenbase = base-128;
- if(elevenbase==-128)
- elevenbase=-127;
- elevenbase*=8;
- //i want the positive value here
- int tabVal = -alphaBase[table][3-index%4]-1;
- //and the sign, please
- int sign = 1-(index/4);
-
- if(sign)
- tabVal=tabVal+1;
- int elevenTabVal = tabVal*8;
- if(mul!=0)
- elevenTabVal*=mul;
- else
- elevenTabVal/=8;
- if(sign)
- elevenTabVal=-elevenTabVal;
- //calculate sum
- int elevenbits = elevenbase+elevenTabVal;
- //clamp..
- if(elevenbits>=1024)
- elevenbits=1023;
- else if(elevenbits<-1023)
- elevenbits=-1023;
- //this is the value we would actually output..
- //but there aren't any good 11-bit file or uncompressed GL formats
- //so we extend to 15 bits signed.
- sign = elevenbits<0;
- elevenbits=abs(elevenbits);
- int16 fifteenbits = (elevenbits<<5)+(elevenbits>>5);
- int16 sixteenbits=fifteenbits;
- if(sign)
- sixteenbits=-sixteenbits;
-
- return sixteenbits;
- }
- // Does decompression and then immediately converts from 11 bit signed to a 16-bit format
- // Calculates the 11 bit value represented by base, table, mul and index, and extends it to 16 bits.
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- uint16 get16bits11bits(int base, int table, int mul, int index)
- {
- int elevenbase = base*8+4;
- //i want the positive value here
- int tabVal = -alphaBase[table][3-index%4]-1;
- //and the sign, please
- int sign = 1-(index/4);
-
- if(sign)
- tabVal=tabVal+1;
- int elevenTabVal = tabVal*8;
- if(mul!=0)
- elevenTabVal*=mul;
- else
- elevenTabVal/=8;
- if(sign)
- elevenTabVal=-elevenTabVal;
- //calculate sum
- int elevenbits = elevenbase+elevenTabVal;
- //clamp..
- if(elevenbits>=256*8)
- elevenbits=256*8-1;
- else if(elevenbits<0)
- elevenbits=0;
- //elevenbits now contains the 11 bit alpha value as defined in the spec.
- //extend to 16 bits before returning, since we don't have any good 11-bit file formats.
- uint16 sixteenbits = (elevenbits<<5)+(elevenbits>>6);
- return sixteenbits;
- }
- // Decompresses a block using one of the GL_COMPRESSED_R11_EAC or GL_COMPRESSED_SIGNED_R11_EAC-formats
- // NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2005-2013. All Rights Reserved.
- void decompressBlockAlpha16bitC(uint8* data, uint8* img, int width, int height, int ix, int iy, int channels)
- {
- int alpha = data[0];
- int table = data[1];
- if(formatSigned)
- {
- //if we have a signed format, the base value is given as a signed byte. We convert it to (0-255) here,
- //so more code can be shared with the unsigned mode.
- alpha = *((signed char*)(&data[0]));
- alpha = alpha+128;
- }
- int bit=0;
- int byte=2;
- //extract an alpha value for each pixel.
- for(int x=0; x<4; x++)
- {
- for(int y=0; y<4; y++)
- {
- //Extract table index
- int index=0;
- for(int bitpos=0; bitpos<3; bitpos++)
- {
- index|=getbit(data[byte],7-bit,2-bitpos);
- bit++;
- if(bit>7)
- {
- bit=0;
- byte++;
- }
- }
- int windex = channels*(2*(ix+x+(iy+y)*width));
- #if !PGMOUT
- if(formatSigned)
- {
- *(int16 *)&img[windex] = get16bits11signed(alpha,(table%16),(table/16),index);
- }
- else
- {
- *(uint16 *)&img[windex] = get16bits11bits(alpha,(table%16),(table/16),index);
- }
- #else
- //make data compatible with the .pgm format. See the comment in compressBlockAlpha16() for details.
- uint16 uSixteen;
- if (formatSigned)
- {
- //the pgm-format only allows unsigned images,
- //so we add 2^15 to get a 16-bit value.
- uSixteen = get16bits11signed(alpha,(table%16),(table/16),index) + 256*128;
- }
- else
- {
- uSixteen = get16bits11bits(alpha,(table%16),(table/16),index);
- }
- //byte swap for pgm
- img[windex] = uSixteen/256;
- img[windex+1] = uSixteen%256;
- #endif
- }
- }
- }
- void decompressBlockAlpha16bit(uint8* data, uint8* img, int width, int height, int ix, int iy)
- {
- decompressBlockAlpha16bitC(data, img, width, height, ix, iy, 1);
- }
|