diff --git a/lutconv2.c b/lutconv2.c index 0611eb4..911ccdb 100644 --- a/lutconv2.c +++ b/lutconv2.c @@ -445,6 +445,43 @@ int horconv( void ) } return 1; } + if ( (width == 1024) && (height == 32) ) + { + /* 32x32x32 LUT */ + printf("conv: horizontal 32x32x32 LUT\n"); + ddshead.width = width = 32; + ddshead.height = height = 32; + ddshead.depth = depth = 32; + ddshead.pitch = 32*4; + s = width*height*depth*4; + outdata = malloc(s); + i = 0; + x = 0; + y = 0; + z = 0; + while ( i < s ) + { + outdata[i++] = indata[(x+y*1024+z*32)*(3+alpha)]; + outdata[i++] = indata[(x+y*1024+z*32)*(3+alpha)+1]; + outdata[i++] = indata[(x+y*1024+z*32)*(3+alpha)+2]; + if ( alpha ) + outdata[i++] = indata[(x+y*1024+z*32) + *(3+alpha)+3]; + else outdata[i++] = 255; + x++; + if ( x >= 32 ) + { + x = 0; + y++; + } + if ( y >= 32 ) + { + y = 0; + z++; + } + } + return 1; + } printf("conv: Never heard of a LUT texture of %ux%u\n",width,height); return 0; } @@ -533,7 +570,7 @@ int loadpng( const char *filename ) int main( int argc, char **argv ) { - printf("LUTCONV 2.0 - (C)2017 Marisa Kirisame, UnSX Team.\n" + printf("LUTCONV 2.1 - (C)2017 Marisa Kirisame, UnSX Team.\n" "This program is free software under the GNU GPL v3.\n" "See https://www.gnu.org/licenses/gpl.html for details.\n\n"); if ( argc < 2 ) diff --git a/lutflat.c b/lutflat.c new file mode 100644 index 0000000..a6ef46d --- /dev/null +++ b/lutflat.c @@ -0,0 +1,272 @@ +/* + lutflat.c : LUT flattener. + Converts DDS Volume Map LUTs back into flat textures. + (C)2017 Marisa Kirisame, UnSX Team. + Released under the GNU General Public License version 3 (or later). +*/ +#include +#include +#include +#include +#include +#include + +#define dword uint32_t +#define byte uint8_t +#pragma pack(push,1) +typedef struct +{ + dword magic, size, flags, height, width, pitch, depth, mipmaps, + reserved1[11], pf_size, pf_flags, pf_fourcc, pf_bitcount, pf_rmask, + pf_gmask, pf_bmask, pf_amask, caps[4], reserved2; +} ddsheader_t; +#pragma pack(pop) + +uint8_t *indata, *outdata; +int width, height, depth; +unsigned pngw, pngh; + +int flattenlut( void ) +{ + int x = 0, y = 0, z = 0, i = 0, s = width*height*depth*4; + /* guess the format */ + if ( (width == 256) && (height == 256) && (depth == 256) ) + { + printf("flatten: 256x256x256 table\n"); + pngw = pngh = 4096; + while ( i < s ) + { + outdata[(x+y*4096+(z&0x0F)*1048576+(z&0xF0)*16)*3] + = indata[i++]; + outdata[(x+y*4096+(z&0x0F)*1048576+(z&0xF0)*16)*3+1] + = indata[i++]; + outdata[(x+y*4096+(z&0x0F)*1048576+(z&0xF0)*16)*3+2] + = indata[i++]; + i++; + x++; + if ( x >= 256 ) + { + x = 0; + y++; + } + if ( y >= 256 ) + { + y = 0; + z++; + } + } + return 1; + } + else if ( (width == 64) && (height == 64) && (depth == 64) ) + { + printf("flatten: 64x64x64 table\n"); + pngw = pngh = 512; + while ( i < s ) + { + outdata[(x+y*512+(z&0x7)*32768+(z&0x38)*8)*3] + = indata[i++]; + outdata[(x+y*512+(z&0x7)*32768+(z&0x38)*8)*3+1] + = indata[i++]; + outdata[(x+y*512+(z&0x7)*32768+(z&0x38)*8)*3+2] + = indata[i++]; + i++; + x++; + if ( x >= 64 ) + { + x = 0; + y++; + } + if ( y >= 64 ) + { + y = 0; + z++; + } + } + return 1; + } + else if ( (width == 32) && (height == 32) && (depth == 32) ) + { + printf("flatten: 32x32x32 table\n"); + pngw = 1024; + pngh = 32; + while ( i < s ) + { + outdata[(x+y*1024+z*32)*3] = indata[i++]; + outdata[(x+y*1024+z*32)*3+1] = indata[i++]; + outdata[(x+y*1024+z*32)*3+2] = indata[i++]; + i++; + x++; + if ( x >= 32 ) + { + x = 0; + y++; + } + if ( y >= 32 ) + { + y = 0; + z++; + } + } + return 1; + } + else if ( (width == 16) && (height == 16) && (depth == 16) ) + { + printf("flatten: 16x16x16 table\n"); + pngw = pngh = 64; + while ( i < s ) + { + outdata[(x+y*64+(z&0x3)*1024+(z&0xc)*4)*3] + = indata[i++]; + outdata[(x+y*64+(z&0x3)*1024+(z&0xc)*4)*3+1] + = indata[i++]; + outdata[(x+y*64+(z&0x3)*1024+(z&0xc)*4)*3+2] + = indata[i++]; + i++; + x++; + if ( x >= 16 ) + { + x = 0; + y++; + } + if ( y >= 16 ) + { + y = 0; + z++; + } + } + return 1; + } + printf("flat: Unsupported dimensions %ux%ux%u\n",width,height,depth); + return 0; +} + +int savepng( const char *filename ) +{ + if ( !filename ) + { + printf("png: no filename passed\n"); + return 1; + } + png_structp pngp; + png_infop infp; + FILE *pf; + if ( !(pf = fopen(filename,"wb")) ) + { + printf("png: could not open file: %s\n",strerror(errno)); + return 1; + } + pngp = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); + if ( !pngp ) + { + printf("png: failed to create png_struct\n"); + fclose(pf); + return 1; + } + infp = png_create_info_struct(pngp); + if ( !infp ) + { + printf("png: failed to create png_info\n"); + fclose(pf); + png_destroy_write_struct(&pngp,&infp); + return 1; + } + if ( setjmp(png_jmpbuf(pngp)) ) + { + printf("png: failed to set up error handler\n"); + png_destroy_write_struct(&pngp,&infp); + fclose(pf); + return 1; + } + png_init_io(pngp,pf); + png_set_IHDR(pngp,infp,pngw,pngh,8,PNG_COLOR_TYPE_RGB, + PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_BASE, + PNG_FILTER_TYPE_BASE); + png_write_info(pngp,infp); + png_bytepp rptr = malloc(sizeof(png_bytep)*pngh); + for ( unsigned i=0; i +#include +#include +#include +#include + +#define dword uint32_t +#define byte uint8_t +#pragma pack(push,1) +typedef struct +{ + dword magic, size, flags, height, width, pitch, depth, mipmaps, + reserved1[11], pf_size, pf_flags, pf_fourcc, pf_bitcount, pf_rmask, + pf_gmask, pf_bmask, pf_amask, caps[4], reserved2; +} ddsheader_t; +#pragma pack(pop) + +uint8_t *indata, *outdata; +int width, height, depth; +float gauss8[8] = +{ + 0.134598, 0.127325, 0.107778, 0.081638, + 0.055335, 0.033562, 0.018216, 0.008847 +}; + +void getpx( int x, int y, int z, float *r, float *g, float *b ) +{ + /* clamp coords */ + if ( x < 0 ) x = 0; + if ( y < 0 ) y = 0; + if ( z < 0 ) z = 0; + if ( x >= width ) x = width-1; + if ( y >= height ) y = height-1; + if ( z >= depth ) z = depth-1; + *r = indata[(x+y*width+z*width*height)*4]/255.0; + *g = indata[(x+y*width+z*width*height)*4+1]/255.0; + *b = indata[(x+y*width+z*width*height)*4+2]/255.0; +} + +void putpx( int x, int y, int z, float r, float g, float b ) +{ + /* clamp coords */ + if ( x < 0 ) x = 0; + if ( y < 0 ) y = 0; + if ( z < 0 ) z = 0; + if ( x >= width ) x = width-1; + if ( y >= height ) y = height-1; + if ( z >= depth ) z = depth-1; + /* clamp color */ + if ( r < 0.0 ) r = 0.0; + if ( g < 0.0 ) g = 0.0; + if ( b < 0.0 ) b = 0.0; + if ( r > 1.0 ) r = 1.0; + if ( g > 1.0 ) g = 1.0; + if ( b > 1.0 ) b = 1.0; + outdata[(x+y*width+z*width*height)*4] = (r*255); + outdata[(x+y*width+z*width*height)*4+1] = (g*255); + outdata[(x+y*width+z*width*height)*4+2] = (b*255); + outdata[(x+y*width+z*width*height)*4+3] = 255; /* always opaque */ +} + +int smoothenlut( void ) +{ + int x = 0, y = 0, z = 0, i = 0, s = width*height*depth; + float r1, g1, b1, r2, g2, b2; + int j, k, l; + while ( i < s ) + { + r2 = g2 = b2 = 0.0; + for ( l=-7; l<=7; l++ ) + { + for ( k=-7; k<=7; k++ ) + { + for ( j=-7; j<=7; j++ ) + { + getpx(x+j,y+k,z+l,&r1,&g1,&b1); + r2 += r1*gauss8[abs(j)]*gauss8[abs(k)] + *gauss8[abs(l)]; + g2 += g1*gauss8[abs(j)]*gauss8[abs(k)] + *gauss8[abs(l)]; + b2 += b1*gauss8[abs(j)]*gauss8[abs(k)] + *gauss8[abs(l)]; + } + } + } + putpx(x,y,z,r2,g2,b2); + i++; + x++; + if ( x >= width ) + { + x = 0; + y++; + } + if ( y >= height ) + { + y = 0; + z++; + } + /* print a progress bar because this can take long */ + printf("\rlutsmooth: Applying blur... %3d%%",(i*100)/s); + } + putchar('\n'); + return 1; +} + +int main( int argc, char **argv ) +{ + printf("LUTSMOOTH 1.0 - (C)2017 Marisa Kirisame, UnSX Team.\n" + "This program is free software under the GNU GPL v3.\n" + "See https://www.gnu.org/licenses/gpl.html for details.\n\n"); + FILE *fin, *fout; + char fname[255] = {0}; + ddsheader_t head; + for ( int i=1; i