+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; i<w*h*4; i++ )
+ dst[i] = src[i];
+ break;
+
+ case k_EImageFormat_ABGR8888:
+ for( int i=0; i<w*h; i++ )
+ {
+ dst[i*4+0] = src[i*4+3];
+ dst[i*4+1] = src[i*4+2];
+ dst[i*4+2] = src[i*4+1];
+ dst[i*4+3] = src[i*4+0];
+ }
+ break;
+
+ case k_EImageFormat_RGB888:
+ for( int i=0; i<w*h; i++ )
+ {
+ dst[i*4+0] = src[i*3+0];
+ dst[i*4+1] = src[i*3+1];
+ dst[i*4+2] = src[i*3+2];
+ dst[i*4+3] = 0xFF;
+ }
+ break;
+
+ case k_EImageFormat_BGR888:
+ for( int i=0; i<w*h; i++ )
+ {
+ dst[i*4+0] = src[i*3+2];
+ dst[i*4+1] = src[i*3+1];
+ dst[i*4+2] = src[i*3+0];
+ dst[i*4+3] = 0xFF;
+ }
+ break;
+
+ case k_EImageFormat_RGB565:
+ case k_EImageFormat_I8:
+ case k_EImageFormat_IA88:
+ /* Planned */
+ break;
+
+ case k_EImageFormat_ARGB8888:
+ for( int i=0; i<w*h; i++ )
+ {
+ dst[i*4+0] = src[i*4+1];
+ dst[i*4+1] = src[i*4+2];
+ dst[i*4+2] = src[i*4+3];
+ dst[i*4+3] = src[i*4+0];
+ }
+ break;
+
+ case k_EImageFormat_BGRA8888:
+ for( int i=0; i<w*h; i++ )
+ {
+ dst[i*4+0] = src[i*4+2];
+ dst[i*4+1] = src[i*4+1];
+ dst[i*4+2] = src[i*4+0];
+ dst[i*4+3] = src[i*4+3];
+ }
+ break;
+
+ case k_EImageFormat_DXT1:
+ nbvtf_decompress_dxt( src, w, h, 0, dst );
+ break;
+
+ case k_EImageFormat_DXT5:
+ nbvtf_decompress_dxt( src, w, h, 1, dst );
+ break;
+
+ default:
+ break;
+ }
+}
+
+#ifdef NBVTF_AS_SO
+__attribute__((visibility("default")))
+#endif
+int nbvtf_write_dds_dxt1( uint8_t *reference, int w, int h, int qual, const char *dest )
+{
+ if( !nbvtf_power2x(w,h) )
+ {
+ NBVTF_ERR( "nbvtf_write:err image dimentions were not power of two (%d %d)\n", w, h );
+ return 0;
+ }
+
+ struct DDS_HEADER header = {0};
+ header.dwSize = DDS_HEADER_SIZE;
+ header.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
+ header.dwHeight = h;
+ header.dwWidth = w;
+ header.dwPitchOrLinearSize = nbvtf__max(1, ((w + 3) / 4)) * BLOCK_SIZE_DXT1;
+ header.ddspf.dwSize = DDS_HEADER_PFSIZE;
+ header.ddspf.dwFlags |= DDPF_FOURCC;
+ header.ddspf.dwFourCC = ((uint32_t)'D'<<0) |
+ ((uint32_t)'X'<<8) |
+ ((uint32_t)'T'<<16) |
+ ((uint32_t)'1'<<24);
+
+ header.dwFlags |= DDSD_LINEARSIZE;
+ header.dwMipMapCount = 0;
+ header.dwCaps = DDSCAPS_TEXTURE;
+
+ // Magic number
+ uint32_t magic = DDS_MAGICNUM;
+
+ FILE *file = fopen( dest, "wb" );
+ fwrite( &magic, sizeof(uint32_t), 1, file );
+ fwrite( &header, DDS_HEADER_SIZE, 1, file );
+
+ uint32_t size_highres = nbvtf_sizeimg( w, h, k_EImageFormat_DXT1 );
+ uint8_t *working_buffer = malloc( size_highres );
+
+ nbvtf_compress_dxt( reference, w, h, 0, qual, working_buffer );
+ fwrite( working_buffer, size_highres, 1, file );
+
+ free( working_buffer );
+ fclose( file );
+ return 1;
+}
+
+static void nbvtf_correct_normal( uint8_t *src, uint8_t *dst, int w, int h )
+{
+ for( int i=0; i < w*h; i++ )
+ {
+ dst[i*4+0] = src[i*4+0];
+ dst[i*4+1] = 0xFF-src[i*4+1];
+ dst[i*4+2] = src[i*4+2];
+ dst[i*4+3] = src[i*4+3];
+ }
+}
+