Skip to content

Commit 33450bf

Browse files
committed
support for loading from BMP files
1 parent cb28bc7 commit 33450bf

File tree

4 files changed

+8074
-3
lines changed

4 files changed

+8074
-3
lines changed

src/gpujpeg_common.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1152,7 +1152,9 @@ gpujpeg_image_calculate_size(struct gpujpeg_image_parameters* param)
11521152
}
11531153
}
11541154

1155-
static void *gpujpeg_cuda_malloc_host(size_t size) {
1155+
void*
1156+
gpujpeg_cuda_malloc_host(size_t size)
1157+
{
11561158
void *ptr;
11571159
GPUJPEG_CHECK_EX(cudaMallocHost(&ptr, size), "Could not alloc host pointer", return NULL);
11581160
return ptr;

src/gpujpeg_common_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,9 @@ cudaError_t
520520
gpujpeg_cuda_memcpy_async_partially_pinned(void* dst, const void* src, size_t count, enum cudaMemcpyKind kind,
521521
cudaStream_t stream, size_t pinned_sz);
522522

523+
void*
524+
gpujpeg_cuda_malloc_host(size_t size);
525+
523526
#ifdef __cplusplus
524527
} // extern "C"
525528
#endif // __cplusplus

src/utils/image_delegate.c

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,69 @@
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+
5364
enum {
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+
58116
static 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

459536
image_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

Comments
 (0)