Skip to content

Commit 5c9ee47

Browse files
committed
channel remap: support for 444_U8_P012
1 parent ede68fc commit 5c9ee47

File tree

3 files changed

+40
-15
lines changed

3 files changed

+40
-15
lines changed

libgpujpeg/gpujpeg_encoder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ gpujpeg_encoder_suggest_restart_interval(const struct gpujpeg_image_parameters*
243243
* The number of image channes must equal the length of the string. Set to "" (empty string) to revert this setting.
244244
* Letters 'Z' or 'F' can be used instead of indices to fill given output channel with zeros or all-ones.
245245
*
246-
* Currently, the remapping is implemented for GPUJPEG_4444_U8_P0123 only.
246+
* Currently, the remapping is implemented for GPUJPEG_4444_U8_P0123 and GPUJPEG_444_U8_P012.
247247
*/
248248
#define GPUJPEG_ENC_OPT_CHANNEL_REMAP "enc_opt_channel_remap"
249249

src/gpujpeg_encoder.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -670,22 +670,23 @@ enc_opt_set_channel_remap(struct gpujpeg_encoder* encoder, const char* val)
670670
return GPUJPEG_ERROR;
671671
}
672672
encoder->coder.preprocessor.channel_remap = 0; // clear old
673-
while ( *val != '\0' ) {
674-
encoder->coder.preprocessor.channel_remap >>= 4;
675-
int src_chan = *val - '0';
676-
if ( *val == 'F' ) {
673+
const char *ptr = val + strlen(val) - 1;
674+
while ( ptr >= val ) {
675+
int src_chan = *ptr - '0';
676+
if ( *ptr == 'F' ) {
677677
src_chan = 4;
678678
}
679-
else if ( *val == 'Z' ) {
679+
else if ( *ptr == 'Z' ) {
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", *val,
683+
ERROR_MSG("Invalid channel index %c for " GPUJPEG_ENC_OPT_CHANNEL_REMAP " (mapping %d channels)!\n", *ptr,
684684
mapped_count);
685685
return GPUJPEG_ERROR;
686686
}
687-
encoder->coder.preprocessor.channel_remap |= src_chan << 12;
688-
val++;
687+
encoder->coder.preprocessor.channel_remap <<= 4;
688+
encoder->coder.preprocessor.channel_remap |= src_chan;
689+
ptr--;
689690
}
690691
encoder->coder.preprocessor.channel_remap |= mapped_count << 24;
691692
return GPUJPEG_NOERR;

src/gpujpeg_preprocessor.cu

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,24 @@ channel_remap_kernel_4444_u8_p0123(uint8_t* data, int width, int pitch, int heig
523523
}
524524
}
525525

526+
__global__ void
527+
channel_remap_kernel_444_u8_p012(uint8_t* data, int width, int pitch, int height, unsigned int byte_map)
528+
{
529+
int x = blockIdx.x * blockDim.x + threadIdx.x; // column index
530+
int y = blockIdx.y * blockDim.y + threadIdx.y; // row index
531+
532+
if ( x >= width || y >= height ) {
533+
return;
534+
}
535+
536+
data += y * pitch + x * 3;
537+
uint32_t val = data[2] << 16 | data[1] << 8 | data[0];
538+
val = __byte_perm(val, 0xFF, byte_map);
539+
data[0] = val & 0xFF;
540+
data[1] = (val >> 8) & 0xFF;
541+
data[2] = val >> 16;
542+
}
543+
526544
static int
527545
channel_remap(struct gpujpeg_encoder* encoder)
528546
{
@@ -537,12 +555,13 @@ channel_remap(struct gpujpeg_encoder* encoder)
537555
}
538556
const unsigned mapping = coder->preprocessor.channel_remap & 0xFFFF;
539557

558+
dim3 block(16, 16);
559+
int width = coder->param_image.width;
560+
int height = coder->param_image.height;
561+
int pitch = (width * gpujpeg_pixel_format_get_comp_count(coder->param_image.pixel_format)) +
562+
coder->param_image.width_padding;
563+
dim3 grid((width + block.x - 1) / block.x, (height + block.y - 1) / block.y);
540564
if ( coder->param_image.pixel_format == GPUJPEG_4444_U8_P0123 ) {
541-
dim3 block(16, 16);
542-
int width = coder->param_image.width;
543-
int height = coder->param_image.height;
544-
dim3 grid((width + block.x - 1) / block.x, (height + block.y - 1) / block.y);
545-
int pitch = width * sizeof(uint32_t) + coder->param_image.width_padding;
546565
bool aligned = coder->param_image.width_padding % sizeof(uint32_t) == 0;
547566
if (aligned) {
548567
channel_remap_kernel_4444_u8_p0123<true><<<grid, block, 0, encoder->stream>>>(encoder->coder.d_data_raw, width,
@@ -552,8 +571,13 @@ channel_remap(struct gpujpeg_encoder* encoder)
552571
pitch, height, mapping);
553572
}
554573
}
574+
else if ( coder->param_image.pixel_format == GPUJPEG_444_U8_P012 ) {
575+
channel_remap_kernel_444_u8_p012<<<grid, block, 0, encoder->stream>>>(encoder->coder.d_data_raw, width, pitch,
576+
height, mapping);
577+
}
555578
else {
556-
ERROR_MSG("Pixel format %s currently unsupported for channel remap!\n",
579+
ERROR_MSG("Pixel format %s currently not supported for channel remap!\n"
580+
"444-u8-p012 and 4444-u8-p0123 are currently supported.\n",
557581
gpujpeg_pixel_format_get_name(coder->param_image.pixel_format));
558582
return -1;
559583
}

0 commit comments

Comments
 (0)