Skip to content

Commit 7de2626

Browse files
committed
add option for bottom-up images
refers to GH-100
1 parent 6a79a22 commit 7de2626

File tree

7 files changed

+70
-7
lines changed

7 files changed

+70
-7
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.6 LANGUAGES C CUDA)
3+
project(gpujpeg VERSION 0.27.7 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-07-10 - 0.27.7
2+
----------
3+
4+
- add encoder option for vertically flipped images
5+
16
2025-07-08 - 0.27.6
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.6],[https://github.com/CESNET/GPUJPEG/issues],[libgpujpeg],[https://github.com/CESNET/GPUJPEG])
3+
AC_INIT([libgpujpeg],[0.27.7],[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_encoder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ gpujpeg_encoder_suggest_restart_interval(const struct gpujpeg_image_parameters*
231231
#define GPUJPEG_ENC_HDR_VAL_SPIFF "SPIFF"
232232
/// @}
233233

234+
/// input image is vertically flipped (bottom-up): values @ref GPUJPEG_VAL_TRUE or @ref GPUJPEG_VAL_FALSE
235+
#define GPUJPEG_ENC_OPT_FLIPPED_BOOL "enc_opt_flipped"
236+
234237
/**
235238
* sets encoder option
236239
* @retval GPUJPEG_NOERR option was sucessfully set

src/gpujpeg_encoder.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,19 @@ gpujpeg_encoder_set_option(struct gpujpeg_encoder* encoder, const char *opt, con
688688
}
689689
return GPUJPEG_NOERR;
690690
}
691+
if ( strcmp(opt, GPUJPEG_ENC_OPT_FLIPPED_BOOL) == 0 ) {
692+
if ( strcasecmp(val, GPUJPEG_VAL_TRUE) == 0 ) {
693+
encoder->coder.preprocessor.input_flipped = true;
694+
}
695+
else if ( strcasecmp(val, GPUJPEG_VAL_FALSE) == 0 ) {
696+
encoder->coder.preprocessor.input_flipped = false;
697+
}
698+
else {
699+
ERROR_MSG("Unknown option %s for " GPUJPEG_ENC_OPT_FLIPPED_BOOL "\n", val);
700+
return GPUJPEG_ERROR;
701+
}
702+
return GPUJPEG_NOERR;
703+
}
691704
ERROR_MSG("Invalid encoder option: %s!\n", opt);
692705
return GPUJPEG_ERROR;
693706
}

src/gpujpeg_preprocessor.cu

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -461,20 +461,57 @@ gpujpeg_preprocessor_encoder_copy_planar_data(struct gpujpeg_encoder * encoder)
461461
return 0;
462462
}
463463

464+
static __global__ void
465+
vertical_flip_kernel(uint32_t* data,
466+
int width, // image linesize/4
467+
int height // image height in pixels
468+
)
469+
{
470+
int x = blockIdx.x * blockDim.x + threadIdx.x; // column index
471+
int y = blockIdx.y * blockDim.y + threadIdx.y; // row index
472+
473+
if ( x < width ) {
474+
// Flipped row index
475+
int flipped_y = height - 1 - y;
476+
uint32_t tmp = data[y * width + x];
477+
data[y * width + x] = data[flipped_y * width + x];
478+
data[flipped_y * width + x] = tmp;
479+
}
480+
}
481+
482+
static int
483+
flip_lines(struct gpujpeg_encoder* encoder)
484+
{
485+
struct gpujpeg_coder* coder = &encoder->coder;
486+
for ( int i = 0; i < coder->param.comp_count; ++i ) {
487+
dim3 block(RGB_8BIT_THREADS, 1);
488+
int width = coder->component[i].data_width / 4;
489+
int height = coder->component[i].data_height;
490+
dim3 grid((width + block.x - 1) / block.x, height / 2); // only half of height
491+
vertical_flip_kernel<<<grid, block, 0, encoder->stream>>>((uint32_t*)coder->component[i].d_data, width, height);
492+
}
493+
gpujpeg_cuda_check_error("Preprocessor flip failed", return -1);
494+
return 0;
495+
}
496+
464497
/* Documented at declaration */
465498
int
466499
gpujpeg_preprocessor_encode(struct gpujpeg_encoder * encoder)
467500
{
468501
struct gpujpeg_coder * coder = &encoder->coder;
469502
/// @todo support padding for other formats
470-
assert(!coder->param_image.width_padding ||
503+
assert(coder->param_image.width_padding == 0 ||
471504
(coder->param_image.pixel_format == GPUJPEG_444_U8_P012 && coder->preprocessor.kernel != nullptr));
472505

473-
if (coder->preprocessor.kernel != nullptr) {
474-
return gpujpeg_preprocessor_encode_interlaced(encoder);
475-
} else {
476-
return gpujpeg_preprocessor_encoder_copy_planar_data(encoder);
506+
int ret = coder->preprocessor.kernel != nullptr ? gpujpeg_preprocessor_encode_interlaced(encoder)
507+
: gpujpeg_preprocessor_encoder_copy_planar_data(encoder);
508+
if (ret != 0) {
509+
return ret;
510+
}
511+
if (coder->preprocessor.input_flipped) {
512+
return flip_lines(encoder);
477513
}
514+
return ret;
478515
}
479516

480517
/* vi: set expandtab sw=4: */

src/gpujpeg_preprocessor_common.cuh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
#include "../libgpujpeg/gpujpeg_common.h"
3434
#include "../libgpujpeg/gpujpeg_type.h"
3535

36+
#ifndef __cplusplus
37+
#include <stdbool.h>
38+
#endif
39+
3640
#define RGB_8BIT_THREADS 256
3741

3842
/**
@@ -55,6 +59,7 @@ struct gpujpeg_preprocessor_data
5559

5660
struct gpujpeg_preprocessor {
5761
void* kernel; // function poitner
62+
bool input_flipped; // [preprocess only] input is flipped
5863
struct gpujpeg_preprocessor_data data;
5964
};
6065

0 commit comments

Comments
 (0)