5050#include "stb_image_write.h"
5151#include "y4m.h"
5252
53+ static void
54+ gpujpeg_cuda_free_host (void * ptr );
55+ static void *
56+ gpujpeg_cuda_realloc_sized_host (void * ptr , int oldsz , int newsz );
57+ // we want use custom allocator but only way to do this in stbi is to define the below
58+ #define STBI_MALLOC gpujpeg_cuda_malloc_host
59+ #define STBI_FREE gpujpeg_cuda_free_host
60+ #define STBI_REALLOC_SIZED gpujpeg_cuda_realloc_sized_host
61+ #define STB_IMAGE_IMPLEMENTATION
62+ #include "stb_image.h"
63+
5364enum {
5465 DEPTH_8B = 8 ,
5566 MAXVAL_8B = 255 ,
5667};
5768
69+ static void
70+ gpujpeg_cuda_free_host (void * ptr )
71+ {
72+ GPUJPEG_CHECK_EX (cudaFreeHost (ptr ), "Could not free host pointer" , );
73+ }
74+
75+ static void *
76+ gpujpeg_cuda_realloc_sized_host (void * ptr , int oldsz , int newsz )
77+ {
78+ char * nptr = gpujpeg_cuda_malloc_host (newsz );
79+ if (nptr == NULL ) {
80+ return NULL ;
81+ }
82+ memcpy (nptr , ptr , MIN (oldsz , newsz ));
83+ gpujpeg_cuda_free_host (ptr );
84+ return nptr ;
85+ }
86+
87+ static int
88+ bmp_load_delegate (const char * filename , size_t * image_size , void * * image_data , allocator_t alloc )
89+ {
90+ int x = 0 ;
91+ int y = 0 ;
92+ int ch = 0 ;
93+ stbi_uc * out = stbi_load (filename , & x , & y , & ch , 0 );
94+ if ( out == NULL ) {
95+ ERROR_MSG ("[stbi] Cannot load input file file %s: %s\n" , filename , stbi_failure_reason ());
96+ return -1 ;
97+ }
98+ * image_size = (size_t ) x * y * ch ;
99+ if (alloc == gpujpeg_cuda_malloc_host ) {
100+ * image_data = out ;
101+ return 0 ;
102+ }
103+ WARN_MSG ("Allocator is not gpujpeg_cuda_malloc_host. Will memcpy, which will be slower, please report!\n" );
104+ * image_data = alloc (* image_size );
105+ if (* image_data != NULL ) {
106+ memcpy (* image_data , out , * image_size );
107+ }
108+ else {
109+ ERROR_MSG ("Cannot allocate output buffer!\n" );
110+ return -1 ;
111+ }
112+ gpujpeg_cuda_free_host (out );
113+ return * image_data == NULL ? -1 : 0 ;
114+ }
115+
58116static int pam_load_delegate (const char * filename , size_t * image_size , void * * image_data , allocator_t alloc ) {
59117 struct pam_metadata info ;
60118 bool ret = pam_read (filename , & info , (unsigned char * * ) image_data , alloc );
@@ -387,7 +445,26 @@ bmp_image_probe_delegate(const char* filename, enum gpujpeg_image_file_format fo
387445 param_image -> color_space = GPUJPEG_CS_DEFAULT ;
388446 return true;
389447 }
390- abort (); ///< @todo implement
448+ int comp = 0 ;
449+ if ( !stbi_info (filename , & param_image -> width , & param_image -> height , & comp ) ) {
450+ ERROR_MSG ("[stbi] Cannot obtain metadata from file %s: %s\n" , filename , stbi_failure_reason ());
451+ return -1 ;
452+ }
453+ if ( comp == 1 ) {
454+ // presumably sRGB, so not entirely correct (transfer, BT.709 primaries) but BT601_256LVLS chosen because is the
455+ // only one full-range
456+ param_image -> color_space = GPUJPEG_YCBCR_BT601_256LVLS ;
457+ param_image -> pixel_format = GPUJPEG_U8 ;
458+ }
459+ else if ( comp == 3 ) {
460+ param_image -> color_space = GPUJPEG_RGB ;
461+ param_image -> pixel_format = GPUJPEG_444_U8_P012 ;
462+ }
463+ else {
464+ ERROR_MSG ("[stbi] Unsupported channel count %d for %s\n" , comp , filename );
465+ return -1 ;
466+ }
467+ return 0 ;
391468}
392469
393470/// generates deterministic random pattern
@@ -458,6 +535,8 @@ tst_image_load_delegate(const char* filename, size_t* image_size, void** image_d
458535
459536image_load_delegate_t gpujpeg_get_image_load_delegate (enum gpujpeg_image_file_format format ) {
460537 switch (format ) {
538+ case GPUJPEG_IMAGE_FILE_BMP :
539+ return bmp_load_delegate ;
461540 case GPUJPEG_IMAGE_FILE_PGM :
462541 case GPUJPEG_IMAGE_FILE_PPM :
463542 case GPUJPEG_IMAGE_FILE_PNM :
@@ -467,7 +546,6 @@ image_load_delegate_t gpujpeg_get_image_load_delegate(enum gpujpeg_image_file_fo
467546 return y4m_load_delegate ;
468547 case GPUJPEG_IMAGE_FILE_TST :
469548 return tst_image_load_delegate ;
470- case GPUJPEG_IMAGE_FILE_BMP : ///< @todo implement
471549 case GPUJPEG_IMAGE_FILE_UNKNOWN :
472550 case GPUJPEG_IMAGE_FILE_JPEG :
473551 case GPUJPEG_IMAGE_FILE_RAW :
0 commit comments