mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-01-26 15:54:51 +00:00
Switch out etcpack with the ZLIB licensed rg_etc1 library
This commit is contained in:
parent
8050390ac5
commit
75e9af1379
@ -16,6 +16,7 @@ LOCAL_SRC_FILES :=\
|
||||
base/colorutil.cpp \
|
||||
base/error_context.cpp \
|
||||
base/stringutil.cpp \
|
||||
ext/rg_etc1/rg_etc1.cpp \
|
||||
ext/cityhash/city.cpp \
|
||||
ext/sha1/sha1.cpp \
|
||||
ext/stb_image/stb_image.c \
|
||||
@ -51,6 +52,7 @@ LOCAL_SRC_FILES :=\
|
||||
gfx/texture_atlas.cpp \
|
||||
gfx/texture_gen.cpp \
|
||||
image/zim_load.cpp \
|
||||
image/zim_save.cpp \
|
||||
image/png_load.cpp \
|
||||
ui/ui.cpp \
|
||||
ui/ui_context.cpp \
|
||||
|
@ -9,7 +9,7 @@ Features
|
||||
* JSON read/write (two libraries that should be made more similar)
|
||||
* basic OpenGL utility code, like compressed texture loading
|
||||
* 2D texture atlases and drawing code
|
||||
* ETC1 texture loading support
|
||||
* ETC1 texture save/load support
|
||||
* basic logging
|
||||
* Really simple audio mixer with OGG sample support
|
||||
* RIFF file read/write
|
||||
@ -29,7 +29,7 @@ Licenses
|
||||
This library, for my convenience, incorporates code from a variety of public domain or similarly-licensed code. This is the list:
|
||||
|
||||
* glew (GL extension wrangler), MIT license. TODO: should just use a submodule.
|
||||
* etcpack by Ericsson, in a cleaned up form. Has strange license but not very limiting - you can only use the code for making textures for hardware supporting ETC1, or something like that. Don't think it affects the rest of the code in any way.
|
||||
* rg_etc1. ZLIB license.
|
||||
* sha1, public domain implementation by Dominik Reichl
|
||||
* vjson in a heavily modified form, originally by Ivan Vashchaev (TODO: break out into its own repo?)
|
||||
* libzip with attribution "Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner"
|
||||
|
@ -1,7 +0,0 @@
|
||||
This folder contains code adapted from etcpack by ERICSSON ///.
|
||||
|
||||
The license comments have been left at the top of each file, but some code may have moved around.
|
||||
|
||||
See LICENSE.TXT for details. It says that use of the code is limited to applications using the
|
||||
code to compress textures for use with a Khronos-derived API. This game engine only supports
|
||||
OpenGL ES 2.0, which certainly qualifies, so there is no issue there.
|
@ -1,418 +0,0 @@
|
||||
/**
|
||||
|
||||
@~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 LICENSE AGREEMENT (THE "LICENSE AGREEMENT"). IF YOU DO NOT
|
||||
ACCEPT SUCH TERMS AND CONDITIONS YOU MAY NOT USE THE SOFTWARE.
|
||||
|
||||
Under the terms and conditions of the License Agreement, 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, which products are used for (i) compression and/or
|
||||
decompression to create content creation tools for usage with a
|
||||
Khronos API, and/or (ii) compression and/or decompression for the
|
||||
purpose of usage with a middleware API that is built on top of a
|
||||
Khronos API, such as JCPs based on a Khronos API (in particular
|
||||
"Mobile 3D Graphics API for J2ME" and its future versions and "Java
|
||||
Bindings for OpenGL ES" and its future versions), and/or (iii)
|
||||
compression and/or decompression to implement a Khronos specification.
|
||||
|
||||
If Licensee institutes patent litigation against Ericsson or any
|
||||
licensee of the Software for using the Software for making,
|
||||
developing, manufacturing, selling, using and/or distributing products
|
||||
within the scope of the Khronos framework, Ericsson shall have the
|
||||
right to terminate this License Agreement with immediate
|
||||
effect. However, should Licensee institute patent litigation against
|
||||
any other licensee of the Software based on such licensee´s use of any
|
||||
other software distributed together with the Software then Ericsson
|
||||
shall have no right to terminate this License Agreement.
|
||||
|
||||
The License Agreement does not transfer to Licensee any ownership to
|
||||
any Ericsson or third party intellectual property rights.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS". ERICSSON MAKES NO REPRESENTATIONS OF
|
||||
ANY KIND, EXTENDS NO WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||
IMPLIED; INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY 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, DISTRIBUTION, LEASE, USE
|
||||
OR IMPORTATION UNDER THE LICENSE AGREEMENT WILL BE FREE FROM
|
||||
INFRINGEMENT OF PATENTS, COPYRIGHTS OR OTHER INTELLECTUAL PROPERTY
|
||||
RIGHTS OF OTHERS, AND THE VALIDITY OF THE LICENSE AND THE LICENSE
|
||||
AGREEMENT IS SUBJECT TO LICENSEE'S SOLE RESPONSIBILITY TO MAKE SUCH
|
||||
DETERMINATION AND ACQUIRE SUCH LICENSES AS MAY BE NECESSARY WITH
|
||||
RESPECT TO PATENTS AND OTHER INTELLECTUAL PROPERTY OF THIRD PARTIES.
|
||||
|
||||
IN NO EVENT WILL ERICSSON BE LIABLE TO THE LICENSEE FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
|
||||
ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT
|
||||
NOT LIMITED TO 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), EVEN IF SUCH HOLDER OR
|
||||
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 "///".
|
||||
|
||||
The parties agree that this License Agreement based on these terms and
|
||||
conditions is governed by the laws of Sweden, and in the event of any
|
||||
dispute as a result of this License Agreement, the parties submit
|
||||
themselves to the exclusive jurisdiction of the Swedish Courts.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CLAMP(ll,x,ul) (((x)<(ll)) ? (ll) : (((x)>(ul)) ? (ul) : (x)))
|
||||
#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))
|
||||
#define RED(img,width,x,y) img[3*(y*width+x)+0]
|
||||
#define GREEN(img,width,x,y) img[3*(y*width+x)+1]
|
||||
#define BLUE(img,width,x,y) img[3*(y*width+x)+2]
|
||||
|
||||
typedef unsigned char uint8;
|
||||
|
||||
int unscramble[4] = {2, 3, 1, 0};
|
||||
|
||||
static const 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}};
|
||||
|
||||
void decompressBlockDiffFlip(unsigned int block_part1, unsigned int block_part2, uint8 *img,int width,int height,int startx,int starty)
|
||||
{
|
||||
uint8 avg_color[3], enc_color1[3], enc_color2[3];
|
||||
char diff[3];
|
||||
int table;
|
||||
int index,shift;
|
||||
int r,g,b;
|
||||
int diffbit;
|
||||
int flipbit;
|
||||
unsigned int pixel_indices_MSB, pixel_indices_LSB;
|
||||
int x,y;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
|
||||
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(x=startx; x<startx+2; x++)
|
||||
{
|
||||
for(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(img,width,x,y) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
|
||||
g=GREEN(img,width,x,y)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
|
||||
b=BLUE(img,width,x,y) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We should flip
|
||||
shift = 0;
|
||||
for(x=startx; x<startx+4; x++)
|
||||
{
|
||||
for(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(img,width,x,y) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
|
||||
g=GREEN(img,width,x,y)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
|
||||
b=BLUE(img,width,x,y) =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(x=startx+2; x<startx+4; x++)
|
||||
{
|
||||
for(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(img,width,x,y) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
|
||||
g=GREEN(img,width,x,y)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
|
||||
b=BLUE(img,width,x,y) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We should flip
|
||||
shift=2;
|
||||
for(x=startx; x<startx+4; x++)
|
||||
{
|
||||
for(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(img,width,x,y) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
|
||||
g=GREEN(img,width,x,y)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
|
||||
b=BLUE(img,width,x,y) =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;
|
||||
|
||||
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(x=startx; x<startx+2; x++)
|
||||
{
|
||||
for(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(img,width,x,y) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
|
||||
g=GREEN(img,width,x,y)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
|
||||
b=BLUE(img,width,x,y) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We should flip
|
||||
shift = 0;
|
||||
for(x=startx; x<startx+4; x++)
|
||||
{
|
||||
for(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(img,width,x,y) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
|
||||
g=GREEN(img,width,x,y)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
|
||||
b=BLUE(img,width,x,y) =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);
|
||||
|
||||
enc_color2[0]= enc_color1[0] + diff[0];
|
||||
enc_color2[1]= enc_color1[1] + diff[1];
|
||||
enc_color2[2]= enc_color1[2] + diff[2];
|
||||
|
||||
// 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(x=startx+2; x<startx+4; x++)
|
||||
{
|
||||
for(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(img,width,x,y) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
|
||||
g=GREEN(img,width,x,y)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
|
||||
b=BLUE(img,width,x,y) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We should flip
|
||||
shift=2;
|
||||
for(x=startx; x<startx+4; x++)
|
||||
{
|
||||
for(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(img,width,x,y) =CLAMP(0,avg_color[0]+compressParams[table][index],255);
|
||||
g=GREEN(img,width,x,y)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
|
||||
b=BLUE(img,width,x,y) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
|
||||
}
|
||||
shift += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int bswap(unsigned int x) {
|
||||
return ((x & 0xFF000000) >> 24) |
|
||||
((x & 0x00FF0000) >> 8) |
|
||||
((x & 0x0000FF00) << 8) |
|
||||
((x & 0x000000FF) << 24);
|
||||
}
|
||||
|
||||
void DecompressBlock(const uint8 *compressed, uint8 *out, int out_width, int alpha=255) {
|
||||
uint8 rgb[4*4*3];
|
||||
unsigned int block_part1, block_part2;
|
||||
memcpy(&block_part1, compressed, 4);
|
||||
memcpy(&block_part2, compressed + 4, 4);
|
||||
block_part1 = bswap(block_part1);
|
||||
block_part2 = bswap(block_part2);
|
||||
decompressBlockDiffFlip(block_part1, block_part2, rgb, 4, 4, 0, 0);
|
||||
for (int y = 0; y < 4; y++) {
|
||||
for (int x = 0; x < 4; x++) {
|
||||
out[(y * out_width + x) * 4 + 0] = rgb[(4 * y + x) * 3 + 0];
|
||||
out[(y * out_width + x) * 4 + 1] = rgb[(4 * y + x) * 3 + 1];
|
||||
out[(y * out_width + x) * 4 + 2] = rgb[(4 * y + x) * 3 + 2];
|
||||
out[(y * out_width + x) * 4 + 3] = alpha;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
typedef unsigned char uint8;
|
||||
|
||||
/* In etcdec.cxx */
|
||||
void decompressBlockDiffFlip(unsigned int block_part1, unsigned int block_part2, uint8 *img,int width,int height,int startx,int starty);
|
||||
|
||||
// Writes RGBA output instead of RGB.
|
||||
void DecompressBlock(const uint8 *compressed, uint8 *out, int out_width, int alpha=255);
|
File diff suppressed because it is too large
Load Diff
@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define PERCEPTUAL_WEIGHT_R_SQUARED 0.299
|
||||
#define PERCEPTUAL_WEIGHT_G_SQUARED 0.587
|
||||
#define PERCEPTUAL_WEIGHT_B_SQUARED 0.114
|
||||
|
||||
typedef unsigned char uint8;
|
||||
|
||||
// These functions take RGB888.
|
||||
void compressBlockDiffFlipSlow(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2);
|
||||
|
||||
void compressBlockDiffFlipMedium(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2);
|
||||
|
||||
void compressBlockDiffFlipFast(uint8 *img, uint8 *imgdec,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2);
|
||||
|
||||
void compressBlockDiffFlipSlowPerceptual(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2);
|
||||
|
||||
void compressBlockDiffFlipMediumPerceptual(uint8 *img,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2);
|
||||
|
||||
void compressBlockDiffFlipFastPerceptual(uint8 *img, uint8 *imgdec,int width,int height,int startx,int starty, unsigned int &compressed1, unsigned int &compressed2);
|
||||
|
||||
|
||||
// This one takes RGBA8888 and converts to RGB first.
|
||||
// Writes 64 bits of compressed data to output[0..7].
|
||||
// Quality is 0 to 5. The odd numbers use perceptual metrics.
|
||||
void CompressBlock(const uint8 *in, int in_width, uint8 *output, int quality);
|
File diff suppressed because it is too large
Load Diff
@ -1,212 +0,0 @@
|
||||
// image.cxx
|
||||
//
|
||||
// NO WARRANTY
|
||||
//
|
||||
// BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, ERICSSON MAKES NO
|
||||
// REPRESENTATIONS OF ANY KIND, EXTENDS NO WARRANTIES OF ANY KIND; EITHER
|
||||
// EXPRESS OR IMPLIED; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY 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, LEASE, USE OR
|
||||
// IMPORTATION WILL BE FREE FROM INFRINGEMENT OF PATENTS, COPYRIGHTS OR
|
||||
// OTHER INTELLECTUAL PROPERTY RIGHTS OF OTHERS, AND IT SHALL BE THE SOLE
|
||||
// RESPONSIBILITY OF THE LICENSEE TO MAKE SUCH DETERMINATION AS IS
|
||||
// NECESSARY WITH RESPECT TO THE ACQUISITION OF LICENSES UNDER PATENTS
|
||||
// AND OTHER INTELLECTUAL PROPERTY OF THIRD PARTIES;
|
||||
//
|
||||
// IN NO EVENT WILL ERICSSON, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
// GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF
|
||||
// THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO
|
||||
// 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), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
//
|
||||
// (C) Ericsson AB 2005. All Rights Reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "image.h"
|
||||
|
||||
// Removes comments in a .ppm file
|
||||
// (i.e., lines starting with #)
|
||||
//
|
||||
// Written by Jacob Strom
|
||||
//
|
||||
void removeComments(FILE *f1)
|
||||
{
|
||||
int c;
|
||||
|
||||
while((c = getc(f1)) == '#')
|
||||
{
|
||||
char line[1024];
|
||||
fgets(line, 1024, f1);
|
||||
}
|
||||
ungetc(c, f1);
|
||||
}
|
||||
|
||||
|
||||
// Removes white spaces in a .ppm file
|
||||
//
|
||||
// Written by Jacob Strom
|
||||
//
|
||||
void removeSpaces(FILE *f1)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = getc(f1);
|
||||
while(c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r')
|
||||
{
|
||||
c = getc(f1);
|
||||
}
|
||||
ungetc(c, f1);
|
||||
}
|
||||
|
||||
// fReadPPM
|
||||
//
|
||||
// Written by Jacob Strom
|
||||
//
|
||||
// reads a ppm file with P6 header (meaning binary, as opposed to P5, which is ascII)
|
||||
// and returns the image in pixels.
|
||||
//
|
||||
// The header must look like this:
|
||||
//
|
||||
// P6
|
||||
// # Comments (not necessary)
|
||||
// width height
|
||||
// 255
|
||||
//
|
||||
// after that follows RGBRGBRGB...
|
||||
//
|
||||
bool fReadPPM(const char *filename, int &width, int &height, unsigned char *&pixels, bool reverse_y)
|
||||
{
|
||||
FILE *f1;
|
||||
int mustbe255;
|
||||
f1 = fopen(filename, "rb");
|
||||
|
||||
if(f1)
|
||||
{
|
||||
char line[255];
|
||||
|
||||
removeSpaces(f1);
|
||||
removeComments(f1);
|
||||
removeSpaces(f1);
|
||||
|
||||
fscanf(f1, "%s", line);
|
||||
|
||||
if(strcmp(line, "P6")!=0)
|
||||
{
|
||||
printf("Error: %s is not binary\n", filename);
|
||||
printf("(Binary .ppm files start with P6).\n");
|
||||
fclose(f1);
|
||||
return false;
|
||||
}
|
||||
removeSpaces(f1);
|
||||
removeComments(f1);
|
||||
removeSpaces(f1);
|
||||
|
||||
fscanf(f1, "%d %d", &width, &height);
|
||||
if( width<=0 || height <=0)
|
||||
{
|
||||
printf("Error: width or height negative. File: %s\n",filename);
|
||||
fclose(f1);
|
||||
return false;
|
||||
}
|
||||
|
||||
removeSpaces(f1);
|
||||
removeComments(f1);
|
||||
removeSpaces(f1);
|
||||
|
||||
fscanf(f1, "%d", &mustbe255);
|
||||
if( mustbe255!= 255 )
|
||||
{
|
||||
printf("Error: Color resolution must be 255. File: %s\n",filename);
|
||||
fclose(f1);
|
||||
return false;
|
||||
}
|
||||
|
||||
// We need to remove the newline.
|
||||
char c = 0;
|
||||
while(c != '\n')
|
||||
fscanf(f1, "%c", &c);
|
||||
|
||||
|
||||
pixels = (unsigned char*) malloc(3*width*height);
|
||||
|
||||
if(!pixels)
|
||||
{
|
||||
printf("Error: Could not allocate memory for image. File: %s\n", filename);
|
||||
fclose(f1);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(reverse_y)
|
||||
{
|
||||
for(int yy = 0; yy<height; yy++)
|
||||
{
|
||||
if(fread(&pixels[(height-yy-1)*width*3], 3*width, 1, f1) != 1)
|
||||
{
|
||||
printf("Error: Could not read all pixels. File: %s\n", filename);
|
||||
free(pixels);
|
||||
fclose(f1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fread(pixels, 3*width*height, 1, f1) != 1)
|
||||
{
|
||||
printf("Error: Could not read all pixels. File: %s\n", filename);
|
||||
free(pixels);
|
||||
fclose(f1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If we have reached this point, we have successfully loaded the image.
|
||||
|
||||
fclose(f1);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error: Coult not open file %s\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Write PPM --- Written by Jacob Strom
|
||||
bool fWritePPM(const char *filename, int width, int height, unsigned char *pixels, bool reverse_y)
|
||||
{
|
||||
FILE *fsave;
|
||||
fsave = fopen(filename, "wb");
|
||||
|
||||
|
||||
if(fsave)
|
||||
{
|
||||
int q;
|
||||
fprintf(fsave, "P6\n%d %d\n255\n", width, height);
|
||||
for(q = 0; q< height; q++)
|
||||
{
|
||||
unsigned char *adr;
|
||||
if(reverse_y)
|
||||
adr = pixels+3*width*(height-1-q);
|
||||
else
|
||||
adr = pixels+3*width*q;
|
||||
fwrite(adr, 3*width, 1, fsave);
|
||||
}
|
||||
fclose(fsave);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error: Could not open the file %s.\n",filename);
|
||||
return(false);
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
// NO WARRANTY
|
||||
//
|
||||
// BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, ERICSSON MAKES NO
|
||||
// REPRESENTATIONS OF ANY KIND, EXTENDS NO WARRANTIES OF ANY KIND; EITHER
|
||||
// EXPRESS OR IMPLIED; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY 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, LEASE, USE OR
|
||||
// IMPORTATION WILL BE FREE FROM INFRINGEMENT OF PATENTS, COPYRIGHTS OR
|
||||
// OTHER INTELLECTUAL PROPERTY RIGHTS OF OTHERS, AND IT SHALL BE THE SOLE
|
||||
// RESPONSIBILITY OF THE LICENSEE TO MAKE SUCH DETERMINATION AS IS
|
||||
// NECESSARY WITH RESPECT TO THE ACQUISITION OF LICENSES UNDER PATENTS
|
||||
// AND OTHER INTELLECTUAL PROPERTY OF THIRD PARTIES;
|
||||
//
|
||||
// IN NO EVENT WILL ERICSSON, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
// GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF
|
||||
// THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO
|
||||
// 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), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
//
|
||||
// (C) Ericsson AB 2005. All Rights Reserved.
|
||||
//
|
||||
#ifndef IMAGE_H
|
||||
#define IMAGE_H
|
||||
|
||||
bool fReadPPM(const char *filename, int &width, int &height, unsigned char *&pixels,bool reverse_y);
|
||||
bool fWritePPM(const char *filename, int width, int height, unsigned char *pixels,bool reverse_y);
|
||||
|
||||
#endif
|
@ -1,69 +0,0 @@
|
||||
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 LICENSE AGREEMENT (THE "LICENSE AGREEMENT"). IF YOU DO NOT
|
||||
ACCEPT SUCH TERMS AND CONDITIONS YOU MAY NOT USE THE SOFTWARE.
|
||||
|
||||
Under the terms and conditions of the License Agreement, 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, which products are used for (i) compression and/or
|
||||
decompression to create content creation tools for usage with a
|
||||
Khronos API, and/or (ii) compression and/or decompression for the
|
||||
purpose of usage with a middleware API that is built on top of a
|
||||
Khronos API, such as JCPs based on a Khronos API (in particular
|
||||
"Mobile 3D Graphics API for J2ME" and its future versions and "Java
|
||||
Bindings for OpenGL ES" and its future versions), and/or (iii)
|
||||
compression and/or decompression to implement a Khronos API.
|
||||
|
||||
If Licensee institutes patent litigation against Ericsson or any
|
||||
licensee of the Software for using the Software for making,
|
||||
developing, manufacturing, selling, using and/or distributing products
|
||||
within the scope of the Khronos framework, Ericsson shall have the
|
||||
right to terminate this License Agreement with immediate
|
||||
effect. However, should Licensee institute patent litigation against
|
||||
any other licensee of the Software based on such licensee´s use of any
|
||||
other software distributed together with the Software then Ericsson
|
||||
shall have no right to terminate this License Agreement.
|
||||
|
||||
The License Agreement does not transfer to Licensee any ownership to
|
||||
any Ericsson or third party intellectual property rights.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS". ERICSSON MAKES NO REPRESENTATIONS OF
|
||||
ANY KIND, EXTENDS NO WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
||||
IMPLIED; INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY 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, DISTRIBUTION, LEASE, USE
|
||||
OR IMPORTATION UNDER THE LICENSE AGREEMENT WILL BE FREE FROM
|
||||
INFRINGEMENT OF PATENTS, COPYRIGHTS OR OTHER INTELLECTUAL PROPERTY
|
||||
RIGHTS OF OTHERS, AND THE VALIDITY OF THE LICENSE AND THE LICENSE
|
||||
AGREEMENT IS SUBJECT TO LICENSEE'S SOLE RESPONSIBILITY TO MAKE SUCH
|
||||
DETERMINATION AND ACQUIRE SUCH LICENSES AS MAY BE NECESSARY WITH
|
||||
RESPECT TO PATENTS AND OTHER INTELLECTUAL PROPERTY OF THIRD PARTIES.
|
||||
|
||||
IN NO EVENT WILL ERICSSON BE LIABLE TO THE LICENSEE FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
|
||||
ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT
|
||||
NOT LIMITED TO 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), EVEN IF SUCH HOLDER OR
|
||||
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 "///".
|
||||
|
||||
The parties agree that this License Agreement based on these terms and
|
||||
conditions is governed by the laws of Sweden, and in the event of any
|
||||
dispute as a result of this License Agreement, the parties submit
|
||||
themselves to the exclusive jurisdiction of the Swedish Courts.
|
@ -1,49 +0,0 @@
|
||||
ETCPACK v1.06
|
||||
--------------------------------------------------------------------------
|
||||
Changes in v1.06 against v1.05:
|
||||
|
||||
1. Updated this file so it has the correct version number.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
Changes in v1.05 against v1.04:
|
||||
|
||||
1. Updated license agreement to include item (iii) inside
|
||||
files. Removed old license text.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
Changes in v1.04 against v1.03:
|
||||
|
||||
1. Updated license agreement to include item (iii).
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
Changes in v1.03 against v1.02:
|
||||
|
||||
1. Partinioned code in unpacking (etcdec.cxx) and the rest.
|
||||
2. Also made changes so that PSNR values are calculated using double
|
||||
internally.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
Changes in v1.02 against v1.01:
|
||||
|
||||
Added possibility to flip images vertically. Default is to have the first
|
||||
pixel (first three bytes in the .ppm file) ending up in s=0, t=0.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
Changes in v1.01 against v1.00:
|
||||
|
||||
Four bugs fixed:
|
||||
|
||||
1. In method uncompressFile, after memory is allocated the newimg
|
||||
pointer, the code checked whether the img pointer, not the newimg
|
||||
pointer is NULL. This has been fixed.
|
||||
|
||||
2. In method compressFile the array srcimg is never
|
||||
deleted/freed. This has been fixed.
|
||||
|
||||
3. When compressing smaller images than 4*4 (Mipmaps) with
|
||||
fast/nonperceptual the application sometimes crashes. This has been
|
||||
fixed.
|
||||
|
||||
4. Memory leak --- missing free(imgdec) in the end of
|
||||
compressImageFile() inserted, and thus the bug has been fixed.
|
||||
--------------------------------------------------------------------------
|
2442
ext/rg_etc1/rg_etc1.cpp
Normal file
2442
ext/rg_etc1/rg_etc1.cpp
Normal file
File diff suppressed because it is too large
Load Diff
76
ext/rg_etc1/rg_etc1.h
Normal file
76
ext/rg_etc1/rg_etc1.h
Normal file
@ -0,0 +1,76 @@
|
||||
// File: rg_etc1.h - Fast, high quality ETC1 block packer/unpacker - Rich Geldreich <richgel99@gmail.com>
|
||||
// Please see ZLIB license at the end of this file.
|
||||
#pragma once
|
||||
|
||||
namespace rg_etc1
|
||||
{
|
||||
// Unpacks an 8-byte ETC1 compressed block to a block of 4x4 32bpp RGBA pixels.
|
||||
// Returns false if the block is invalid. Invalid blocks will still be unpacked with clamping.
|
||||
// This function is thread safe, and does not dynamically allocate any memory.
|
||||
// If preserve_alpha is true, the alpha channel of the destination pixels will not be overwritten. Otherwise, alpha will be set to 255.
|
||||
bool unpack_etc1_block(const void *pETC1_block, unsigned int* pDst_pixels_rgba, int stride, bool preserve_alpha = false);
|
||||
|
||||
// Quality setting = the higher the quality, the slower.
|
||||
// To pack large textures, it is highly recommended to call pack_etc1_block() in parallel, on different blocks, from multiple threads (particularly when using cHighQuality).
|
||||
enum etc1_quality
|
||||
{
|
||||
cLowQuality,
|
||||
cMediumQuality,
|
||||
cHighQuality,
|
||||
};
|
||||
|
||||
struct etc1_pack_params
|
||||
{
|
||||
etc1_quality m_quality;
|
||||
bool m_dithering;
|
||||
|
||||
inline etc1_pack_params()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_quality = cHighQuality;
|
||||
m_dithering = false;
|
||||
}
|
||||
};
|
||||
|
||||
// Important: pack_etc1_block_init() must be called before calling pack_etc1_block().
|
||||
void pack_etc1_block_init();
|
||||
|
||||
// Packs a 4x4 block of 32bpp RGBA pixels to an 8-byte ETC1 block.
|
||||
// 32-bit RGBA pixels must always be arranged as (R,G,B,A) (R first, A last) in memory, independent of platform endianness. A should always be 255.
|
||||
// Returns squared error of result.
|
||||
// This function is thread safe, and does not dynamically allocate any memory.
|
||||
// pack_etc1_block() does not currently support "perceptual" colorspace metrics - it primarily optimizes for RGB RMSE.
|
||||
unsigned int pack_etc1_block(void* pETC1_block, const unsigned int* pSrc_pixels_rgba, etc1_pack_params& pack_params);
|
||||
|
||||
} // namespace rg_etc1
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// rg_etc1 uses the ZLIB license:
|
||||
// http://opensource.org/licenses/Zlib
|
||||
//
|
||||
// Copyright (c) 2012 Rich Geldreich
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
@ -4,7 +4,7 @@
|
||||
|
||||
#if !defined(USING_GLES2)
|
||||
#include "image/png_load.h"
|
||||
#include "ext/etcpack/etcdec.h"
|
||||
#include "ext/rg_etc1/rg_etc1.h"
|
||||
#endif
|
||||
|
||||
#include "image/zim_load.h"
|
||||
@ -183,8 +183,8 @@ uint8_t *ETC1ToRGBA(uint8_t *etc1, int width, int height) {
|
||||
memset(rgba, 0xFF, width * height * 4);
|
||||
for (int y = 0; y < height; y += 4) {
|
||||
for (int x = 0; x < width; x += 4) {
|
||||
DecompressBlock(etc1 + ((y / 4) * width/4 + (x / 4)) * 8,
|
||||
rgba + (y * width + x) * 4, width, 255);
|
||||
rg_etc1::unpack_etc1_block(etc1 + ((y / 4) * width/4 + (x / 4)) * 8,
|
||||
(uint32_t *)rgba + (y * width + x), width, false);
|
||||
}
|
||||
}
|
||||
return rgba;
|
||||
|
@ -33,6 +33,10 @@ enum {
|
||||
ZIM_DITHER = 64, // If set, dithers during save if color reduction is necessary.
|
||||
ZIM_CLAMP = 128, // Texture should default to clamp instead of wrap.
|
||||
ZIM_ZLIB_COMPRESSED = 256,
|
||||
ZIM_ETC1_LOW = 512,
|
||||
ZIM_ETC1_MEDIUM = 1024,
|
||||
ZIM_ETC1_HIGH = 0, // default
|
||||
ZIM_ETC1_DITHER = 2048,
|
||||
};
|
||||
|
||||
// ZIM will only ever support up to 12 levels (4096x4096 max).
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "base/logging.h"
|
||||
#include "ext/etcpack/etcpack.h"
|
||||
#include "ext/rg_etc1/rg_etc1.h"
|
||||
#include "image/zim_save.h"
|
||||
#include "zlib.h"
|
||||
|
||||
@ -101,6 +101,17 @@ void Convert(const uint8_t *image_data, int width, int height, int pitch, int fl
|
||||
break;
|
||||
}
|
||||
case ZIM_ETC1: {
|
||||
rg_etc1::pack_etc1_block_init();
|
||||
rg_etc1::etc1_pack_params params;
|
||||
params.m_dithering = false; //(flags & ZIM_ETC1_DITHER) != 0;
|
||||
if (flags & ZIM_ETC1_LOW) {
|
||||
params.m_quality = rg_etc1::cLowQuality;
|
||||
} else if (flags & ZIM_ETC1_MEDIUM) {
|
||||
params.m_quality = rg_etc1::cMediumQuality;
|
||||
} else {
|
||||
params.m_quality = rg_etc1::cHighQuality;
|
||||
}
|
||||
|
||||
// Check for power of 2
|
||||
if (!ispowerof2(width) || !ispowerof2(height)) {
|
||||
FLOG("Image must have power of 2 dimensions, %ix%i just isn't that.", width, height);
|
||||
@ -113,8 +124,11 @@ void Convert(const uint8_t *image_data, int width, int height, int pitch, int fl
|
||||
#pragma omp parallel for
|
||||
for (int y = 0; y < blockh; y++) {
|
||||
for (int x = 0; x < blockw; x++) {
|
||||
CompressBlock(image_data + ((y * 4) * (pitch/4) + x * 4) * 4, width,
|
||||
(*data) + (blockw * y + x) * 8, 1);
|
||||
uint32_t block[16];
|
||||
for (int iy = 0; iy < 4; iy++) {
|
||||
memcpy(block + 4 * iy, image_data + ((y * 4 + iy) * (pitch/4) + x * 4) * 4, 16);
|
||||
}
|
||||
rg_etc1::pack_etc1_block((*data) + (blockw * y + x) * 8, block, params);
|
||||
}
|
||||
}
|
||||
width = blockw * 4;
|
||||
|
@ -201,8 +201,7 @@
|
||||
<ClInclude Include="data\listable.h" />
|
||||
<ClInclude Include="ext\cityhash\city.h" />
|
||||
<ClInclude Include="ext\cityhash\citycrc.h" />
|
||||
<ClInclude Include="ext\etcpack\etcdec.h" />
|
||||
<ClInclude Include="ext\etcpack\etcpack.h" />
|
||||
<ClInclude Include="ext\rg_etc1\rg_etc1.h" />
|
||||
<ClInclude Include="ext\sha1\sha1.h" />
|
||||
<ClInclude Include="ext\stb_image\stb_image.h" />
|
||||
<ClInclude Include="ext\stb_vorbis\stb_vorbis.h" />
|
||||
@ -294,8 +293,7 @@
|
||||
<ClCompile Include="base\threadutil.cpp" />
|
||||
<ClCompile Include="base\timeutil.cpp" />
|
||||
<ClCompile Include="ext\cityhash\city.cpp" />
|
||||
<ClCompile Include="ext\etcpack\etcdec.cpp" />
|
||||
<ClCompile Include="ext\etcpack\etcpack.cpp" />
|
||||
<ClCompile Include="ext\rg_etc1\rg_etc1.cpp" />
|
||||
<ClCompile Include="ext\sha1\sha1.cpp" />
|
||||
<ClCompile Include="ext\stb_image\stb_image.c" />
|
||||
<ClCompile Include="ext\stb_vorbis\stb_vorbis.c" />
|
||||
|
@ -53,9 +53,6 @@
|
||||
<ClInclude Include="gfx_es2\glsl_program.h">
|
||||
<Filter>gfx</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ext\etcpack\etcdec.h">
|
||||
<Filter>ext</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="audio\wav_read.h">
|
||||
<Filter>audio</Filter>
|
||||
</ClInclude>
|
||||
@ -98,9 +95,6 @@
|
||||
<ClInclude Include="math\math_util.h">
|
||||
<Filter>math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ext\etcpack\etcpack.h">
|
||||
<Filter>ext</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\timeutil.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
@ -242,6 +236,9 @@
|
||||
<ClInclude Include="ext\cityhash\citycrc.h">
|
||||
<Filter>ext</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ext\rg_etc1\rg_etc1.h">
|
||||
<Filter>ext</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="gfx\gl_debug_log.cpp">
|
||||
@ -274,9 +271,6 @@
|
||||
<ClCompile Include="gfx_es2\glsl_program.cpp">
|
||||
<Filter>gfx</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ext\etcpack\etcdec.cpp">
|
||||
<Filter>ext</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="audio\wav_read.cpp">
|
||||
<Filter>audio</Filter>
|
||||
</ClCompile>
|
||||
@ -301,9 +295,6 @@
|
||||
<ClCompile Include="gfx\texture_atlas.cpp">
|
||||
<Filter>gfx</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ext\etcpack\etcpack.cpp">
|
||||
<Filter>ext</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\timeutil.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
@ -429,6 +420,9 @@
|
||||
<ClCompile Include="ext\cityhash\city.cpp">
|
||||
<Filter>ext</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ext\rg_etc1\rg_etc1.cpp">
|
||||
<Filter>ext</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="gfx">
|
||||
|
@ -70,6 +70,8 @@ int main(int argc, char **argv) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// TODO: make setting?
|
||||
flags |= ZIM_ETC1_MEDIUM;
|
||||
if ((flags & ZIM_FORMAT_MASK) == ZIM_ETC1) {
|
||||
if (flags & ZIM_GEN_MIPS) {
|
||||
fprintf(stderr, "WARNING: Cannot generate ETC1 mips at runtime\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user