Merge pull request #19660 from alalek:update_openjpeg

pull/19664/head
Alexander Alekhin 4 years ago
commit 6fbf93750b
  1. 87
      3rdparty/openjpeg/CHANGELOG.md
  2. 5
      3rdparty/openjpeg/CMakeLists.txt
  3. 6
      3rdparty/openjpeg/openjp2/CMakeLists.txt
  4. 1768
      3rdparty/openjpeg/openjp2/dwt.c
  5. 20
      3rdparty/openjpeg/openjp2/dwt.h
  6. 1189
      3rdparty/openjpeg/openjp2/j2k.c
  7. 28
      3rdparty/openjpeg/openjp2/j2k.h
  8. 22
      3rdparty/openjpeg/openjp2/jp2.c
  9. 14
      3rdparty/openjpeg/openjp2/jp2.h
  10. 14
      3rdparty/openjpeg/openjp2/libopenjp2.pc.cmake.in
  11. 215
      3rdparty/openjpeg/openjp2/mct.c
  12. 5
      3rdparty/openjpeg/openjp2/mct.h
  13. 176
      3rdparty/openjpeg/openjp2/mqc.c
  14. 9
      3rdparty/openjpeg/openjp2/mqc.h
  15. 90
      3rdparty/openjpeg/openjp2/mqc_inl.h
  16. 45
      3rdparty/openjpeg/openjp2/openjpeg.c
  17. 86
      3rdparty/openjpeg/openjp2/openjpeg.h
  18. 5
      3rdparty/openjpeg/openjp2/opj_codec.h
  19. 6
      3rdparty/openjpeg/openjp2/opj_common.h
  20. 10
      3rdparty/openjpeg/openjp2/opj_intmath.h
  21. 457
      3rdparty/openjpeg/openjp2/pi.c
  22. 25
      3rdparty/openjpeg/openjp2/pi.h
  23. 863
      3rdparty/openjpeg/openjp2/t1.c
  24. 5
      3rdparty/openjpeg/openjp2/t1.h
  25. 50
      3rdparty/openjpeg/openjp2/t2.c
  26. 2
      3rdparty/openjpeg/openjp2/t2.h
  27. 155
      3rdparty/openjpeg/openjp2/tcd.c
  28. 41
      3rdparty/openjpeg/openjp2/tcd.h

