|
|
@@ -1,1876 +0,0 @@
|
|
|
-//
|
|
|
-// Copyright (c) 2008-2019 the Urho3D project.
|
|
|
-//
|
|
|
-// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
-// of this software and associated documentation files (the "Software"), to deal
|
|
|
-// in the Software without restriction, including without limitation the rights
|
|
|
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
-// copies of the Software, and to permit persons to whom the Software is
|
|
|
-// furnished to do so, subject to the following conditions:
|
|
|
-//
|
|
|
-// The above copyright notice and this permission notice shall be included in
|
|
|
-// all copies or substantial portions of the Software.
|
|
|
-//
|
|
|
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
-// THE SOFTWARE.
|
|
|
-//
|
|
|
-
|
|
|
-/*
|
|
|
-
|
|
|
-@~English
|
|
|
-@page license License
|
|
|
-
|
|
|
-@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 2013. All Rights Reserved.
|
|
|
-////
|
|
|
-
|
|
|
-#include <stdio.h>
|
|
|
-#include <stdlib.h>
|
|
|
-
|
|
|
-#include "DecompressETC2.h"
|
|
|
-
|
|
|
-namespace Urho3D
|
|
|
-{
|
|
|
-
|
|
|
-// 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 0
|
|
|
-#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 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 2013. All Rights Reserved.
|
|
|
-void read_big_endian_2byte_word(unsigned short *blockadr, FILE *f)
|
|
|
-{
|
|
|
- uint8 bytes[2];
|
|
|
- unsigned short block;
|
|
|
- // This is to silence -Wunused-result from GCC 4.8+.
|
|
|
- size_t numitems;
|
|
|
-
|
|
|
- numitems = fread(&bytes[0], 1, 1, f);
|
|
|
- numitems = 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 2013. All Rights Reserved.
|
|
|
-void read_big_endian_4byte_word(unsigned int *blockadr, FILE *f)
|
|
|
-{
|
|
|
- uint8 bytes[4];
|
|
|
- unsigned int block;
|
|
|
- // This is to silence -Wunused-result from GCC 4.8+.
|
|
|
- size_t numitems;
|
|
|
-
|
|
|
- numitems = fread(&bytes[0], 1, 1, f);
|
|
|
- numitems = fread(&bytes[1], 1, 1, f);
|
|
|
- numitems = fread(&bytes[2], 1, 1, f);
|
|
|
- numitems = 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 2013. All Rights Reserved.
|
|
|
-uint8 getbit(uint8 input, int frompos, int topos)
|
|
|
-{
|
|
|
- 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 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 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 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 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 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);
|
|
|
-}
|
|
|
-
|
|
|
-}
|