/* lutsmooth.c : LUT smoothening. Softens Volume LUTs by applying gaussian blur across all three axes. (C)2017 Marisa Kirisame, UnSX Team. Released under the MIT license. */ #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; 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