@ -1,5 +1,92 @@
# Changelog
## [v2.4.0](https://github.com/uclouvain/openjpeg/releases/v2.4.0) (2020-12-28)
[Full Changelog](https://github.com/uclouvain/openjpeg/compare/v2.3.1...v2.4.0)
**Closed issues:**
- OPENJPEG\_INSTALL\_DOC\_DIR does not control a destination directory where HTML docs would be installed. [\#1309](https://github.com/uclouvain/openjpeg/issues/1309)
- Heap-buffer-overflow in lib/openjp2/pi.c:312 [\#1302](https://github.com/uclouvain/openjpeg/issues/1302)
- Heap-buffer-overflow in lib/openjp2/t2.c:973 [\#1299](https://github.com/uclouvain/openjpeg/issues/1299)
- Heap-buffer-overflow in lib/openjp2/pi.c:623 [\#1293](https://github.com/uclouvain/openjpeg/issues/1293)
- Global-buffer-overflow in lib/openjp2/dwt.c:1980 [\#1286](https://github.com/uclouvain/openjpeg/issues/1286)
- Heap-buffer-overflow in lib/openjp2/tcd.c:2417 [\#1284](https://github.com/uclouvain/openjpeg/issues/1284)
- Heap-buffer-overflow in lib/openjp2/mqc.c:499 [\#1283](https://github.com/uclouvain/openjpeg/issues/1283)
- Openjpeg could not encode 32bit RGB float image [\#1281](https://github.com/uclouvain/openjpeg/issues/1281)
- Openjpeg could not encode 32bit RGB float image [\#1280](https://github.com/uclouvain/openjpeg/issues/1280)
- ISO/IEC 15444-1:2019 \(E\) compared with 'cio.h' [\#1277](https://github.com/uclouvain/openjpeg/issues/1277)
- Test-suite failure due to hash mismatch [\#1264](https://github.com/uclouvain/openjpeg/issues/1264)
- Heap use-after-free [\#1261](https://github.com/uclouvain/openjpeg/issues/1261)
- Memory leak when failing to allocate object... [\#1259](https://github.com/uclouvain/openjpeg/issues/1259)
- Memory leak of Tier 1 handle when OpenJPEG fails to set it as TLS... [\#1257](https://github.com/uclouvain/openjpeg/issues/1257)
- Any plan to build release for CVE-2020-8112/CVE-2020-6851 [\#1247](https://github.com/uclouvain/openjpeg/issues/1247)
- failing to convert 16-bit file: opj\_t2\_encode\_packet\(\): only 5251 bytes remaining in output buffer. 5621 needed. [\#1243](https://github.com/uclouvain/openjpeg/issues/1243)
- CMake+VS2017 Compile OK, thirdparty Compile OK, but thirdparty not install [\#1239](https://github.com/uclouvain/openjpeg/issues/1239)
- New release to solve CVE-2019-6988 ? [\#1238](https://github.com/uclouvain/openjpeg/issues/1238)
- Many tests fail to pass after the update of libtiff to version 4.1.0 [\#1233](https://github.com/uclouvain/openjpeg/issues/1233)
- Another heap buffer overflow in libopenjp2 [\#1231](https://github.com/uclouvain/openjpeg/issues/1231)
- Heap buffer overflow in libopenjp2 [\#1228](https://github.com/uclouvain/openjpeg/issues/1228)
- Endianness of binary volume \(JP3D\) [\#1224](https://github.com/uclouvain/openjpeg/issues/1224)
- New release to resolve CVE-2019-12973 [\#1222](https://github.com/uclouvain/openjpeg/issues/1222)
- how to set the block size,like 128,256 ? [\#1216](https://github.com/uclouvain/openjpeg/issues/1216)
- compress YUV files to motion jpeg2000 standard [\#1213](https://github.com/uclouvain/openjpeg/issues/1213)
- Repair/update Java wrapper, and include in release [\#1208](https://github.com/uclouvain/openjpeg/issues/1208)
- abc [\#1206](https://github.com/uclouvain/openjpeg/issues/1206)
- Slow decoding [\#1202](https://github.com/uclouvain/openjpeg/issues/1202)
- Installation question [\#1201](https://github.com/uclouvain/openjpeg/issues/1201)
- Typo in test\_decode\_area - \*ptilew is assigned instead of \*ptileh [\#1195](https://github.com/uclouvain/openjpeg/issues/1195)
- Creating a J2K file with one POC is broken [\#1191](https://github.com/uclouvain/openjpeg/issues/1191)
- Make fails on Arch Linux [\#1174](https://github.com/uclouvain/openjpeg/issues/1174)
- Heap buffer overflow in opj\_t1\_clbl\_decode\_processor\(\) triggered with Ghostscript [\#1158](https://github.com/uclouvain/openjpeg/issues/1158)
- opj\_stream\_get\_number\_byte\_left: Assertion `p\_stream-\>m\_byte\_offset \>= 0' failed. [\#1151](https://github.com/uclouvain/openjpeg/issues/1151)
- The fuzzer ignores too many inputs [\#1079](https://github.com/uclouvain/openjpeg/issues/1079)
- out of bounds read [\#1068](https://github.com/uclouvain/openjpeg/issues/1068)
**Merged pull requests:**
- Change defined WIN32 [\#1310](https://github.com/uclouvain/openjpeg/pull/1310) ([Jamaika1](https://github.com/Jamaika1))
- docs: fix simple typo, producted -\> produced [\#1308](https://github.com/uclouvain/openjpeg/pull/1308) ([timgates42](https://github.com/timgates42))
- Set ${OPENJPEG\_INSTALL\_DOC\_DIR} to DESTINATION of HTMLs [\#1307](https://github.com/uclouvain/openjpeg/pull/1307) ([lemniscati](https://github.com/lemniscati))
- Use INC\_DIR for OPENJPEG\_INCLUDE\_DIRS \(fixes uclouvain\#1174\) [\#1306](https://github.com/uclouvain/openjpeg/pull/1306) ([matthew-sharp](https://github.com/matthew-sharp))
- pi.c: avoid out of bounds access with POC \(fixes \#1302\) [\#1304](https://github.com/uclouvain/openjpeg/pull/1304) ([rouault](https://github.com/rouault))
- Encoder: grow again buffer size [\#1303](https://github.com/uclouvain/openjpeg/pull/1303) ([zodf0055980](https://github.com/zodf0055980))
- opj\_j2k\_write\_sod\(\): avoid potential heap buffer overflow \(fixes \#1299\) \(probably master only\) [\#1301](https://github.com/uclouvain/openjpeg/pull/1301) ([rouault](https://github.com/rouault))
- pi.c: avoid out of bounds access with POC \(refs https://github.com/uclouvain/openjpeg/issues/1293\#issuecomment-737122836\) [\#1300](https://github.com/uclouvain/openjpeg/pull/1300) ([rouault](https://github.com/rouault))
- opj\_t2\_encode\_packet\(\): avoid out of bound access of \#1297, but likely not the proper fix [\#1298](https://github.com/uclouvain/openjpeg/pull/1298) ([rouault](https://github.com/rouault))
- opj\_t2\_encode\_packet\(\): avoid out of bound access of \#1294, but likely not the proper fix [\#1296](https://github.com/uclouvain/openjpeg/pull/1296) ([rouault](https://github.com/rouault))
- opj\_j2k\_setup\_encoder\(\): validate POC compno0 and compno1 \(fixes \#1293\) [\#1295](https://github.com/uclouvain/openjpeg/pull/1295) ([rouault](https://github.com/rouault))
- Encoder: avoid global buffer overflow on irreversible conversion when… [\#1292](https://github.com/uclouvain/openjpeg/pull/1292) ([rouault](https://github.com/rouault))
- Decoding: deal with some SPOT6 images that have tiles with a single tile-part with TPsot == 0 and TNsot == 0, and with missing EOC [\#1291](https://github.com/uclouvain/openjpeg/pull/1291) ([rouault](https://github.com/rouault))
- Free p\_tcd\_marker\_info to avoid memory leak [\#1288](https://github.com/uclouvain/openjpeg/pull/1288) ([zodf0055980](https://github.com/zodf0055980))
- Encoder: grow again buffer size [\#1287](https://github.com/uclouvain/openjpeg/pull/1287) ([zodf0055980](https://github.com/zodf0055980))
- Encoder: avoid uint32 overflow when allocating memory for codestream buffer \(fixes \#1243\) [\#1276](https://github.com/uclouvain/openjpeg/pull/1276) ([rouault](https://github.com/rouault))
- Java compatibility from 1.5 to 1.6 [\#1263](https://github.com/uclouvain/openjpeg/pull/1263) ([jiapei100](https://github.com/jiapei100))
- opj\_decompress: fix double-free on input directory with mix of valid and invalid images [\#1262](https://github.com/uclouvain/openjpeg/pull/1262) ([rouault](https://github.com/rouault))
- openjp2: Plug image leak when failing to allocate codestream index. [\#1260](https://github.com/uclouvain/openjpeg/pull/1260) ([sebras](https://github.com/sebras))
- openjp2: Plug memory leak when setting data as TLS fails. [\#1258](https://github.com/uclouvain/openjpeg/pull/1258) ([sebras](https://github.com/sebras))
- openjp2: Error out if failing to create Tier 1 handle. [\#1256](https://github.com/uclouvain/openjpeg/pull/1256) ([sebras](https://github.com/sebras))
- Testing for invalid values of width, height, numcomps [\#1254](https://github.com/uclouvain/openjpeg/pull/1254) ([szukw000](https://github.com/szukw000))
- Single-threaded performance improvements in forward DWT for 5-3 and 9-7 \(and other improvements\) [\#1253](https://github.com/uclouvain/openjpeg/pull/1253) ([rouault](https://github.com/rouault))
- Add support for multithreading in encoder [\#1248](https://github.com/uclouvain/openjpeg/pull/1248) ([rouault](https://github.com/rouault))
- Add support for generation of PLT markers in encoder [\#1246](https://github.com/uclouvain/openjpeg/pull/1246) ([rouault](https://github.com/rouault))
- Fix warnings about signed/unsigned casts in pi.c [\#1244](https://github.com/uclouvain/openjpeg/pull/1244) ([rouault](https://github.com/rouault))
- opj\_decompress: add sanity checks to avoid segfault in case of decoding error [\#1240](https://github.com/uclouvain/openjpeg/pull/1240) ([rouault](https://github.com/rouault))
- ignore wrong icc [\#1236](https://github.com/uclouvain/openjpeg/pull/1236) ([szukw000](https://github.com/szukw000))
- Implement writing of IMF profiles [\#1235](https://github.com/uclouvain/openjpeg/pull/1235) ([rouault](https://github.com/rouault))
- tests: add alternate checksums for libtiff 4.1 [\#1234](https://github.com/uclouvain/openjpeg/pull/1234) ([rouault](https://github.com/rouault))
- opj\_tcd\_init\_tile\(\): avoid integer overflow [\#1232](https://github.com/uclouvain/openjpeg/pull/1232) ([rouault](https://github.com/rouault))
- tests/fuzzers: link fuzz binaries using $LIB\_FUZZING\_ENGINE. [\#1230](https://github.com/uclouvain/openjpeg/pull/1230) ([Dor1s](https://github.com/Dor1s))
- opj\_j2k\_update\_image\_dimensions\(\): reject images whose coordinates are beyond INT\_MAX \(fixes \#1228\) [\#1229](https://github.com/uclouvain/openjpeg/pull/1229) ([rouault](https://github.com/rouault))
- Fix resource leaks [\#1226](https://github.com/uclouvain/openjpeg/pull/1226) ([dodys](https://github.com/dodys))
- abi-check.sh: fix false postive ABI error, and display output error log [\#1218](https://github.com/uclouvain/openjpeg/pull/1218) ([rouault](https://github.com/rouault))
- pi.c: avoid integer overflow, resulting in later invalid access to memory in opj\_t2\_decode\_packets\(\) [\#1217](https://github.com/uclouvain/openjpeg/pull/1217) ([rouault](https://github.com/rouault))
- Add check to validate SGcod/SPcoc/SPcod parameter values. [\#1211](https://github.com/uclouvain/openjpeg/pull/1211) ([sebras](https://github.com/sebras))
- Fix buffer overflow reading an image file less than four characters [\#1196](https://github.com/uclouvain/openjpeg/pull/1196) ([robert-ancell](https://github.com/robert-ancell))
- compression: emit POC marker when only one single POC is requested \(f… [\#1192](https://github.com/uclouvain/openjpeg/pull/1192) ([rouault](https://github.com/rouault))
- Fix several potential vulnerabilities [\#1185](https://github.com/uclouvain/openjpeg/pull/1185) ([Young-X](https://github.com/Young-X))
- openjp2/j2k: Report error if all wanted components are not decoded. [\#1164](https://github.com/uclouvain/openjpeg/pull/1164) ([sebras](https://github.com/sebras))
## [v2.3.1](https://github.com/uclouvain/openjpeg/releases/v2.3.1) (2019-04-02)
[Full Changelog](https://github.com/uclouvain/openjpeg/compare/v2.3.0...v2.3.1)

@ -18,8 +18,8 @@ ocv_warnings_disable(CMAKE_C_FLAGS
#-----------------------------------------------------------------------------
# OPENJPEG version number, useful for packaging and doxygen doc:
set(OPENJPEG_VERSION_MAJOR 2)
set(OPENJPEG_VERSION_MINOR 3)
set(OPENJPEG_VERSION_BUILD 1)
set(OPENJPEG_VERSION_MINOR 4)
set(OPENJPEG_VERSION_BUILD 0)
set(OPENJPEG_VERSION
"${OPENJPEG_VERSION_MAJOR}.${OPENJPEG_VERSION_MINOR}.${OPENJPEG_VERSION_BUILD}")
set(PACKAGE_VERSION
@ -43,6 +43,7 @@ set(PACKAGE_VERSION
# 2.2.0 | 7
# 2.3.0 | 7
# 2.3.1 | 7
# 2.4.0 | 7
# above is the recommendation by the OPJ team. If you really need to override this default,
# you can specify your own OPENJPEG_SOVERSION at cmake configuration time:
# cmake -DOPENJPEG_SOVERSION:STRING=42 /path/to/openjpeg

@ -33,7 +33,11 @@ endif()
# set(WIN32 YES)
# endif()
ocv_warnings_disable(CMAKE_C_FLAGS -Wundef -Wstrict-prototypes -Wcast-function-type)
ocv_warnings_disable(CMAKE_C_FLAGS
-Wundef -Wstrict-prototypes -Wcast-function-type
-Wshadow # v2.4.0: GCC
-Wunused-function # v2.4.0: Clang
)
add_library(${OPENJPEG_LIBRARY_NAME} STATIC ${OPENJPEG_SRCS})

File diff suppressed because it is too large Load Diff

@ -56,9 +56,11 @@ DWT.C are used by some function in TCD.C.
/**
Forward 5-3 wavelet transform in 2-D.
Apply a reversible DWT transform to a component of an image.
@param p_tcd TCD handle
@param tilec Tile component information (current tile)
*/
OPJ_BOOL opj_dwt_encode(opj_tcd_tilecomp_t * tilec);
OPJ_BOOL opj_dwt_encode(opj_tcd_t *p_tcd,
opj_tcd_tilecomp_t * tilec);
/**
Inverse 5-3 wavelet transform in 2-D.
@ -71,12 +73,6 @@ OPJ_BOOL opj_dwt_decode(opj_tcd_t *p_tcd,
opj_tcd_tilecomp_t* tilec,
OPJ_UINT32 numres);
/**
Get the gain of a subband for the reversible 5-3 DWT.
@param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH)
@return Returns 0 if orient = 0, returns 1 if orient = 1 or 2, returns 2 otherwise
*/
OPJ_UINT32 opj_dwt_getgain(OPJ_UINT32 orient) ;
/**
Get the norm of a wavelet function of a subband at a specified level for the reversible 5-3 DWT.
@param level Level of the wavelet function
@ -87,9 +83,11 @@ OPJ_FLOAT64 opj_dwt_getnorm(OPJ_UINT32 level, OPJ_UINT32 orient);
/**
Forward 9-7 wavelet transform in 2-D.
Apply an irreversible DWT transform to a component of an image.
@param p_tcd TCD handle
@param tilec Tile component information (current tile)
*/
OPJ_BOOL opj_dwt_encode_real(opj_tcd_tilecomp_t * tilec);
OPJ_BOOL opj_dwt_encode_real(opj_tcd_t *p_tcd,
opj_tcd_tilecomp_t * tilec);
/**
Inverse 9-7 wavelet transform in 2-D.
Apply an irreversible inverse DWT transform to a component of an image.
@ -101,12 +99,6 @@ OPJ_BOOL opj_dwt_decode_real(opj_tcd_t *p_tcd,
opj_tcd_tilecomp_t* OPJ_RESTRICT tilec,
OPJ_UINT32 numres);
/**
Get the gain of a subband for the irreversible 9-7 DWT.
@param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH)
@return Returns the gain of the 9-7 wavelet transform
*/
OPJ_UINT32 opj_dwt_getgain_real(OPJ_UINT32 orient);
/**
Get the norm of a wavelet function of a subband at a specified level for the irreversible 9-7 DWT
@param level Level of the wavelet function

File diff suppressed because it is too large Load Diff

@ -531,8 +531,14 @@ typedef struct opj_j2k_enc {
OPJ_BYTE * m_header_tile_data;
/* size of the encoded_data */
OPJ_UINT32 m_header_tile_data_size;
/* whether to generate PLT markers */
OPJ_BOOL m_PLT;
/* reserved bytes in m_encoded_tile_size for PLT markers */
OPJ_UINT32 m_reserved_bytes_for_PLT;
} opj_j2k_enc_t;
@ -577,15 +583,16 @@ typedef struct opj_j2k {
/** the current tile coder/decoder **/
struct opj_tcd * m_tcd;
/** Number of threads to use */
int m_num_threads;
/** Thread pool */
opj_thread_pool_t* m_tp;
/** Image width coming from JP2 IHDR box. 0 from a pure codestream */
OPJ_UINT32 ihdr_w;
/** Image height coming from JP2 IHDR box. 0 from a pure codestream */
OPJ_UINT32 ihdr_h;
OPJ_UINT32 enumcs;
/** Set to 1 by the decoder initialization if OPJ_DPARAMETERS_DUMP_FLAG is set */
unsigned int dump_state;
}
opj_j2k_t;
@ -827,6 +834,19 @@ OPJ_BOOL opj_j2k_set_decoded_resolution_factor(opj_j2k_t *p_j2k,
OPJ_UINT32 res_factor,
opj_event_mgr_t * p_manager);
/**
* Specify extra options for the encoder.
*
* @param p_j2k the jpeg2000 codec.
* @param p_options options
* @param p_manager the user event manager
*
* @see opj_encoder_set_extra_options() for more details.
*/
OPJ_BOOL opj_j2k_encoder_set_extra_options(
opj_j2k_t *p_j2k,
const char* const* p_options,
opj_event_mgr_t * p_manager);
/**
* Writes a tile.

@ -586,6 +586,12 @@ static OPJ_BOOL opj_jp2_read_ihdr(opj_jp2_t *jp2,
opj_read_bytes(p_image_header_data, &(jp2->numcomps), 2); /* NC */
p_image_header_data += 2;
if (jp2->h < 1 || jp2->w < 1 || jp2->numcomps < 1) {
opj_event_msg(p_manager, EVT_ERROR,
"Wrong values for: w(%d) h(%d) numcomps(%d) (ihdr)\n",
jp2->w, jp2->h, jp2->numcomps);
return OPJ_FALSE;
}
if ((jp2->numcomps - 1U) >=
16384U) { /* unsigned underflow is well defined: 1U <= jp2->numcomps <= 16384U */
opj_event_msg(p_manager, EVT_ERROR, "Invalid number of components (ihdr)\n");
@ -1584,9 +1590,7 @@ static OPJ_BOOL opj_jp2_read_colr(opj_jp2_t *jp2,
"COLR BOX meth value is not a regular value (%d), "
"so we will ignore the entire Colour Specification box. \n", jp2->meth);
}
if (jp2->color.jp2_has_colr) {
jp2->j2k->enumcs = jp2->enumcs;
}
return OPJ_TRUE;
}
@ -3236,6 +3240,18 @@ OPJ_BOOL opj_jp2_set_decoded_resolution_factor(opj_jp2_t *p_jp2,
return opj_j2k_set_decoded_resolution_factor(p_jp2->j2k, res_factor, p_manager);
}
/* ----------------------------------------------------------------------- */
OPJ_BOOL opj_jp2_encoder_set_extra_options(
opj_jp2_t *p_jp2,
const char* const* p_options,
opj_event_mgr_t * p_manager)
{
return opj_j2k_encoder_set_extra_options(p_jp2->j2k, p_options, p_manager);
}
/* ----------------------------------------------------------------------- */
/* JPIP specific */
#ifdef USE_JPIP

@ -459,6 +459,20 @@ OPJ_BOOL opj_jp2_set_decoded_resolution_factor(opj_jp2_t *p_jp2,
OPJ_UINT32 res_factor,
opj_event_mgr_t * p_manager);
/**
* Specify extra options for the encoder.
*
* @param p_jp2 the jpeg2000 codec.
* @param p_options options
* @param p_manager the user event manager
*
* @see opj_encoder_set_extra_options() for more details.
*/
OPJ_BOOL opj_jp2_encoder_set_extra_options(
opj_jp2_t *p_jp2,
const char* const* p_options,
opj_event_mgr_t * p_manager);
/* TODO MSD: clean these 3 functions */
/**

@ -1,14 +0,0 @@
prefix=@CMAKE_INSTALL_PREFIX@
bindir=${prefix}/@OPENJPEG_INSTALL_BIN_DIR@
mandir=${prefix}/@OPENJPEG_INSTALL_MAN_DIR@
docdir=${prefix}/@OPENJPEG_INSTALL_DOC_DIR@
libdir=${prefix}/@OPENJPEG_INSTALL_LIB_DIR@
includedir=${prefix}/@OPENJPEG_INSTALL_INCLUDE_DIR@
Name: openjp2
Description: JPEG2000 library (Part 1 and 2)
URL: http://www.openjpeg.org/
Version: @OPENJPEG_VERSION@
Libs: -L${libdir} -lopenjp2
Libs.private: -lm
Cflags: -I${includedir}

@ -183,7 +183,7 @@ void opj_mct_decode(
OPJ_INT32* OPJ_RESTRICT c2,
OPJ_SIZE_T n)
{
OPJ_UINT32 i;
OPJ_SIZE_T i;
for (i = 0; i < n; ++i) {
OPJ_INT32 y = c0[i];
OPJ_INT32 u = c1[i];
@ -209,175 +209,72 @@ OPJ_FLOAT64 opj_mct_getnorm(OPJ_UINT32 compno)
/* <summary> */
/* Forward irreversible MCT. */
/* </summary> */
#ifdef __SSE4_1__
void opj_mct_encode_real(
OPJ_INT32* OPJ_RESTRICT c0,
OPJ_INT32* OPJ_RESTRICT c1,
OPJ_INT32* OPJ_RESTRICT c2,
OPJ_FLOAT32* OPJ_RESTRICT c0,
OPJ_FLOAT32* OPJ_RESTRICT c1,
OPJ_FLOAT32* OPJ_RESTRICT c2,
OPJ_SIZE_T n)
{
OPJ_SIZE_T i;
const OPJ_SIZE_T len = n;
const __m128i ry = _mm_set1_epi32(2449);
const __m128i gy = _mm_set1_epi32(4809);
const __m128i by = _mm_set1_epi32(934);
const __m128i ru = _mm_set1_epi32(1382);
const __m128i gu = _mm_set1_epi32(2714);
/* const __m128i bu = _mm_set1_epi32(4096); */
/* const __m128i rv = _mm_set1_epi32(4096); */
const __m128i gv = _mm_set1_epi32(3430);
const __m128i bv = _mm_set1_epi32(666);
const __m128i mulround = _mm_shuffle_epi32(_mm_cvtsi32_si128(4096),
_MM_SHUFFLE(1, 0, 1, 0));
for (i = 0; i < (len & ~3U); i += 4) {
__m128i lo, hi;
__m128i y, u, v;
__m128i r = _mm_load_si128((const __m128i *) & (c0[i]));
__m128i g = _mm_load_si128((const __m128i *) & (c1[i]));
__m128i b = _mm_load_si128((const __m128i *) & (c2[i]));
lo = r;
hi = _mm_shuffle_epi32(r, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, ry);
hi = _mm_mul_epi32(hi, ry);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
y = _mm_blend_epi16(lo, hi, 0xCC);
lo = g;
hi = _mm_shuffle_epi32(g, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, gy);
hi = _mm_mul_epi32(hi, gy);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
y = _mm_add_epi32(y, _mm_blend_epi16(lo, hi, 0xCC));
lo = b;
hi = _mm_shuffle_epi32(b, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, by);
hi = _mm_mul_epi32(hi, by);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
y = _mm_add_epi32(y, _mm_blend_epi16(lo, hi, 0xCC));
_mm_store_si128((__m128i *) & (c0[i]), y);
/*lo = b;
hi = _mm_shuffle_epi32(b, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, mulround);
hi = _mm_mul_epi32(hi, mulround);*/
lo = _mm_cvtepi32_epi64(_mm_shuffle_epi32(b, _MM_SHUFFLE(3, 2, 2, 0)));
hi = _mm_cvtepi32_epi64(_mm_shuffle_epi32(b, _MM_SHUFFLE(3, 2, 3, 1)));
lo = _mm_slli_epi64(lo, 12);
hi = _mm_slli_epi64(hi, 12);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
u = _mm_blend_epi16(lo, hi, 0xCC);
lo = r;
hi = _mm_shuffle_epi32(r, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, ru);
hi = _mm_mul_epi32(hi, ru);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
u = _mm_sub_epi32(u, _mm_blend_epi16(lo, hi, 0xCC));
lo = g;
hi = _mm_shuffle_epi32(g, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, gu);
hi = _mm_mul_epi32(hi, gu);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
u = _mm_sub_epi32(u, _mm_blend_epi16(lo, hi, 0xCC));
_mm_store_si128((__m128i *) & (c1[i]), u);
#ifdef __SSE__
const __m128 YR = _mm_set1_ps(0.299f);
const __m128 YG = _mm_set1_ps(0.587f);
const __m128 YB = _mm_set1_ps(0.114f);
const __m128 UR = _mm_set1_ps(-0.16875f);
const __m128 UG = _mm_set1_ps(-0.331260f);
const __m128 UB = _mm_set1_ps(0.5f);
const __m128 VR = _mm_set1_ps(0.5f);
const __m128 VG = _mm_set1_ps(-0.41869f);
const __m128 VB = _mm_set1_ps(-0.08131f);
for (i = 0; i < (n >> 3); i ++) {
__m128 r, g, b, y, u, v;
r = _mm_load_ps(c0);
g = _mm_load_ps(c1);
b = _mm_load_ps(c2);
y = _mm_add_ps(_mm_add_ps(_mm_mul_ps(r, YR), _mm_mul_ps(g, YG)),
_mm_mul_ps(b, YB));
u = _mm_add_ps(_mm_add_ps(_mm_mul_ps(r, UR), _mm_mul_ps(g, UG)),
_mm_mul_ps(b, UB));
v = _mm_add_ps(_mm_add_ps(_mm_mul_ps(r, VR), _mm_mul_ps(g, VG)),
_mm_mul_ps(b, VB));
_mm_store_ps(c0, y);
_mm_store_ps(c1, u);
_mm_store_ps(c2, v);
c0 += 4;
c1 += 4;
c2 += 4;
/*lo = r;
hi = _mm_shuffle_epi32(r, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, mulround);
hi = _mm_mul_epi32(hi, mulround);*/
lo = _mm_cvtepi32_epi64(_mm_shuffle_epi32(r, _MM_SHUFFLE(3, 2, 2, 0)));
hi = _mm_cvtepi32_epi64(_mm_shuffle_epi32(r, _MM_SHUFFLE(3, 2, 3, 1)));
lo = _mm_slli_epi64(lo, 12);
hi = _mm_slli_epi64(hi, 12);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
v = _mm_blend_epi16(lo, hi, 0xCC);
lo = g;
hi = _mm_shuffle_epi32(g, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, gv);
hi = _mm_mul_epi32(hi, gv);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
v = _mm_sub_epi32(v, _mm_blend_epi16(lo, hi, 0xCC));
lo = b;
hi = _mm_shuffle_epi32(b, _MM_SHUFFLE(3, 3, 1, 1));
lo = _mm_mul_epi32(lo, bv);
hi = _mm_mul_epi32(hi, bv);
lo = _mm_add_epi64(lo, mulround);
hi = _mm_add_epi64(hi, mulround);
lo = _mm_srli_epi64(lo, 13);
hi = _mm_slli_epi64(hi, 32 - 13);
v = _mm_sub_epi32(v, _mm_blend_epi16(lo, hi, 0xCC));
_mm_store_si128((__m128i *) & (c2[i]), v);
}
for (; i < len; ++i) {
OPJ_INT32 r = c0[i];
OPJ_INT32 g = c1[i];
OPJ_INT32 b = c2[i];
OPJ_INT32 y = opj_int_fix_mul(r, 2449) + opj_int_fix_mul(g,
4809) + opj_int_fix_mul(b, 934);
OPJ_INT32 u = -opj_int_fix_mul(r, 1382) - opj_int_fix_mul(g,
2714) + opj_int_fix_mul(b, 4096);
OPJ_INT32 v = opj_int_fix_mul(r, 4096) - opj_int_fix_mul(g,
3430) - opj_int_fix_mul(b, 666);
c0[i] = y;
c1[i] = u;
c2[i] = v;
r = _mm_load_ps(c0);
g = _mm_load_ps(c1);
b = _mm_load_ps(c2);
y = _mm_add_ps(_mm_add_ps(_mm_mul_ps(r, YR), _mm_mul_ps(g, YG)),
_mm_mul_ps(b, YB));
u = _mm_add_ps(_mm_add_ps(_mm_mul_ps(r, UR), _mm_mul_ps(g, UG)),
_mm_mul_ps(b, UB));
v = _mm_add_ps(_mm_add_ps(_mm_mul_ps(r, VR), _mm_mul_ps(g, VG)),
_mm_mul_ps(b, VB));
_mm_store_ps(c0, y);
_mm_store_ps(c1, u);
_mm_store_ps(c2, v);
c0 += 4;
c1 += 4;
c2 += 4;
}
}
#else
void opj_mct_encode_real(
OPJ_INT32* OPJ_RESTRICT c0,
OPJ_INT32* OPJ_RESTRICT c1,
OPJ_INT32* OPJ_RESTRICT c2,
OPJ_SIZE_T n)
{
OPJ_UINT32 i;
n &= 7;
#endif
for (i = 0; i < n; ++i) {
OPJ_INT32 r = c0[i];
OPJ_INT32 g = c1[i];
OPJ_INT32 b = c2[i];
OPJ_INT32 y = opj_int_fix_mul(r, 2449) + opj_int_fix_mul(g,
4809) + opj_int_fix_mul(b, 934);
OPJ_INT32 u = -opj_int_fix_mul(r, 1382) - opj_int_fix_mul(g,
2714) + opj_int_fix_mul(b, 4096);
OPJ_INT32 v = opj_int_fix_mul(r, 4096) - opj_int_fix_mul(g,
3430) - opj_int_fix_mul(b, 666);
OPJ_FLOAT32 r = c0[i];
OPJ_FLOAT32 g = c1[i];
OPJ_FLOAT32 b = c2[i];
OPJ_FLOAT32 y = 0.299f * r + 0.587f * g + 0.114f * b;
OPJ_FLOAT32 u = -0.16875f * r - 0.331260f * g + 0.5f * b;
OPJ_FLOAT32 v = 0.5f * r - 0.41869f * g - 0.08131f * b;
c0[i] = y;
c1[i] = u;
c2[i] = v;
}
}
#endif
/* <summary> */
/* Inverse irreversible MCT. */
@ -388,7 +285,7 @@ void opj_mct_decode_real(
OPJ_FLOAT32* OPJ_RESTRICT c2,
OPJ_SIZE_T n)
{
OPJ_UINT32 i;
OPJ_SIZE_T i;
#ifdef __SSE__
__m128 vrv, vgu, vgv, vbu;
vrv = _mm_set1_ps(1.402f);

@ -85,8 +85,9 @@ Apply an irreversible multi-component transform to an image
@param c2 Samples blue component
@param n Number of samples for each component
*/
void opj_mct_encode_real(OPJ_INT32* OPJ_RESTRICT c0, OPJ_INT32* OPJ_RESTRICT c1,
OPJ_INT32* OPJ_RESTRICT c2, OPJ_SIZE_T n);
void opj_mct_encode_real(OPJ_FLOAT32* OPJ_RESTRICT c0,
OPJ_FLOAT32* OPJ_RESTRICT c1,
OPJ_FLOAT32* OPJ_RESTRICT c2, OPJ_SIZE_T n);
/**
Apply an irreversible multi-component inverse transform to an image
@param c0 Samples for luminance component

@ -46,27 +46,6 @@
/** @name Local static functions */
/*@{*/
/**
Output a byte, doing bit-stuffing if necessary.
After a 0xff byte, the next byte must be smaller than 0x90.
@param mqc MQC handle
*/
static void opj_mqc_byteout(opj_mqc_t *mqc);
/**
Renormalize mqc->a and mqc->c while encoding, so that mqc->a stays between 0x8000 and 0x10000
@param mqc MQC handle
*/
static void opj_mqc_renorme(opj_mqc_t *mqc);
/**
Encode the most probable symbol
@param mqc MQC handle
*/
static void opj_mqc_codemps(opj_mqc_t *mqc);
/**
Encode the most least symbol
@param mqc MQC handle
*/
static void opj_mqc_codelps(opj_mqc_t *mqc);
/**
Fill mqc->c with 1's for flushing
@param mqc MQC handle
@ -182,80 +161,6 @@ static const opj_mqc_state_t mqc_states[47 * 2] = {
==========================================================
*/
static void opj_mqc_byteout(opj_mqc_t *mqc)
{
/* bp is initialized to start - 1 in opj_mqc_init_enc() */
/* but this is safe, see opj_tcd_code_block_enc_allocate_data() */
assert(mqc->bp >= mqc->start - 1);
if (*mqc->bp == 0xff) {
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 20);
mqc->c &= 0xfffff;
mqc->ct = 7;
} else {
if ((mqc->c & 0x8000000) == 0) {
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 19);
mqc->c &= 0x7ffff;
mqc->ct = 8;
} else {
(*mqc->bp)++;
if (*mqc->bp == 0xff) {
mqc->c &= 0x7ffffff;
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 20);
mqc->c &= 0xfffff;
mqc->ct = 7;
} else {
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 19);
mqc->c &= 0x7ffff;
mqc->ct = 8;
}
}
}
}
static void opj_mqc_renorme(opj_mqc_t *mqc)
{
do {
mqc->a <<= 1;
mqc->c <<= 1;
mqc->ct--;
if (mqc->ct == 0) {
opj_mqc_byteout(mqc);
}
} while ((mqc->a & 0x8000) == 0);
}
static void opj_mqc_codemps(opj_mqc_t *mqc)
{
mqc->a -= (*mqc->curctx)->qeval;
if ((mqc->a & 0x8000) == 0) {
if (mqc->a < (*mqc->curctx)->qeval) {
mqc->a = (*mqc->curctx)->qeval;
} else {
mqc->c += (*mqc->curctx)->qeval;
}
*mqc->curctx = (*mqc->curctx)->nmps;
opj_mqc_renorme(mqc);
} else {
mqc->c += (*mqc->curctx)->qeval;
}
}
static void opj_mqc_codelps(opj_mqc_t *mqc)
{
mqc->a -= (*mqc->curctx)->qeval;
if (mqc->a < (*mqc->curctx)->qeval) {
mqc->c += (*mqc->curctx)->qeval;
} else {
mqc->a = (*mqc->curctx)->qeval;
}
*mqc->curctx = (*mqc->curctx)->nlps;
opj_mqc_renorme(mqc);
}
static void opj_mqc_setbits(opj_mqc_t *mqc)
{
OPJ_UINT32 tempc = mqc->c + mqc->a;
@ -303,14 +208,6 @@ void opj_mqc_init_enc(opj_mqc_t *mqc, OPJ_BYTE *bp)
mqc->end_of_byte_stream_counter = 0;
}
void opj_mqc_encode(opj_mqc_t *mqc, OPJ_UINT32 d)
{
if ((*mqc->curctx)->mps == d) {
opj_mqc_codemps(mqc);
} else {
opj_mqc_codelps(mqc);
}
}
void opj_mqc_flush(opj_mqc_t *mqc)
{
@ -329,8 +226,6 @@ void opj_mqc_flush(opj_mqc_t *mqc)
}
}
#define BYPASS_CT_INIT 0xDEADBEEF
void opj_mqc_bypass_init_enc(opj_mqc_t *mqc)
{
/* This function is normally called after at least one opj_mqc_flush() */
@ -475,6 +370,43 @@ void opj_mqc_erterm_enc(opj_mqc_t *mqc)
}
}
static INLINE void opj_mqc_renorme(opj_mqc_t *mqc)
{
opj_mqc_renorme_macro(mqc, mqc->a, mqc->c, mqc->ct);
}
/**
Encode the most probable symbol
@param mqc MQC handle
*/
static INLINE void opj_mqc_codemps(opj_mqc_t *mqc)
{
opj_mqc_codemps_macro(mqc, mqc->curctx, mqc->a, mqc->c, mqc->ct);
}
/**
Encode the most least symbol
@param mqc MQC handle
*/
static INLINE void opj_mqc_codelps(opj_mqc_t *mqc)
{
opj_mqc_codelps_macro(mqc, mqc->curctx, mqc->a, mqc->c, mqc->ct);
}
/**
Encode a symbol using the MQ-coder
@param mqc MQC handle
@param d The symbol to be encoded (0 or 1)
*/
static INLINE void opj_mqc_encode(opj_mqc_t *mqc, OPJ_UINT32 d)
{
if ((*mqc->curctx)->mps == d) {
opj_mqc_codemps(mqc);
} else {
opj_mqc_codelps(mqc);
}
}
void opj_mqc_segmark_enc(opj_mqc_t *mqc)
{
OPJ_UINT32 i;
@ -557,4 +489,36 @@ void opj_mqc_setstate(opj_mqc_t *mqc, OPJ_UINT32 ctxno, OPJ_UINT32 msb,
mqc->ctxs[ctxno] = &mqc_states[msb + (OPJ_UINT32)(prob << 1)];
}
void opj_mqc_byteout(opj_mqc_t *mqc)
{
/* bp is initialized to start - 1 in opj_mqc_init_enc() */
/* but this is safe, see opj_tcd_code_block_enc_allocate_data() */
assert(mqc->bp >= mqc->start - 1);
if (*mqc->bp == 0xff) {
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 20);
mqc->c &= 0xfffff;
mqc->ct = 7;
} else {
if ((mqc->c & 0x8000000) == 0) {
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 19);
mqc->c &= 0x7ffff;
mqc->ct = 8;
} else {
(*mqc->bp)++;
if (*mqc->bp == 0xff) {
mqc->c &= 0x7ffffff;
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 20);
mqc->c &= 0xfffff;
mqc->ct = 7;
} else {
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 19);
mqc->c &= 0x7ffff;
mqc->ct = 8;
}
}
}
}

@ -96,6 +96,8 @@ typedef struct opj_mqc {
OPJ_BYTE backup[OPJ_COMMON_CBLK_DATA_EXTRA];
} opj_mqc_t;
#define BYPASS_CT_INIT 0xDEADBEEF
#include "mqc_inl.h"
/** @name Exported functions */
@ -135,12 +137,7 @@ Set the current context used for coding/decoding
@param ctxno Number that identifies the context
*/
#define opj_mqc_setcurctx(mqc, ctxno) (mqc)->curctx = &(mqc)->ctxs[(OPJ_UINT32)(ctxno)]
/**
Encode a symbol using the MQ-coder
@param mqc MQC handle
@param d The symbol to be encoded (0 or 1)
*/
void opj_mqc_encode(opj_mqc_t *mqc, OPJ_UINT32 d);
/**
Flush the encoder, so that all remaining data is written
@param mqc MQC handle

@ -156,13 +156,13 @@ static INLINE OPJ_UINT32 opj_mqc_raw_decode(opj_mqc_t *mqc)
} \
}
#define DOWNLOAD_MQC_VARIABLES(mqc, curctx, c, a, ct) \
#define DOWNLOAD_MQC_VARIABLES(mqc, curctx, a, c, ct) \
register const opj_mqc_state_t **curctx = mqc->curctx; \
register OPJ_UINT32 c = mqc->c; \
register OPJ_UINT32 a = mqc->a; \
register OPJ_UINT32 ct = mqc->ct
#define UPLOAD_MQC_VARIABLES(mqc, curctx, c, a, ct) \
#define UPLOAD_MQC_VARIABLES(mqc, curctx, a, c, ct) \
mqc->curctx = curctx; \
mqc->c = c; \
mqc->a = a; \
@ -193,4 +193,90 @@ Decode a symbol
#define opj_mqc_decode(d, mqc) \
opj_mqc_decode_macro(d, mqc, mqc->curctx, mqc->a, mqc->c, mqc->ct)
/**
Output a byte, doing bit-stuffing if necessary.
After a 0xff byte, the next byte must be smaller than 0x90.
@param mqc MQC handle
*/
void opj_mqc_byteout(opj_mqc_t *mqc);
/**
Renormalize mqc->a and mqc->c while encoding, so that mqc->a stays between 0x8000 and 0x10000
@param mqc MQC handle
@param a_ value of mqc->a
@param c_ value of mqc->c_
@param ct_ value of mqc->ct_
*/
#define opj_mqc_renorme_macro(mqc, a_, c_, ct_) \
{ \
do { \
a_ <<= 1; \
c_ <<= 1; \
ct_--; \
if (ct_ == 0) { \
mqc->c = c_; \
opj_mqc_byteout(mqc); \
c_ = mqc->c; \
ct_ = mqc->ct; \
} \
} while( (a_ & 0x8000) == 0); \
}
#define opj_mqc_codemps_macro(mqc, curctx, a, c, ct) \
{ \
a -= (*curctx)->qeval; \
if ((a & 0x8000) == 0) { \
if (a < (*curctx)->qeval) { \
a = (*curctx)->qeval; \
} else { \
c += (*curctx)->qeval; \
} \
*curctx = (*curctx)->nmps; \
opj_mqc_renorme_macro(mqc, a, c, ct); \
} else { \
c += (*curctx)->qeval; \
} \
}
#define opj_mqc_codelps_macro(mqc, curctx, a, c, ct) \
{ \
a -= (*curctx)->qeval; \
if (a < (*curctx)->qeval) { \
c += (*curctx)->qeval; \
} else { \
a = (*curctx)->qeval; \
} \
*curctx = (*curctx)->nlps; \
opj_mqc_renorme_macro(mqc, a, c, ct); \
}
#define opj_mqc_encode_macro(mqc, curctx, a, c, ct, d) \
{ \
if ((*curctx)->mps == (d)) { \
opj_mqc_codemps_macro(mqc, curctx, a, c, ct); \
} else { \
opj_mqc_codelps_macro(mqc, curctx, a, c, ct); \
} \
}
#define opj_mqc_bypass_enc_macro(mqc, c, ct, d) \
{\
if (ct == BYPASS_CT_INIT) {\
ct = 8;\
}\
ct--;\
c = c + ((d) << ct);\
if (ct == 0) {\
*mqc->bp = (OPJ_BYTE)c;\
ct = 8;\
/* If the previous byte was 0xff, make sure that the next msb is 0 */ \
if (*mqc->bp == 0xff) {\
ct = 7;\
}\
mqc->bp++;\
c = 0;\
}\
}
#endif /* OPJ_MQC_INL_H */

@ -652,6 +652,14 @@ opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format)
struct opj_image *,
struct opj_event_mgr *)) opj_j2k_setup_encoder;
l_codec->m_codec_data.m_compression.opj_encoder_set_extra_options = (OPJ_BOOL(
*)(void *,
const char* const*,
struct opj_event_mgr *)) opj_j2k_encoder_set_extra_options;
l_codec->opj_set_threads =
(OPJ_BOOL(*)(void * p_codec, OPJ_UINT32 num_threads)) opj_j2k_set_threads;
l_codec->m_codec = opj_j2k_create_compress();
if (! l_codec->m_codec) {
opj_free(l_codec);
@ -690,6 +698,14 @@ opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format)
struct opj_image *,
struct opj_event_mgr *)) opj_jp2_setup_encoder;
l_codec->m_codec_data.m_compression.opj_encoder_set_extra_options = (OPJ_BOOL(
*)(void *,
const char* const*,
struct opj_event_mgr *)) opj_jp2_encoder_set_extra_options;
l_codec->opj_set_threads =
(OPJ_BOOL(*)(void * p_codec, OPJ_UINT32 num_threads)) opj_jp2_set_threads;
l_codec->m_codec = opj_jp2_create(OPJ_FALSE);
if (! l_codec->m_codec) {
opj_free(l_codec);
@ -718,11 +734,11 @@ void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t
parameters->cp_cinema = OPJ_OFF; /* DEPRECATED */
parameters->rsiz = OPJ_PROFILE_NONE;
parameters->max_comp_size = 0;
parameters->numresolution = 6;
parameters->numresolution = OPJ_COMP_PARAM_DEFAULT_NUMRESOLUTION;
parameters->cp_rsiz = OPJ_STD_RSIZ; /* DEPRECATED */
parameters->cblockw_init = 64;
parameters->cblockh_init = 64;
parameters->prog_order = OPJ_LRCP;
parameters->cblockw_init = OPJ_COMP_PARAM_DEFAULT_CBLOCKW;
parameters->cblockh_init = OPJ_COMP_PARAM_DEFAULT_CBLOCKH;
parameters->prog_order = OPJ_COMP_PARAM_DEFAULT_PROG_ORDER;
parameters->roi_compno = -1; /* no ROI */
parameters->subsampling_dx = 1;
parameters->subsampling_dy = 1;
@ -788,6 +804,27 @@ OPJ_BOOL OPJ_CALLCONV opj_setup_encoder(opj_codec_t *p_codec,
return OPJ_FALSE;
}
/* ----------------------------------------------------------------------- */
OPJ_BOOL OPJ_CALLCONV opj_encoder_set_extra_options(opj_codec_t *p_codec,
const char* const* options)
{
if (p_codec) {
opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
if (! l_codec->is_decompressor) {
return l_codec->m_codec_data.m_compression.opj_encoder_set_extra_options(
l_codec->m_codec,
options,
&(l_codec->m_event_mgr));
}
}
return OPJ_FALSE;
}
/* ----------------------------------------------------------------------- */
OPJ_BOOL OPJ_CALLCONV opj_start_compress(opj_codec_t *p_codec,
opj_image_t * p_image,
opj_stream_t *p_stream)

@ -78,7 +78,7 @@ Most compilers implement their own version of this keyword ...
#if defined(OPJ_STATIC) || !defined(_WIN32)
/* http://gcc.gnu.org/wiki/Visibility */
# if __GNUC__ >= 4
# if !defined(_WIN32) && __GNUC__ >= 4
# if defined(OPJ_STATIC) /* static library uses "hidden" */
# define OPJ_API __attribute__ ((visibility ("hidden")))
# else
@ -204,11 +204,11 @@ typedef size_t OPJ_SIZE_T;
#define OPJ_PROFILE_BC_MULTI 0x0200 /** Multi Tile Broadcast profile defined in 15444-1 AMD3 */
#define OPJ_PROFILE_BC_MULTI_R 0x0300 /** Multi Tile Reversible Broadcast profile defined in 15444-1 AMD3 */
#define OPJ_PROFILE_IMF_2K 0x0400 /** 2K Single Tile Lossy IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_4K 0x0401 /** 4K Single Tile Lossy IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_8K 0x0402 /** 8K Single Tile Lossy IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_2K_R 0x0403 /** 2K Single/Multi Tile Reversible IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_4K 0x0500 /** 4K Single Tile Lossy IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_8K 0x0600 /** 8K Single Tile Lossy IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_2K_R 0x0700 /** 2K Single/Multi Tile Reversible IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_4K_R 0x0800 /** 4K Single/Multi Tile Reversible IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_8K_R 0x0801 /** 8K Single/Multi Tile Reversible IMF profile defined in 15444-1 AMD 8 */
#define OPJ_PROFILE_IMF_8K_R 0x0900 /** 8K Single/Multi Tile Reversible IMF profile defined in 15444-1 AMD 8 */
/**
* JPEG 2000 Part-2 extensions
@ -225,6 +225,36 @@ typedef size_t OPJ_SIZE_T;
#define OPJ_IS_IMF(v) (((v) >= OPJ_PROFILE_IMF_2K)&&((v) <= ((OPJ_PROFILE_IMF_8K_R) | (0x009b))))
#define OPJ_IS_PART2(v) ((v) & OPJ_PROFILE_PART2)
#define OPJ_GET_IMF_PROFILE(v) ((v) & 0xff00) /** Extract IMF profile without mainlevel/sublevel */
#define OPJ_GET_IMF_MAINLEVEL(v) ((v) & 0xf) /** Extract IMF main level */
#define OPJ_GET_IMF_SUBLEVEL(v) (((v) >> 4) & 0xf) /** Extract IMF sub level */
#define OPJ_IMF_MAINLEVEL_MAX 11 /** Maximum main level */
/** Max. Components Sampling Rate (MSamples/sec) per IMF main level */
#define OPJ_IMF_MAINLEVEL_1_MSAMPLESEC 65 /** MSamples/sec for IMF main level 1 */
#define OPJ_IMF_MAINLEVEL_2_MSAMPLESEC 130 /** MSamples/sec for IMF main level 2 */
#define OPJ_IMF_MAINLEVEL_3_MSAMPLESEC 195 /** MSamples/sec for IMF main level 3 */
#define OPJ_IMF_MAINLEVEL_4_MSAMPLESEC 260 /** MSamples/sec for IMF main level 4 */
#define OPJ_IMF_MAINLEVEL_5_MSAMPLESEC 520 /** MSamples/sec for IMF main level 5 */
#define OPJ_IMF_MAINLEVEL_6_MSAMPLESEC 1200 /** MSamples/sec for IMF main level 6 */
#define OPJ_IMF_MAINLEVEL_7_MSAMPLESEC 2400 /** MSamples/sec for IMF main level 7 */
#define OPJ_IMF_MAINLEVEL_8_MSAMPLESEC 4800 /** MSamples/sec for IMF main level 8 */
#define OPJ_IMF_MAINLEVEL_9_MSAMPLESEC 9600 /** MSamples/sec for IMF main level 9 */
#define OPJ_IMF_MAINLEVEL_10_MSAMPLESEC 19200 /** MSamples/sec for IMF main level 10 */
#define OPJ_IMF_MAINLEVEL_11_MSAMPLESEC 38400 /** MSamples/sec for IMF main level 11 */
/** Max. compressed Bit Rate (Mbits/s) per IMF sub level */
#define OPJ_IMF_SUBLEVEL_1_MBITSSEC 200 /** Mbits/s for IMF sub level 1 */
#define OPJ_IMF_SUBLEVEL_2_MBITSSEC 400 /** Mbits/s for IMF sub level 2 */
#define OPJ_IMF_SUBLEVEL_3_MBITSSEC 800 /** Mbits/s for IMF sub level 3 */
#define OPJ_IMF_SUBLEVEL_4_MBITSSEC 1600 /** Mbits/s for IMF sub level 4 */
#define OPJ_IMF_SUBLEVEL_5_MBITSSEC 3200 /** Mbits/s for IMF sub level 5 */
#define OPJ_IMF_SUBLEVEL_6_MBITSSEC 6400 /** Mbits/s for IMF sub level 6 */
#define OPJ_IMF_SUBLEVEL_7_MBITSSEC 12800 /** Mbits/s for IMF sub level 7 */
#define OPJ_IMF_SUBLEVEL_8_MBITSSEC 25600 /** Mbits/s for IMF sub level 8 */
#define OPJ_IMF_SUBLEVEL_9_MBITSSEC 51200 /** Mbits/s for IMF sub level 9 */
/**
* JPEG 2000 codestream and component size limits in cinema profiles
* */
@ -318,6 +348,10 @@ typedef void (*opj_msg_callback)(const char *msg, void *client_data);
==========================================================
*/
#ifndef OPJ_UINT32_SEMANTICALLY_BUT_INT32
#define OPJ_UINT32_SEMANTICALLY_BUT_INT32 OPJ_INT32
#endif
/**
* Progression order changes
*
@ -333,10 +367,10 @@ typedef struct opj_poc {
OPJ_PROG_ORDER prg1, prg;
/** Progression order string*/
OPJ_CHAR progorder[5];
/** Tile number */
/** Tile number (starting at 1) */
OPJ_UINT32 tile;
/** Start and end values for Tile width and height*/
OPJ_INT32 tx0, tx1, ty0, ty1;
OPJ_UINT32_SEMANTICALLY_BUT_INT32 tx0, tx1, ty0, ty1;
/** Start value, initialised in pi_initialise_encode*/
OPJ_UINT32 layS, resS, compS, prcS;
/** End value, initialised in pi_initialise_encode */
@ -1314,15 +1348,14 @@ OPJ_API OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec,
* number, or "ALL_CPUS". If OPJ_NUM_THREADS is set and this function is called,
* this function will override the behaviour of the environment variable.
*
* Currently this function must be called after opj_setup_decoder() and
* before opj_read_header().
*
* Note: currently only has effect on the decompressor.
* This function must be called after opj_setup_decoder() and
* before opj_read_header() for the decoding side, or after opj_setup_encoder()
* and before opj_start_compress() for the encoding side.
*
* @param p_codec decompressor handler
* @param p_codec decompressor or compressor handler
* @param num_threads number of threads.
*
* @return OPJ_TRUE if the decoder is correctly set
* @return OPJ_TRUE if the function is successful.
*/
OPJ_API OPJ_BOOL OPJ_CALLCONV opj_codec_set_threads(opj_codec_t *p_codec,
int num_threads);
@ -1546,6 +1579,33 @@ OPJ_API OPJ_BOOL OPJ_CALLCONV opj_setup_encoder(opj_codec_t *p_codec,
opj_cparameters_t *parameters,
opj_image_t *image);
/**
* Specify extra options for the encoder.
*
* This may be called after opj_setup_encoder() and before opj_start_compress()
*
* This is the way to add new options in a fully ABI compatible way, without
* extending the opj_cparameters_t structure.
*
* Currently supported options are:
* <ul>
* <li>PLT=YES/NO. Defaults to NO. If set to YES, PLT marker segments,
* indicating the length of each packet in the tile-part header, will be
* written. Since 2.3.2</li>
* </ul>
*
* @param p_codec Compressor handle
* @param p_options Compression options. This should be a NULL terminated
* array of strings. Each string is of the form KEY=VALUE.
*
* @return OPJ_TRUE in case of success.
* @since 2.3.2
*/
OPJ_API OPJ_BOOL OPJ_CALLCONV opj_encoder_set_extra_options(
opj_codec_t *p_codec,
const char* const* p_options);
/**
* Start to compress the current image.
* @param p_codec Compressor handle

@ -148,6 +148,11 @@ typedef struct opj_codec_private {
opj_cparameters_t * p_param,
struct opj_image * p_image,
struct opj_event_mgr * p_manager);
OPJ_BOOL(* opj_encoder_set_extra_options)(void * p_codec,
const char* const* p_options,
struct opj_event_mgr * p_manager);
} m_compression;
} m_codec_data;
/** FIXME DOC*/

@ -38,4 +38,10 @@
*/
#define OPJ_COMMON_CBLK_DATA_EXTRA 2 /**< Margin for a fake FFFF marker */
#define OPJ_COMP_PARAM_DEFAULT_CBLOCKW 64
#define OPJ_COMP_PARAM_DEFAULT_CBLOCKH 64
#define OPJ_COMP_PARAM_DEFAULT_PROG_ORDER OPJ_LRCP
#define OPJ_COMP_PARAM_DEFAULT_NUMRESOLUTION 6
#endif /* OPJ_COMMMON_H */

@ -208,6 +208,16 @@ static INLINE OPJ_INT32 opj_int_floordivpow2(OPJ_INT32 a, OPJ_INT32 b)
{
return a >> b;
}
/**
Divide an integer by a power of 2 and round downwards
@return Returns a divided by 2^b
*/
static INLINE OPJ_UINT32 opj_uint_floordivpow2(OPJ_UINT32 a, OPJ_UINT32 b)
{
return a >> b;
}
/**
Get logarithm of an integer and round downwards
@return Returns log2(a)

@ -36,6 +36,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#define OPJ_UINT32_SEMANTICALLY_BUT_INT32 OPJ_UINT32
#include "opj_includes.h"
/** @defgroup PI PI - Implementation of a packet iterator */
@ -91,10 +93,10 @@ static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi);
*/
static void opj_pi_update_encode_poc_and_final(opj_cp_t *p_cp,
OPJ_UINT32 p_tileno,
OPJ_INT32 p_tx0,
OPJ_INT32 p_tx1,
OPJ_INT32 p_ty0,
OPJ_INT32 p_ty1,
OPJ_UINT32 p_tx0,
OPJ_UINT32 p_tx1,
OPJ_UINT32 p_ty0,
OPJ_UINT32 p_ty1,
OPJ_UINT32 p_max_prec,
OPJ_UINT32 p_max_res,
OPJ_UINT32 p_dx_min,
@ -118,10 +120,10 @@ static void opj_pi_update_encode_poc_and_final(opj_cp_t *p_cp,
static void opj_pi_update_encode_not_poc(opj_cp_t *p_cp,
OPJ_UINT32 p_num_comps,
OPJ_UINT32 p_tileno,
OPJ_INT32 p_tx0,
OPJ_INT32 p_tx1,
OPJ_INT32 p_ty0,
OPJ_INT32 p_ty1,
OPJ_UINT32 p_tx0,
OPJ_UINT32 p_tx1,
OPJ_UINT32 p_ty0,
OPJ_UINT32 p_ty1,
OPJ_UINT32 p_max_prec,
OPJ_UINT32 p_max_res,
OPJ_UINT32 p_dx_min,
@ -144,10 +146,10 @@ static void opj_pi_update_encode_not_poc(opj_cp_t *p_cp,
static void opj_get_encoding_parameters(const opj_image_t *p_image,
const opj_cp_t *p_cp,
OPJ_UINT32 tileno,
OPJ_INT32 * p_tx0,
OPJ_INT32 * p_tx1,
OPJ_INT32 * p_ty0,
OPJ_INT32 * p_ty1,
OPJ_UINT32 * p_tx0,
OPJ_UINT32 * p_tx1,
OPJ_UINT32 * p_ty0,
OPJ_UINT32 * p_ty1,
OPJ_UINT32 * p_dx_min,
OPJ_UINT32 * p_dy_min,
OPJ_UINT32 * p_max_prec,
@ -176,10 +178,10 @@ static void opj_get_encoding_parameters(const opj_image_t *p_image,
static void opj_get_all_encoding_parameters(const opj_image_t *p_image,
const opj_cp_t *p_cp,
OPJ_UINT32 tileno,
OPJ_INT32 * p_tx0,
OPJ_INT32 * p_tx1,
OPJ_INT32 * p_ty0,
OPJ_INT32 * p_ty1,
OPJ_UINT32 * p_tx0,
OPJ_UINT32 * p_tx1,
OPJ_UINT32 * p_ty0,
OPJ_UINT32 * p_ty1,
OPJ_UINT32 * p_dx_min,
OPJ_UINT32 * p_dy_min,
OPJ_UINT32 * p_max_prec,
@ -192,10 +194,12 @@ static void opj_get_all_encoding_parameters(const opj_image_t *p_image,
* @param p_image the image used to initialize the packet iterator (in fact only the number of components is relevant.
* @param p_cp the coding parameters.
* @param tileno the index of the tile from which creating the packet iterator.
* @param manager Event manager
*/
static opj_pi_iterator_t * opj_pi_create(const opj_image_t *p_image,
const opj_cp_t *p_cp,
OPJ_UINT32 tileno);
OPJ_UINT32 tileno,
opj_event_mgr_t* manager);
/**
* FIXME DOC
*/
@ -230,18 +234,19 @@ static OPJ_BOOL opj_pi_check_next_level(OPJ_INT32 pos,
==========================================================
*/
static void opj_pi_emit_error(opj_pi_iterator_t * pi, const char* msg)
{
(void)pi;
(void)msg;
}
static OPJ_BOOL opj_pi_next_lrcp(opj_pi_iterator_t * pi)
{
opj_pi_comp_t *comp = NULL;
opj_pi_resolution_t *res = NULL;
OPJ_UINT32 index = 0;
if (pi->poc.compno0 >= pi->numcomps ||
pi->poc.compno1 >= pi->numcomps + 1) {
opj_event_msg(pi->manager, EVT_ERROR,
"opj_pi_next_lrcp(): invalid compno0/compno1\n");
return OPJ_FALSE;
}
if (!pi->first) {
comp = &pi->comps[pi->compno];
res = &comp->resolutions[pi->resno];
@ -272,7 +277,7 @@ static OPJ_BOOL opj_pi_next_lrcp(opj_pi_iterator_t * pi)
/* include should be resized when a POC arises, or */
/* the POC should be rejected */
if (index >= pi->include_size) {
opj_pi_emit_error(pi, "Invalid access to pi->include");
opj_event_msg(pi->manager, EVT_ERROR, "Invalid access to pi->include");
return OPJ_FALSE;
}
if (!pi->include[index]) {
@ -295,6 +300,13 @@ static OPJ_BOOL opj_pi_next_rlcp(opj_pi_iterator_t * pi)
opj_pi_resolution_t *res = NULL;
OPJ_UINT32 index = 0;
if (pi->poc.compno0 >= pi->numcomps ||
pi->poc.compno1 >= pi->numcomps + 1) {
opj_event_msg(pi->manager, EVT_ERROR,
"opj_pi_next_rlcp(): invalid compno0/compno1\n");
return OPJ_FALSE;
}
if (!pi->first) {
comp = &pi->comps[pi->compno];
res = &comp->resolutions[pi->resno];
@ -318,7 +330,7 @@ static OPJ_BOOL opj_pi_next_rlcp(opj_pi_iterator_t * pi)
index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno *
pi->step_c + pi->precno * pi->step_p;
if (index >= pi->include_size) {
opj_pi_emit_error(pi, "Invalid access to pi->include");
opj_event_msg(pi->manager, EVT_ERROR, "Invalid access to pi->include");
return OPJ_FALSE;
}
if (!pi->include[index]) {
@ -341,6 +353,13 @@ static OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi)
opj_pi_resolution_t *res = NULL;
OPJ_UINT32 index = 0;
if (pi->poc.compno0 >= pi->numcomps ||
pi->poc.compno1 >= pi->numcomps + 1) {
opj_event_msg(pi->manager, EVT_ERROR,
"opj_pi_next_rpcl(): invalid compno0/compno1\n");
return OPJ_FALSE;
}
if (!pi->first) {
goto LABEL_SKIP;
} else {
@ -376,16 +395,16 @@ static OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi)
pi->poc.tx1 = pi->tx1;
}
for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1;
pi->y += (OPJ_INT32)(pi->dy - (OPJ_UINT32)(pi->y % (OPJ_INT32)pi->dy))) {
for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1;
pi->x += (OPJ_INT32)(pi->dx - (OPJ_UINT32)(pi->x % (OPJ_INT32)pi->dx))) {
for (pi->y = (OPJ_UINT32)pi->poc.ty0; pi->y < (OPJ_UINT32)pi->poc.ty1;
pi->y += (pi->dy - (pi->y % pi->dy))) {
for (pi->x = (OPJ_UINT32)pi->poc.tx0; pi->x < (OPJ_UINT32)pi->poc.tx1;
pi->x += (pi->dx - (pi->x % pi->dx))) {
for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
OPJ_UINT32 levelno;
OPJ_INT32 trx0, try0;
OPJ_INT32 trx1, try1;
OPJ_UINT32 trx0, try0;
OPJ_UINT32 trx1, try1;
OPJ_UINT32 rpx, rpy;
OPJ_INT32 prci, prcj;
OPJ_UINT32 prci, prcj;
comp = &pi->comps[pi->compno];
if (pi->resno >= comp->numresolutions) {
continue;
@ -404,10 +423,10 @@ static OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi)
(comp->dy << levelno) > INT_MAX) {
continue;
}
trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno));
try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno));
trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno));
try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno));
trx0 = opj_uint_ceildiv(pi->tx0, (comp->dx << levelno));
try0 = opj_uint_ceildiv(pi->ty0, (comp->dy << levelno));
trx1 = opj_uint_ceildiv(pi->tx1, (comp->dx << levelno));
try1 = opj_uint_ceildiv(pi->ty1, (comp->dy << levelno));
rpx = res->pdx + levelno;
rpy = res->pdy + levelno;
@ -421,12 +440,12 @@ static OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi)
}
/* See ISO-15441. B.12.1.3 Resolution level-position-component-layer progression */
if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) &&
((try0 << levelno) % (1 << rpy))))) {
if (!((pi->y % (comp->dy << rpy) == 0) || ((pi->y == pi->ty0) &&
((try0 << levelno) % (1U << rpy))))) {
continue;
}
if (!((pi->x % (OPJ_INT32)(comp->dx << rpx) == 0) || ((pi->x == pi->tx0) &&
((trx0 << levelno) % (1 << rpx))))) {
if (!((pi->x % (comp->dx << rpx) == 0) || ((pi->x == pi->tx0) &&
((trx0 << levelno) % (1U << rpx))))) {
continue;
}
@ -438,18 +457,18 @@ static OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi)
continue;
}
prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x,
(OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx)
- opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx);
prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y,
(OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy)
- opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy);
pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw);
prci = opj_uint_floordivpow2(opj_uint_ceildiv(pi->x,
(comp->dx << levelno)), res->pdx)
- opj_uint_floordivpow2(trx0, res->pdx);
prcj = opj_uint_floordivpow2(opj_uint_ceildiv(pi->y,
(comp->dy << levelno)), res->pdy)
- opj_uint_floordivpow2(try0, res->pdy);
pi->precno = prci + prcj * res->pw;
for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno *
pi->step_c + pi->precno * pi->step_p;
if (index >= pi->include_size) {
opj_pi_emit_error(pi, "Invalid access to pi->include");
opj_event_msg(pi->manager, EVT_ERROR, "Invalid access to pi->include");
return OPJ_FALSE;
}
if (!pi->include[index]) {
@ -473,6 +492,13 @@ static OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi)
opj_pi_resolution_t *res = NULL;
OPJ_UINT32 index = 0;
if (pi->poc.compno0 >= pi->numcomps ||
pi->poc.compno1 >= pi->numcomps + 1) {
opj_event_msg(pi->manager, EVT_ERROR,
"opj_pi_next_pcrl(): invalid compno0/compno1\n");
return OPJ_FALSE;
}
if (!pi->first) {
comp = &pi->comps[pi->compno];
goto LABEL_SKIP;
@ -508,19 +534,19 @@ static OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi)
pi->poc.ty1 = pi->ty1;
pi->poc.tx1 = pi->tx1;
}
for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1;
pi->y += (OPJ_INT32)(pi->dy - (OPJ_UINT32)(pi->y % (OPJ_INT32)pi->dy))) {
for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1;
pi->x += (OPJ_INT32)(pi->dx - (OPJ_UINT32)(pi->x % (OPJ_INT32)pi->dx))) {
for (pi->y = (OPJ_UINT32)pi->poc.ty0; pi->y < (OPJ_UINT32)pi->poc.ty1;
pi->y += (pi->dy - (pi->y % pi->dy))) {
for (pi->x = (OPJ_UINT32)pi->poc.tx0; pi->x < (OPJ_UINT32)pi->poc.tx1;
pi->x += (pi->dx - (pi->x % pi->dx))) {
for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
comp = &pi->comps[pi->compno];
for (pi->resno = pi->poc.resno0;
pi->resno < opj_uint_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
OPJ_UINT32 levelno;
OPJ_INT32 trx0, try0;
OPJ_INT32 trx1, try1;
OPJ_UINT32 trx0, try0;
OPJ_UINT32 trx1, try1;
OPJ_UINT32 rpx, rpy;
OPJ_INT32 prci, prcj;
OPJ_UINT32 prci, prcj;
res = &comp->resolutions[pi->resno];
levelno = comp->numresolutions - 1 - pi->resno;
/* Avoids division by zero */
@ -535,10 +561,10 @@ static OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi)
(comp->dy << levelno) > INT_MAX) {
continue;
}
trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno));
try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno));
trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno));
try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno));
trx0 = opj_uint_ceildiv(pi->tx0, (comp->dx << levelno));
try0 = opj_uint_ceildiv(pi->ty0, (comp->dy << levelno));
trx1 = opj_uint_ceildiv(pi->tx1, (comp->dx << levelno));
try1 = opj_uint_ceildiv(pi->ty1, (comp->dy << levelno));
rpx = res->pdx + levelno;
rpy = res->pdy + levelno;
@ -552,12 +578,12 @@ static OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi)
}
/* See ISO-15441. B.12.1.4 Position-component-resolution level-layer progression */
if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) &&
((try0 << levelno) % (1 << rpy))))) {
if (!((pi->y % (comp->dy << rpy) == 0) || ((pi->y == pi->ty0) &&
((try0 << levelno) % (1U << rpy))))) {
continue;
}
if (!((pi->x % (OPJ_INT32)(comp->dx << rpx) == 0) || ((pi->x == pi->tx0) &&
((trx0 << levelno) % (1 << rpx))))) {
if (!((pi->x % (comp->dx << rpx) == 0) || ((pi->x == pi->tx0) &&
((trx0 << levelno) % (1U << rpx))))) {
continue;
}
@ -569,18 +595,18 @@ static OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi)
continue;
}
prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x,
(OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx)
- opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx);
prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y,
(OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy)
- opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy);
pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw);
prci = opj_uint_floordivpow2(opj_uint_ceildiv(pi->x,
(comp->dx << levelno)), res->pdx)
- opj_uint_floordivpow2(trx0, res->pdx);
prcj = opj_uint_floordivpow2(opj_uint_ceildiv(pi->y,
(comp->dy << levelno)), res->pdy)
- opj_uint_floordivpow2(try0, res->pdy);
pi->precno = prci + prcj * res->pw;
for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno *
pi->step_c + pi->precno * pi->step_p;
if (index >= pi->include_size) {
opj_pi_emit_error(pi, "Invalid access to pi->include");
opj_event_msg(pi->manager, EVT_ERROR, "Invalid access to pi->include");
return OPJ_FALSE;
}
if (!pi->include[index]) {
@ -604,6 +630,13 @@ static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi)
opj_pi_resolution_t *res = NULL;
OPJ_UINT32 index = 0;
if (pi->poc.compno0 >= pi->numcomps ||
pi->poc.compno1 >= pi->numcomps + 1) {
opj_event_msg(pi->manager, EVT_ERROR,
"opj_pi_next_cprl(): invalid compno0/compno1\n");
return OPJ_FALSE;
}
if (!pi->first) {
comp = &pi->comps[pi->compno];
goto LABEL_SKIP;
@ -639,17 +672,17 @@ static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi)
pi->poc.ty1 = pi->ty1;
pi->poc.tx1 = pi->tx1;
}
for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1;
pi->y += (OPJ_INT32)(pi->dy - (OPJ_UINT32)(pi->y % (OPJ_INT32)pi->dy))) {
for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1;
pi->x += (OPJ_INT32)(pi->dx - (OPJ_UINT32)(pi->x % (OPJ_INT32)pi->dx))) {
for (pi->y = (OPJ_UINT32)pi->poc.ty0; pi->y < (OPJ_UINT32)pi->poc.ty1;
pi->y += (pi->dy - (pi->y % pi->dy))) {
for (pi->x = (OPJ_UINT32)pi->poc.tx0; pi->x < (OPJ_UINT32)pi->poc.tx1;
pi->x += (pi->dx - (pi->x % pi->dx))) {
for (pi->resno = pi->poc.resno0;
pi->resno < opj_uint_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
OPJ_UINT32 levelno;
OPJ_INT32 trx0, try0;
OPJ_INT32 trx1, try1;
OPJ_UINT32 trx0, try0;
OPJ_UINT32 trx1, try1;
OPJ_UINT32 rpx, rpy;
OPJ_INT32 prci, prcj;
OPJ_UINT32 prci, prcj;
res = &comp->resolutions[pi->resno];
levelno = comp->numresolutions - 1 - pi->resno;
/* Avoids division by zero on id_000004,sig_06,src_000679,op_arith8,pos_49,val_-17 */
@ -663,10 +696,10 @@ static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi)
(comp->dy << levelno) > INT_MAX) {
continue;
}
trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno));
try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno));
trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno));
try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno));
trx0 = opj_uint_ceildiv(pi->tx0, (comp->dx << levelno));
try0 = opj_uint_ceildiv(pi->ty0, (comp->dy << levelno));
trx1 = opj_uint_ceildiv(pi->tx1, (comp->dx << levelno));
try1 = opj_uint_ceildiv(pi->ty1, (comp->dy << levelno));
rpx = res->pdx + levelno;
rpy = res->pdy + levelno;
@ -680,12 +713,12 @@ static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi)
}
/* See ISO-15441. B.12.1.5 Component-position-resolution level-layer progression */
if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) &&
((try0 << levelno) % (1 << rpy))))) {
if (!((pi->y % (comp->dy << rpy) == 0) || ((pi->y == pi->ty0) &&
((try0 << levelno) % (1U << rpy))))) {
continue;
}
if (!((pi->x % (OPJ_INT32)(comp->dx << rpx) == 0) || ((pi->x == pi->tx0) &&
((trx0 << levelno) % (1 << rpx))))) {
if (!((pi->x % (comp->dx << rpx) == 0) || ((pi->x == pi->tx0) &&
((trx0 << levelno) % (1U << rpx))))) {
continue;
}
@ -697,18 +730,18 @@ static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi)
continue;
}
prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x,
(OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx)
- opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx);
prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y,
(OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy)
- opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy);
pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw);
prci = opj_uint_floordivpow2(opj_uint_ceildiv(pi->x,
(comp->dx << levelno)), res->pdx)
- opj_uint_floordivpow2(trx0, res->pdx);
prcj = opj_uint_floordivpow2(opj_uint_ceildiv(pi->y,
(comp->dy << levelno)), res->pdy)
- opj_uint_floordivpow2(try0, res->pdy);
pi->precno = (OPJ_UINT32)(prci + prcj * res->pw);
for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno *
pi->step_c + pi->precno * pi->step_p;
if (index >= pi->include_size) {
opj_pi_emit_error(pi, "Invalid access to pi->include");
opj_event_msg(pi->manager, EVT_ERROR, "Invalid access to pi->include");
return OPJ_FALSE;
}
if (!pi->include[index]) {
@ -729,10 +762,10 @@ LABEL_SKIP:
static void opj_get_encoding_parameters(const opj_image_t *p_image,
const opj_cp_t *p_cp,
OPJ_UINT32 p_tileno,
OPJ_INT32 * p_tx0,
OPJ_INT32 * p_tx1,
OPJ_INT32 * p_ty0,
OPJ_INT32 * p_ty1,
OPJ_UINT32 * p_tx0,
OPJ_UINT32 * p_tx1,
OPJ_UINT32 * p_ty0,
OPJ_UINT32 * p_ty1,
OPJ_UINT32 * p_dx_min,
OPJ_UINT32 * p_dy_min,
OPJ_UINT32 * p_max_prec,
@ -768,12 +801,12 @@ static void opj_get_encoding_parameters(const opj_image_t *p_image,
/* find extent of tile */
l_tx0 = p_cp->tx0 + p *
p_cp->tdx; /* can't be greater than p_image->x1 so won't overflow */
*p_tx0 = (OPJ_INT32)opj_uint_max(l_tx0, p_image->x0);
*p_tx1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_tx0, p_cp->tdx), p_image->x1);
*p_tx0 = opj_uint_max(l_tx0, p_image->x0);
*p_tx1 = opj_uint_min(opj_uint_adds(l_tx0, p_cp->tdx), p_image->x1);
l_ty0 = p_cp->ty0 + q *
p_cp->tdy; /* can't be greater than p_image->y1 so won't overflow */
*p_ty0 = (OPJ_INT32)opj_uint_max(l_ty0, p_image->y0);
*p_ty1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_ty0, p_cp->tdy), p_image->y1);
*p_ty0 = opj_uint_max(l_ty0, p_image->y0);
*p_ty1 = opj_uint_min(opj_uint_adds(l_ty0, p_cp->tdy), p_image->y1);
/* max precision is 0 (can only grow) */
*p_max_prec = 0;
@ -786,17 +819,17 @@ static void opj_get_encoding_parameters(const opj_image_t *p_image,
for (compno = 0; compno < p_image->numcomps; ++compno) {
/* arithmetic variables to calculate */
OPJ_UINT32 l_level_no;
OPJ_INT32 l_rx0, l_ry0, l_rx1, l_ry1;
OPJ_INT32 l_px0, l_py0, l_px1, py1;
OPJ_UINT32 l_rx0, l_ry0, l_rx1, l_ry1;
OPJ_UINT32 l_px0, l_py0, l_px1, py1;
OPJ_UINT32 l_pdx, l_pdy;
OPJ_UINT32 l_pw, l_ph;
OPJ_UINT32 l_product;
OPJ_INT32 l_tcx0, l_tcy0, l_tcx1, l_tcy1;
OPJ_UINT32 l_tcx0, l_tcy0, l_tcx1, l_tcy1;
l_tcx0 = opj_int_ceildiv(*p_tx0, (OPJ_INT32)l_img_comp->dx);
l_tcy0 = opj_int_ceildiv(*p_ty0, (OPJ_INT32)l_img_comp->dy);
l_tcx1 = opj_int_ceildiv(*p_tx1, (OPJ_INT32)l_img_comp->dx);
l_tcy1 = opj_int_ceildiv(*p_ty1, (OPJ_INT32)l_img_comp->dy);
l_tcx0 = opj_uint_ceildiv(*p_tx0, l_img_comp->dx);
l_tcy0 = opj_uint_ceildiv(*p_ty0, l_img_comp->dy);
l_tcx1 = opj_uint_ceildiv(*p_tx1, l_img_comp->dx);
l_tcy1 = opj_uint_ceildiv(*p_ty1, l_img_comp->dy);
if (l_tccp->numresolutions > *p_max_res) {
*p_max_res = l_tccp->numresolutions;
@ -820,19 +853,19 @@ static void opj_get_encoding_parameters(const opj_image_t *p_image,
/* various calculations of extents */
l_level_no = l_tccp->numresolutions - 1 - resno;
l_rx0 = opj_int_ceildivpow2(l_tcx0, (OPJ_INT32)l_level_no);
l_ry0 = opj_int_ceildivpow2(l_tcy0, (OPJ_INT32)l_level_no);
l_rx1 = opj_int_ceildivpow2(l_tcx1, (OPJ_INT32)l_level_no);
l_ry1 = opj_int_ceildivpow2(l_tcy1, (OPJ_INT32)l_level_no);
l_rx0 = opj_uint_ceildivpow2(l_tcx0, l_level_no);
l_ry0 = opj_uint_ceildivpow2(l_tcy0, l_level_no);
l_rx1 = opj_uint_ceildivpow2(l_tcx1, l_level_no);
l_ry1 = opj_uint_ceildivpow2(l_tcy1, l_level_no);
l_px0 = opj_int_floordivpow2(l_rx0, (OPJ_INT32)l_pdx) << l_pdx;
l_py0 = opj_int_floordivpow2(l_ry0, (OPJ_INT32)l_pdy) << l_pdy;
l_px1 = opj_int_ceildivpow2(l_rx1, (OPJ_INT32)l_pdx) << l_pdx;
l_px0 = opj_uint_floordivpow2(l_rx0, l_pdx) << l_pdx;
l_py0 = opj_uint_floordivpow2(l_ry0, l_pdy) << l_pdy;
l_px1 = opj_uint_ceildivpow2(l_rx1, l_pdx) << l_pdx;
py1 = opj_int_ceildivpow2(l_ry1, (OPJ_INT32)l_pdy) << l_pdy;
py1 = opj_uint_ceildivpow2(l_ry1, l_pdy) << l_pdy;
l_pw = (l_rx0 == l_rx1) ? 0 : (OPJ_UINT32)((l_px1 - l_px0) >> l_pdx);
l_ph = (l_ry0 == l_ry1) ? 0 : (OPJ_UINT32)((py1 - l_py0) >> l_pdy);
l_pw = (l_rx0 == l_rx1) ? 0 : ((l_px1 - l_px0) >> l_pdx);
l_ph = (l_ry0 == l_ry1) ? 0 : ((py1 - l_py0) >> l_pdy);
l_product = l_pw * l_ph;
@ -850,10 +883,10 @@ static void opj_get_encoding_parameters(const opj_image_t *p_image,
static void opj_get_all_encoding_parameters(const opj_image_t *p_image,
const opj_cp_t *p_cp,
OPJ_UINT32 tileno,
OPJ_INT32 * p_tx0,
OPJ_INT32 * p_tx1,
OPJ_INT32 * p_ty0,
OPJ_INT32 * p_ty1,
OPJ_UINT32 * p_tx0,
OPJ_UINT32 * p_tx1,
OPJ_UINT32 * p_ty0,
OPJ_UINT32 * p_ty1,
OPJ_UINT32 * p_dx_min,
OPJ_UINT32 * p_dy_min,
OPJ_UINT32 * p_max_prec,
@ -894,12 +927,12 @@ static void opj_get_all_encoding_parameters(const opj_image_t *p_image,
/* here calculation of tx0, tx1, ty0, ty1, maxprec, l_dx and l_dy */
l_tx0 = p_cp->tx0 + p *
p_cp->tdx; /* can't be greater than p_image->x1 so won't overflow */
*p_tx0 = (OPJ_INT32)opj_uint_max(l_tx0, p_image->x0);
*p_tx1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_tx0, p_cp->tdx), p_image->x1);
*p_tx0 = opj_uint_max(l_tx0, p_image->x0);
*p_tx1 = opj_uint_min(opj_uint_adds(l_tx0, p_cp->tdx), p_image->x1);
l_ty0 = p_cp->ty0 + q *
p_cp->tdy; /* can't be greater than p_image->y1 so won't overflow */
*p_ty0 = (OPJ_INT32)opj_uint_max(l_ty0, p_image->y0);
*p_ty1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_ty0, p_cp->tdy), p_image->y1);
*p_ty0 = opj_uint_max(l_ty0, p_image->y0);
*p_ty1 = opj_uint_min(opj_uint_adds(l_ty0, p_cp->tdy), p_image->y1);
/* max precision and resolution is 0 (can only grow)*/
*p_max_prec = 0;
@ -912,18 +945,18 @@ static void opj_get_all_encoding_parameters(const opj_image_t *p_image,
for (compno = 0; compno < p_image->numcomps; ++compno) {
/* aritmetic variables to calculate*/
OPJ_UINT32 l_level_no;
OPJ_INT32 l_rx0, l_ry0, l_rx1, l_ry1;
OPJ_INT32 l_px0, l_py0, l_px1, py1;
OPJ_UINT32 l_rx0, l_ry0, l_rx1, l_ry1;
OPJ_UINT32 l_px0, l_py0, l_px1, py1;
OPJ_UINT32 l_product;
OPJ_INT32 l_tcx0, l_tcy0, l_tcx1, l_tcy1;
OPJ_UINT32 l_tcx0, l_tcy0, l_tcx1, l_tcy1;
OPJ_UINT32 l_pdx, l_pdy, l_pw, l_ph;
lResolutionPtr = p_resolutions[compno];
lResolutionPtr = p_resolutions ? p_resolutions[compno] : NULL;
l_tcx0 = opj_int_ceildiv(*p_tx0, (OPJ_INT32)l_img_comp->dx);
l_tcy0 = opj_int_ceildiv(*p_ty0, (OPJ_INT32)l_img_comp->dy);
l_tcx1 = opj_int_ceildiv(*p_tx1, (OPJ_INT32)l_img_comp->dx);
l_tcy1 = opj_int_ceildiv(*p_ty1, (OPJ_INT32)l_img_comp->dy);
l_tcx0 = opj_uint_ceildiv(*p_tx0, l_img_comp->dx);
l_tcy0 = opj_uint_ceildiv(*p_ty0, l_img_comp->dy);
l_tcx1 = opj_uint_ceildiv(*p_tx1, l_img_comp->dx);
l_tcy1 = opj_uint_ceildiv(*p_ty1, l_img_comp->dy);
if (l_tccp->numresolutions > *p_max_res) {
*p_max_res = l_tccp->numresolutions;
@ -939,33 +972,37 @@ static void opj_get_all_encoding_parameters(const opj_image_t *p_image,
/* precinct width and height*/
l_pdx = l_tccp->prcw[resno];
l_pdy = l_tccp->prch[resno];
*lResolutionPtr++ = l_pdx;
*lResolutionPtr++ = l_pdy;
if (lResolutionPtr) {
*lResolutionPtr++ = l_pdx;
*lResolutionPtr++ = l_pdy;
}
if (l_pdx + l_level_no < 32 &&
l_img_comp->dx <= UINT_MAX / (1u << (l_pdx + l_level_no))) {
l_dx = l_img_comp->dx * (1u << (l_pdx + l_level_no));
/* take the minimum size for l_dx for each comp and resolution*/
*p_dx_min = (OPJ_UINT32)opj_int_min((OPJ_INT32) * p_dx_min, (OPJ_INT32)l_dx);
*p_dx_min = opj_uint_min(*p_dx_min, l_dx);
}
if (l_pdy + l_level_no < 32 &&
l_img_comp->dy <= UINT_MAX / (1u << (l_pdy + l_level_no))) {
l_dy = l_img_comp->dy * (1u << (l_pdy + l_level_no));
*p_dy_min = (OPJ_UINT32)opj_int_min((OPJ_INT32) * p_dy_min, (OPJ_INT32)l_dy);
*p_dy_min = opj_uint_min(*p_dy_min, l_dy);
}
/* various calculations of extents*/
l_rx0 = opj_int_ceildivpow2(l_tcx0, (OPJ_INT32)l_level_no);
l_ry0 = opj_int_ceildivpow2(l_tcy0, (OPJ_INT32)l_level_no);
l_rx1 = opj_int_ceildivpow2(l_tcx1, (OPJ_INT32)l_level_no);
l_ry1 = opj_int_ceildivpow2(l_tcy1, (OPJ_INT32)l_level_no);
l_px0 = opj_int_floordivpow2(l_rx0, (OPJ_INT32)l_pdx) << l_pdx;
l_py0 = opj_int_floordivpow2(l_ry0, (OPJ_INT32)l_pdy) << l_pdy;
l_px1 = opj_int_ceildivpow2(l_rx1, (OPJ_INT32)l_pdx) << l_pdx;
py1 = opj_int_ceildivpow2(l_ry1, (OPJ_INT32)l_pdy) << l_pdy;
l_pw = (l_rx0 == l_rx1) ? 0 : (OPJ_UINT32)((l_px1 - l_px0) >> l_pdx);
l_ph = (l_ry0 == l_ry1) ? 0 : (OPJ_UINT32)((py1 - l_py0) >> l_pdy);
*lResolutionPtr++ = l_pw;
*lResolutionPtr++ = l_ph;
l_rx0 = opj_uint_ceildivpow2(l_tcx0, l_level_no);
l_ry0 = opj_uint_ceildivpow2(l_tcy0, l_level_no);
l_rx1 = opj_uint_ceildivpow2(l_tcx1, l_level_no);
l_ry1 = opj_uint_ceildivpow2(l_tcy1, l_level_no);
l_px0 = opj_uint_floordivpow2(l_rx0, l_pdx) << l_pdx;
l_py0 = opj_uint_floordivpow2(l_ry0, l_pdy) << l_pdy;
l_px1 = opj_uint_ceildivpow2(l_rx1, l_pdx) << l_pdx;
py1 = opj_uint_ceildivpow2(l_ry1, l_pdy) << l_pdy;
l_pw = (l_rx0 == l_rx1) ? 0 : ((l_px1 - l_px0) >> l_pdx);
l_ph = (l_ry0 == l_ry1) ? 0 : ((py1 - l_py0) >> l_pdy);
if (lResolutionPtr) {
*lResolutionPtr++ = l_pw;
*lResolutionPtr++ = l_ph;
}
l_product = l_pw * l_ph;
/* update precision*/
@ -981,7 +1018,8 @@ static void opj_get_all_encoding_parameters(const opj_image_t *p_image,
static opj_pi_iterator_t * opj_pi_create(const opj_image_t *image,
const opj_cp_t *cp,
OPJ_UINT32 tileno)
OPJ_UINT32 tileno,
opj_event_mgr_t* manager)
{
/* loop*/
OPJ_UINT32 pino, compno;
@ -1015,6 +1053,8 @@ static opj_pi_iterator_t * opj_pi_create(const opj_image_t *image,
l_current_pi = l_pi;
for (pino = 0; pino < l_poc_bound ; ++pino) {
l_current_pi->manager = manager;
l_current_pi->comps = (opj_pi_comp_t*) opj_calloc(image->numcomps,
sizeof(opj_pi_comp_t));
if (! l_current_pi->comps) {
@ -1045,10 +1085,10 @@ static opj_pi_iterator_t * opj_pi_create(const opj_image_t *image,
static void opj_pi_update_encode_poc_and_final(opj_cp_t *p_cp,
OPJ_UINT32 p_tileno,
OPJ_INT32 p_tx0,
OPJ_INT32 p_tx1,
OPJ_INT32 p_ty0,
OPJ_INT32 p_ty1,
OPJ_UINT32 p_tx0,
OPJ_UINT32 p_tx1,
OPJ_UINT32 p_ty0,
OPJ_UINT32 p_ty1,
OPJ_UINT32 p_max_prec,
OPJ_UINT32 p_max_res,
OPJ_UINT32 p_dx_min,
@ -1125,10 +1165,10 @@ static void opj_pi_update_encode_poc_and_final(opj_cp_t *p_cp,
static void opj_pi_update_encode_not_poc(opj_cp_t *p_cp,
OPJ_UINT32 p_num_comps,
OPJ_UINT32 p_tileno,
OPJ_INT32 p_tx0,
OPJ_INT32 p_tx1,
OPJ_INT32 p_ty0,
OPJ_INT32 p_ty1,
OPJ_UINT32 p_tx0,
OPJ_UINT32 p_tx1,
OPJ_UINT32 p_ty0,
OPJ_UINT32 p_ty1,
OPJ_UINT32 p_max_prec,
OPJ_UINT32 p_max_res,
OPJ_UINT32 p_dx_min,
@ -1167,10 +1207,10 @@ static void opj_pi_update_encode_not_poc(opj_cp_t *p_cp,
l_current_poc->prg = l_tcp->prg;
l_current_poc->prcS = 0;
l_current_poc->prcE = p_max_prec;
l_current_poc->txS = (OPJ_UINT32)p_tx0;
l_current_poc->txE = (OPJ_UINT32)p_tx1;
l_current_poc->tyS = (OPJ_UINT32)p_ty0;
l_current_poc->tyE = (OPJ_UINT32)p_ty1;
l_current_poc->txS = p_tx0;
l_current_poc->txE = p_tx1;
l_current_poc->tyS = p_ty0;
l_current_poc->tyE = p_ty1;
l_current_poc->dx = p_dx_min;
l_current_poc->dy = p_dy_min;
++ l_current_poc;
@ -1352,7 +1392,8 @@ static OPJ_BOOL opj_pi_check_next_level(OPJ_INT32 pos,
*/
opj_pi_iterator_t *opj_pi_create_decode(opj_image_t *p_image,
opj_cp_t *p_cp,
OPJ_UINT32 p_tile_no)
OPJ_UINT32 p_tile_no,
opj_event_mgr_t* manager)
{
OPJ_UINT32 numcomps = p_image->numcomps;
@ -1367,7 +1408,7 @@ opj_pi_iterator_t *opj_pi_create_decode(opj_image_t *p_image,
/* encoding prameters to set */
OPJ_UINT32 l_max_res;
OPJ_UINT32 l_max_prec;
OPJ_INT32 l_tx0, l_tx1, l_ty0, l_ty1;
OPJ_UINT32 l_tx0, l_tx1, l_ty0, l_ty1;
OPJ_UINT32 l_dx_min, l_dy_min;
OPJ_UINT32 l_bound;
OPJ_UINT32 l_step_p, l_step_c, l_step_r, l_step_l ;
@ -1407,7 +1448,7 @@ opj_pi_iterator_t *opj_pi_create_decode(opj_image_t *p_image,
}
/* memory allocation for pi */
l_pi = opj_pi_create(p_image, p_cp, p_tile_no);
l_pi = opj_pi_create(p_image, p_cp, p_tile_no, manager);
if (!l_pi) {
opj_free(l_tmp_data);
opj_free(l_tmp_ptr);
@ -1548,11 +1589,34 @@ opj_pi_iterator_t *opj_pi_create_decode(opj_image_t *p_image,
}
OPJ_UINT32 opj_get_encoding_packet_count(const opj_image_t *p_image,
const opj_cp_t *p_cp,
OPJ_UINT32 p_tile_no)
{
OPJ_UINT32 l_max_res;
OPJ_UINT32 l_max_prec;
OPJ_UINT32 l_tx0, l_tx1, l_ty0, l_ty1;
OPJ_UINT32 l_dx_min, l_dy_min;
/* preconditions in debug*/
assert(p_cp != 00);
assert(p_image != 00);
assert(p_tile_no < p_cp->tw * p_cp->th);
/* get encoding parameters*/
opj_get_all_encoding_parameters(p_image, p_cp, p_tile_no, &l_tx0, &l_tx1,
&l_ty0, &l_ty1, &l_dx_min, &l_dy_min, &l_max_prec, &l_max_res, NULL);
return p_cp->tcps[p_tile_no].numlayers * l_max_prec * p_image->numcomps *
l_max_res;
}
opj_pi_iterator_t *opj_pi_initialise_encode(const opj_image_t *p_image,
opj_cp_t *p_cp,
OPJ_UINT32 p_tile_no,
J2K_T2_MODE p_t2_mode)
J2K_T2_MODE p_t2_mode,
opj_event_mgr_t* manager)
{
OPJ_UINT32 numcomps = p_image->numcomps;
@ -1567,7 +1631,7 @@ opj_pi_iterator_t *opj_pi_initialise_encode(const opj_image_t *p_image,
/* encoding prameters to set*/
OPJ_UINT32 l_max_res;
OPJ_UINT32 l_max_prec;
OPJ_INT32 l_tx0, l_tx1, l_ty0, l_ty1;
OPJ_UINT32 l_tx0, l_tx1, l_ty0, l_ty1;
OPJ_UINT32 l_dx_min, l_dy_min;
OPJ_UINT32 l_bound;
OPJ_UINT32 l_step_p, l_step_c, l_step_r, l_step_l ;
@ -1606,7 +1670,7 @@ opj_pi_iterator_t *opj_pi_initialise_encode(const opj_image_t *p_image,
}
/* memory allocation for pi*/
l_pi = opj_pi_create(p_image, p_cp, p_tile_no);
l_pi = opj_pi_create(p_image, p_cp, p_tile_no, manager);
if (!l_pi) {
opj_free(l_tmp_data);
opj_free(l_tmp_ptr);
@ -1761,7 +1825,8 @@ void opj_pi_create_encode(opj_pi_iterator_t *pi,
pi[pino].poc.prg = tcp->prg;
if (!(cp->m_specific_param.m_enc.m_tp_on && ((!OPJ_IS_CINEMA(cp->rsiz) &&
(t2_mode == FINAL_PASS)) || OPJ_IS_CINEMA(cp->rsiz)))) {
!OPJ_IS_IMF(cp->rsiz) &&
(t2_mode == FINAL_PASS)) || OPJ_IS_CINEMA(cp->rsiz) || OPJ_IS_IMF(cp->rsiz)))) {
pi[pino].poc.resno0 = tcp->resS;
pi[pino].poc.resno1 = tcp->resE;
pi[pino].poc.compno0 = tcp->compS;
@ -1770,10 +1835,10 @@ void opj_pi_create_encode(opj_pi_iterator_t *pi,
pi[pino].poc.layno1 = tcp->layE;
pi[pino].poc.precno0 = tcp->prcS;
pi[pino].poc.precno1 = tcp->prcE;
pi[pino].poc.tx0 = (OPJ_INT32)tcp->txS;
pi[pino].poc.ty0 = (OPJ_INT32)tcp->tyS;
pi[pino].poc.tx1 = (OPJ_INT32)tcp->txE;
pi[pino].poc.ty1 = (OPJ_INT32)tcp->tyE;
pi[pino].poc.tx0 = tcp->txS;
pi[pino].poc.ty0 = tcp->tyS;
pi[pino].poc.tx1 = tcp->txE;
pi[pino].poc.ty1 = tcp->tyE;
} else {
for (i = tppos + 1; i < 4; i++) {
switch (prog[i]) {
@ -1797,10 +1862,10 @@ void opj_pi_create_encode(opj_pi_iterator_t *pi,
pi[pino].poc.precno1 = tcp->prcE;
break;
default:
pi[pino].poc.tx0 = (OPJ_INT32)tcp->txS;
pi[pino].poc.ty0 = (OPJ_INT32)tcp->tyS;
pi[pino].poc.tx1 = (OPJ_INT32)tcp->txE;
pi[pino].poc.ty1 = (OPJ_INT32)tcp->tyE;
pi[pino].poc.tx0 = tcp->txS;
pi[pino].poc.ty0 = tcp->tyS;
pi[pino].poc.tx1 = tcp->txE;
pi[pino].poc.ty1 = tcp->tyE;
break;
}
break;
@ -1840,10 +1905,10 @@ void opj_pi_create_encode(opj_pi_iterator_t *pi,
default:
tcp->tx0_t = tcp->txS;
tcp->ty0_t = tcp->tyS;
pi[pino].poc.tx0 = (OPJ_INT32)tcp->tx0_t;
pi[pino].poc.tx1 = (OPJ_INT32)(tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx));
pi[pino].poc.ty0 = (OPJ_INT32)tcp->ty0_t;
pi[pino].poc.ty1 = (OPJ_INT32)(tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy));
pi[pino].poc.tx0 = tcp->tx0_t;
pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx);
pi[pino].poc.ty0 = tcp->ty0_t;
pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy);
tcp->tx0_t = (OPJ_UINT32)pi[pino].poc.tx1;
tcp->ty0_t = (OPJ_UINT32)pi[pino].poc.ty1;
break;
@ -1875,10 +1940,10 @@ void opj_pi_create_encode(opj_pi_iterator_t *pi,
pi[pino].poc.precno1 = tcp->prc_t;
break;
default:
pi[pino].poc.tx0 = (OPJ_INT32)(tcp->tx0_t - tcp->dx - (tcp->tx0_t % tcp->dx));
pi[pino].poc.tx1 = (OPJ_INT32)tcp->tx0_t ;
pi[pino].poc.ty0 = (OPJ_INT32)(tcp->ty0_t - tcp->dy - (tcp->ty0_t % tcp->dy));
pi[pino].poc.ty1 = (OPJ_INT32)tcp->ty0_t ;
pi[pino].poc.tx0 = tcp->tx0_t - tcp->dx - (tcp->tx0_t % tcp->dx);
pi[pino].poc.tx1 = tcp->tx0_t ;
pi[pino].poc.ty0 = tcp->ty0_t - tcp->dy - (tcp->ty0_t % tcp->dy);
pi[pino].poc.ty1 = tcp->ty0_t ;
break;
}
break;
@ -1965,8 +2030,8 @@ void opj_pi_create_encode(opj_pi_iterator_t *pi,
if (tcp->ty0_t >= tcp->tyE) {
if (opj_pi_check_next_level(i - 1, cp, tileno, pino, prog)) {
tcp->ty0_t = tcp->tyS;
pi[pino].poc.ty0 = (OPJ_INT32)tcp->ty0_t;
pi[pino].poc.ty1 = (OPJ_INT32)(tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy));
pi[pino].poc.ty0 = tcp->ty0_t;
pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy);
tcp->ty0_t = (OPJ_UINT32)pi[pino].poc.ty1;
incr_top = 1;
resetX = 1;
@ -1975,21 +2040,21 @@ void opj_pi_create_encode(opj_pi_iterator_t *pi,
resetX = 0;
}
} else {
pi[pino].poc.ty0 = (OPJ_INT32)tcp->ty0_t;
pi[pino].poc.ty1 = (OPJ_INT32)(tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy));
pi[pino].poc.ty0 = tcp->ty0_t;
pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy);
tcp->ty0_t = (OPJ_UINT32)pi[pino].poc.ty1;
incr_top = 0;
resetX = 1;
}
if (resetX == 1) {
tcp->tx0_t = tcp->txS;
pi[pino].poc.tx0 = (OPJ_INT32)tcp->tx0_t;
pi[pino].poc.tx1 = (OPJ_INT32)(tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx));
pi[pino].poc.tx0 = tcp->tx0_t;
pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx);
tcp->tx0_t = (OPJ_UINT32)pi[pino].poc.tx1;
}
} else {
pi[pino].poc.tx0 = (OPJ_INT32)tcp->tx0_t;
pi[pino].poc.tx1 = (OPJ_INT32)(tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx));
pi[pino].poc.tx0 = tcp->tx0_t;
pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx);
tcp->tx0_t = (OPJ_UINT32)pi[pino].poc.tx1;
incr_top = 0;
}
@ -2042,7 +2107,7 @@ void opj_pi_update_encoding_parameters(const opj_image_t *p_image,
/* encoding parameters to set */
OPJ_UINT32 l_max_res;
OPJ_UINT32 l_max_prec;
OPJ_INT32 l_tx0, l_tx1, l_ty0, l_ty1;
OPJ_UINT32 l_tx0, l_tx1, l_ty0, l_ty1;
OPJ_UINT32 l_dx_min, l_dy_min;
/* pointers */

@ -102,11 +102,13 @@ typedef struct opj_pi_iterator {
/** Components*/
opj_pi_comp_t *comps;
/** FIXME DOC*/
OPJ_INT32 tx0, ty0, tx1, ty1;
OPJ_UINT32 tx0, ty0, tx1, ty1;
/** FIXME DOC*/
OPJ_INT32 x, y;
OPJ_UINT32 x, y;
/** FIXME DOC*/
OPJ_UINT32 dx, dy;
/** event manager */
opj_event_mgr_t* manager;
} opj_pi_iterator_t;
/** @name Exported functions */
@ -119,13 +121,15 @@ typedef struct opj_pi_iterator {
* @param cp the coding parameters.
* @param tileno index of the tile being encoded.
* @param t2_mode the type of pass for generating the packet iterator
* @param manager Event manager
*
* @return a list of packet iterator that points to the first packet of the tile (not true).
*/
opj_pi_iterator_t *opj_pi_initialise_encode(const opj_image_t *image,
opj_cp_t *cp,
OPJ_UINT32 tileno,
J2K_T2_MODE t2_mode);
J2K_T2_MODE t2_mode,
opj_event_mgr_t* manager);
/**
* Updates the encoding parameters of the codec.
@ -161,12 +165,14 @@ Create a packet iterator for Decoder
@param image Raw image for which the packets will be listed
@param cp Coding parameters
@param tileno Number that identifies the tile for which to list the packets
@param manager Event manager
@return Returns a packet iterator that points to the first packet of the tile
@see opj_pi_destroy
*/
opj_pi_iterator_t *opj_pi_create_decode(opj_image_t * image,
opj_cp_t * cp,
OPJ_UINT32 tileno);
OPJ_UINT32 tileno,
opj_event_mgr_t* manager);
/**
* Destroys a packet iterator array.
*
@ -182,6 +188,17 @@ Modify the packet iterator to point to the next packet
@return Returns false if pi pointed to the last packet or else returns true
*/
OPJ_BOOL opj_pi_next(opj_pi_iterator_t * pi);
/**
* Return the number of packets in the tile.
* @param image the image being encoded.
* @param cp Coding parameters
* @param tileno Number that identifies the tile.
*/
OPJ_UINT32 opj_get_encoding_packet_count(const opj_image_t *p_image,
const opj_cp_t *p_cp,
OPJ_UINT32 p_tile_no);
/* ----------------------------------------------------------------------- */
/*@}*/

File diff suppressed because it is too large Load Diff

@ -198,7 +198,6 @@ typedef struct opj_t1 {
OPJ_UINT32 h;
OPJ_UINT32 datasize;
OPJ_UINT32 flagssize;
OPJ_UINT32 data_stride;
OPJ_BOOL encoder;
/* Thre 3 variables below are only used by the decoder */
@ -216,13 +215,13 @@ typedef struct opj_t1 {
/**
Encode the code-blocks of a tile
@param t1 T1 handle
@param tcd TCD handle
@param tile The tile to encode
@param tcp Tile coding parameters
@param mct_norms FIXME DOC
@param mct_numcomps Number of components used for MCT
*/
OPJ_BOOL opj_t1_encode_cblks(opj_t1_t *t1,
OPJ_BOOL opj_t1_encode_cblks(opj_tcd_t* tcd,
opj_tcd_tile_t *tile,
opj_tcp_t *tcp,
const OPJ_FLOAT64 * mct_norms,

@ -224,6 +224,7 @@ OPJ_BOOL opj_t2_encode_packets(opj_t2_t* p_t2,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 p_max_len,
opj_codestream_info_t *cstr_info,
opj_tcd_marker_info_t* p_marker_info,
OPJ_UINT32 p_tp_num,
OPJ_INT32 p_tp_pos,
OPJ_UINT32 p_pino,
@ -244,7 +245,7 @@ OPJ_BOOL opj_t2_encode_packets(opj_t2_t* p_t2,
l_image->numcomps : 1;
OPJ_UINT32 l_nb_pocs = l_tcp->numpocs + 1;
l_pi = opj_pi_initialise_encode(l_image, l_cp, p_tile_no, p_t2_mode);
l_pi = opj_pi_initialise_encode(l_image, l_cp, p_tile_no, p_t2_mode, p_manager);
if (!l_pi) {
return OPJ_FALSE;
}
@ -310,6 +311,20 @@ OPJ_BOOL opj_t2_encode_packets(opj_t2_t* p_t2,
opj_pi_destroy(l_pi, l_nb_pocs);
return OPJ_FALSE;
}
if (p_marker_info && p_marker_info->need_PLT) {
/* One time use intended */
assert(p_marker_info->packet_count == 0);
assert(p_marker_info->p_packet_size == NULL);
p_marker_info->p_packet_size = (OPJ_UINT32*) opj_malloc(
opj_get_encoding_packet_count(l_image, l_cp, p_tile_no) * sizeof(OPJ_UINT32));
if (p_marker_info->p_packet_size == NULL) {
opj_pi_destroy(l_pi, l_nb_pocs);
return OPJ_FALSE;
}
}
while (opj_pi_next(l_current_pi)) {
if (l_current_pi->layno < p_maxlayers) {
l_nb_bytes = 0;
@ -326,6 +341,11 @@ OPJ_BOOL opj_t2_encode_packets(opj_t2_t* p_t2,
* p_data_written += l_nb_bytes;
if (p_marker_info && p_marker_info->need_PLT) {
p_marker_info->p_packet_size[p_marker_info->packet_count] = l_nb_bytes;
p_marker_info->packet_count ++;
}
/* INDEX >> */
if (cstr_info) {
if (cstr_info->index_write) {
@ -405,7 +425,7 @@ OPJ_BOOL opj_t2_decode_packets(opj_tcd_t* tcd,
#endif
/* create a packet iterator */
l_pi = opj_pi_create_decode(l_image, l_cp, p_tile_no);
l_pi = opj_pi_create_decode(l_image, l_cp, p_tile_no, p_manager);
if (!l_pi) {
return OPJ_FALSE;
}
@ -673,6 +693,14 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
OPJ_BOOL packet_empty = OPJ_FALSE;
#endif
#ifdef DEBUG_VERBOSE
if (p_t2_mode == FINAL_PASS) {
fprintf(stderr,
"encode packet compono=%d, resno=%d, precno=%d, layno=%d\n",
compno, resno, precno, layno);
}
#endif
/* <SOP 0xff91> */
if (tcp->csty & J2K_CP_CSTY_SOP) {
if (length < 6) {
@ -711,6 +739,15 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
continue;
}
/* Avoid out of bounds access of https://github.com/uclouvain/openjpeg/issues/1294 */
/* but likely not a proper fix. */
if (precno >= res->pw * res->ph) {
opj_event_msg(p_manager, EVT_ERROR,
"opj_t2_encode_packet(): accessing precno=%u >= %u\n",
precno, res->pw * res->ph);
return OPJ_FALSE;
}
prc = &band->precincts[precno];
opj_tgt_reset(prc->incltree);
opj_tgt_reset(prc->imsbtree);
@ -778,6 +815,15 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
continue;
}
/* Avoid out of bounds access of https://github.com/uclouvain/openjpeg/issues/1297 */
/* but likely not a proper fix. */
if (precno >= res->pw * res->ph) {
opj_event_msg(p_manager, EVT_ERROR,
"opj_t2_encode_packet(): accessing precno=%u >= %u\n",
precno, res->pw * res->ph);
return OPJ_FALSE;
}
prc = &band->precincts[precno];
l_nb_blocks = prc->cw * prc->ch;
cblk = prc->cblks.enc;

@ -73,6 +73,7 @@ Encode the packets of a tile to a destination buffer
@param p_data_written FIXME DOC
@param len the length of the destination buffer
@param cstr_info Codestream information structure
@param p_marker_info Marker information structure
@param tpnum Tile part number of the current tile
@param tppos The position of the tile part flag in the progression order
@param pino FIXME DOC
@ -87,6 +88,7 @@ OPJ_BOOL opj_t2_encode_packets(opj_t2_t* t2,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 len,
opj_codestream_info_t *cstr_info,
opj_tcd_marker_info_t* p_marker_info,
OPJ_UINT32 tpnum,
OPJ_INT32 tppos,
OPJ_UINT32 pino,

@ -112,7 +112,7 @@ void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img)
* Initializes tile coding/decoding
*/
static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
OPJ_BOOL isEncoder, OPJ_FLOAT32 fraction, OPJ_SIZE_T sizeof_block,
OPJ_BOOL isEncoder, OPJ_SIZE_T sizeof_block,
opj_event_mgr_t* manager);
/**
@ -182,6 +182,7 @@ static OPJ_BOOL opj_tcd_t2_encode(opj_tcd_t *p_tcd,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 p_max_dest_size,
opj_codestream_info_t *p_cstr_info,
opj_tcd_marker_info_t* p_marker_info,
opj_event_mgr_t *p_manager);
static OPJ_BOOL opj_tcd_rate_allocate_encode(opj_tcd_t *p_tcd,
@ -573,9 +574,10 @@ OPJ_BOOL opj_tcd_rateallocate(opj_tcd_t *tcd,
opj_tcd_makelayer(tcd, layno, thresh, 0);
if (cp->m_specific_param.m_enc.m_fixed_quality) { /* fixed_quality */
if (OPJ_IS_CINEMA(cp->rsiz)) {
if (OPJ_IS_CINEMA(cp->rsiz) || OPJ_IS_IMF(cp->rsiz)) {
if (! opj_t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest,
p_data_written, maxlen, cstr_info, tcd->cur_tp_num, tcd->tp_pos, tcd->cur_pino,
p_data_written, maxlen, cstr_info, NULL, tcd->cur_tp_num, tcd->tp_pos,
tcd->cur_pino,
THRESH_CALC, p_manager)) {
lo = thresh;
@ -605,7 +607,8 @@ OPJ_BOOL opj_tcd_rateallocate(opj_tcd_t *tcd,
}
} else {
if (! opj_t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest,
p_data_written, maxlen, cstr_info, tcd->cur_tp_num, tcd->tp_pos, tcd->cur_pino,
p_data_written, maxlen, cstr_info, NULL, tcd->cur_tp_num, tcd->tp_pos,
tcd->cur_pino,
THRESH_CALC, p_manager)) {
/* TODO: what to do with l ??? seek / tell ??? */
/* opj_event_msg(tcd->cinfo, EVT_INFO, "rate alloc: len=%d, max=%d\n", l, maxlen); */
@ -718,10 +721,9 @@ OPJ_BOOL opj_alloc_tile_component_data(opj_tcd_tilecomp_t *l_tilec)
/* ----------------------------------------------------------------------- */
static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
OPJ_BOOL isEncoder, OPJ_FLOAT32 fraction, OPJ_SIZE_T sizeof_block,
OPJ_BOOL isEncoder, OPJ_SIZE_T sizeof_block,
opj_event_mgr_t* manager)
{
OPJ_UINT32(*l_gain_ptr)(OPJ_UINT32) = 00;
OPJ_UINT32 compno, resno, bandno, precno, cblkno;
opj_tcp_t * l_tcp = 00;
opj_cp_t * l_cp = 00;
@ -737,7 +739,6 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
OPJ_UINT32 p, q;
OPJ_UINT32 l_level_no;
OPJ_UINT32 l_pdx, l_pdy;
OPJ_UINT32 l_gain;
OPJ_INT32 l_x0b, l_y0b;
OPJ_UINT32 l_tx0, l_ty0;
/* extent of precincts , top left, bottom right**/
@ -876,11 +877,6 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
l_level_no = l_tilec->numresolutions;
l_res = l_tilec->resolutions;
l_step_size = l_tccp->stepsizes;
if (l_tccp->qmfbid == 0) {
l_gain_ptr = &opj_dwt_getgain_real;
} else {
l_gain_ptr = &opj_dwt_getgain;
}
/*fprintf(stderr, "\tlevel_no=%d\n",l_level_no);*/
for (resno = 0; resno < l_tilec->numresolutions; ++resno) {
@ -905,8 +901,24 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
/* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */
l_tl_prc_x_start = opj_int_floordivpow2(l_res->x0, (OPJ_INT32)l_pdx) << l_pdx;
l_tl_prc_y_start = opj_int_floordivpow2(l_res->y0, (OPJ_INT32)l_pdy) << l_pdy;
l_br_prc_x_end = opj_int_ceildivpow2(l_res->x1, (OPJ_INT32)l_pdx) << l_pdx;
l_br_prc_y_end = opj_int_ceildivpow2(l_res->y1, (OPJ_INT32)l_pdy) << l_pdy;
{
OPJ_UINT32 tmp = ((OPJ_UINT32)opj_int_ceildivpow2(l_res->x1,
(OPJ_INT32)l_pdx)) << l_pdx;
if (tmp > (OPJ_UINT32)INT_MAX) {
opj_event_msg(manager, EVT_ERROR, "Integer overflow\n");
return OPJ_FALSE;
}
l_br_prc_x_end = (OPJ_INT32)tmp;
}
{
OPJ_UINT32 tmp = ((OPJ_UINT32)opj_int_ceildivpow2(l_res->y1,
(OPJ_INT32)l_pdy)) << l_pdy;
if (tmp > (OPJ_UINT32)INT_MAX) {
opj_event_msg(manager, EVT_ERROR, "Integer overflow\n");
return OPJ_FALSE;
}
l_br_prc_y_end = (OPJ_INT32)tmp;
}
/*fprintf(stderr, "\t\t\tprc_x_start=%d, prc_y_start=%d, br_prc_x_end=%d, br_prc_y_end=%d \n", l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end ,l_br_prc_y_end );*/
l_res->pw = (l_res->x0 == l_res->x1) ? 0U : (OPJ_UINT32)((
@ -951,7 +963,6 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
l_band = l_res->bands;
for (bandno = 0; bandno < l_res->numbands; ++bandno, ++l_band, ++l_step_size) {
OPJ_INT32 numbps;
/*fprintf(stderr, "\t\t\tband_no=%d/%d\n", bandno, l_res->numbands );*/
if (resno == 0) {
@ -987,11 +998,24 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
}
}
/** avoid an if with storing function pointer */
l_gain = (*l_gain_ptr)(l_band->bandno);
numbps = (OPJ_INT32)(l_image_comp->prec + l_gain);
l_band->stepsize = (OPJ_FLOAT32)(((1.0 + l_step_size->mant / 2048.0) * pow(2.0,
(OPJ_INT32)(numbps - l_step_size->expn)))) * fraction;
{
/* Table E-1 - Sub-band gains */
/* BUG_WEIRD_TWO_INVK (look for this identifier in dwt.c): */
/* the test (!isEncoder && l_tccp->qmfbid == 0) is strongly */
/* linked to the use of two_invK instead of invK */
const OPJ_INT32 log2_gain = (!isEncoder &&
l_tccp->qmfbid == 0) ? 0 : (l_band->bandno == 0) ? 0 :
(l_band->bandno == 3) ? 2 : 1;
/* Nominal dynamic range. Equation E-4 */
const OPJ_INT32 Rb = (OPJ_INT32)l_image_comp->prec + log2_gain;
/* Delta_b value of Equation E-3 in "E.1 Inverse quantization
* procedure" of the standard */
l_band->stepsize = (OPJ_FLOAT32)(((1.0 + l_step_size->mant / 2048.0) * pow(2.0,
(OPJ_INT32)(Rb - l_step_size->expn))));
}
/* Mb value of Equation E-2 in "E.1 Inverse quantization
* procedure" of the standard */
l_band->numbps = l_step_size->expn + (OPJ_INT32)l_tccp->numgbits -
@ -1174,14 +1198,14 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
OPJ_BOOL opj_tcd_init_encode_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
opj_event_mgr_t* p_manager)
{
return opj_tcd_init_tile(p_tcd, p_tile_no, OPJ_TRUE, 1.0F,
return opj_tcd_init_tile(p_tcd, p_tile_no, OPJ_TRUE,
sizeof(opj_tcd_cblk_enc_t), p_manager);
}
OPJ_BOOL opj_tcd_init_decode_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
opj_event_mgr_t* p_manager)
{
return opj_tcd_init_tile(p_tcd, p_tile_no, OPJ_FALSE, 0.5F,
return opj_tcd_init_tile(p_tcd, p_tile_no, OPJ_FALSE,
sizeof(opj_tcd_cblk_dec_t), p_manager);
}
@ -1219,10 +1243,16 @@ static OPJ_BOOL opj_tcd_code_block_enc_allocate_data(opj_tcd_cblk_enc_t *
/* +1 is needed for https://github.com/uclouvain/openjpeg/issues/835 */
/* and actually +2 required for https://github.com/uclouvain/openjpeg/issues/982 */
/* and +7 for https://github.com/uclouvain/openjpeg/issues/1283 (-M 3) */
/* and +26 for https://github.com/uclouvain/openjpeg/issues/1283 (-M 7) */
/* and +28 for https://github.com/uclouvain/openjpeg/issues/1283 (-M 44) */
/* and +33 for https://github.com/uclouvain/openjpeg/issues/1283 (-M 4) */
/* and +63 for https://github.com/uclouvain/openjpeg/issues/1283 (-M 4 -IMF 2K) */
/* and +74 for https://github.com/uclouvain/openjpeg/issues/1283 (-M 4 -n 8 -s 7,7 -I) */
/* TODO: is there a theoretical upper-bound for the compressed code */
/* block size ? */
l_data_size = 2 + (OPJ_UINT32)((p_code_block->x1 - p_code_block->x0) *
(p_code_block->y1 - p_code_block->y0) * (OPJ_INT32)sizeof(OPJ_UINT32));
l_data_size = 74 + (OPJ_UINT32)((p_code_block->x1 - p_code_block->x0) *
(p_code_block->y1 - p_code_block->y0) * (OPJ_INT32)sizeof(OPJ_UINT32));
if (l_data_size > p_code_block->data_size) {
if (p_code_block->data) {
@ -1354,6 +1384,7 @@ OPJ_BOOL opj_tcd_encode_tile(opj_tcd_t *p_tcd,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 p_max_length,
opj_codestream_info_t *p_cstr_info,
opj_tcd_marker_info_t* p_marker_info,
opj_event_mgr_t *p_manager)
{
@ -1433,7 +1464,7 @@ OPJ_BOOL opj_tcd_encode_tile(opj_tcd_t *p_tcd,
/* FIXME _ProfStart(PGROUP_T2); */
if (! opj_tcd_t2_encode(p_tcd, p_dest, p_data_written, p_max_length,
p_cstr_info, p_manager)) {
p_cstr_info, p_marker_info, p_manager)) {
return OPJ_FALSE;
}
/* FIXME _ProfStop(PGROUP_T2); */
@ -2017,7 +2048,8 @@ static OPJ_BOOL opj_tcd_mct_decode(opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager)
opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
opj_tcp_t * l_tcp = p_tcd->tcp;
opj_tcd_tilecomp_t * l_tile_comp = l_tile->comps;
OPJ_UINT32 l_samples, i;
OPJ_SIZE_T l_samples;
OPJ_UINT32 i;
if (l_tcp->mct == 0 || p_tcd->used_component != NULL) {
return OPJ_TRUE;
@ -2030,8 +2062,8 @@ static OPJ_BOOL opj_tcd_mct_decode(opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager)
/* A bit inefficient: we process more data than needed if */
/* resno_decoded < l_tile_comp->minimum_num_resolutions-1, */
/* but we would need to take into account a stride then */
l_samples = (OPJ_UINT32)((res_comp0->x1 - res_comp0->x0) *
(res_comp0->y1 - res_comp0->y0));
l_samples = (OPJ_SIZE_T)(res_comp0->x1 - res_comp0->x0) *
(OPJ_SIZE_T)(res_comp0->y1 - res_comp0->y0);
if (l_tile->numcomps >= 3) {
if (l_tile_comp->minimum_num_resolutions !=
l_tile->comps[1].minimum_num_resolutions ||
@ -2065,8 +2097,8 @@ static OPJ_BOOL opj_tcd_mct_decode(opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager)
opj_tcd_resolution_t* res_comp0 = l_tile->comps[0].resolutions +
p_tcd->image->comps[0].resno_decoded;
l_samples = (res_comp0->win_x1 - res_comp0->win_x0) *
(res_comp0->win_y1 - res_comp0->win_y0);
l_samples = (OPJ_SIZE_T)(res_comp0->win_x1 - res_comp0->win_x0) *
(OPJ_SIZE_T)(res_comp0->win_y1 - res_comp0->win_y0);
if (l_tile->numcomps >= 3) {
opj_tcd_resolution_t* res_comp1 = l_tile->comps[1].resolutions +
p_tcd->image->comps[1].resno_decoded;
@ -2332,7 +2364,7 @@ static void opj_tcd_code_block_enc_deallocate(opj_tcd_precinct_t * p_precinct)
}
}
OPJ_SIZE_T opj_tcd_get_encoded_tile_size(opj_tcd_t *p_tcd)
OPJ_SIZE_T opj_tcd_get_encoder_input_buffer_size(opj_tcd_t *p_tcd)
{
OPJ_UINT32 i;
OPJ_SIZE_T l_data_size = 0;
@ -2390,7 +2422,8 @@ static OPJ_BOOL opj_tcd_dc_level_shift_encode(opj_tcd_t *p_tcd)
}
} else {
for (i = 0; i < l_nb_elem; ++i) {
*l_current_ptr = (*l_current_ptr - l_tccp->m_dc_level_shift) * (1 << 11);
*((OPJ_FLOAT32 *) l_current_ptr) = (OPJ_FLOAT32)(*l_current_ptr -
l_tccp->m_dc_level_shift);
++l_current_ptr;
}
}
@ -2448,8 +2481,11 @@ static OPJ_BOOL opj_tcd_mct_encode(opj_tcd_t *p_tcd)
opj_free(l_data);
} else if (l_tcp->tccps->qmfbid == 0) {
opj_mct_encode_real(l_tile->comps[0].data, l_tile->comps[1].data,
l_tile->comps[2].data, samples);
opj_mct_encode_real(
(OPJ_FLOAT32*)l_tile->comps[0].data,
(OPJ_FLOAT32*)l_tile->comps[1].data,
(OPJ_FLOAT32*)l_tile->comps[2].data,
samples);
} else {
opj_mct_encode(l_tile->comps[0].data, l_tile->comps[1].data,
l_tile->comps[2].data, samples);
@ -2467,11 +2503,11 @@ static OPJ_BOOL opj_tcd_dwt_encode(opj_tcd_t *p_tcd)
for (compno = 0; compno < l_tile->numcomps; ++compno) {
if (l_tccp->qmfbid == 1) {
if (! opj_dwt_encode(l_tile_comp)) {
if (! opj_dwt_encode(p_tcd, l_tile_comp)) {
return OPJ_FALSE;
}
} else if (l_tccp->qmfbid == 0) {
if (! opj_dwt_encode_real(l_tile_comp)) {
if (! opj_dwt_encode_real(p_tcd, l_tile_comp)) {
return OPJ_FALSE;
}
}
@ -2485,16 +2521,10 @@ static OPJ_BOOL opj_tcd_dwt_encode(opj_tcd_t *p_tcd)
static OPJ_BOOL opj_tcd_t1_encode(opj_tcd_t *p_tcd)
{
opj_t1_t * l_t1;
const OPJ_FLOAT64 * l_mct_norms;
OPJ_UINT32 l_mct_numcomps = 0U;
opj_tcp_t * l_tcp = p_tcd->tcp;
l_t1 = opj_t1_create(OPJ_TRUE);
if (l_t1 == 00) {
return OPJ_FALSE;
}
if (l_tcp->mct == 1) {
l_mct_numcomps = 3U;
/* irreversible encoding */
@ -2508,13 +2538,9 @@ static OPJ_BOOL opj_tcd_t1_encode(opj_tcd_t *p_tcd)
l_mct_norms = (const OPJ_FLOAT64 *)(l_tcp->mct_norms);
}
if (! opj_t1_encode_cblks(l_t1, p_tcd->tcd_image->tiles, l_tcp, l_mct_norms,
l_mct_numcomps)) {
opj_t1_destroy(l_t1);
return OPJ_FALSE;
}
opj_t1_destroy(l_t1);
return opj_t1_encode_cblks(p_tcd,
p_tcd->tcd_image->tiles, l_tcp, l_mct_norms,
l_mct_numcomps);
return OPJ_TRUE;
}
@ -2524,6 +2550,7 @@ static OPJ_BOOL opj_tcd_t2_encode(opj_tcd_t *p_tcd,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 p_max_dest_size,
opj_codestream_info_t *p_cstr_info,
opj_tcd_marker_info_t* p_marker_info,
opj_event_mgr_t *p_manager)
{
opj_t2_t * l_t2;
@ -2542,6 +2569,7 @@ static OPJ_BOOL opj_tcd_t2_encode(opj_tcd_t *p_tcd,
p_data_written,
p_max_dest_size,
p_cstr_info,
p_marker_info,
p_tcd->tp_num,
p_tcd->tp_pos,
p_tcd->cur_pino,
@ -2600,7 +2628,7 @@ OPJ_BOOL opj_tcd_copy_tile_data(opj_tcd_t *p_tcd,
OPJ_UINT32 l_size_comp, l_remaining;
OPJ_SIZE_T l_nb_elem;
l_data_size = opj_tcd_get_encoded_tile_size(p_tcd);
l_data_size = opj_tcd_get_encoder_input_buffer_size(p_tcd);
if (l_data_size != p_src_length) {
return OPJ_FALSE;
}
@ -2802,3 +2830,30 @@ static OPJ_BOOL opj_tcd_is_whole_tilecomp_decoding(opj_tcd_t *p_tcd,
(((OPJ_UINT32)tilec->x1 - tcx1) >> shift) == 0 &&
(((OPJ_UINT32)tilec->y1 - tcy1) >> shift) == 0)));
}
/* ----------------------------------------------------------------------- */
opj_tcd_marker_info_t* opj_tcd_marker_info_create(OPJ_BOOL need_PLT)
{
opj_tcd_marker_info_t *l_tcd_marker_info =
(opj_tcd_marker_info_t*) opj_calloc(1, sizeof(opj_tcd_marker_info_t));
if (!l_tcd_marker_info) {
return NULL;
}
l_tcd_marker_info->need_PLT = need_PLT;
return l_tcd_marker_info;
}
/* ----------------------------------------------------------------------- */
void opj_tcd_marker_info_destroy(opj_tcd_marker_info_t *p_tcd_marker_info)
{
if (p_tcd_marker_info) {
opj_free(p_tcd_marker_info->p_packet_size);
opj_free(p_tcd_marker_info);
}
}
/* ----------------------------------------------------------------------- */

@ -284,6 +284,22 @@ typedef struct opj_tcd {
OPJ_BOOL* used_component;
} opj_tcd_t;
/**
* Structure to hold information needed to generate some markers.
* Used by encoder.
*/
typedef struct opj_tcd_marker_info {
/** In: Whether information to generate PLT markers in needed */
OPJ_BOOL need_PLT;
/** OUT: Number of elements in p_packet_size[] array */
OPJ_UINT32 packet_count;
/** OUT: Array of size packet_count, such that p_packet_size[i] is
* the size in bytes of the ith packet */
OPJ_UINT32* p_packet_size;
} opj_tcd_marker_info_t;
/** @name Exported functions */
/*@{*/
/* ----------------------------------------------------------------------- */
@ -306,6 +322,21 @@ Destroy a previously created TCD handle
*/
void opj_tcd_destroy(opj_tcd_t *tcd);
/**
* Create a new opj_tcd_marker_info_t* structure
* @param need_PLT Whether information is needed to generate PLT markers.
*/
opj_tcd_marker_info_t* opj_tcd_marker_info_create(OPJ_BOOL need_PLT);
/**
Destroy a previously created opj_tcd_marker_info_t* structure
@param p_tcd_marker_info Structure to destroy
*/
void opj_tcd_marker_info_destroy(opj_tcd_marker_info_t *p_tcd_marker_info);
/**
* Initialize the tile coder and may reuse some memory.
* @param p_tcd TCD handle.
@ -364,6 +395,7 @@ OPJ_UINT32 opj_tcd_get_decoded_tile_size(opj_tcd_t *p_tcd,
* @param p_data_written pointer to an int that is incremented by the number of bytes really written on p_dest
* @param p_len Maximum length of the destination buffer
* @param p_cstr_info Codestream information structure
* @param p_marker_info Marker information structure
* @param p_manager the user event manager
* @return true if the coding is successful.
*/
@ -373,6 +405,7 @@ OPJ_BOOL opj_tcd_encode_tile(opj_tcd_t *p_tcd,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 p_len,
struct opj_codestream_info *p_cstr_info,
opj_tcd_marker_info_t* p_marker_info,
opj_event_mgr_t *p_manager);
@ -415,9 +448,11 @@ OPJ_BOOL opj_tcd_update_tile_data(opj_tcd_t *p_tcd,
OPJ_UINT32 p_dest_length);
/**
*
* Get the size in bytes of the input buffer provided before encoded.
* This must be the size provided to the p_src_length argument of
* opj_tcd_copy_tile_data()
*/
OPJ_SIZE_T opj_tcd_get_encoded_tile_size(opj_tcd_t *p_tcd);
OPJ_SIZE_T opj_tcd_get_encoder_input_buffer_size(opj_tcd_t *p_tcd);
/**
* Initialize the tile coder and may reuse some meory.
@ -433,6 +468,8 @@ OPJ_BOOL opj_tcd_init_encode_tile(opj_tcd_t *p_tcd,
/**
* Copies tile data from the given memory block onto the system.
*
* p_src_length must be equal to opj_tcd_get_encoder_input_buffer_size()
*/
OPJ_BOOL opj_tcd_copy_tile_data(opj_tcd_t *p_tcd,
OPJ_BYTE * p_src,

Loading…
Cancel
Save