Skip to content

Commit 55aec0f

Browse files
committed
Bump OpenJPH
Signed-off-by: Pierre-Anthony Lemieux <pal@palemieux.com>
1 parent 437f5cd commit 55aec0f

25 files changed

Lines changed: 466 additions & 304 deletions

.github/workflows/ci_steps.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ jobs:
214214
if: inputs.OPENEXR_FORCE_INTERNAL_OPENJPH == 'OFF' && inputs.msystem == ''
215215
run: |
216216
set -x
217-
share/ci/scripts/install_openjph.sh 0.22.0
217+
share/ci/scripts/install_openjph.sh 0.27.3
218218
echo "OPENEXR_PATH=$OPENEXR_PATH:$PROGRAM_FILES/openjph/bin:$PROGRAM_FILES/openjph/lib" >> $GITHUB_ENV
219219
shell: bash
220220

MODULE.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ module(
99
bazel_dep(name = "bazel_skylib", version = "1.9.0")
1010
bazel_dep(name = "imath", version = "3.2.2.bcr.1")
1111
bazel_dep(name = "libdeflate", version = "1.25")
12-
bazel_dep(name = "openjph", version = "0.27.0")
12+
bazel_dep(name = "openjph", version = "0.27.3")
1313
bazel_dep(name = "platforms", version = "1.1.0")
1414
bazel_dep(name = "rules_cc", version = "0.2.18")

cmake/OpenEXRSetup.cmake

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,8 @@ option(OPENEXR_FORCE_INTERNAL_OPENJPH "Force downloading OpenJPH from a git repo
271271
if (NOT OPENEXR_FORCE_INTERNAL_OPENJPH)
272272
find_package(openjph CONFIG QUIET)
273273
if(openjph_FOUND)
274-
if(openjph_VERSION VERSION_LESS "0.21.0")
275-
message(FATAL_ERROR "OpenJPH >= 0.21.0 required, but found ${openjph_VERSION}")
274+
if(openjph_VERSION VERSION_LESS "0.27.3")
275+
message(FATAL_ERROR "OpenJPH >= 0.27.3 required, but found ${openjph_VERSION}")
276276
endif()
277277

278278
message(STATUS "Using OpenJPH ${openjph_VERSION} from ${openjph_DIR}")
@@ -282,7 +282,7 @@ if (NOT OPENEXR_FORCE_INTERNAL_OPENJPH)
282282
find_package(PkgConfig)
283283
if(PKG_CONFIG_FOUND)
284284
include(FindPkgConfig)
285-
pkg_check_modules(openjph IMPORTED_TARGET GLOBAL QUIET openjph=0.21)
285+
pkg_check_modules(openjph IMPORTED_TARGET GLOBAL QUIET openjph=0.27.3)
286286
if(openjph_FOUND)
287287
set(EXR_OPENJPH_LIB PkgConfig::openjph)
288288
message(STATUS "Using OpenJPH ${openjph_VERSION} from ${openjph_LINK_LIBRARIES}")
@@ -294,7 +294,7 @@ endif()
294294
if(EXR_OPENJPH_LIB)
295295
# Using external library
296296
# For OpenEXR.pc.in for static build
297-
set(EXR_OPENJPH_PKGCONFIG_REQUIRES "openjph >= 0.21.0")
297+
set(EXR_OPENJPH_PKGCONFIG_REQUIRES "openjph >= 0.27.3")
298298
else()
299299
# Using internal openjph
300300

external/OpenJPH/CMakeLists.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ option(OJPH_ENABLE_TIFF_SUPPORT "Enables input and output support for TIFF files
4040
option(OJPH_BUILD_TESTS "Enables building test code" OFF)
4141
option(OJPH_BUILD_EXECUTABLES "Enables building command line executables" ON)
4242
option(OJPH_BUILD_STREAM_EXPAND "Enables building ojph_stream_expand executable" OFF)
43+
option(OJPH_BUILD_FUZZER "Enables building oss-fuzzing target executable" OFF)
4344

4445
option(OJPH_DISABLE_SIMD "Disables the use of SIMD instructions -- agnostic to architectures" OFF)
4546
option(OJPH_DISABLE_SSE "Disables the use of SSE SIMD instructions and associated files" OFF)
@@ -230,10 +231,19 @@ install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc"
230231
)
231232

232233
################################################################################################
233-
# Testing (OJPH_BUILD_TESTS)
234+
# Testing and fuzzing (OJPH_BUILD_TESTS)
234235
################################################################################################
235236

236237
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND OJPH_BUILD_TESTS)
237238
enable_testing()
238239
add_subdirectory(tests)
239240
endif()
241+
242+
################################################################################################
243+
# Testing and fuzzing (OJPH_BUILD_FUZZER)
244+
################################################################################################
245+
246+
if(OJPH_BUILD_FUZZER)
247+
add_subdirectory(fuzzing)
248+
endif()
249+

external/OpenJPH/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ The standard is available free of charge from [ITU website](https://www.itu.int/
1818
* [Usage Example](./docs/usage_examples.md)
1919
* [Web-based Demos](./docs/web_demos.md)
2020
* [Doxygen Documentation Style](./docs/doxygen_style.md)
21+
* [OSS-Fuzzing](./docs/fuzzing.md)
2122

2223
# Repositories #
2324
[![Packaging status](https://repology.org/badge/vertical-allrepos/openjph.svg)](https://repology.org/project/openjph/versions)
24-

external/OpenJPH/src/core/codestream/ojph_codestream_local.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,17 @@ namespace ojph {
548548
ui32 num_comments)
549549
{
550550
//finalize
551-
siz.check_validity(cod);
551+
siz.set_cod(cod);
552+
// set the tile size if it was not set by the user
553+
size tile_size = siz.get_tile_size();
554+
if (tile_size.h == 0 && tile_size.w == 0)
555+
{
556+
point img_offset = siz.get_image_offset();
557+
point img_extent = siz.get_image_extent();
558+
size t(img_extent.x + img_offset.x, img_extent.y + img_offset.y);
559+
siz.set_tile_size(t);
560+
}
561+
siz.check_validity();
552562
cod.check_validity(siz);
553563
cod.update_atk(&atk);
554564
qcd.check_validity(siz, cod);

external/OpenJPH/src/core/codestream/ojph_params.cpp

Lines changed: 88 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -58,29 +58,25 @@ namespace ojph {
5858
////////////////////////////////////////////////////////////////////////////
5959
void param_siz::set_image_extent(point dims)
6060
{
61-
state->Xsiz = dims.x;
62-
state->Ysiz = dims.y;
61+
state->set_image_extent(dims);
6362
}
6463

6564
////////////////////////////////////////////////////////////////////////////
6665
void param_siz::set_tile_size(size s)
6766
{
68-
state->XTsiz = s.w;
69-
state->YTsiz = s.h;
67+
state->set_tile_size(s);
7068
}
7169

7270
////////////////////////////////////////////////////////////////////////////
7371
void param_siz::set_image_offset(point offset)
74-
{ // WARNING need to check if these are valid
75-
state->XOsiz = offset.x;
76-
state->YOsiz = offset.y;
72+
{
73+
state->set_image_offset(offset);
7774
}
7875

7976
////////////////////////////////////////////////////////////////////////////
8077
void param_siz::set_tile_offset(point offset)
81-
{ // WARNING need to check if these are valid
82-
state->XTOsiz = offset.x;
83-
state->YTOsiz = offset.y;
78+
{
79+
state->set_tile_offset(offset);
8480
}
8581

8682
////////////////////////////////////////////////////////////////////////////
@@ -703,24 +699,24 @@ namespace ojph {
703699
if (file->read(&Ysiz, 4) != 4)
704700
OJPH_ERROR(0x00050046, "error reading SIZ marker");
705701
Ysiz = swap_byte(Ysiz);
706-
if (file->read(&XOsiz, 4) != 4)
702+
ui32 t_XOsiz, t_YOsiz;
703+
if (file->read(&t_XOsiz, 4) != 4)
707704
OJPH_ERROR(0x00050047, "error reading SIZ marker");
708-
XOsiz = swap_byte(XOsiz);
709-
if (file->read(&YOsiz, 4) != 4)
705+
if (file->read(&t_YOsiz, 4) != 4)
710706
OJPH_ERROR(0x00050048, "error reading SIZ marker");
711-
YOsiz = swap_byte(YOsiz);
712-
if (file->read(&XTsiz, 4) != 4)
707+
set_image_offset(point(swap_byte(t_XOsiz), swap_byte(t_YOsiz)));
708+
ui32 t_XTsiz, t_YTsiz;
709+
if (file->read(&t_XTsiz, 4) != 4)
713710
OJPH_ERROR(0x00050049, "error reading SIZ marker");
714-
XTsiz = swap_byte(XTsiz);
715-
if (file->read(&YTsiz, 4) != 4)
711+
if (file->read(&t_YTsiz, 4) != 4)
716712
OJPH_ERROR(0x0005004A, "error reading SIZ marker");
717-
YTsiz = swap_byte(YTsiz);
718-
if (file->read(&XTOsiz, 4) != 4)
713+
set_tile_size(size(swap_byte(t_XTsiz), swap_byte(t_YTsiz)));
714+
ui32 t_XTOsiz, t_YTOsiz;
715+
if (file->read(&t_XTOsiz, 4) != 4)
719716
OJPH_ERROR(0x0005004B, "error reading SIZ marker");
720-
XTOsiz = swap_byte(XTOsiz);
721-
if (file->read(&YTOsiz, 4) != 4)
717+
if (file->read(&t_YTOsiz, 4) != 4)
722718
OJPH_ERROR(0x0005004C, "error reading SIZ marker");
723-
YTOsiz = swap_byte(YTOsiz);
719+
set_tile_offset(point(swap_byte(t_XTOsiz), swap_byte(t_YTOsiz)));
724720
if (file->read(&Csiz, 2) != 2)
725721
OJPH_ERROR(0x0005004D, "error reading SIZ marker");
726722
Csiz = swap_byte(Csiz);
@@ -745,6 +741,8 @@ namespace ojph {
745741

746742
ws_kern_support_needed = (Rsiz & 0x20) != 0;
747743
dfs_support_needed = (Rsiz & 0x80) != 0;
744+
745+
check_validity();
748746
}
749747

750748
//////////////////////////////////////////////////////////////////////////
@@ -994,10 +992,21 @@ namespace ojph {
994992
OJPH_ERROR(0x0005007E, "unsupported settings in a COD-SPcod parameter");
995993

996994
ui8 num_decompositions = get_num_decompositions();
997-
if (Scod & 1)
998-
for (int i = 0; i <= num_decompositions; ++i)
995+
if (Scod & 1) {
996+
for (int i = 0; i <= num_decompositions; ++i) {
999997
if (file->read(&SPcod.precinct_size[i], 1) != 1)
1000998
OJPH_ERROR(0x0005007B, "error reading COD segment");
999+
if (i)
1000+
if ((SPcod.precinct_size[i] & 0x0F) == 0 ||
1001+
(SPcod.precinct_size[i] >> 4) == 0)
1002+
OJPH_ERROR(0x0005007F,
1003+
"Precinct width or height for resolutions other than the"
1004+
" coarsest must be larger than 1; here, they are %d and %d,"
1005+
" respectively.",
1006+
1 << (SPcod.precinct_size[i] & 0x0F),
1007+
1 << (SPcod.precinct_size[i] >> 4));
1008+
}
1009+
}
10011010
if (Lcod != 12 + ((Scod & 1) ? 1 + SPcod.num_decomp : 0))
10021011
OJPH_ERROR(0x0005007C, "error in COD segment length");
10031012
}
@@ -1053,10 +1062,21 @@ namespace ojph {
10531062
OJPH_ERROR(0x0005012D, "unsupported settings in a COC-SPcoc parameter");
10541063

10551064
ui8 num_decompositions = get_num_decompositions();
1056-
if (Scod & 1)
1057-
for (int i = 0; i <= num_decompositions; ++i)
1065+
if (Scod & 1) {
1066+
for (int i = 0; i <= num_decompositions; ++i) {
10581067
if (file->read(&SPcod.precinct_size[i], 1) != 1)
10591068
OJPH_ERROR(0x0005012A, "error reading COC segment");
1069+
if (i)
1070+
if ((SPcod.precinct_size[i] & 0x0F) == 0 ||
1071+
(SPcod.precinct_size[i] >> 4) == 0)
1072+
OJPH_ERROR(0x0005012E,
1073+
"Precinct width or height for resolutions other than the"
1074+
" coarsest must be larger than 1; here, they are %d and %d,"
1075+
" respectively.",
1076+
1 << (SPcod.precinct_size[i] & 0x0F),
1077+
1 << (SPcod.precinct_size[i] >> 4));
1078+
}
1079+
}
10601080
ui32 t = 9;
10611081
t += num_comps < 257 ? 0 : 1;
10621082
t += (Scod & 1) ? 1 + num_decompositions : 0;
@@ -1196,8 +1216,10 @@ namespace ojph {
11961216
qcd_component < 3 ? employing_color_transform : false);
11971217
else if (qcd_wavelet_kern == param_cod::DWT_IRV97)
11981218
{
1199-
if (this->base_delta == -1.0f)
1200-
this->base_delta = 1.0f / (float)(1 << qcd_bit_depth);
1219+
if (this->base_delta == -1.0f) {
1220+
ui32 t = ojph_min(16, qcd_bit_depth);
1221+
this->base_delta = 1.0f / (float)(1 << t);
1222+
}
12011223
set_irrev_quant(qcd_num_decompositions);
12021224
}
12031225
else
@@ -1230,8 +1252,16 @@ namespace ojph {
12301252
c < 3 ? employing_color_transform : false);
12311253
else if (cp->get_wavelet_kern() == param_cod::DWT_IRV97)
12321254
{
1233-
if (qp->base_delta == -1.0f)
1234-
qp->base_delta = 1.0f / (float)(1 << bit_depth);
1255+
if (qp->base_delta == -1.0f) {
1256+
if (qcd_wavelet_kern == param_cod::DWT_IRV97) {
1257+
assert(this->base_delta != -1.0f);
1258+
qp->base_delta = this->base_delta;
1259+
}
1260+
else {
1261+
ui32 t = ojph_min(16, qcd_bit_depth);
1262+
qp->base_delta = 1.0f / (float)(1 << t);
1263+
}
1264+
}
12351265
qp->set_irrev_quant(num_decompositions);
12361266
}
12371267
else
@@ -1255,8 +1285,16 @@ namespace ojph {
12551285
c < 3 ? employing_color_transform : false);
12561286
else if (cp->get_wavelet_kern() == param_cod::DWT_IRV97)
12571287
{
1258-
if (qp->base_delta == -1.0f)
1259-
qp->base_delta = 1.0f / (float)(1 << bit_depth);
1288+
if (qp->base_delta == -1.0f) {
1289+
if (qcd_wavelet_kern == param_cod::DWT_IRV97) {
1290+
assert(this->base_delta != -1.0f);
1291+
qp->base_delta = this->base_delta;
1292+
}
1293+
else {
1294+
ui32 t = ojph_min(16, qcd_bit_depth);
1295+
qp->base_delta = 1.0f / (float)(1 << t);
1296+
}
1297+
}
12601298
qp->set_irrev_quant(num_decompositions);
12611299
}
12621300
else
@@ -1401,11 +1439,15 @@ namespace ojph {
14011439

14021440
//////////////////////////////////////////////////////////////////////////
14031441
float param_qcd::get_irrev_delta(const param_dfs* dfs,
1404-
ui32 num_decompositions,
1442+
ui32 num_decompositions, ui32 comp_num,
14051443
ui32 resolution, ui32 subband) const
14061444
{
14071445
float arr[] = { 1.0f, 2.0f, 2.0f, 4.0f };
1408-
assert((Sqcd & 0x1F) == 2);
1446+
if ((Sqcd & 0x1F) != 2)
1447+
OJPH_ERROR(0x00050101, "There is something wrong in the configuration "
1448+
"of the codestream; for component %d, the codestream defines an "
1449+
"irreversible transform, for which the codestream provides a "
1450+
"reversible (no quantization) step sizes in Sqcd/Sqcc.", comp_num);
14091451

14101452
ui32 idx;
14111453
if (dfs != NULL && dfs->exists())
@@ -1657,6 +1699,9 @@ namespace ojph {
16571699
if ((Sqcd & 0x1F) == 0)
16581700
{
16591701
num_subbands = (Lqcd - 3);
1702+
if (num_subbands == 0)
1703+
OJPH_ERROR(0x0005008A, "QCD marker segment that specifies no "
1704+
"quantization informtion");
16601705
if (num_subbands > 97 || Lqcd != 3 + num_subbands)
16611706
OJPH_ERROR(0x00050083, "wrong Lqcd value of %d in QCD marker", Lqcd);
16621707
for (ui32 i = 0; i < num_subbands; ++i)
@@ -1674,6 +1719,9 @@ namespace ojph {
16741719
else if ((Sqcd & 0x1F) == 2)
16751720
{
16761721
num_subbands = (Lqcd - 3) / 2;
1722+
if (num_subbands == 0)
1723+
OJPH_ERROR(0x0005008B, "QCD marker segment that specifies no "
1724+
"quantization informtion");
16771725
if (num_subbands > 97 || Lqcd != 3 + 2 * num_subbands)
16781726
OJPH_ERROR(0x00050086, "wrong Lqcd value of %d in QCD marker", Lqcd);
16791727
for (ui32 i = 0; i < num_subbands; ++i)
@@ -1712,6 +1760,9 @@ namespace ojph {
17121760
if ((Sqcd & 0x1F) == 0)
17131761
{
17141762
num_subbands = (Lqcd - offset);
1763+
if (num_subbands == 0)
1764+
OJPH_ERROR(0x000500AC, "QCC marker segment that specifies no "
1765+
"quantization informtion");
17151766
if (num_subbands > 97 || Lqcd != offset + num_subbands)
17161767
OJPH_ERROR(0x000500A5, "wrong Lqcd value of %d in QCC marker", Lqcd);
17171768
for (ui32 i = 0; i < num_subbands; ++i)
@@ -1729,6 +1780,9 @@ namespace ojph {
17291780
else if ((Sqcd & 0x1F) == 2)
17301781
{
17311782
num_subbands = (Lqcd - offset) / 2;
1783+
if (num_subbands == 0)
1784+
OJPH_ERROR(0x000500AD, "QCC marker segment that specifies no "
1785+
"quantization informtion");
17321786
if (num_subbands > 97 || Lqcd != offset + 2 * num_subbands)
17331787
OJPH_ERROR(0x000500A8, "wrong Lqcc value of %d in QCC marker", Lqcd);
17341788
for (ui32 i = 0; i < num_subbands; ++i)

external/OpenJPH/src/core/codestream/ojph_params_local.h

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -217,21 +217,35 @@ namespace ojph {
217217
cptr[comp_num].YRsiz = (ui8)downsampling.y;
218218
}
219219

220-
void check_validity(const param_cod& cod)
220+
void set_image_extent(point dims) { Xsiz = dims.x; Ysiz = dims.y; }
221+
point get_image_extent() const { return point(Xsiz, Ysiz); }
222+
void set_tile_size(size s) { XTsiz = s.w; YTsiz = s.h; }
223+
size get_tile_size() const { return size(XTsiz, YTsiz); }
224+
void set_image_offset(point offset)
225+
{ XOsiz = offset.x; YOsiz = offset.y; }
226+
point get_image_offset() const
227+
{ return point(XOsiz, YOsiz); }
228+
void set_tile_offset(point offset)
229+
{ XTOsiz = offset.x; YTOsiz = offset.y; }
230+
point get_tile_offset() const
231+
{ return point(XTOsiz, YTOsiz); }
232+
233+
void set_cod(const param_cod& cod) { this->cod = &cod; }
234+
235+
void check_validity()
221236
{
222-
this->cod = &cod;
223-
224-
if (XTsiz == 0 && YTsiz == 0)
225-
{ XTsiz = Xsiz + XOsiz; YTsiz = Ysiz + YOsiz; }
226237
if (Xsiz == 0 || Ysiz == 0 || XTsiz == 0 || YTsiz == 0)
227238
OJPH_ERROR(0x00040001,
228-
"You cannot set image extent nor tile size to zero");
239+
"Image extent and/or tile size cannot be zero");
229240
if (XTOsiz > XOsiz || YTOsiz > YOsiz)
230241
OJPH_ERROR(0x00040002,
231-
"tile offset has to be smaller than image offset");
242+
"Tile offset has to be smaller than the image offset");
232243
if (XTsiz + XTOsiz <= XOsiz || YTsiz + YTOsiz <= YOsiz)
233244
OJPH_ERROR(0x00040003,
234-
"the top left tile must intersect with the image");
245+
"The top left tile must intersect with the image");
246+
if (Xsiz <= XOsiz || Ysiz <= YOsiz)
247+
OJPH_ERROR(0x00040004,
248+
"The image extent must be larger than the image offset");
235249
}
236250

237251
ui16 get_num_components() const { return Csiz; }
@@ -701,7 +715,7 @@ namespace ojph {
701715
ui32 resolution, ui32 subband) const;
702716
ui32 propose_precision(const param_cod* cod) const;
703717
float get_irrev_delta(const param_dfs* dfs,
704-
ui32 num_decompositions,
718+
ui32 num_decompositions, ui32 comp_num,
705719
ui32 resolution, ui32 subband) const;
706720
bool write(outfile_base *file);
707721
bool write_qcc(outfile_base *file, ui32 num_comps);

0 commit comments

Comments
 (0)