X-Git-Url: https://harrygodden.com/git/?p=convexer.git;a=blobdiff_plain;f=nbvtf%2Fnbvtf.h;fp=nbvtf%2Fnbvtf.h;h=5db305b812d8620e8db6270ee3ce4727f82d4360;hp=aa82cbf6a302823416a011f99a956e89e0f43383;hb=ea8476b5ce234e3098116bf08c17b0def5115bfd;hpb=0d0b6bf37c8a9c4494071973103a89b4aa82574a diff --git a/nbvtf/nbvtf.h b/nbvtf/nbvtf.h index aa82cbf..5db305b 100644 --- a/nbvtf/nbvtf.h +++ b/nbvtf/nbvtf.h @@ -57,10 +57,12 @@ extern "C" { #define NBVTF_SHOW_STDERR #define STB_IMAGE_IMPLEMENTATION + #define STB_IMAGE_WRITE_IMPLEMENTATION #endif #define STBI_NO_THREAD_LOCALS #include "stb/stb_image.h" +#include "stb/stb_image_write.h" #ifdef USE_LIBRGBCX // #define RGBCX_NO_ALGORITHM @@ -88,40 +90,39 @@ extern "C" { typedef enum EImageFormat { - // Name // Supported? + /* Format Export Import */ k_EImageFormat_NONE = -1, - k_EImageFormat_RGBA8888 = 0, // YES - k_EImageFormat_ABGR8888, - k_EImageFormat_RGB888, // YES - k_EImageFormat_BGR888, - k_EImageFormat_RGB565, - k_EImageFormat_I8, - k_EImageFormat_IA88, - k_EImageFormat_P8, - k_EImageFormat_A8, - k_EImageFormat_RGB888_BLUESCREEN, - k_EImageFormat_BGR888_BLUESCREEN, - k_EImageFormat_ARGB8888, - k_EImageFormat_BGRA8888, - k_EImageFormat_DXT1, // YES - k_EImageFormat_DXT3, - k_EImageFormat_DXT5, // YES - k_EImageFormat_BGRX8888, - k_EImageFormat_BGR565, - k_EImageFormat_BGRX5551, - k_EImageFormat_BGRA4444, - k_EImageFormat_DXT1_ONEBITALPHA, - k_EImageFormat_BGRA5551, - k_EImageFormat_UV88, - k_EImageFormat_UVWQ8888, - k_EImageFormat_RGBA16161616F, - k_EImageFormat_RGBA16161616, - k_EImageFormat_UVLX8888 + k_EImageFormat_RGBA8888 = 0, // - yes + k_EImageFormat_ABGR8888, // yes yes + k_EImageFormat_RGB888, // - yes + k_EImageFormat_BGR888, // yes yes + k_EImageFormat_RGB565, // - planned + k_EImageFormat_I8, // - planned + k_EImageFormat_IA88, // - planned + k_EImageFormat_P8, // - - + k_EImageFormat_A8, // - - + k_EImageFormat_RGB888_BLUESCREEN,// - - + k_EImageFormat_BGR888_BLUESCREEN,// - - + k_EImageFormat_ARGB8888, // - yes + k_EImageFormat_BGRA8888, // - yes + k_EImageFormat_DXT1, // yes yes + k_EImageFormat_DXT3, // - - + k_EImageFormat_DXT5, // yes yes + k_EImageFormat_BGRX8888, // - - + k_EImageFormat_BGR565, // - planned + k_EImageFormat_BGRX5551, // - - + k_EImageFormat_BGRA4444, // - - + k_EImageFormat_DXT1_ONEBITALPHA, // - planned + k_EImageFormat_BGRA5551, // - - + k_EImageFormat_UV88, // - - + k_EImageFormat_UVWQ8888, // - - + k_EImageFormat_RGBA16161616F, // - - + k_EImageFormat_RGBA16161616, // - - + k_EImageFormat_UVLX8888 // - - } EImageFormat_t; const char *vtf_format_strings[] = { - // Name // Supported? "RGBA8888", "ABGR8888", "RGB888", @@ -564,6 +565,29 @@ void nbvtf_dxt_block( uint8_t *dest, uint8_t *src, int alpha, int qual ) #endif } +void nbvtf_dxt_block_unpack( uint8_t *src, uint8_t *dest, int alpha ) +{ +#ifdef USE_LIBRGBCX + if( alpha ) + { + rgbcx__unpack_bc3( src, dest ); + } + else + { + rgbcx__unpack_bc1( src, dest ); + } +#endif + +#if USE_STB_DXT + stb_decompress_dxt_block( src, dest, alpha ); +#endif + +#ifndef HAS_DXT_COMPRESSOR + for( int i=0; i> 2; + blocks_y = ((uint32_t)h) >> 2; + + int padx = w % 4 != 0? 1: 0; + int pady = h % 4 != 0? 1: 0; + + int block_size = alpha? 16: 8; + + uint8_t *dxt_block = src; + uint8_t working_block[ 4*4*4 ]; + + // Compress rows + for( int y = 0; y < blocks_y; y ++ ) + { + for( int x = 0; x < blocks_x; x ++ ) + { + nbvtf_dxt_block_unpack( dxt_block, working_block, alpha ); + + uint8_t *dest_begin = dest + (y*w*4 + x*4)*4; + for( int i = 0; i < 4; i ++ ) + memcpy( dest_begin + w*4*i, working_block + i*4*4, 4*4 ); + + dxt_block += block_size; + } + + if( padx ) + dxt_block += block_size; + } + + if( pady ) + for( int x = 0; x < blocks_x; x ++ ) + dxt_block += block_size; + + if( padx && pady ) + { + } +} +static void nbvtf_swizzle_to( uint8_t *src, int n, int nc, uint8_t *dest ) { for( int i = 0; i < n; i ++ ) { @@ -634,7 +700,7 @@ void nbvtf_swizzle_to( uint8_t *src, int n, int nc, uint8_t *dest ) } } -void nbvtf_write_img_data( uint8_t *src, int w, int h, +static void nbvtf_write_img_data( uint8_t *src, int w, int h, EImageFormat_t format, int qual, uint8_t *wb, FILE *file ) { switch( format ) @@ -661,7 +727,119 @@ void nbvtf_write_img_data( uint8_t *src, int w, int h, } } +static size_t nbvtf_img_size( int w, int h, EImageFormat_t format ) +{ + int block_count = nbvtf__max(1, ((w + 3) / 4)) * + nbvtf__max(1, ((h + 3) / 4)); + switch( format ) + { + case k_EImageFormat_RGBA8888: + case k_EImageFormat_ABGR8888: + case k_EImageFormat_ARGB8888: + case k_EImageFormat_BGRA8888: + return 4*w*h; + + case k_EImageFormat_RGB888: + case k_EImageFormat_BGR888: + return 3*w*h; + + case k_EImageFormat_RGB565: + case k_EImageFormat_IA88: + return 2*w*h; + + case k_EImageFormat_I8: + return w*h; + + case k_EImageFormat_DXT1: + return block_count * BLOCK_SIZE_DXT1; + + case k_EImageFormat_DXT5: + return block_count * BLOCK_SIZE_DXT5; + + default: + break; + } +} + +static void nbvtf_read_img_data( uint8_t *src, int w, int h, + EImageFormat_t format, uint8_t *dst ) +{ + switch( format ) + { + case k_EImageFormat_RGBA8888: + for( int i=0; iwidth; + *h = header->height; + + uint8_t *rgba = malloc( header->width * header->height * 4 ); + + if( !rgba ) + return NULL; + + size_t memory = 0; + int x = header->width, + y = header->height; + + int mip_iter = 0; + + while( nbvtf_lower( &x, &y ) ) + { + if( mip_iter == header->mipmapCount ) + break; + + mip_iter ++; + memory += nbvtf_img_size( x, y, header->highResImageFormat ); + } + + if( header->lowResImageWidth == 0 || header->lowResImageHeight == 0 || + header->lowResImageFormat == 0xffffffff ) + { + /* no thumbnail? */ + } + else + memory += nbvtf_img_size( header->lowResImageWidth, + header->lowResImageHeight, + header->lowResImageFormat ); + + /* Decode high res image into rgba */ + nbvtf_read_img_data( ((uint8_t *)header) + header->headerSize + memory, + header->width, header->height, + header->highResImageFormat, + rgba ); + + if( normal ) + { + nbvtf_correct_normal( rgba, rgba, header->width, header->height ); + stbi_write_png( "/tmp/cxr_hello_n.png", header->width, header->height, + 4, rgba, header->width*4 ); + } + else + stbi_write_png( "/tmp/cxr_hello.png", header->width, header->height, + 4, rgba, header->width*4 ); + + + return rgba; +} + +#ifdef NBVTF_AS_SO +__attribute__((visibility("default"))) +#endif +uint8_t *nbvtf_raw_data( vtfheader_t *header, int32_t *w, int32_t *h, int32_t *format ) +{ + *w = header->width; + *h = header->height; + *format = header->highResImageFormat; + + return ((uint8_t *)header) + header->headerSize; +} + +#ifdef NBVTF_AS_SO +__attribute__((visibility("default"))) +#endif +void nbvtf_free( uint8_t *data ) +{ + free(data); +} + #ifdef NBVTF_AS_SO __attribute__((visibility("default"))) #endif