@@ -494,6 +494,47 @@ flip_lines(struct gpujpeg_encoder* encoder)
494494 return 0 ;
495495}
496496
497+ template <enum gpujpeg_pixel_format>
498+ __global__ void
499+ channel_remap_kernel (uint8_t * data, int width, int height, unsigned int byte_map);
500+
501+ template <>
502+ __global__ void
503+ channel_remap_kernel<GPUJPEG_4444_U8_P0123>(uint8_t * data, int width, int height, unsigned int byte_map)
504+ {
505+ int x = blockIdx .x * blockDim .x + threadIdx .x ; // column index
506+ int y = blockIdx .y * blockDim .y + threadIdx .y ; // row index
507+
508+ if ( x >= width || y >= height ) {
509+ return ;
510+ }
511+
512+ uint32_t * data32 = (uint32_t *)data;
513+ uint32_t val = data32[y * width + x];
514+ data32[y * width + x] = __byte_perm (val, 0xFF , byte_map);
515+ }
516+
517+ static int
518+ channel_remap (struct gpujpeg_encoder * encoder)
519+ {
520+ struct gpujpeg_coder * coder = &encoder->coder ;
521+ if ( coder->param_image .pixel_format == GPUJPEG_4444_U8_P0123 ) {
522+ dim3 block (16 , 16 );
523+ int width = coder->param_image .width ;
524+ int height = coder->param_image .height ;
525+ dim3 grid ((width + block.x - 1 ) / block.x , (height + block.y - 1 ) / block.y );
526+ channel_remap_kernel<GPUJPEG_4444_U8_P0123><<<grid, block, 0 , encoder->stream>>> (
527+ encoder->coder .d_data_raw , width, height, coder->preprocessor .channel_remap );
528+ }
529+ else {
530+ ERROR_MSG (" Pixel format %s currently unsupported for channel remap!\n " ,
531+ gpujpeg_pixel_format_get_name (coder->param_image .pixel_format ));
532+ return -1 ;
533+ }
534+ gpujpeg_cuda_check_error (" channel_remap_kernel failed" , return -1 );
535+ return 0 ;
536+ }
537+
497538/* Documented at declaration */
498539int
499540gpujpeg_preprocessor_encode (struct gpujpeg_encoder * encoder)
@@ -503,6 +544,13 @@ gpujpeg_preprocessor_encode(struct gpujpeg_encoder * encoder)
503544 assert (coder->param_image .width_padding == 0 ||
504545 (coder->param_image .pixel_format == GPUJPEG_444_U8_P012 && coder->preprocessor .kernel != nullptr ));
505546
547+ if ( coder->preprocessor .channel_remap != 0 ) {
548+ const int ret = channel_remap (encoder);
549+ if ( ret != 0 ) {
550+ return ret;
551+ }
552+ }
553+
506554 int ret = coder->preprocessor .kernel != nullptr ? gpujpeg_preprocessor_encode_interlaced (encoder)
507555 : gpujpeg_preprocessor_encoder_copy_planar_data (encoder);
508556 if (ret != 0 ) {
0 commit comments