mirror of https://github.com/aap/librw.git
implemented DXT decompression
This commit is contained in:
parent
69356264d7
commit
069c66b699
|
@ -29,6 +29,7 @@ int32 build = 0xFFFF;
|
||||||
#else
|
#else
|
||||||
int32 platform = PLATFORM_NULL;
|
int32 platform = PLATFORM_NULL;
|
||||||
#endif
|
#endif
|
||||||
|
bool32 streamAppendFrames = 0;
|
||||||
char *debugFile = nil;
|
char *debugFile = nil;
|
||||||
|
|
||||||
// TODO: comparison tolerances
|
// TODO: comparison tolerances
|
||||||
|
|
|
@ -511,8 +511,30 @@ rasterToImage(Raster *raster)
|
||||||
int32 depth;
|
int32 depth;
|
||||||
Image *image;
|
Image *image;
|
||||||
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||||
if(natras->format)
|
if(natras->format){
|
||||||
assert(0 && "no custom formats yet");
|
image = Image::create(raster->width, raster->height, 32);
|
||||||
|
image->allocate();
|
||||||
|
uint8 *pix = raster->lock(0);
|
||||||
|
switch(natras->format){
|
||||||
|
case D3DFMT_DXT1:
|
||||||
|
image->setPixelsDXT(1, pix);
|
||||||
|
if((raster->format & 0xF00) == Raster::C555)
|
||||||
|
image->removeMask();
|
||||||
|
break;
|
||||||
|
case D3DFMT_DXT3:
|
||||||
|
image->setPixelsDXT(3, pix);
|
||||||
|
break;
|
||||||
|
case D3DFMT_DXT5:
|
||||||
|
image->setPixelsDXT(5, pix);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
raster->unlock(0);
|
||||||
|
image->destroy();
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
raster->unlock(0);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
switch(raster->format & 0xF00){
|
switch(raster->format & 0xF00){
|
||||||
case Raster::C1555:
|
case Raster::C1555:
|
||||||
depth = 16;
|
depth = 16;
|
||||||
|
|
228
src/image.cpp
228
src/image.cpp
|
@ -419,6 +419,234 @@ Image::setPixels(uint8 *pixels)
|
||||||
this->flags |= 1;
|
this->flags |= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
decompressDXT1(uint8 *adst, int32 w, int32 h, uint8 *src)
|
||||||
|
{
|
||||||
|
/* j loops through old texels
|
||||||
|
* x and y loop through new texels */
|
||||||
|
uint32 x = 0, y = 0;
|
||||||
|
uint32 c[4][4];
|
||||||
|
uint8 idx[16];
|
||||||
|
uint8 (*dst)[4] = (uint8(*)[4])adst;
|
||||||
|
for(uint32 j = 0; j < w*h/2; j += 8){
|
||||||
|
/* calculate colors */
|
||||||
|
uint32 col0 = *((uint16*)&src[j+0]);
|
||||||
|
uint32 col1 = *((uint16*)&src[j+2]);
|
||||||
|
c[0][0] = ((col0>>11) & 0x1F)*0xFF/0x1F;
|
||||||
|
c[0][1] = ((col0>> 5) & 0x3F)*0xFF/0x3F;
|
||||||
|
c[0][2] = ( col0 & 0x1F)*0xFF/0x1F;
|
||||||
|
c[0][3] = 0xFF;
|
||||||
|
|
||||||
|
c[1][0] = ((col1>>11) & 0x1F)*0xFF/0x1F;
|
||||||
|
c[1][1] = ((col1>> 5) & 0x3F)*0xFF/0x3F;
|
||||||
|
c[1][2] = ( col1 & 0x1F)*0xFF/0x1F;
|
||||||
|
c[1][3] = 0xFF;
|
||||||
|
if(col0 > col1){
|
||||||
|
c[2][0] = (2*c[0][0] + 1*c[1][0])/3;
|
||||||
|
c[2][1] = (2*c[0][1] + 1*c[1][1])/3;
|
||||||
|
c[2][2] = (2*c[0][2] + 1*c[1][2])/3;
|
||||||
|
c[2][3] = 0xFF;
|
||||||
|
|
||||||
|
c[3][0] = (1*c[0][0] + 2*c[1][0])/3;
|
||||||
|
c[3][1] = (1*c[0][1] + 2*c[1][1])/3;
|
||||||
|
c[3][2] = (1*c[0][2] + 2*c[1][2])/3;
|
||||||
|
c[3][3] = 0xFF;
|
||||||
|
}else{
|
||||||
|
c[2][0] = (c[0][0] + c[1][0])/2;
|
||||||
|
c[2][1] = (c[0][1] + c[1][1])/2;
|
||||||
|
c[2][2] = (c[0][2] + c[1][2])/2;
|
||||||
|
c[2][3] = 0xFF;
|
||||||
|
|
||||||
|
c[3][0] = 0x00;
|
||||||
|
c[3][1] = 0x00;
|
||||||
|
c[3][2] = 0x00;
|
||||||
|
c[3][3] = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make index list */
|
||||||
|
uint32 indices = *((uint32*)&src[j+4]);
|
||||||
|
for(int32 k = 0; k < 16; k++){
|
||||||
|
idx[k] = indices & 0x3;
|
||||||
|
indices >>= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write bytes */
|
||||||
|
for(uint32 k = 0; k < 4; k++)
|
||||||
|
for(uint32 l = 0; l < 4; l++){
|
||||||
|
dst[(y+l)*w + x+k][0] = c[idx[l*4+k]][0];
|
||||||
|
dst[(y+l)*w + x+k][1] = c[idx[l*4+k]][1];
|
||||||
|
dst[(y+l)*w + x+k][2] = c[idx[l*4+k]][2];
|
||||||
|
dst[(y+l)*w + x+k][3] = c[idx[l*4+k]][3];
|
||||||
|
}
|
||||||
|
x += 4;
|
||||||
|
if(x >= w){
|
||||||
|
y += 4;
|
||||||
|
x = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
decompressDXT3(uint8 *adst, int32 w, int32 h, uint8 *src)
|
||||||
|
{
|
||||||
|
/* j loops through old texels
|
||||||
|
* x and y loop through new texels */
|
||||||
|
uint32 x = 0, y = 0;
|
||||||
|
uint32 c[4][4];
|
||||||
|
uint8 idx[16];
|
||||||
|
uint8 a[16];
|
||||||
|
uint8 (*dst)[4] = (uint8(*)[4])adst;
|
||||||
|
for(uint32 j = 0; j < w*h; j += 16){
|
||||||
|
/* calculate colors */
|
||||||
|
uint32 col0 = *((uint16*)&src[j+8]);
|
||||||
|
uint32 col1 = *((uint16*)&src[j+10]);
|
||||||
|
c[0][0] = ((col0>>11) & 0x1F)*0xFF/0x1F;
|
||||||
|
c[0][1] = ((col0>> 5) & 0x3F)*0xFF/0x3F;
|
||||||
|
c[0][2] = ( col0 & 0x1F)*0xFF/0x1F;
|
||||||
|
|
||||||
|
c[1][0] = ((col1>>11) & 0x1F)*0xFF/0x1F;
|
||||||
|
c[1][1] = ((col1>> 5) & 0x3F)*0xFF/0x3F;
|
||||||
|
c[1][2] = ( col1 & 0x1F)*0xFF/0x1F;
|
||||||
|
|
||||||
|
c[2][0] = (2*c[0][0] + 1*c[1][0])/3;
|
||||||
|
c[2][1] = (2*c[0][1] + 1*c[1][1])/3;
|
||||||
|
c[2][2] = (2*c[0][2] + 1*c[1][2])/3;
|
||||||
|
|
||||||
|
c[3][0] = (1*c[0][0] + 2*c[1][0])/3;
|
||||||
|
c[3][1] = (1*c[0][1] + 2*c[1][1])/3;
|
||||||
|
c[3][2] = (1*c[0][2] + 2*c[1][2])/3;
|
||||||
|
|
||||||
|
/* make index list */
|
||||||
|
uint32 indices = *((uint32*)&src[j+12]);
|
||||||
|
for(int32 k = 0; k < 16; k++){
|
||||||
|
idx[k] = indices & 0x3;
|
||||||
|
indices >>= 2;
|
||||||
|
}
|
||||||
|
uint64 alphas = *((uint64*)&src[j+0]);
|
||||||
|
for(int32 k = 0; k < 16; k++){
|
||||||
|
a[k] = (alphas & 0xF)*17;
|
||||||
|
alphas >>= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write bytes */
|
||||||
|
for(uint32 k = 0; k < 4; k++)
|
||||||
|
for(uint32 l = 0; l < 4; l++){
|
||||||
|
dst[(y+l)*w + x+k][0] = c[idx[l*4+k]][0];
|
||||||
|
dst[(y+l)*w + x+k][1] = c[idx[l*4+k]][1];
|
||||||
|
dst[(y+l)*w + x+k][2] = c[idx[l*4+k]][2];
|
||||||
|
dst[(y+l)*w + x+k][3] = a[l*4+k];
|
||||||
|
}
|
||||||
|
x += 4;
|
||||||
|
if(x >= w){
|
||||||
|
y += 4;
|
||||||
|
x = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
decompressDXT5(uint8 *adst, int32 w, int32 h, uint8 *src)
|
||||||
|
{
|
||||||
|
/* j loops through old texels
|
||||||
|
* x and y loop through new texels */
|
||||||
|
uint32 x = 0, y = 0;
|
||||||
|
uint32 c[4][4];
|
||||||
|
uint32 a[8];
|
||||||
|
uint8 idx[16];
|
||||||
|
uint8 aidx[16];
|
||||||
|
uint8 (*dst)[4] = (uint8(*)[4])adst;
|
||||||
|
for(uint32 j = 0; j < w*h; j += 16){
|
||||||
|
/* calculate colors */
|
||||||
|
uint32 col0 = *((uint16*)&src[j+8]);
|
||||||
|
uint32 col1 = *((uint16*)&src[j+10]);
|
||||||
|
c[0][0] = ((col0>>11) & 0x1F)*0xFF/0x1F;
|
||||||
|
c[0][1] = ((col0>> 5) & 0x3F)*0xFF/0x3F;
|
||||||
|
c[0][2] = ( col0 & 0x1F)*0xFF/0x1F;
|
||||||
|
|
||||||
|
c[1][0] = ((col1>>11) & 0x1F)*0xFF/0x1F;
|
||||||
|
c[1][1] = ((col1>> 5) & 0x3F)*0xFF/0x3F;
|
||||||
|
c[1][2] = ( col1 & 0x1F)*0xFF/0x1F;
|
||||||
|
if(col0 > col1){
|
||||||
|
c[2][0] = (2*c[0][0] + 1*c[1][0])/3;
|
||||||
|
c[2][1] = (2*c[0][1] + 1*c[1][1])/3;
|
||||||
|
c[2][2] = (2*c[0][2] + 1*c[1][2])/3;
|
||||||
|
|
||||||
|
c[3][0] = (1*c[0][0] + 2*c[1][0])/3;
|
||||||
|
c[3][1] = (1*c[0][1] + 2*c[1][1])/3;
|
||||||
|
c[3][2] = (1*c[0][2] + 2*c[1][2])/3;
|
||||||
|
}else{
|
||||||
|
c[2][0] = (c[0][0] + c[1][0])/2;
|
||||||
|
c[2][1] = (c[0][1] + c[1][1])/2;
|
||||||
|
c[2][2] = (c[0][2] + c[1][2])/2;
|
||||||
|
|
||||||
|
c[3][0] = 0x00;
|
||||||
|
c[3][1] = 0x00;
|
||||||
|
c[3][2] = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[0] = src[j+0];
|
||||||
|
a[1] = src[j+1];
|
||||||
|
if(a[0] > a[1]){
|
||||||
|
a[2] = (6*a[0] + 1*a[1])/7;
|
||||||
|
a[3] = (5*a[0] + 2*a[1])/7;
|
||||||
|
a[4] = (4*a[0] + 3*a[1])/7;
|
||||||
|
a[5] = (3*a[0] + 4*a[1])/7;
|
||||||
|
a[6] = (2*a[0] + 5*a[1])/7;
|
||||||
|
a[7] = (1*a[0] + 6*a[1])/7;
|
||||||
|
}else{
|
||||||
|
a[2] = (4*a[0] + 1*a[1])/5;
|
||||||
|
a[3] = (3*a[0] + 2*a[1])/5;
|
||||||
|
a[4] = (2*a[0] + 3*a[1])/5;
|
||||||
|
a[5] = (1*a[0] + 4*a[1])/5;
|
||||||
|
a[6] = 0;
|
||||||
|
a[7] = 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make index list */
|
||||||
|
uint32 indices = *((uint32*)&src[j+12]);
|
||||||
|
for(int32 k = 0; k < 16; k++){
|
||||||
|
idx[k] = indices & 0x3;
|
||||||
|
indices >>= 2;
|
||||||
|
}
|
||||||
|
// only 6 indices
|
||||||
|
uint64 alphas = *((uint64*)&src[j+2]);
|
||||||
|
for(int32 k = 0; k < 16; k++){
|
||||||
|
aidx[k] = alphas & 0x7;
|
||||||
|
alphas >>= 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write bytes */
|
||||||
|
for(uint32 k = 0; k < 4; k++)
|
||||||
|
for(uint32 l = 0; l < 4; l++){
|
||||||
|
dst[(y+l)*w + x+k][0] = c[idx[l*4+k]][0];
|
||||||
|
dst[(y+l)*w + x+k][1] = c[idx[l*4+k]][1];
|
||||||
|
dst[(y+l)*w + x+k][2] = c[idx[l*4+k]][2];
|
||||||
|
dst[(y+l)*w + x+k][3] = a[aidx[l*4+k]];
|
||||||
|
}
|
||||||
|
x += 4;
|
||||||
|
if(x >= w){
|
||||||
|
y += 4;
|
||||||
|
x = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Image::setPixelsDXT(int32 type, uint8 *pixels)
|
||||||
|
{
|
||||||
|
switch(type){
|
||||||
|
case 1:
|
||||||
|
decompressDXT1(this->pixels, this->width, this->height, pixels);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
decompressDXT3(this->pixels, this->width, this->height, pixels);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
decompressDXT5(this->pixels, this->width, this->height, pixels);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Image::setPalette(uint8 *palette)
|
Image::setPalette(uint8 *palette)
|
||||||
{
|
{
|
||||||
|
|
|
@ -181,6 +181,7 @@ struct Image
|
||||||
void allocate(void);
|
void allocate(void);
|
||||||
void free(void);
|
void free(void);
|
||||||
void setPixels(uint8 *pixels);
|
void setPixels(uint8 *pixels);
|
||||||
|
void setPixelsDXT(int32 type, uint8 *pixels);
|
||||||
void setPalette(uint8 *palette);
|
void setPalette(uint8 *palette);
|
||||||
bool32 hasAlpha(void);
|
bool32 hasAlpha(void);
|
||||||
void unindex(void);
|
void unindex(void);
|
||||||
|
|
Loading…
Reference in New Issue