Skip to content

Commit 23bd3df

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

12 files changed

+59
-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")

FAQ.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- [Encoding different color spaces than full-range YCbCr BT.601](#encoding-different-color-spaces-than-full-range-ycbcr-bt601)
77
- [Optimizing encoding/decoding performance](#optimizing-encodingdecoding-performance)
88
- [Decoding (foreign) JPEG fails](#decoding-foreign-jpeg-fails)
9+
- [Channel remapping - ARGB etc. encode/decode](#channel-remapping---argb-etc-encodedecode)
910
- [Encoding/decoding alpha channel](#encodingdecoding-alpha-channel)
1011
- [Alpha support in command-line application](#alpha-support-in-command-line-application)
1112
- [API for alpha](#api-for-alpha)
@@ -120,6 +121,18 @@ are supported. Basically a **baseline** **DCT-based** **Huffman-encoded** JPEGs
120121
Few features of **extended** process are supported as well (4 Huffman tables). If the decoder
121122
is incapable of decoding the above mentioned JPEG, you are encouraged to fill a bug report.
122123

124+
## Channel remapping - ARGB etc. encode/decode
125+
126+
Pixel formats with different channel order can be pre/postprocessed with
127+
encoder or decoder option, eg.:
128+
129+
gpujpegtool -s 1920x1080 -c rgb -f 4444-u8-p0123 -e in.gbra -O enc_opt_channel_remap=2103 out.jpg
130+
gpujpegtool -O dec_opt_channel_remap=210 in.jpg out.pnm
131+
132+
or in code:
133+
134+
gpujpeg_encoder_set_option(encoder, GPUJPEG_ENC_OPT_CHANNEL_REMAP, "1230");
135+
123136
## Encoding/decoding alpha channel
124137
Encoding is currently supported only for a single packed pixel format
125138
444-u8-p012a (`GPUJPEG_444_U8_P012A`). Let us know if you'd need some other

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

0 commit comments

Comments
 (0)