Skip to content

Commit 7e86a21

Browse files
committed
implement channel remap also for the decoder
+ make version 0.27.8
1 parent 50b2904 commit 7e86a21

11 files changed

+46
-20
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cmake_minimum_required(VERSION 3.10.0 FATAL_ERROR)
22
# change version also in configure.ac
3-
project(gpujpeg VERSION 0.27.7 LANGUAGES C CUDA)
3+
project(gpujpeg VERSION 0.27.8 LANGUAGES C CUDA)
44

55
# options
66
set(BUILD_OPENGL OFF CACHE STRING "Build with OpenGL support, options are: AUTO ON OFF")

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2025-08-22 - 0.27.8
2+
----------
3+
4+
- implement channel remapping via option in pre/postprocessor
5+
16
2025-07-10 - 0.27.7
27
----------
38

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
AC_PREREQ([2.65])
22
# change version also in CMakeLists.txt
3-
AC_INIT([libgpujpeg],[0.27.7],[https://github.com/CESNET/GPUJPEG/issues],[libgpujpeg],[https://github.com/CESNET/GPUJPEG])
3+
AC_INIT([libgpujpeg],[0.27.8],[https://github.com/CESNET/GPUJPEG/issues],[libgpujpeg],[https://github.com/CESNET/GPUJPEG])
44
AC_CONFIG_MACRO_DIR([m4])
55
AC_CONFIG_SRCDIR([src/main.c])
66
AC_CONFIG_AUX_DIR([.])

libgpujpeg/gpujpeg_decoder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,10 @@ gpujpeg_decoder_get_image_info(uint8_t *image, size_t image_size, struct gpujpeg
270270
/// use RLE when writing TGA with gpujpeg_image_save_to_file (default is true), 0 or 1 please note that the option is
271271
/// global so it affects all decoder instances
272272
#define GPUJPEG_DEC_OPT_TGA_RLE_BOOL "dec_opt_tga_rle" ///< GPUJPEG_VAL_TRUE or GPUJPEG_VAL_FALSE
273+
274+
/// @copydoc GPUJPEG_ENC_OPT_CHANNEL_REMAP
275+
#define GPUJPEG_DEC_OPT_CHANNEL_REMAP "dec_opt_channel_remap"
276+
273277
/**
274278
* sets decoder option
275279
* @retval GPUJPEG_NOERR option was sucessfully set

libgpujpeg/gpujpeg_encoder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ gpujpeg_encoder_suggest_restart_interval(const struct gpujpeg_image_parameters*
235235
#define GPUJPEG_ENC_OPT_FLIPPED_BOOL "enc_opt_flipped"
236236

237237
/**
238-
* remap input channel order
238+
* remap channel order
239239
*
240240
* Format is "XYZ" or "XYZW" where the letters stand for input channel indices (0-indexed) mapped to output position;
241241
* so eg. for remapping from ARGB to RGBA the option value will be "1230".

src/gpujpeg_common_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,9 @@ gpujpeg_cuda_malloc_host(size_t size);
539539
void
540540
gpujpeg_init_term_colors();
541541

542+
int
543+
gpujpeg_opt_set_channel_remap(struct gpujpeg_coder* coder, const char* val, const char* optname);
544+
542545
#ifdef __cplusplus
543546
} // extern "C"
544547
#endif // __cplusplus

src/gpujpeg_decoder.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,9 @@ gpujpeg_decoder_set_option(struct gpujpeg_decoder* decoder, const char *opt, con
493493
image_delegate_stbi_tga_set_rle(strcmp(val, GPUJPEG_VAL_TRUE) == 0);
494494
return GPUJPEG_NOERR;
495495
}
496+
if ( strcmp(opt, GPUJPEG_DEC_OPT_CHANNEL_REMAP) == 0 ) {
497+
return gpujpeg_opt_set_channel_remap(&decoder->coder, val, GPUJPEG_DEC_OPT_CHANNEL_REMAP);
498+
}
496499
ERROR_MSG("Invalid decoder option: %s!\n", opt);
497500
return GPUJPEG_ERROR;
498501
}
@@ -502,6 +505,8 @@ gpujpeg_decoder_print_options()
502505
{
503506
printf("\t" GPUJPEG_DEC_OPT_TGA_RLE_BOOL "=[" GPUJPEG_VAL_FALSE "|" GPUJPEG_VAL_TRUE
504507
"] - set decoder option (not) to output RLE TGA\n");
508+
printf("\t" GPUJPEG_DEC_OPT_CHANNEL_REMAP "=XYZ[W] - input channel mapping, eg. '210F' for GBRX,\n"
509+
"\t\t'210' for GBR; special placeholders 'F' and 'Z' to set a channel to all-ones or all-zeros\n");
505510
}
506511

507512
/* Documented at declaration */

src/gpujpeg_encoder.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -652,11 +652,11 @@ gpujpeg_encoder_set_jpeg_header(struct gpujpeg_encoder *encoder, enum gpujpeg_he
652652
encoder->header_type = header_type;
653653
}
654654

655-
static int
656-
enc_opt_set_channel_remap(struct gpujpeg_encoder* encoder, const char* val)
655+
int
656+
gpujpeg_opt_set_channel_remap(struct gpujpeg_coder* coder, const char* val, const char *optname)
657657
{
658658
if ( strcmp(val, "help") == 0 ) {
659-
printf("syntax for " GPUJPEG_ENC_OPT_CHANNEL_REMAP ":\n");
659+
printf("syntax for %s:\n", optname);
660660
printf("\t\"XYZ\" or \"XYZW\" where the letters are input channel indices\n");
661661
printf("\tplaceholder 'Z' or 'F' can be used to set the channel to all-zeros or all-ones\n");
662662
printf("\n");
@@ -669,7 +669,7 @@ enc_opt_set_channel_remap(struct gpujpeg_encoder* encoder, const char* val)
669669
ERROR_MSG("Mapping for more than %d channels specified!\n", GPUJPEG_MAX_COMPONENT_COUNT);
670670
return GPUJPEG_ERROR;
671671
}
672-
encoder->coder.preprocessor.channel_remap = 0; // clear old
672+
coder->preprocessor.channel_remap = 0; // clear old
673673
const char *ptr = val + strlen(val) - 1;
674674
while ( ptr >= val ) {
675675
int src_chan = *ptr - '0';
@@ -680,15 +680,15 @@ enc_opt_set_channel_remap(struct gpujpeg_encoder* encoder, const char* val)
680680
src_chan = 5;
681681
}
682682
else if ( src_chan < 0 || src_chan >= mapped_count ) {
683-
ERROR_MSG("Invalid channel index %c for " GPUJPEG_ENC_OPT_CHANNEL_REMAP " (mapping %d channels)!\n", *ptr,
684-
mapped_count);
683+
ERROR_MSG("Invalid channel index %c for %s (mapping %d channels)!\n", *ptr,
684+
optname, mapped_count);
685685
return GPUJPEG_ERROR;
686686
}
687-
encoder->coder.preprocessor.channel_remap <<= 4;
688-
encoder->coder.preprocessor.channel_remap |= src_chan;
687+
coder->preprocessor.channel_remap <<= 4;
688+
coder->preprocessor.channel_remap |= src_chan;
689689
ptr--;
690690
}
691-
encoder->coder.preprocessor.channel_remap |= mapped_count << 24;
691+
coder->preprocessor.channel_remap |= mapped_count << 24;
692692
return GPUJPEG_NOERR;
693693
}
694694

@@ -742,7 +742,7 @@ gpujpeg_encoder_set_option(struct gpujpeg_encoder* encoder, const char *opt, con
742742
return GPUJPEG_NOERR;
743743
}
744744
if ( strcmp(opt, GPUJPEG_ENC_OPT_CHANNEL_REMAP) == 0 ) {
745-
return enc_opt_set_channel_remap(encoder, val);
745+
return gpujpeg_opt_set_channel_remap(&encoder->coder, val, GPUJPEG_ENC_OPT_CHANNEL_REMAP);
746746
}
747747
ERROR_MSG("Invalid encoder option: %s!\n", opt);
748748
return GPUJPEG_ERROR;

src/gpujpeg_postprocessor.cu

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,13 @@ gpujpeg_postprocessor_decode(struct gpujpeg_coder* coder, cudaStream_t stream)
479479
);
480480
gpujpeg_cuda_check_error("Preprocessor encoding failed", return -1);
481481

482+
if ( coder->preprocessor.channel_remap != 0 ) {
483+
const int ret = gpujpeg_preprocessor_channel_remap(coder, stream);
484+
if ( ret != 0 ) {
485+
return ret;
486+
}
487+
}
488+
482489
return 0;
483490
}
484491

src/gpujpeg_preprocessor.cu

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -513,11 +513,9 @@ channel_remap_kernel(uint8_t* data, int width, int pitch, int height, unsigned i
513513
gpujpeg_comp_to_raw_store<pixel_format>(data, width, height, offset, x, y, r);
514514
}
515515

516-
static int
517-
channel_remap(struct gpujpeg_encoder* encoder)
516+
int
517+
gpujpeg_preprocessor_channel_remap(struct gpujpeg_coder* coder, cudaStream_t stream)
518518
{
519-
struct gpujpeg_coder* coder = &encoder->coder;
520-
521519
const unsigned comp_count = gpujpeg_pixel_format_get_comp_count(coder->param_image.pixel_format);
522520
const unsigned mapped_count = coder->preprocessor.channel_remap >> 24;
523521
if (comp_count != mapped_count) {
@@ -551,7 +549,7 @@ channel_remap(struct gpujpeg_encoder* encoder)
551549
GPUJPEG_ASSERT(0 && "Preprocess from GPUJPEG_PIXFMT_NONE not allowed");
552550
}
553551
#undef SWITDH_KERNEL
554-
kernel<<<grid, block, 0, encoder->stream>>>(encoder->coder.d_data_raw, width, pitch, height, mapping);
552+
kernel<<<grid, block, 0, stream>>>(coder->d_data_raw, width, pitch, height, mapping);
555553
gpujpeg_cuda_check_error("channel_remap_kernel failed", return -1);
556554
return 0;
557555
}
@@ -566,7 +564,7 @@ gpujpeg_preprocessor_encode(struct gpujpeg_encoder * encoder)
566564
// (coder->param_image.pixel_format == GPUJPEG_444_U8_P012 && coder->preprocessor.kernel != nullptr));
567565

568566
if ( coder->preprocessor.channel_remap != 0 ) {
569-
const int ret = channel_remap(encoder);
567+
const int ret = gpujpeg_preprocessor_channel_remap(coder, encoder->stream);
570568
if ( ret != 0 ) {
571569
return ret;
572570
}

0 commit comments

Comments
 (0)