summaryrefslogtreecommitdiff
path: root/openjpeg
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-09-27 16:08:57 +0100
committerRobin Watts <robin.watts@artifex.com>2016-09-27 16:52:27 +0100
commit9a78bfb8698061e22e3d460b8c15825992e44def (patch)
treed1350b9c7a02da811ec438eae175ca9689bf9d4c /openjpeg
parentb4cc6d28e9a456a34a7348d98ff78ada9da727bb (diff)
downloadghostpdl-9a78bfb8698061e22e3d460b8c15825992e44def.tar.gz
Import new OpenJPEG version.
Squashed version of openjpeg-update-20160927 This squashes the following commits: * Import new OpenJPEG version. From https://github.com/uclouvain/openjpeg Final commit is: commit 34dae137a9a8c04feaa9763ae7e09a86ecb10400 Author: Mathieu Malaterre <mathieu.malaterre@gmail.com> Date: Mon Sep 26 12:01:31 2016 +0200 OPENJPEG_NAMESPACE is configurable by user * Zap the OpenJPEG stuff we don't need * Add predefined openjpeg headers. * Import patches from Sumatra's tree. * Update Makefiles for new openjpeg * Update MSVC for new files * OpenJPEG allocation fixes. The old version of openjpeg allocates using malloc/free. The new version of openjpeg allocates via opj_malloc (and co). We can capture these and pass them down to our own allocators, but we cannot get openjpeg to pass us a gs_memory_t * to use. We therefore resort to using a static to hold 'the current gs_memory_t *' before we call openjpeg. To keep this threadsafe we add some private data to the gslibctx, which the openjpeg implementation can use to hold a lock. We add calls to both jpx decode implementations to init this private data (where the luratech implementation is null).
Diffstat (limited to 'openjpeg')
-rw-r--r--openjpeg/AUTHORS.md (renamed from openjpeg/AUTHORS)12
-rw-r--r--openjpeg/CHANGELOG.md391
-rw-r--r--openjpeg/CHANGES1116
-rw-r--r--openjpeg/NEWS61
-rw-r--r--openjpeg/NEWS.md67
-rw-r--r--openjpeg/THANKS33
-rw-r--r--openjpeg/THANKS.md38
-rw-r--r--openjpeg/src/lib/openjp2/CMakeLists.txt100
-rw-r--r--openjpeg/src/lib/openjp2/bio.c39
-rw-r--r--openjpeg/src/lib/openjp2/cidx_manager.c4
-rw-r--r--openjpeg/src/lib/openjp2/cio.c47
-rw-r--r--openjpeg/src/lib/openjp2/cio.h37
-rw-r--r--openjpeg/src/lib/openjp2/dwt.c316
-rw-r--r--openjpeg/src/lib/openjp2/dwt.h9
-rw-r--r--openjpeg/src/lib/openjp2/event.h6
-rw-r--r--openjpeg/src/lib/openjp2/function_list.c16
-rw-r--r--openjpeg/src/lib/openjp2/function_list.h2
-rw-r--r--openjpeg/src/lib/openjp2/image.c42
-rw-r--r--openjpeg/src/lib/openjp2/indexbox_manager.h2
-rw-r--r--openjpeg/src/lib/openjp2/invert.c8
-rw-r--r--openjpeg/src/lib/openjp2/j2k.c2582
-rw-r--r--openjpeg/src/lib/openjp2/j2k.h59
-rw-r--r--openjpeg/src/lib/openjp2/jp2.c833
-rw-r--r--openjpeg/src/lib/openjp2/jp2.h20
-rw-r--r--openjpeg/src/lib/openjp2/libopenjp2.pc.cmake.in14
-rw-r--r--openjpeg/src/lib/openjp2/mct.c264
-rw-r--r--openjpeg/src/lib/openjp2/mct.h8
-rw-r--r--openjpeg/src/lib/openjp2/mqc.c149
-rw-r--r--openjpeg/src/lib/openjp2/mqc.h5
-rw-r--r--openjpeg/src/lib/openjp2/mqc_inl.h159
-rw-r--r--openjpeg/src/lib/openjp2/openjpeg.c36
-rw-r--r--openjpeg/src/lib/openjp2/openjpeg.h70
-rw-r--r--openjpeg/src/lib/openjp2/opj_clock.c3
-rw-r--r--openjpeg/src/lib/openjp2/opj_codec.h12
-rw-r--r--openjpeg/src/lib/openjp2/opj_config.h.cmake.in10
-rw-r--r--openjpeg/src/lib/openjp2/opj_config_private.h.cmake.in31
-rw-r--r--openjpeg/src/lib/openjp2/opj_includes.h88
-rw-r--r--openjpeg/src/lib/openjp2/opj_intmath.h55
-rw-r--r--openjpeg/src/lib/openjp2/opj_malloc.c239
-rw-r--r--openjpeg/src/lib/openjp2/opj_malloc.h109
-rw-r--r--openjpeg/src/lib/openjp2/phix_manager.c4
-rw-r--r--openjpeg/src/lib/openjp2/pi.c86
-rw-r--r--openjpeg/src/lib/openjp2/pi.h2
-rw-r--r--openjpeg/src/lib/openjp2/ppix_manager.c4
-rw-r--r--openjpeg/src/lib/openjp2/raw.c2
-rw-r--r--openjpeg/src/lib/openjp2/t1.c1572
-rw-r--r--openjpeg/src/lib/openjp2/t1.h87
-rw-r--r--openjpeg/src/lib/openjp2/t1_generate_luts.c67
-rw-r--r--openjpeg/src/lib/openjp2/t1_luts.h14
-rw-r--r--openjpeg/src/lib/openjp2/t2.c152
-rw-r--r--openjpeg/src/lib/openjp2/t2.h3
-rw-r--r--openjpeg/src/lib/openjp2/tcd.c1065
-rw-r--r--openjpeg/src/lib/openjp2/tcd.h65
-rw-r--r--openjpeg/src/lib/openjp2/tgt.c16
-rw-r--r--openjpeg/src/lib/openjp2/tgt.h5
-rw-r--r--openjpeg/src/lib/openjp2/thix_manager.c4
-rw-r--r--openjpeg/src/lib/openjp2/thread.c968
-rw-r--r--openjpeg/src/lib/openjp2/thread.h253
-rw-r--r--openjpeg/src/lib/openjp2/tls_keys.h37
59 files changed, 7261 insertions, 4237 deletions
diff --git a/openjpeg/AUTHORS b/openjpeg/AUTHORS.md
index 998ea5d14..35aa84b55 100644
--- a/openjpeg/AUTHORS
+++ b/openjpeg/AUTHORS.md
@@ -1,12 +1,18 @@
-Authors of OpenJPEG
-See also the files THANKS and CHANGES
+# Authors of OpenJPEG
+See also [THANKS](https://github.com/uclouvain/openjpeg/blob/master/THANKS.md)
David Janssens designed and implemented the first version of OpenJPEG.
+
Kaori Hagihara designed and implemented the first version of OpenJPIP.
+
Jerome Fimes implemented the alpha version of OpenJPEG 2.0.
+
Giuseppe Baruffa added the JPWL functionalities.
-Mickaël Savinaud implemented the final OpenJPEG 2.0 version based on a big merge between 1.5 version and alpha version of 2.0.
+
+Mickaël Savinaud implemented the final OpenJPEG 2.0 version based on a big merge between 1.5 version and alpha version of 2.0.
+
Mathieu Malaterre participated to the OpenJPEG 2.0 version and improved the libraries and utilities.
+
Yannick Verschueren,
Herve Drolon,
Francois-Olivier Devaux,
diff --git a/openjpeg/CHANGELOG.md b/openjpeg/CHANGELOG.md
new file mode 100644
index 000000000..df3ef2b6a
--- /dev/null
+++ b/openjpeg/CHANGELOG.md
@@ -0,0 +1,391 @@
+# Changelog
+
+## [v2.1.1](https://github.com/uclouvain/openjpeg/releases/tag/v2.1.1) (2016-07-05)
+[Full Changelog](https://github.com/uclouvain/openjpeg/compare/version.2.1...v2.1.1)
+
+**Implemented enhancements:**
+
+- opj\_malloc replacement [\#625](https://github.com/uclouvain/openjpeg/issues/625)
+- backport "-p" and "-force-rgb" options in 1.5 [\#606](https://github.com/uclouvain/openjpeg/issues/606)
+- Use travis-ci matrix build [\#581](https://github.com/uclouvain/openjpeg/issues/581)
+- Add Coverity Scan analysis [\#580](https://github.com/uclouvain/openjpeg/issues/580)
+- Unnecessary rate distortion calculations [\#479](https://github.com/uclouvain/openjpeg/issues/479)
+- Add images from various security issues to test suite [\#415](https://github.com/uclouvain/openjpeg/issues/415)
+- Coding speed for 9/7 on 32bits platforms \(x86/ARM\) can be improved with a quick fix [\#220](https://github.com/uclouvain/openjpeg/issues/220)
+
+**Fixed bugs:**
+
+- Out-of-Bounds Access in function opj\_tgt\_reset of tgt.c [\#775](https://github.com/uclouvain/openjpeg/issues/775)
+- Heap Buffer Overflow in function color\_cmyk\_to\_rgb of color.c [\#774](https://github.com/uclouvain/openjpeg/issues/774)
+- division-by-zero \(SIGFPE\) error in opj\_tcd\_init\_tile function \(line 730 of tcd.c\) [\#733](https://github.com/uclouvain/openjpeg/issues/733)
+- Out-Of-Bounds Read in sycc422\_to\_rgb function [\#726](https://github.com/uclouvain/openjpeg/issues/726)
+- Heap Corruption in opj\_free function [\#725](https://github.com/uclouvain/openjpeg/issues/725)
+- Out-Of-Bounds Read in opj\_tcd\_free\_tile function [\#724](https://github.com/uclouvain/openjpeg/issues/724)
+- Cannot handle box of undefined size [\#653](https://github.com/uclouvain/openjpeg/issues/653)
+- Compilation fails without platform-supplied aligned malloc [\#642](https://github.com/uclouvain/openjpeg/issues/642)
+- HP compiler warns about redeclaration of static function [\#640](https://github.com/uclouvain/openjpeg/issues/640)
+- Implementation-defined behavior of malloc causes different behavior on Linux and AIX [\#635](https://github.com/uclouvain/openjpeg/issues/635)
+- Build on AIX fails because "opj\_includes.h" is included after system headers [\#633](https://github.com/uclouvain/openjpeg/issues/633)
+- Compiling with SSE2 on Linux 32-bit causes crashes in OpenJPEG [\#624](https://github.com/uclouvain/openjpeg/issues/624)
+- Build on AIX fails because of "restrict" pointers [\#620](https://github.com/uclouvain/openjpeg/issues/620)
+- bug in new tif conversion code [\#609](https://github.com/uclouvain/openjpeg/issues/609)
+- bin/jp2/convert.c line 1085 Resource leak [\#607](https://github.com/uclouvain/openjpeg/issues/607)
+- bin/jp2/convert.c memory leak [\#601](https://github.com/uclouvain/openjpeg/issues/601)
+- Resource leak in opj\_j2k\_create\_cstr\_index in case of failure [\#599](https://github.com/uclouvain/openjpeg/issues/599)
+- Resource leak in opj\_j2k\_encode in case of failure [\#598](https://github.com/uclouvain/openjpeg/issues/598)
+- Resource leak in opj\_j2k\_decode\_one\_tile in case of failure [\#597](https://github.com/uclouvain/openjpeg/issues/597)
+- Resource Leak [\#573](https://github.com/uclouvain/openjpeg/issues/573)
+- opj\_compress fails to compress lossless on gcc/x86 \(-m32\) [\#571](https://github.com/uclouvain/openjpeg/issues/571)
+- Use-after-free in opj\_j2k\_write\_mco [\#563](https://github.com/uclouvain/openjpeg/issues/563)
+- openjpeg-master-2015-07-30 failed to compile on LINUX [\#556](https://github.com/uclouvain/openjpeg/issues/556)
+- PNG images are always read as RGB\(A\) images [\#536](https://github.com/uclouvain/openjpeg/issues/536)
+- g4\_colr.j2c not handled properly [\#532](https://github.com/uclouvain/openjpeg/issues/532)
+- Bigendian: opj\_compress + opj\_decompress fails [\#518](https://github.com/uclouvain/openjpeg/issues/518)
+- Suspicious code in j2k.c [\#517](https://github.com/uclouvain/openjpeg/issues/517)
+- Decode times almost double\(!!\) on Visual Studio 2013, 2015 [\#505](https://github.com/uclouvain/openjpeg/issues/505)
+- opj\_data/input/nonregression/issue226.j2k [\#500](https://github.com/uclouvain/openjpeg/issues/500)
+- opj\_setup\_encoder always returns true [\#497](https://github.com/uclouvain/openjpeg/issues/497)
+- Double free in j2k\_read\_ppm\_v3 parsing \(\(presumably invalid\) image. [\#496](https://github.com/uclouvain/openjpeg/issues/496)
+- Invalid write in opj\_j2k\_update\_image\_data [\#495](https://github.com/uclouvain/openjpeg/issues/495)
+- Undefined printf format specifier %ud used in code [\#494](https://github.com/uclouvain/openjpeg/issues/494)
+- Potential double free on malloc failure in opj\_j2k\_copy\_default\_tcp\_and\_create\_tcp\(\) [\#492](https://github.com/uclouvain/openjpeg/issues/492)
+- Do not link with -ffast-math [\#488](https://github.com/uclouvain/openjpeg/issues/488)
+- Heap-buffer-overflow in opj\_dwt\_decode [\#486](https://github.com/uclouvain/openjpeg/issues/486)
+- opj\_dump fails on Windows 7, 64 bits [\#482](https://github.com/uclouvain/openjpeg/issues/482)
+- SIGSEGV in opj\_j2k\_update\_image\_data via pdfium\_test [\#481](https://github.com/uclouvain/openjpeg/issues/481)
+- Heap-buffer-overflow in opj\_j2k\_tcp\_destroy [\#477](https://github.com/uclouvain/openjpeg/issues/477)
+- Invalid image causes write past end of heap buffer [\#476](https://github.com/uclouvain/openjpeg/issues/476)
+- Assertion `l\_res-\>x0 \>= 0' fails when parsing invalid images [\#475](https://github.com/uclouvain/openjpeg/issues/475)
+- Bug on opj\_write\_bytes\_BE function [\#472](https://github.com/uclouvain/openjpeg/issues/472)
+- Refactor j2k\_read\_ppm\_v3 function [\#470](https://github.com/uclouvain/openjpeg/issues/470)
+- compression: strange precinct dimensions [\#466](https://github.com/uclouvain/openjpeg/issues/466)
+- \(:- Console message in opj\_decompress -:\) [\#465](https://github.com/uclouvain/openjpeg/issues/465)
+- opj\_decompress fails to decompress any files [\#463](https://github.com/uclouvain/openjpeg/issues/463)
+- bio-\>ct is unnecessarily set to zero in opj\_bio\_flush method [\#461](https://github.com/uclouvain/openjpeg/issues/461)
+- Maximal unsigned short is 65535, not 65536 [\#460](https://github.com/uclouvain/openjpeg/issues/460)
+- OpenJpeg fails to encode components with different precision properly [\#459](https://github.com/uclouvain/openjpeg/issues/459)
+- component precision upscaling isn't correct in opj\_decompress [\#458](https://github.com/uclouvain/openjpeg/issues/458)
+- Multiple precision components won't get encoded to jp2 if 1 component is unsigned 1 bit [\#457](https://github.com/uclouvain/openjpeg/issues/457)
+- Incorrect code in ../bin/jp2/convert.c, function rawtoimage\_common\(...\) [\#456](https://github.com/uclouvain/openjpeg/issues/456)
+- \[OpenJPEG-trunk\] opj\_stream\_get\_number\_byte\_left throws assert [\#455](https://github.com/uclouvain/openjpeg/issues/455)
+- NR-DEC-kodak\_2layers\_lrcp.j2c-31-decode-md5 fails randomly when running tests in parallel [\#454](https://github.com/uclouvain/openjpeg/issues/454)
+- compare\_raw\_files doesn't report an error on invalid arguments / missing input files [\#453](https://github.com/uclouvain/openjpeg/issues/453)
+- Forward discrete wavelet transform: implement periodic symmetric extension at boundaries [\#452](https://github.com/uclouvain/openjpeg/issues/452)
+- Bug in tiff reading method in convert.c [\#449](https://github.com/uclouvain/openjpeg/issues/449)
+- Image in pdf don't display [\#447](https://github.com/uclouvain/openjpeg/issues/447)
+- Multiple issues causing opj\_decompress to segfault [\#446](https://github.com/uclouvain/openjpeg/issues/446)
+- opj\_compress: 40% of encode time is spent freeing data [\#445](https://github.com/uclouvain/openjpeg/issues/445)
+- Multiple warnings when configuring OpenJPEG on MacOS with CMake 3.x \(trunk\) [\#443](https://github.com/uclouvain/openjpeg/issues/443)
+- valgrind memleak found [\#437](https://github.com/uclouvain/openjpeg/issues/437)
+- global-buffer-overflow src/lib/openjp2/t1.c:1146 opj\_t1\_getwmsedec [\#436](https://github.com/uclouvain/openjpeg/issues/436)
+- Warning introduced on trunk r2923 & r2924 [\#435](https://github.com/uclouvain/openjpeg/issues/435)
+- heap-buffer-overflow in opj\_t1\_decode\_cblks [\#432](https://github.com/uclouvain/openjpeg/issues/432)
+- Heap-buffer-overflow in opj\_tcd\_init\_decode\_tile [\#431](https://github.com/uclouvain/openjpeg/issues/431)
+- Heap-buffer-overflow in opj\_j2k\_tcp\_destroy [\#430](https://github.com/uclouvain/openjpeg/issues/430)
+- Heap-buffer-overflow in opj\_jp2\_apply\_pclr [\#429](https://github.com/uclouvain/openjpeg/issues/429)
+- issue412 revisited [\#428](https://github.com/uclouvain/openjpeg/issues/428)
+- Image distorted \(sides look cankered\) [\#423](https://github.com/uclouvain/openjpeg/issues/423)
+- openjpeg-2.x-trunk-r2918 is broken in color.c [\#422](https://github.com/uclouvain/openjpeg/issues/422)
+- Heap-buffer-overflow in opj\_tcd\_init\_decode\_tile [\#420](https://github.com/uclouvain/openjpeg/issues/420)
+- Heap-use-after-free in opj\_t1\_decode\_cblks [\#418](https://github.com/uclouvain/openjpeg/issues/418)
+- UNKNOWN in opj\_read\_bytes\_LE [\#417](https://github.com/uclouvain/openjpeg/issues/417)
+- Transparency problem [\#416](https://github.com/uclouvain/openjpeg/issues/416)
+- Image with per channel alpha \(cdef\) does not decode properly [\#414](https://github.com/uclouvain/openjpeg/issues/414)
+- OpenJPEG crashes with attached image [\#413](https://github.com/uclouvain/openjpeg/issues/413)
+- Palette image with cdef fails to decompress [\#412](https://github.com/uclouvain/openjpeg/issues/412)
+- Invalid member values from opj\_read\_header or opj\_decode ? [\#411](https://github.com/uclouvain/openjpeg/issues/411)
+- MD5 Checksum hangs under valgrind on MacOS X [\#410](https://github.com/uclouvain/openjpeg/issues/410)
+- Heap-buffer-overflow in opj\_tcd\_get\_decoded\_tile\_size [\#408](https://github.com/uclouvain/openjpeg/issues/408)
+- C++ style comments in trunk/src/lib/openjp2/j2k.c [\#407](https://github.com/uclouvain/openjpeg/issues/407)
+- Backport bugfixes from trunk to 2.1 branch [\#405](https://github.com/uclouvain/openjpeg/issues/405)
+- Heap-buffer-overflow in parse\_cmdline\_encoder [\#403](https://github.com/uclouvain/openjpeg/issues/403)
+- Heap-buffer-overflow in opj\_v4dwt\_interleave\_h [\#400](https://github.com/uclouvain/openjpeg/issues/400)
+- Heap-buffer-overflow in opj\_dwt\_decode [\#399](https://github.com/uclouvain/openjpeg/issues/399)
+- Heap-use-after-free in opj\_t1\_decode\_cblks [\#398](https://github.com/uclouvain/openjpeg/issues/398)
+- Heap-buffer-overflow in opj\_jp2\_apply\_cdef [\#397](https://github.com/uclouvain/openjpeg/issues/397)
+- Heap-buffer-overflow in opj\_t2\_read\_packet\_header [\#396](https://github.com/uclouvain/openjpeg/issues/396)
+- Heap-buffer-overflow in opj\_t2\_read\_packet\_header [\#395](https://github.com/uclouvain/openjpeg/issues/395)
+- Heap-buffer-overflow in opj\_dwt\_decode\_1 [\#394](https://github.com/uclouvain/openjpeg/issues/394)
+- Heap-double-free in j2k\_read\_ppm\_v3 [\#393](https://github.com/uclouvain/openjpeg/issues/393)
+- Security hole in j2k.c [\#392](https://github.com/uclouvain/openjpeg/issues/392)
+- Security: double-free in opj\_tcd\_code\_block\_dec\_deallocate [\#391](https://github.com/uclouvain/openjpeg/issues/391)
+- check for negative-size params in code [\#390](https://github.com/uclouvain/openjpeg/issues/390)
+- Heap-buffer-overflow in opj\_t2\_read\_packet\_header [\#389](https://github.com/uclouvain/openjpeg/issues/389)
+- Heap overflow in OpenJpeg 1.5.2 [\#388](https://github.com/uclouvain/openjpeg/issues/388)
+- openjpip.so.6 file too short [\#387](https://github.com/uclouvain/openjpeg/issues/387)
+- Corrupted JP3D file [\#386](https://github.com/uclouvain/openjpeg/issues/386)
+- variable assigned to itself [\#383](https://github.com/uclouvain/openjpeg/issues/383)
+- Null pointer dereferencing [\#382](https://github.com/uclouvain/openjpeg/issues/382)
+- bad use of case statement [\#381](https://github.com/uclouvain/openjpeg/issues/381)
+- Release 2.1 as a Ubuntu package [\#380](https://github.com/uclouvain/openjpeg/issues/380)
+- Bug in libopenjpwl.pc [\#374](https://github.com/uclouvain/openjpeg/issues/374)
+- inconsistent tile numbering in decode output message [\#370](https://github.com/uclouvain/openjpeg/issues/370)
+- error in code block calculations [\#369](https://github.com/uclouvain/openjpeg/issues/369)
+- r2872 fails to compile due to "attempt to use poisoned malloc" error in j2k.c [\#368](https://github.com/uclouvain/openjpeg/issues/368)
+- OSX build gives libopenjp2.6.dylib with not-absolute install name id [\#367](https://github.com/uclouvain/openjpeg/issues/367)
+- opj\_decompress gives error but successfully decompress in OPJ 2.1 [\#366](https://github.com/uclouvain/openjpeg/issues/366)
+- pngtoimage\(\) and imagetopng\(\) have wrong byte order for 16-Bit image [\#365](https://github.com/uclouvain/openjpeg/issues/365)
+- PDF crash in chrome - part2 \(due to attachment limit\) [\#364](https://github.com/uclouvain/openjpeg/issues/364)
+- PDF crash in chrome - part1 [\#363](https://github.com/uclouvain/openjpeg/issues/363)
+- PDF crash in chrome - part0 [\#362](https://github.com/uclouvain/openjpeg/issues/362)
+- Compilation fails on Windows with mingw32 gcc4.8 [\#361](https://github.com/uclouvain/openjpeg/issues/361)
+- security issue [\#360](https://github.com/uclouvain/openjpeg/issues/360)
+- improve memory management [\#359](https://github.com/uclouvain/openjpeg/issues/359)
+- how to compress a yuv420 raw data using opj\_compress [\#357](https://github.com/uclouvain/openjpeg/issues/357)
+- Some memory allocation are not checked [\#355](https://github.com/uclouvain/openjpeg/issues/355)
+- Static library symbols shall be marked as hidden [\#354](https://github.com/uclouvain/openjpeg/issues/354)
+- opj\_compress rejects valid bmp files [\#353](https://github.com/uclouvain/openjpeg/issues/353)
+- opj\_compress crashes when number of resolutions is set to zero [\#352](https://github.com/uclouvain/openjpeg/issues/352)
+- Compilation error under Visual Studio 2003 [\#351](https://github.com/uclouvain/openjpeg/issues/351)
+- opj\_compress description example error \[Low priority\] [\#350](https://github.com/uclouvain/openjpeg/issues/350)
+- opj\_write\_bytes\_BE is wrong in trunk [\#345](https://github.com/uclouvain/openjpeg/issues/345)
+- PART1ONLY option in release.sh doesn't work properly [\#332](https://github.com/uclouvain/openjpeg/issues/332)
+- openjpeg crash error [\#330](https://github.com/uclouvain/openjpeg/issues/330)
+- openjpeg decompress error [\#329](https://github.com/uclouvain/openjpeg/issues/329)
+- openjpeg decompress issue [\#326](https://github.com/uclouvain/openjpeg/issues/326)
+- limited tif support [\#322](https://github.com/uclouvain/openjpeg/issues/322)
+- asoc value of 65536 is allowed [\#321](https://github.com/uclouvain/openjpeg/issues/321)
+- opj\_skip\_from\_file error [\#314](https://github.com/uclouvain/openjpeg/issues/314)
+- Heavy quota usage in openjpeg [\#309](https://github.com/uclouvain/openjpeg/issues/309)
+- Verify -help actually match letter [\#307](https://github.com/uclouvain/openjpeg/issues/307)
+- g3\_colr.j2c not handled [\#288](https://github.com/uclouvain/openjpeg/issues/288)
+- reopen/fix issue 165 [\#280](https://github.com/uclouvain/openjpeg/issues/280)
+- kakadu conformance tests [\#279](https://github.com/uclouvain/openjpeg/issues/279)
+- missing break after case statement in opj\_dwt\_decode\_real [\#274](https://github.com/uclouvain/openjpeg/issues/274)
+- Run Coverity on trunk [\#270](https://github.com/uclouvain/openjpeg/issues/270)
+- NR-ENC-random-issue-0005.tif-12-encode [\#259](https://github.com/uclouvain/openjpeg/issues/259)
+- Use new add\_test signature to handle cross compilation [\#258](https://github.com/uclouvain/openjpeg/issues/258)
+- Loss decoding quality in 2.0.0 [\#254](https://github.com/uclouvain/openjpeg/issues/254)
+- Decompress that worked in 1.5.1 fails in 2.0 [\#252](https://github.com/uclouvain/openjpeg/issues/252)
+- Expected endianness with raw input is not documented leading to SEGFAULT [\#251](https://github.com/uclouvain/openjpeg/issues/251)
+- OpenJPEG writes to stderr [\#246](https://github.com/uclouvain/openjpeg/issues/246)
+- Inconsistent logging of tile index [\#245](https://github.com/uclouvain/openjpeg/issues/245)
+- patch for openjpeg-trunk-r2347 and BIG\_ENDIAN [\#242](https://github.com/uclouvain/openjpeg/issues/242)
+- CMAP: MTYP == 0 \(direct use\) not handled properly [\#235](https://github.com/uclouvain/openjpeg/issues/235)
+- Black Pixel [\#233](https://github.com/uclouvain/openjpeg/issues/233)
+- opj\_compress runtime error after fresh Linux install due to apparent failure to execute ldconfig [\#219](https://github.com/uclouvain/openjpeg/issues/219)
+- openjp2 debug works, release build does not [\#217](https://github.com/uclouvain/openjpeg/issues/217)
+- openjpeg-branch15-r2299 and openjpeg-trunk-r2299 fail to decode a JP2 file [\#212](https://github.com/uclouvain/openjpeg/issues/212)
+- openjpeg-trunk issue with Win7 [\#201](https://github.com/uclouvain/openjpeg/issues/201)
+- undefined reference to `opj\_version' [\#200](https://github.com/uclouvain/openjpeg/issues/200)
+- In tgt.c we used fprintf not the openjpeg message reporter [\#184](https://github.com/uclouvain/openjpeg/issues/184)
+- Windows binaries not working under WinXP [\#176](https://github.com/uclouvain/openjpeg/issues/176)
+- add ability to use intel ipp \(performance primitive\) within OpenJPEG [\#164](https://github.com/uclouvain/openjpeg/issues/164)
+- Migration guide v2 [\#160](https://github.com/uclouvain/openjpeg/issues/160)
+- Cannot decompress JPEG2000Aware3.18.7.3Win32\_kdutranscode6.3.1.j2k [\#158](https://github.com/uclouvain/openjpeg/issues/158)
+- Cannot decompress JPEG2000Aware3.18.7.3Win32.j2k [\#157](https://github.com/uclouvain/openjpeg/issues/157)
+- openjpeg@googlegroups.com has disappeard [\#153](https://github.com/uclouvain/openjpeg/issues/153)
+- OpenJPEG 1.5.0 crashes on a ridiculously big file... [\#151](https://github.com/uclouvain/openjpeg/issues/151)
+- opj\_image vs free [\#146](https://github.com/uclouvain/openjpeg/issues/146)
+- Windows .dll file invalid [\#140](https://github.com/uclouvain/openjpeg/issues/140)
+- Problem with second layer of a 2 layer coded LRCP \(with precincts\) [\#135](https://github.com/uclouvain/openjpeg/issues/135)
+- version 1.4 crashes when opening PDF file with JPEG2000 images [\#133](https://github.com/uclouvain/openjpeg/issues/133)
+- Setup a win64 dashboard [\#132](https://github.com/uclouvain/openjpeg/issues/132)
+- J2KP4files/codestreams\_profile0/p0\_13.j2k question jpeg2000 [\#131](https://github.com/uclouvain/openjpeg/issues/131)
+- Out of memory: Kill process 11204 \(opj\_server\) score 917 or sacrifice child [\#123](https://github.com/uclouvain/openjpeg/issues/123)
+- FILE\* in opj API is unsafe [\#120](https://github.com/uclouvain/openjpeg/issues/120)
+- third-party lib order [\#119](https://github.com/uclouvain/openjpeg/issues/119)
+- openjpeg-1.5.0-Darwin-powerpc.dmg is huge ! [\#113](https://github.com/uclouvain/openjpeg/issues/113)
+- misleading info in JP2 box lead to wrong number of components [\#110](https://github.com/uclouvain/openjpeg/issues/110)
+- Image\_to\_j2k says that j2k files is generated but no file is on the HDD [\#109](https://github.com/uclouvain/openjpeg/issues/109)
+- Error in openjpegV1.4 on compiling image\_to\_j2k: crash on reading bmp file [\#108](https://github.com/uclouvain/openjpeg/issues/108)
+- Update to abi-compliance-checker 1.96 [\#106](https://github.com/uclouvain/openjpeg/issues/106)
+- Decode error on the attached JPEG...works in KDU and with JASPER...please help! [\#101](https://github.com/uclouvain/openjpeg/issues/101)
+- Mac binaries v1.4 is broken [\#95](https://github.com/uclouvain/openjpeg/issues/95)
+- jp2\_read\_boxhdr\(\) has size bug in version 1 [\#92](https://github.com/uclouvain/openjpeg/issues/92)
+- Support for Java JAI Imageio [\#90](https://github.com/uclouvain/openjpeg/issues/90)
+- encoding test failing [\#86](https://github.com/uclouvain/openjpeg/issues/86)
+- source archive on demand [\#85](https://github.com/uclouvain/openjpeg/issues/85)
+- CMakeLists.txt and Makefile.am for JPIP are buggy [\#84](https://github.com/uclouvain/openjpeg/issues/84)
+- pclr-cmap-cdef [\#82](https://github.com/uclouvain/openjpeg/issues/82)
+- Error when compiling openjpeg\_v1\_4\_sources\_r697 [\#79](https://github.com/uclouvain/openjpeg/issues/79)
+- J2K codec issue on Windows Mobile [\#77](https://github.com/uclouvain/openjpeg/issues/77)
+- image\_to\_j2k.exe crashes on large .bmp file [\#75](https://github.com/uclouvain/openjpeg/issues/75)
+- fatal error C1900 building the project on windows [\#65](https://github.com/uclouvain/openjpeg/issues/65)
+- same option but different size [\#54](https://github.com/uclouvain/openjpeg/issues/54)
+- Missing openjpegConfigure.h [\#38](https://github.com/uclouvain/openjpeg/issues/38)
+- Not an issue in openjpeg, but ... [\#37](https://github.com/uclouvain/openjpeg/issues/37)
+- OpenJPEG-1.3.0 pclr, cmap and cdef [\#27](https://github.com/uclouvain/openjpeg/issues/27)
+- realloc maybe too big \(t2.c\) [\#26](https://github.com/uclouvain/openjpeg/issues/26)
+- libopenjpeg/opj\_malloc.h breaks on FreeBSD/Darwin systems [\#20](https://github.com/uclouvain/openjpeg/issues/20)
+- image\_to\_j2k not outputting to win32 console properly [\#18](https://github.com/uclouvain/openjpeg/issues/18)
+- \[OpenJPEG\] OpenJPEG\_v13: tiled image part 2 [\#17](https://github.com/uclouvain/openjpeg/issues/17)
+- JP2 Color Space modification by Matteo Italia [\#13](https://github.com/uclouvain/openjpeg/issues/13)
+- Patch submission \( exotic video formats, and a few things \) [\#12](https://github.com/uclouvain/openjpeg/issues/12)
+- 16 bits lossy compression [\#10](https://github.com/uclouvain/openjpeg/issues/10)
+- pnm file formats not accepting bitdepth greater than 8 bpp [\#8](https://github.com/uclouvain/openjpeg/issues/8)
+- Heap corruption in j2k encoder [\#5](https://github.com/uclouvain/openjpeg/issues/5)
+- JPWL crash in marker reallocation\(+patch\), segfault while decoding image with main header protection [\#4](https://github.com/uclouvain/openjpeg/issues/4)
+- a couple of small errors in libopenjpeg detected by coverity [\#1](https://github.com/uclouvain/openjpeg/issues/1)
+
+**Closed issues:**
+
+- Shared library build broken on ubuntu [\#728](https://github.com/uclouvain/openjpeg/issues/728)
+- opj\_includes.h shouldn't define `\_\_attribute\_\_` [\#727](https://github.com/uclouvain/openjpeg/issues/727)
+- Possible website problems due to Jekyll upgrade [\#713](https://github.com/uclouvain/openjpeg/issues/713)
+- Stable Release? [\#712](https://github.com/uclouvain/openjpeg/issues/712)
+- Meta Issue : try to fix some of these critical bugs before thinking about optimizing the library [\#710](https://github.com/uclouvain/openjpeg/issues/710)
+- Tiled encoding broken for images with non power of 2 dimensions [\#702](https://github.com/uclouvain/openjpeg/issues/702)
+- install\_name \(still\) not set on OS X [\#700](https://github.com/uclouvain/openjpeg/issues/700)
+- Add section in wiki describing where one can get test images [\#699](https://github.com/uclouvain/openjpeg/issues/699)
+- Make EvenManager into singleton [\#698](https://github.com/uclouvain/openjpeg/issues/698)
+- Remove old branches from repo [\#696](https://github.com/uclouvain/openjpeg/issues/696)
+- MQ Coder encode: Conditional jump or move depends on uninitialised value\(s\) [\#695](https://github.com/uclouvain/openjpeg/issues/695)
+- Can we add these files to our test suite ? [\#688](https://github.com/uclouvain/openjpeg/issues/688)
+- -t and -d command line flags for decode are not documented on OpenJPEG website [\#685](https://github.com/uclouvain/openjpeg/issues/685)
+- Decoding at the precinct level [\#676](https://github.com/uclouvain/openjpeg/issues/676)
+- Support unscaled 10 bit data for 2K cinema @ 48 FPS, as per DCI standard [\#671](https://github.com/uclouvain/openjpeg/issues/671)
+- Use parallel jobs in ctest [\#664](https://github.com/uclouvain/openjpeg/issues/664)
+- \[Security\]Multiple Memory error [\#663](https://github.com/uclouvain/openjpeg/issues/663)
+- lossy encoding a 16 bit TIF file : severe artifiacts in decompressed image [\#660](https://github.com/uclouvain/openjpeg/issues/660)
+- opj\_compress and opj\_decompress : get\_next\_file method uses hard-coded unix path separator [\#630](https://github.com/uclouvain/openjpeg/issues/630)
+- Uninitialized variable [\#629](https://github.com/uclouvain/openjpeg/issues/629)
+- Use of enum variable for bit flags prevents compilation as C++ source [\#619](https://github.com/uclouvain/openjpeg/issues/619)
+- Serious problem with quantization during lossy encoding [\#615](https://github.com/uclouvain/openjpeg/issues/615)
+- Decompression does not work with sequential data source [\#613](https://github.com/uclouvain/openjpeg/issues/613)
+- potential overflow in opj\_tcd\_tile\_t [\#605](https://github.com/uclouvain/openjpeg/issues/605)
+- Logical condition [\#596](https://github.com/uclouvain/openjpeg/issues/596)
+- file9.jp2 does not dump correctly on 1.5 [\#595](https://github.com/uclouvain/openjpeg/issues/595)
+- opj\_compress man page is missing documentation of -jpip option [\#593](https://github.com/uclouvain/openjpeg/issues/593)
+- opj\_compress fails to compress lossless on gcc/x86 \(-m32\) in 1.5 branch [\#591](https://github.com/uclouvain/openjpeg/issues/591)
+- Example: opj\_compress -i image.j2k -o image.pgm [\#577](https://github.com/uclouvain/openjpeg/issues/577)
+- Mismatching delete [\#575](https://github.com/uclouvain/openjpeg/issues/575)
+- Compilation fails on Win7 [\#546](https://github.com/uclouvain/openjpeg/issues/546)
+- NR-JP2-file5.jp2-compare2base fails with third party libcms [\#540](https://github.com/uclouvain/openjpeg/issues/540)
+- CTest spits out an error at the end of the test run [\#516](https://github.com/uclouvain/openjpeg/issues/516)
+- opj\_uint\_adds\(\) is questionable [\#515](https://github.com/uclouvain/openjpeg/issues/515)
+- Might consider renaming this method: [\#491](https://github.com/uclouvain/openjpeg/issues/491)
+- opj\_compress run twice gives different fiile sizes for same file [\#490](https://github.com/uclouvain/openjpeg/issues/490)
+- Android Support [\#483](https://github.com/uclouvain/openjpeg/issues/483)
+- Add SSE2/SSE41 implementations for mct.c [\#451](https://github.com/uclouvain/openjpeg/issues/451)
+- Reduce encoder code block memory usage for non 64x64 code block sizes [\#444](https://github.com/uclouvain/openjpeg/issues/444)
+- valgrind "Uninitialized Memory Read" & "Uninitialized Memory Conditional" found [\#438](https://github.com/uclouvain/openjpeg/issues/438)
+- No way to debug opj\_tcd\_init\_encode\_tile or opj\_tcd\_init\_decode\_tile [\#433](https://github.com/uclouvain/openjpeg/issues/433)
+- Add option to call dsymutil on built binaries [\#409](https://github.com/uclouvain/openjpeg/issues/409)
+- Allow opj\_compress and opj\_decompress to read/write images over stdin/stdout [\#379](https://github.com/uclouvain/openjpeg/issues/379)
+- reduce memory significantly for single tile RGB encoding [\#375](https://github.com/uclouvain/openjpeg/issues/375)
+- Switch code repo to github and start using pull request workflow [\#373](https://github.com/uclouvain/openjpeg/issues/373)
+- This is a BigTIFF file. This format not supported [\#125](https://github.com/uclouvain/openjpeg/issues/125)
+- Add a test suite to check the convert functions [\#99](https://github.com/uclouvain/openjpeg/issues/99)
+- Add build config to the dashboard to verify the autotools build [\#88](https://github.com/uclouvain/openjpeg/issues/88)
+
+**Merged pull requests:**
+
+- Correct abi-check.sh for PR [\#791](https://github.com/uclouvain/openjpeg/pull/791) ([mayeut](https://github.com/mayeut))
+- Update tcd.c [\#790](https://github.com/uclouvain/openjpeg/pull/790) ([maddin200](https://github.com/maddin200))
+- Update lcms2 [\#773](https://github.com/uclouvain/openjpeg/pull/773) ([mayeut](https://github.com/mayeut))
+- Use lowercase for cmake commands consistenly [\#769](https://github.com/uclouvain/openjpeg/pull/769) ([julienmalik](https://github.com/julienmalik))
+- Ignore clang's summary warning [\#768](https://github.com/uclouvain/openjpeg/pull/768) ([julienmalik](https://github.com/julienmalik))
+- Fix UBSan gcc warning for first arg to memset non null [\#767](https://github.com/uclouvain/openjpeg/pull/767) ([julienmalik](https://github.com/julienmalik))
+- Update to libtiff-4.0.6 [\#764](https://github.com/uclouvain/openjpeg/pull/764) ([mayeut](https://github.com/mayeut))
+- Fix warnings [\#763](https://github.com/uclouvain/openjpeg/pull/763) ([mayeut](https://github.com/mayeut))
+- Check SSIZ is valid in opj\_j2k\_read\_siz [\#762](https://github.com/uclouvain/openjpeg/pull/762) ([mayeut](https://github.com/mayeut))
+- Fix unsigned int overflow reported by UBSan [\#761](https://github.com/uclouvain/openjpeg/pull/761) ([mayeut](https://github.com/mayeut))
+- Fix unsigned int overflow reported by UBSan [\#759](https://github.com/uclouvain/openjpeg/pull/759) ([mayeut](https://github.com/mayeut))
+- Fix negative shift left reported by UBSan [\#758](https://github.com/uclouvain/openjpeg/pull/758) ([mayeut](https://github.com/mayeut))
+- Fix negative shift left reported by UBSan [\#757](https://github.com/uclouvain/openjpeg/pull/757) ([mayeut](https://github.com/mayeut))
+- Add clang 3.9 build to Travis matrix [\#753](https://github.com/uclouvain/openjpeg/pull/753) ([julienmalik](https://github.com/julienmalik))
+- Fix implicit floating bool conversion [\#752](https://github.com/uclouvain/openjpeg/pull/752) ([julienmalik](https://github.com/julienmalik))
+- Do not define \_\_attribute\_\_ in opj\_includes.h [\#751](https://github.com/uclouvain/openjpeg/pull/751) ([mayeut](https://github.com/mayeut))
+- Allow to read/write 3/5/7/9/11/13/15 bpp TIF files [\#750](https://github.com/uclouvain/openjpeg/pull/750) ([mayeut](https://github.com/mayeut))
+- Fix heap-buffer-overflow in color\_esycc\_to\_rgb [\#748](https://github.com/uclouvain/openjpeg/pull/748) ([mayeut](https://github.com/mayeut))
+- update libpng to from 1.6.17 to 1.6.21 [\#747](https://github.com/uclouvain/openjpeg/pull/747) ([julienmalik](https://github.com/julienmalik))
+- Update cmake & jpylyzer for travis builds [\#746](https://github.com/uclouvain/openjpeg/pull/746) ([julienmalik](https://github.com/julienmalik))
+- Fix Out-Of-Bounds Read in sycc42x\_to\_rgb function [\#745](https://github.com/uclouvain/openjpeg/pull/745) ([mayeut](https://github.com/mayeut))
+- cppcheck fix for openjp2 [\#740](https://github.com/uclouvain/openjpeg/pull/740) ([julienmalik](https://github.com/julienmalik))
+- Fix uninitialized variable reported by cppcheck [\#735](https://github.com/uclouvain/openjpeg/pull/735) ([julienmalik](https://github.com/julienmalik))
+- Remove dead code in opj\_dump [\#734](https://github.com/uclouvain/openjpeg/pull/734) ([julienmalik](https://github.com/julienmalik))
+- issue \#695 MQ Encode: ensure that bp pointer never points to uninitialized memory [\#708](https://github.com/uclouvain/openjpeg/pull/708) ([boxerab](https://github.com/boxerab))
+- Fix issue 135 [\#706](https://github.com/uclouvain/openjpeg/pull/706) ([mayeut](https://github.com/mayeut))
+- Fix implementation of opj\_calloc [\#705](https://github.com/uclouvain/openjpeg/pull/705) ([stweil](https://github.com/stweil))
+- \[git/2.1 regression\] Fix opj\_write\_tile\(\) failure when numresolutions=1 [\#690](https://github.com/uclouvain/openjpeg/pull/690) ([rouault](https://github.com/rouault))
+- Fix fatal crash on 64 bit Linux [\#687](https://github.com/uclouvain/openjpeg/pull/687) ([stweil](https://github.com/stweil))
+- \[libtiff\] Add missing include statement for ssize\_t [\#686](https://github.com/uclouvain/openjpeg/pull/686) ([mayeut](https://github.com/mayeut))
+- Fix duplicate article in comments [\#684](https://github.com/uclouvain/openjpeg/pull/684) ([stweil](https://github.com/stweil))
+- Fix grammar in comment [\#679](https://github.com/uclouvain/openjpeg/pull/679) ([stweil](https://github.com/stweil))
+- Remove whitespace and CR at line endings [\#678](https://github.com/uclouvain/openjpeg/pull/678) ([stweil](https://github.com/stweil))
+- Fix typos [\#665](https://github.com/uclouvain/openjpeg/pull/665) ([jwilk](https://github.com/jwilk))
+- Add missing source for the JPIP library and executables \(issue \#658\) [\#659](https://github.com/uclouvain/openjpeg/pull/659) ([stweil](https://github.com/stweil))
+- Fix undefined size jp2 box handling [\#654](https://github.com/uclouvain/openjpeg/pull/654) ([mayeut](https://github.com/mayeut))
+- opj\_decompress: Update error message [\#651](https://github.com/uclouvain/openjpeg/pull/651) ([stweil](https://github.com/stweil))
+- Fix support of posix\_memalloc for Linux [\#648](https://github.com/uclouvain/openjpeg/pull/648) ([stweil](https://github.com/stweil))
+- Fix typo in comments [\#647](https://github.com/uclouvain/openjpeg/pull/647) ([stweil](https://github.com/stweil))
+- Avoid pointer arithmetic with \(void \*\) pointers [\#644](https://github.com/uclouvain/openjpeg/pull/644) ([smuehlst](https://github.com/smuehlst))
+- Fix HP compiler warning about redeclaration of function \(\#640\) [\#641](https://github.com/uclouvain/openjpeg/pull/641) ([smuehlst](https://github.com/smuehlst))
+- Fix format strings and unneeded assignment [\#638](https://github.com/uclouvain/openjpeg/pull/638) ([stweil](https://github.com/stweil))
+- Fix repository for JPEG2000 test data [\#637](https://github.com/uclouvain/openjpeg/pull/637) ([stweil](https://github.com/stweil))
+- Update allocation functions [\#636](https://github.com/uclouvain/openjpeg/pull/636) ([mayeut](https://github.com/mayeut))
+- Fix OpenJPEG GitHub issue \#633. [\#634](https://github.com/uclouvain/openjpeg/pull/634) ([smuehlst](https://github.com/smuehlst))
+- travis-ci: Include add ons in matrix [\#632](https://github.com/uclouvain/openjpeg/pull/632) ([mayeut](https://github.com/mayeut))
+- Add Appveyor [\#627](https://github.com/uclouvain/openjpeg/pull/627) ([mayeut](https://github.com/mayeut))
+- Use Travis-ci to run ABI check [\#626](https://github.com/uclouvain/openjpeg/pull/626) ([mayeut](https://github.com/mayeut))
+- Fix warnings for C++ [\#623](https://github.com/uclouvain/openjpeg/pull/623) ([stweil](https://github.com/stweil))
+- Fixed problem that C++ compilation failed because of enum variable. [\#622](https://github.com/uclouvain/openjpeg/pull/622) ([smuehlst](https://github.com/smuehlst))
+- Added missing casts for return values of opj\_malloc\(\)/opj\_calloc\(\). [\#618](https://github.com/uclouvain/openjpeg/pull/618) ([smuehlst](https://github.com/smuehlst))
+- Add check for seek support before trying TPsot==TNsot workaround [\#617](https://github.com/uclouvain/openjpeg/pull/617) ([mayeut](https://github.com/mayeut))
+- Fix some typos found by codespell [\#610](https://github.com/uclouvain/openjpeg/pull/610) ([stweil](https://github.com/stweil))
+- Correct leak in color\_cielab\_to\_rgb [\#590](https://github.com/uclouvain/openjpeg/pull/590) ([mayeut](https://github.com/mayeut))
+- Add Travis-ci build matrix [\#584](https://github.com/uclouvain/openjpeg/pull/584) ([mayeut](https://github.com/mayeut))
+- Correct lossless issue on linux x86 [\#579](https://github.com/uclouvain/openjpeg/pull/579) ([mayeut](https://github.com/mayeut))
+- Travis-ci update [\#578](https://github.com/uclouvain/openjpeg/pull/578) ([mayeut](https://github.com/mayeut))
+- Correct CMake version requirements [\#572](https://github.com/uclouvain/openjpeg/pull/572) ([mayeut](https://github.com/mayeut))
+- Add tests for CMYK/esYCC/CIELab [\#567](https://github.com/uclouvain/openjpeg/pull/567) ([mayeut](https://github.com/mayeut))
+- Add support for CIELab, EYCC and CMYK [\#559](https://github.com/uclouvain/openjpeg/pull/559) ([szukw000](https://github.com/szukw000))
+- Remove printf/fprintf to stdout/stderr throughout openjp2 lib [\#558](https://github.com/uclouvain/openjpeg/pull/558) ([mayeut](https://github.com/mayeut))
+- better -ffast-math handling [\#555](https://github.com/uclouvain/openjpeg/pull/555) ([rdieter](https://github.com/rdieter))
+- Add jpylyzer tests for JP2 compression [\#552](https://github.com/uclouvain/openjpeg/pull/552) ([mayeut](https://github.com/mayeut))
+- Add COC/QCC in main header when needed [\#551](https://github.com/uclouvain/openjpeg/pull/551) ([mayeut](https://github.com/mayeut))
+- Use \_\_emul under msvc x86 for fast 64 = 32 \* 32 [\#550](https://github.com/uclouvain/openjpeg/pull/550) ([mayeut](https://github.com/mayeut))
+- Update convert for PNG output [\#549](https://github.com/uclouvain/openjpeg/pull/549) ([mayeut](https://github.com/mayeut))
+- Remove some warnings when building [\#548](https://github.com/uclouvain/openjpeg/pull/548) ([mayeut](https://github.com/mayeut))
+- Switch to libpng-1.6.17 [\#547](https://github.com/uclouvain/openjpeg/pull/547) ([mayeut](https://github.com/mayeut))
+- Add some missing static keywords [\#545](https://github.com/uclouvain/openjpeg/pull/545) ([mayeut](https://github.com/mayeut))
+- Switch to libcms2 mm2/Little-CMS@0e8234e090d6aab33f90e2eb0296f30aa0705e57 [\#544](https://github.com/uclouvain/openjpeg/pull/544) ([mayeut](https://github.com/mayeut))
+- Prevent overflow when coding 16 bits images [\#543](https://github.com/uclouvain/openjpeg/pull/543) ([mayeut](https://github.com/mayeut))
+- Switch to libcms2-2.6 [\#542](https://github.com/uclouvain/openjpeg/pull/542) ([mayeut](https://github.com/mayeut))
+- Update PNG support [\#538](https://github.com/uclouvain/openjpeg/pull/538) ([mayeut](https://github.com/mayeut))
+- Various Minor fixes [\#537](https://github.com/uclouvain/openjpeg/pull/537) ([mayeut](https://github.com/mayeut))
+- Update TIFF conversion to support more bit depth. [\#535](https://github.com/uclouvain/openjpeg/pull/535) ([mayeut](https://github.com/mayeut))
+- Add checks for odd looking cmap & for cmap outside jp2h box [\#534](https://github.com/uclouvain/openjpeg/pull/534) ([mayeut](https://github.com/mayeut))
+- Refactor opj\_j2k\_read\_ppm & opj\_j2k\_read\_ppt [\#533](https://github.com/uclouvain/openjpeg/pull/533) ([mayeut](https://github.com/mayeut))
+- Add option to force component splitting in imagetopnm [\#531](https://github.com/uclouvain/openjpeg/pull/531) ([mayeut](https://github.com/mayeut))
+- fix Suspicious code in j2k.c \#517 [\#529](https://github.com/uclouvain/openjpeg/pull/529) ([renevanderark](https://github.com/renevanderark))
+- Update zlib to version 1.2.8 [\#528](https://github.com/uclouvain/openjpeg/pull/528) ([mayeut](https://github.com/mayeut))
+- Fix opj\_write\_bytes\_BE \(\#518\) [\#521](https://github.com/uclouvain/openjpeg/pull/521) ([manisandro](https://github.com/manisandro))
+- Correctly decode files with incorrect tile-part header fields \(TPsot==TNsot\) [\#514](https://github.com/uclouvain/openjpeg/pull/514) ([mayeut](https://github.com/mayeut))
+- Fixed typos [\#510](https://github.com/uclouvain/openjpeg/pull/510) ([radarhere](https://github.com/radarhere))
+- Formatted the readme file [\#507](https://github.com/uclouvain/openjpeg/pull/507) ([htmfilho](https://github.com/htmfilho))
+
+## [version.2.1](https://github.com/uclouvain/openjpeg/releases/tag/version.2.1) (2014-04-29)
+List of fixed issues and enhancements unavailable, see [NEWS](https://github.com/uclouvain/openjpeg/blob/master/NEWS.md) or [Full Changelog](https://github.com/uclouvain/openjpeg/compare/version.2.0.1...version.2.1)
+
+## [version.2.0.1](https://github.com/uclouvain/openjpeg/releases/tag/version.2.0.1) (2014-04-22)
+List of fixed issues and enhancements unavailable, see [NEWS](https://github.com/uclouvain/openjpeg/blob/master/NEWS.md) or [Full Changelog](https://github.com/uclouvain/openjpeg/compare/version.1.5.2...version.2.0.1)
+
+## [version.1.5.2](https://github.com/uclouvain/openjpeg/releases/tag/version.1.5.2) (2014-03-28)
+List of fixed issues and enhancements unavailable, see [NEWS](https://github.com/uclouvain/openjpeg/blob/master/NEWS.md) or [Full Changelog](https://github.com/uclouvain/openjpeg/compare/version.2.0...version.1.5.2)
+
+## [version.2.0](https://github.com/uclouvain/openjpeg/releases/tag/version.2.0) (2014-03-28)
+List of fixed issues and enhancements unavailable, see [NEWS](https://github.com/uclouvain/openjpeg/blob/master/NEWS.md) or [Full Changelog](https://github.com/uclouvain/openjpeg/compare/version.1.5.1...version.2.0)
+
+## [version.1.5.1](https://github.com/uclouvain/openjpeg/releases/tag/version.1.5.1) (2012-09-13)
+List of fixed issues and enhancements unavailable, see [NEWS](https://github.com/uclouvain/openjpeg/blob/master/NEWS.md) or [Full Changelog](https://github.com/uclouvain/openjpeg/compare/version.1.5...version.1.5.1)
+
+## [version.1.5](https://github.com/uclouvain/openjpeg/releases/tag/version.1.5) (2012-02-07)
+List of fixed issues and enhancements unavailable, see [NEWS](https://github.com/uclouvain/openjpeg/blob/master/NEWS.md) or [Full Changelog](https://github.com/uclouvain/openjpeg/compare/version.1.3...version.1.5)
+
+## [version.1.3](https://github.com/uclouvain/openjpeg/releases/tag/version.1.3) (2011-07-03)
+List of fixed issues and enhancements unavailable, see [NEWS](https://github.com/uclouvain/openjpeg/blob/master/NEWS.md) or [Full Changelog](https://github.com/uclouvain/openjpeg/compare/version.1.4...version.1.3)
+
+## [version.1.4](https://github.com/uclouvain/openjpeg/releases/tag/version.1.4) (2011-07-03)
+List of fixed issues and enhancements unavailable, see [NEWS](https://github.com/uclouvain/openjpeg/blob/master/NEWS.md) or [Full Changelog](https://github.com/uclouvain/openjpeg/compare/version.1.2...version.1.4)
+
+## [version.1.2](https://github.com/uclouvain/openjpeg/releases/tag/version.1.2) (2007-06-04)
+List of fixed issues and enhancements unavailable, see [NEWS](https://github.com/uclouvain/openjpeg/blob/master/NEWS.md) or [Full Changelog](https://github.com/uclouvain/openjpeg/compare/version.1.1...version.1.2)
+
+## [version.1.1](https://github.com/uclouvain/openjpeg/releases/tag/version.1.1) (2007-01-31)
+List of fixed issues and enhancements unavailable, see [NEWS](https://github.com/uclouvain/openjpeg/blob/master/NEWS.md) or [Full Changelog](https://github.com/uclouvain/openjpeg/compare/version.1.0...version.1.1)
+
+
+
+\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* \ No newline at end of file
diff --git a/openjpeg/CHANGES b/openjpeg/CHANGES
deleted file mode 100644
index 541d4aafc..000000000
--- a/openjpeg/CHANGES
+++ /dev/null
@@ -1,1116 +0,0 @@
-2014-04-29 Mathieu Malaterre
-
- * [r2866] .[CPY]: [2.1] Create the 2.1 branch
-
-2014-04-28 Antonin Descampe
-
- * [r2864] [trunk] fixed warning in j2k.c about sign conversion
-
-2014-04-28 Mathieu Malaterre
-
- * [r2863] [trunk] Finalize API for openjpeg 2.1
- public header will only contains minimal information: major,
- minor and build version
- Prefix has been changed from OPENJPEG to OPJ for consistency
- SOVERSION has been removed from header (ABI vs API info)
- OPJ_VERSION string has been removed, since it is accessible
- already (PACKAGE_VERSION)
- Fixes issue 342
- * [r2862] [trunk] Properly handle failure to compress (remove file)
- Fixes issue 323
- * [r2861] [trunk] Missing endianess setting
- Fixes issue 337
- * [r2860] [trunk] properly handle pkg-config on non-UNIX hosts
- Fixes issue 340
- * [r2859] [trunk] Provide #ifdef blockers for OpenJPEG Version
- Fixes issue 342
-
-2014-04-27 Antonin Descampe
-
- * [r2858] [trunk] fixed typo in NEWS
-
-2014-04-25 Antonin Descampe
-
- * [r2857] [trunk] updated NEWS for 2.1.0
-
-2014-04-24 Mathieu Malaterre
-
- * [r2855] [trunk] Make sure OpenJPIP compiles on WIN32
-
-2014-04-24 Antonin Descampe
-
- * [r2852] [trunk] fixed reference to opj_stream_set_user_data_v3 in
- jpip sources.
-
-2014-04-23 Antonin Descampe
-
- * [r2851] [trunk]removed '-x' option for index file as long as it's
- broken
- * [r2849] [trunk]re-formatted help display in executables
- * [r2848] [trunk]formatted some messages. Removed -version option
- to disambiguate
- with -v(erbose) option, added version info in help display
- * [r2847] [trunk]Replaced deprecated opj_stream_set_user_data
- function from API
- with its 'v3' version, and removed all other 'v3' suffixes from
- API.
-
-2014-04-22 Antonin Descampe
-
- * [r2845] [trunk] fixed some warning and errors formatting and add
- a '-version'
- option to opj_compress and opj_decompress binaries
-
-2014-04-17 Antonin Descampe
-
- * [r2838] [trunk] fixed warning related to r2837 and move new field
- at the end of
- parameters structure.
- * [r2837] [trunk] refactoring of rsiz, profiles, and extensions
- management
-
-2014-04-03 Antonin Descampe
-
- * [r2835] [trunk] updated copyright and added copyright notice
- required by ISO, in each file; updated AUTHORS, NEWS
-
-2014-04-02 Antonin Descampe
-
- * [r2832] [trunk] removed debug message in CMakeLists.txt
- * [r2831] [trunk] fixed a bug triggering SEGFAULT on debug mode
- (uninitialized
- structure)
-
-2014-03-27 Mathieu Malaterre
-
- * [r2815] [trunk] Properly copy/paste code from the autotools
- gcc correctly fails compiling this code, I needed to move the
- code outside the main function to get the error. This actually
- match the autotools (incorrect) code. We'll see how they fix this
- code in future release.
- This make the code compatible with previous openjpeg version and
- remove C99 requirement.
- Fixes issue 316
-
-2014-03-26 Mathieu Malaterre
-
- * [r2808] [trunk] Make sure to use long long (this is not C89).
- However this should be ok on most compilers nowadays
- Update issue 316
-
-2014-03-26 Antonin Descampe
-
- * [r2806] [trunk] fixed warnings triggered on linux related to
- r2802
-
-2014-03-26 Mathieu Malaterre
-
- * [r2804] [trunk] Run test suite on issue 316 dataset
- Update issue 316
-
-2014-03-26 Antonin Descampe
-
- * [r2802] [trunk] add ability in opj_compress to input subsampled
- images through
- '-F' (aka raw option). Let the user input raw images with 444,
- 422, 420
- (etc) subsampling. To be used in conjunction with '-mct 0' option
- to
- compress subsampled YCC images.
-
-2014-03-26 Mathieu Malaterre
-
- * [r2801] [trunk] Add small utilities to extract JP2 files from PDF
-
-2014-03-25 Mathieu Malaterre
-
- * [r2799] [trunk] Make sure to test value not pointer
- Update issue 302
-
-2014-03-25 Antonin Descampe
-
- * [r2798] [trunk] fixed bug related to r2791
-
-2014-03-25 Mathieu Malaterre
-
- * [r2796] [trunk] Add sentinel in case list empty.
- I was getting a cmake error `list sub-command REMOVE_ITEM
- requires list to be present`
- * [r2795] [trunk] Import change from 2.0 branch
-
-2014-03-25 Antonin Descampe
-
- * [r2792] [trunk] fixed warning due induced by r2791
- * [r2791] [trunk] add "-mct {0,1,2}" option to opj_compress to
- allow MCT to be
- disabled if needed.
-
-2014-03-25 Mathieu Malaterre
-
- * [r2789] [trunk] Make sure to not use alpha pointer if it is not
- an RGBA input
- Fixes issue 310
- * [r2786] [trunk] Rework previous commit r2610
- This way we are able to gently deprecate the old API, and
- preserve ABI
- Update issue 306
- * [r2785] [trunk] Add documentation
-
-2014-03-24 Mathieu Malaterre
-
- * [r2773] [trunk] Make sure to exit early instead of looping on
- every single pixels
- * [r2772] [trunk] Fix typo in comment (this is not j2k_dump)
-
-2014-03-18 Mathieu Malaterre
-
- * [r2767] [trunk] Revert r2764. It breaks ~230 tests as seen on
- continuous. Since no dataset is available, the issue 296 will be
- left open.
- Update issue 296
- * [r2766] [trunk] User can now control source/target java version
- Fixes issue 303
- * [r2764] [trunk] Import git commit
- fc884aee2b69c78500e65c3d05bf216791a9ea4a from ghostscript team
- Fixes issue 296
- * [r2763] [trunk] Import git commit
- 99a6f1af177c15f4db475186b79d169c993494ef from ghostscript team
- Update issue 296
- * [r2761] [trunk] Update big endian handling no such thing as
- WORDS_BIGENDIAN (prefer OPJ_BIG_ENDIAN)
- Update issue 302
- * [r2756] [trunk] Now that dataset from issue 297 have been
- imported, run test suite.
- None of the dataset triggered any buffer overflow. Recent changes
- in trunk handle all those cases.
- Update issue 297
-
-2014-03-17 Mathieu Malaterre
-
- * [r2754] [trunk] Explicitely reject file4/file6 scenario
- Update issue 286
- * [r2751] [trunk] Update BSD-4 copyright into a BSD-3 copyright
- Fixes issue 300
-
-2014-03-14 Mathieu Malaterre
-
- * [r2748] [trunk] Since r2747 we are now able to track which files
- are missing from the test_suite. Add them.
- * [r2747] [trunk] add mecanism to track of addition of new
- regression files in svn/data. It will report when a J2K files is
- added but no test is found in the test_suite file
- * [r2746] [trunk] Remove duplicate content from test_inline.c
- Thanks to Matthieu Darbois for report (and patch)
- Fixes issue 285
- * [r2745] [trunk] rework code from r2463. Really there has been
- some code duplication from r2413
- Thanks to John Rogers (oracle.com) for report
- * [r2744] [trunk] rework code from r2463. Really there has been
- some code duplication from r2413
- Thanks to John Rogers (oracle.com) for report
- * [r2743] [trunk] Now that issue 165 dataset is in non regression
- repository, activate code to reject them
- Fixes issue 165
- * [r2741] [trunk] Fix issue with & vs &&
- Fixes issue 277
- * [r2740] [trunk] Add internal implementation to dump all
- tiles/comp info
- Eg: opj_dump -f 8 -i input.j2k
- Update issue 3
- * [r2739] [trunk] Prevent a leak when reading PPT markers
- Update issue 295
- * [r2735] [trunk] Move INLINE definition within openjpeg.h header
- since application may use it
- * [r2733] [trunk] Apply final missing patch from sumatrapdf team:
- http://bugs.ghostscript.com/show_bug.cgi?id=694893
- Update issue 231
- * [r2732] [trunk] Rework r2731 since it breaks non-regression
- testing
- * [r2731] [trunk] Be more verbose about failure.
- Update issue 294
- * [r2730] [trunk] Add a temporary work around for issue 293
- As described in the bug report the default allocation mecanism
- for codeblock data is too small for those dataset (16bits). We
- would need a finer (more granular) mecanism to reallocated only
- on demand. For now this help the two failing tests to pass.
- Fixes issue 293
- * [r2726] [trunk] Mark OpenJPEG to be ABI incompatible with
- previous one, move to SONAME 7
- Also declare this is 2.1.0 (or very close)
- * [r2722] [trunk] Remove warnings about unused values introduced in
- r2710
- Thanks to Matthieu Darbois for patch
- Fixes issue 290
-
-2014-03-13 Mathieu Malaterre
-
- * [r2720] [trunk] Add some sanity checks when reading Ippm(i)
- segments
- Update issue 288
- * [r2719] [trunk] Make sure to reallocate ppm data buffer when
- multiple Ippm(i) buffer are found
- This handle the case where remaining data is exactly Nppm(i)
- Fixes issue 287
- * [r2715] [trunk] Add documentation to the checkmd5refs cmake
- module (used for regression testing)
- * [r2714] [trunk] Always report when decompression failed as return
- code value
- * [r2713] [trunk] Fix test NR-DEC-issue171.jp2-71-decode-md5 after
- recent code change
- * [r2712] [trunk] Add a double check for user input
- * [r2711] [trunk] Fix compilation on VS2010 (snprintf is not C89).
- C++11 should avoid this in the future
- * [r2710] [trunk] Just in case this would be helpful for other,
- here is the code used to track issue 80
- Update issue 80
- * [r2709] [trunk] Tweak documentation in t2.c. Be more verbose in
- case of failure.
- * [r2708] [trunk] Add some documention in the pi code
- * [r2707] [trunk] Add debug code to extract decompressed image
- right before PCLR handling
- Update issue 235
- * [r2705] [trunk] Add a small helper to spli ppm into 3 pgm files
- Update issue 235
-
-2014-03-12 Mathieu Malaterre
-
- * [r2703] [trunk] Make sure to use 8bits buffer when applying the
- ICC profile.
- Fixes issue 281
- * [r2701] [trunk] Add debug info to be able to test integration
- with littlecms
- * [r2695] [trunk] TIFF files in test suite can have 1 or 3
- components
- * [r2694] [trunk] Simplify code when reading in TIFF images
- * [r2692] [trunk] Make sure when reading POC that number of layers
- (layer end) is within acceptable bound.
- Fixes issue 80
-
-2014-03-11 Mathieu Malaterre
-
- * [r2691] [trunk] Re-active old warning about missing SOP marker
- * [r2690] [trunk] Add debug info to track issue 80
- Update issue 80
- * [r2688] [trunk] Rework assertion to work on 32bits system
- * [r2687] [trunk] Fix remainings warnings on linux/32bits arch
- * [r2686] [trunk] Rework fseek ifdefs blockers, it breaks the
- 64bits behavior for fseeko
- * [r2685] [trunk] Fix compilation errors when JPWL and/or MJ2 are
- build
-
-2014-03-10 Mathieu Malaterre
-
- * [r2683] [trunk] Another final round of fixes for sign conversion
- warnings.
- Fixes issue 256
- * [r2682] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2681] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2680] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2679] [trunk] Remove old warnings about deprecated API
- * [r2677] [trunk] Remove a set of warning about sign conversion
- Update issue 266
- * [r2676] [trunk] Remove warning about sign conversion in color.c
- Update issue 256
- * [r2672] [trunk] Run richter test suite, correct a regression
- introduced in r2668
- * [r2670] [trunk] Tweak JP2 conformance test suite add
- documentation
- * [r2668] [trunk] Properly handle number of components to run
- kakadu test suite.
- Update issue 266
- * [r2664] [trunk] Fix simple sign conversion warnings only visible
- on 32bits arch
- * [r2663] [trunk] Handle multi components files with PGM outputs
- * [r2661] [trunk] Properly handle PGM file generation when fullpath
- is specified in the cmd line
- This will break a very old behavior (since 2005), but avoid
- writing in un-expected places for users
- This also make the behavior similar with PGX file generation
- * [r2660] [trunk] Fix inversion in code convention
- * [r2659] [trunk] Fix typo in the code
- * [r2658] [trunk] rework actual code to handle DOS/UNIX end of
- lines in a transparent manner.
- This will help cross compilation cases
- * [r2657] [trunk] First pass to cleanup compare_dump_files
- * [r2656] [trunk] Fix compilation when TIFF lib is neither found
- nor compiled
- * [r2655] [trunk] Make sure to always initialize variable
- * [r2654] [trunk] Fix warnings about shadow variables
- * [r2653] [trunk] remove a warning when using strict prototype
- * [r2652] [trunk] Remove 2 warnings about set but not used
- variables
-
-2014-03-07 Mathieu Malaterre
-
- * [r2651] [trunk] Upon failure, need to return proper return code
- * [r2650] [trunk] Add new test suite that run on kakadu conformance
- images
- * [r2644] [trunk] Cleanup commit. Rename compare family since
- comparePGX now support TIFF.
- Rename compareRAWimage for clarity since it merely compare files
- (not images).
- * [r2643] [trunk] Use C-style comments
- * [r2642] [trunk] Rework the code to simplify cleanup code
- * [r2638] [trunk] Also override the default error handler for TIFF
- files
- * [r2636] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2635] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2634] [trunk] Rework r2597, make sure test suite is passing
- now.
- Update issue 256
- * [r2633] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2632] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2631] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2630] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2629] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2628] [trunk] Redo r2623, and remove guilty section
- Update issue 256
- * [r2627] [trunk] Revert r2623 for now
- * [r2626] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2625] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2624] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2623] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2622] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2621] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2620] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2619] [trunk] As reported by clang analyzer thoses values were
- never read
- * [r2618] [trunk] Remove mem leak and warning reported by clang
- * [r2617] [trunk] Remove simple warnings about format
- * [r2616] [trunk] Remove simple warning about functions not used
- * [r2615] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2614] [trunk] Another round of fixes for sign conversion
- warnings.
- Update issue 256
- * [r2613] [trunk] Fix simple warning about sign conversion
- Update issue 256
- * [r2612] [trunk] Another of fixes for warning about sign
- conversion
- Update issue 256
- * [r2611] [trunk] Fix warning about sign conversion
- Update issue 256
- * [r2610] [trunk] un-deprecated opj_stream_destroy API, import
- patch manually
- In some case user still want to be able to call
- opj_stream_destroy.
- Fixes issue 227
- * [r2609] [trunk] Update memory management mecanism
- Fixes issue 253
- * [r2608] [trunk] Remove self-assignement.
- Fixes issue 273
- * [r2605] [trunk] Fix compilation in visual studio, inline cannot
- be used directly.
- Fixes issue 272
- * [r2604] [trunk] Remove warning about implicitly defined function
- * [r2601] [trunk] Remove TIFF warning handler. This help test suite
- run smoothly on windows by removing the message box.
- Fixes issue 276
- * [r2600] [trunk] Fix mem leaks reported by cppcheck
- * [r2599] [trunk] Simplify code and remove bogus out of bound check
-
-2014-03-06 Mathieu Malaterre
-
- * [r2598] [trunk] Revert r2597 for now, since it breaks a lot of
- tests
- * [r2597] [trunk] Remove warning about sign conversion.
- Update issue 256
- * [r2595] [trunk] Remove some easy warnings
- * [r2594] [trunk] Remove warning about sign conversion.
- Update issue 256
- * [r2593] [trunk] Remove warning about sign conversion.
- Update issue 256
- * [r2592] [trunk] Remove warning about sign conversion.
- Update issue 256
- * [r2591] [trunk] Remove warning about sign conversion.
- Update issue 256
- * [r2590] [trunk] Remove warning about sign conversion.
- Update issue 256
- * [r2589] [trunk] Remove some easy warnings about sign compare
- reported by gcc
- * [r2588] [trunk] Remove out of bound access in code and simplify
- code. this is a test tool, security is not an issue here.
- * [r2587] [trunk] Remove simple warning about unused variables
- * [r2586] [trunk] Make sure that all output files from the test
- suite are using a different output name
- Fixes issue 271
-
-2014-03-05 Mathieu Malaterre
-
- * [r2577] [trunk] Handle cmap where direct use is specified
- (issue235_cmapsubbox.jp2)
- I doubt the old code ever work. The new code copy the old
- codestream bytes into the new components (instead of copying the
- pointer).
- Technically the issue235.jp2 file should be handled since I.5.3.5
- specifies that:
- ...
- If the JP2 Header box does not contain a Component Mapping box,
- the components shall be mapped directly to channels,
- such that component i is mapped to channel i.
- ...
- Update issue 235
-
-2014-03-04 Mathieu Malaterre
-
- * [r2572] [trunk] Make sure to reject images such as
- 1336.pdf.asan.47.376.jp2
- Fixes issue 267
- * [r2571] [trunk] remove more conversion warning in multi-lines
- macro.
- C allow simple tricks such as to find those:
- gcc -E tcd.c | sed '/^\#/d' | indent -st -i2 > clean.c
- Update issue 256
- * [r2570] [trunk] Remove some conversion warnings reported by gcc
- Update issue 256
- * [r2569] [trunk] Remove another warning. ftell returns long int
- Update issue 256
- * [r2568] [trunk] Remove more conversion warnings.
- Update issue 256
- * [r2567] [trunk] Remove warning about conversion.
- Update issue 256
- * [r2566] [trunk] Add a TIFF compare function (PEAK/MSE)
- Fixes issue 100
- * [r2565] [trunk] Revert portion of r2562, need to investigate
- issue.
- Update issue 269
-
-2014-03-03 Mathieu Malaterre
-
- * [r2562] [trunk] Remove remaining conversion issues in mqc.c
- * [r2561] [trunk] Remove remainings conversion issues in t2.c +
- clock.c
- * [r2560] [trunk] Remove a simple warning about int -> float
- conversion
- * [r2559] [trunk] rework code to avoid a warning. this also remove
- a division and prefer bit-shift
- * [r2558] [trunk] Remove some more warnings about conversion
- * [r2557] [trunk] Prefer compile time constant to avoid conversion
- double -> int
- * [r2556] [trunk] Review warning about types conversion, and add
- cast when needed
- * [r2553] [trunk] Remove some simple warnings about conversion
- * [r2552] [trunk] fgets takes an int as parameter
- * [r2551] [trunk] Remove warning about cast double -> int. Instead
- use bit-shifting (compile time computation)
- * [r2550] [trunk] Remove easy to fix warnings about conversion
- * [r2549] [trunk] Import left over from patch submitted as issue
- 225 (comment #14)
- Update issue 225
- * [r2548] [trunk] remove some simple warnings about unused params
- * [r2547] [trunk] remove all api with invalid FILE* parameters
- which could leads to issues when applications are compiled with
- different flags from openjpeg.
- Fixes issue 198
- * [r2546] [trunk] Explicitely trigger issue 229, there may be an
- impact in code execution. The assert may get removed afterward
- Update issue 229
- * [r2545] [trunk] Remove simple warnings
- * [r2544] [trunk] Remove 3635.pdf.asan.77.2930.jp2 from opj_dump
- tests
- Update issue 250
- * [r2539] [trunk] Avoid conflicting declarion for fseek in openjp2
- vs fseek in openjpip
- * [r2538] [trunk] Fix md5 values for decode-md5 tests.
- Update issue 250
- * [r2537] [trunk] Remove deprecated functions.
- Update issue 268
- * [r2536] [trunk] Remove warning about unused function
- Update issue 268
- * [r2535] [trunk] Remove deprecated functions (not called anywhere
- in the code base).
- Update issue 268
- * [r2533] [trunk] Remove unused variables from test
-
-2014-03-02 Mathieu Malaterre
-
- * [r2532] [trunk] Remove some simple warnings about var being set
- but not used
- * [r2531] [trunk] Remove warning about -2147483648 (aka INT_MIN),
- causing this decimal constant is unsigned only in ISO C90
- * [r2530] [trunk] Remove simple warnings about comments, missing
- case in switch statement
-
-2014-03-01 Mathieu Malaterre
-
- * [r2529] [trunk] Fix compilation on MSVC compiler
-
-2014-02-28 Mathieu Malaterre
-
- * [r2528] [trunk] Partially rework r2506, original patch from issue
- 171 was totally bogus (untested?) and did break most of the test
- (eg. p1_04 family)
- convert.c duplicate a lot of code, this patch only adresses the
- PGX codec section of the code.
- Update issue 171
- Update issue 264
- * [r2527] [trunk] Make sure to run *-decode-md5 only after *-decode
- tests. Update md5 since recent code change.
- * [r2526] [trunk] Remove easy uint32 <-> int32 conversions
- * [r2525] [trunk] Re-import chunk from r2458 that made textGBR.jp2
- to fail otherwise
- Update issue 225
- * [r2524] [trunk] Rework r2458, instead we should reject
- 451.pdf.SIGSEGV.ce9.3723 since tile-parts are out of order (as
- per kakadu behavior).
- Update issue 225
- * [r2523] [trunk] Mark a file as being invalid for opj_dump
- * [r2522] [trunk] Fix JPIP test with updated md5sum
- * [r2521] [trunk] Really apply r2460 this time, but fix the
- original typo in the submitted patch
- Update issue 225
- * [r2520] [trunk] final round of minor cleanups
- * [r2519] [trunk] Remove PNG generation code for now
- * [r2518] [trunk] Prefer strcpy since it copies trailing 0 directly
- * [r2517] [trunk] Simplify code to centralize code cleanup
- * [r2516] [trunk] Some code cleanup add sentinels
- * [r2515] [trunk] Remove a simple warning, and use static to detect
- unused functions. Simplify function declarations.
- * [r2513] [trunk] run test suite on dataset from issue 171
- Fixes issue 171
- * [r2511] [trunk] Remove some simple warnings in opj_dump
- * [r2510] [trunk] Merge final patch from issue 171 with code
- simplification. also handles signed case properly.
- Fixes issue 171
- * [r2508] [trunk] Fix find_path behavior within cross-compilation
- execution
-
-2014-02-27 Mathieu Malaterre
-
- * [r2507] [trunk] Import patch from issue 218. No dataset to check,
- so blindly applied it.
- Fixes issue 218
- * [r2506] [trunk] Import patch from issue 171. Only the imagetoraw
- part was not applied.
- Update issue 171
- * [r2505] [trunk] Try to run test suite on invalid dataset from
- sumatrapdf team
- Update issue 225
- * [r2503] [trunk] run test suite to illustrate patch from r2458
- * [r2501] [trunk] Make sure that opj_decompress only output a
- single component
- Update issue 110
- * [r2496] [trunk] add issue 46 to the test suite
- Fixes issue 46
- * [r2495] [trunk] improve command line parser syntax checking
- * [r2493] [trunk] add a sentinel in debug code
- * [r2492] [trunk] simplify code using for loop
-
-2014-02-26 Mathieu Malaterre
-
- * [r2491] [trunk] Import test case from issue 208. This appears to
- be fixed now.
- Fixes issue 208
- * [r2489] [trunk] Run test suite on dataset from issue 211. Test is
- now passing nicely.
- Fixes issue 211
- * [r2487] [trunk] run test suite on dataset from issue 135. Add
- fake md5sum to make sure tests is failing.
- Update issue 135
- * [r2485] [trunk] Update missing md5sums
- * [r2484] [trunk] kakadu does not support 451.pdf.SIGSEGV.ce9.372
- we should not pretend to be able to decompress it
-
- Update issue 225
- * [r2483] [trunk] Run test suite on issue 141. Add a fake dataset
- to report that test is failing.
- Update issue 141
- * [r2481] [trunk] Add more details in case test fails
- * [r2480] [trunk] run test suite on input dataset from issue 134
- Fixes issue 134
- * [r2478] [trunk] fixes test NR-DEC-file409752.jp2-40-decode, use
- proper naming convention (need to keep file extension)
- * [r2477] [trunk] add test suite for issue 142
-
- Fixes issue 142
- * [r2476] [trunk] When no output PGX file is found, report an error
- * [r2474] [trunk] Add missing include dir for wx app
- * [r2473] [trunk] Remove some simple warnings about cast, and
- unused functions
- * [r2471] [trunk] Remove a simple warning about a cast
- * [r2470] [trunk] revert r2460 since it breaks
- ETS-C1P0-p0_03.j2k-decode.
- Update issue 225
- * [r2469] [trunk] Revert r2453 since it breaks conformance test
- ETS-C1P1-p1_06.j2k-decode
- * [r2468] [trunk] Import patch from sumatrapdf team. This handle
- testcase 1336.pdf.asan.47.376
- Update issue 225
- * [r2467] [trunk] Import patch from sumatrapdf team. This handle
- testcase 1888.pdf.asan.35.988
- Update issue 225
- * [r2466] [trunk] Import patch from sumatrapdf team. This handle
- testcase 1851.pdf.SIGSEGV.ce9.948
- Update issue 225
- * [r2465] [trunk] Import patch from sumatrapdf team. Start using
- new color space when found.
- Update issue 225
- * [r2464] [trunk] Import patch from sumatrapdf team. This handle
- some Part-2 compliant file, by being more tolerant in COLR box.
- No testcase for now.
- Fixes issue 247
- * [r2463] [trunk] Import patch from sumatrapdf team. This handle
- some testcase with no input dataset, but changes looks ok.
- Update issue 225
- * [r2462] [trunk] Import patch from sumatrapdf team. This handle
- testcase 2977.pdf.asan.67.2198
- Update issue 225
- * [r2461] [trunk] Import (ugly) patch from sumatrapdf team. This
- feels like a hack rather than a solution.
- Fixes issue 226
- * [r2460] [trunk] Import patch from sumatrapdf team. This handle
- testcase 3635.pdf.asan.77.2930
- Update issue 225
- * [r2459] [trunk] Import patch from sumatrapdf team. Original
- commit is 5b0c9985e3359aca9b3fcfd94424166aa61a141a.
- Update issue 225
- * [r2458] [trunk] Import patch from sumatrapdf team. This handle
- testcase 451.pdf.SIGSEGV.ce9.3723
- Update issue 225
- * [r2457] [trunk] Import patch from sumatrapdf team. This handle
- testcase 2.pdf.SIGFPE.706.1112
- Update issue 225
- * [r2456] [trunk] Import patch from sumatrapdf team. This handle
- testcase 1610.pdf.SIGSEGV.59c.681
- Update issue 225
- * [r2455] [trunk] Import patch from sumatrapdf team. This handle
- testcase 2539.pdf.SIGFPE.706.1712
- Update issue 225
- * [r2454] [trunk] Import patch from sumatrapdf team. This handle
- testcase 4035.pdf.SIGSEGV.d8b.3375
- Update issue 225
- * [r2453] [trunk] Import patch from sumatrapdf team. Add detection
- for testcase 1802.pdf.SIGSEGV.36e.894
-
- Update issue 225
- * [r2452] [trunk] Import patch from sumatrapdf team. Add a new
- function to check color box.
-
- Update issue 225
- * [r2451] [trunk] Import patch from sumatrapdf team. This patch
- adds new colorspace handling.
-
- Update issue 225
- * [r2450] [trunk] Import patch from sumatrapdf team. This adds
- alpha handling. This patch changes ABI.
-
- Update issue 225
- * [r2449] [trunk] Update file extension function to handle cases
- where filename containes multiples dots.
-
- Update issue 250
- * [r2447] [trunk] Clearly indicate that mem-b2ace68c-1381.jp2
- should not be decompressed.
-
- Update issue 250
- * [r2446] [trunk] Fix TestJPIP1 on case sensitive system
- * [r2445] [trunk] regex would not be used to remove java
- deprecation warning from dashboard
- * [r2444] [trunk] Remove simple warnings about unused functions
- * [r2443] [trunk] Properly store and use value returned by fread.
- Also invert nmemb and size in fread call.
-
- Fixes issue 262
- * [r2442] [trunk] Fix invalid write access in JPIP code.
-
- Fixes issue 261
-
-2014-02-25 Mathieu Malaterre
-
- * [r2436] [trunk] Run decoder on input dataset from issue 254. Add
- fake md5sum to make sure the test is failing.
-
- Update issue 254
- * [r2433] [trunk] deprecationg warning issued by java compiler
- should be ignored
- * [r2432] [trunk] Create a new static *_impl function to avoid a
- warning triggered by the deprecation mecanism
-
- Fixes issue 257
- * [r2430] [trunk] New decoded files are passing. Adding reference
- files.
-
- Update issue 225
- * [r2428] [trunk] For now assume any provided stream should not get
- decompressed.
-
- Update issue 225
- * [r2427] [trunk] Run decoder on issue 229 test cases
-
- Update issue 229
- * [r2419] [trunk] Revert r2415 for now since it introduce large
- regression
- * [r2418] [trunk] Import commit
- 87b08a096bb8ad61f9dbe4811e208d9c9d7fe63b from ghostpdl
-
- don't define lrintf for MSVC 2013 (fix compilation breakage)
-
- Update issue 225
- * [r2417] [trunk] Import commit
- 4cee6ceab21025079f439bb152fb9d8ae8c5c832 from ghostpdl
-
- Bug 694906: fix potential heap overflow in
- opj_t2_read_packet_header
-
- Update issue 225
- * [r2416] [trunk] import commit
- 83dad6a76536222a3a51146f942e733a2e90ec52 from ghostpdl
-
- fix potential NULL-pointer dereference caused by testing the
- wrong variable
- after opj_realloc (happens only in OOM situations)
-
- Update issue 225
- * [r2415] [trunk] Import commit
- fc884aee2b69c78500e65c3d05bf216791a9ea4a from ghostpdl
-
- prevent heap overflow in opj_t2_read_packet_header
-
- Also prevent a double-free of segment data under OOM conditions.
-
- Problem found in a test file, 1802.pdf.SIGSEGV.36e.894 supplied
- by Mateusz "j00ru" Jurczyk and Gynvael Coldwind of the Google
- Security Team using Address Sanitizer. Many thanks!
-
- Update issue 225
- * [r2414] [trunk] Import commit
- 8ec8321df613986e8642e2975f7182072eb4be62 from ghostpdl
-
- make opj_stream_set_user_data accept a NULL stream
- for consistency with opj_stream_set_* which does so.
-
- Update issue 225
- * [r2413] [trunk] Import commit
- f4139d702559649e577a5df9cfd64b0ca6107a7a from ghostpdl
-
- Several functions accept a buffer size but never actually check
- whether
- the buffer overflows during reading/writing. This fixes all cases
- where
- a size variable has explicitly been marked as unused (through a
- (void)
- cast).
-
- This was discovered while investigating an assertion caused by
- 7cc691f332f26802c64cdc47e17bff8b_signal_sigabrt_7ffff6d59425_2247_2509.pdf
- among others.
-
- Thanks to Mateusz Jurczyk and Gynvael Coldwind of the Google
- Security
- Team for providing the example files.
- * [r2411] [trunk] Clarify raw input in openjpeg. LSB vs MSB are now
- documented.
-
- Fixes issue 62
- * [r2410] [trunk] Run test case for issue 228. Output has been
- validated.
-
- Fixes issue 228
- * [r2407] [trunk] Run sumatrapdf test cases
-
-2014-02-24 Mathieu Malaterre
-
- * [r2404] [trunk] add missing private lib. Update issue 223
- * [r2402] [trunk] Make sure to always output pgx file. Handle case
- where multiple pgx files are generated. Fixes all tests.
- * [r2401] [trunk] add test demonstrating a regression in 1.5.0 and
- up. Update issue 205
- * [r2399] [trunk] improve test suite by checking against a
- reference md5
- * [r2398] [trunk] Fix a simple mem leak
- * [r2397] [trunk] Fix two simple warnings about sign mismatch
- * [r2395] [trunk] Fix warning about signed/unsigned mismatch
- * [r2394] [trunk] Make sure to handle ret value, and properly
- initialize output file
- * [r2393] [trunk] Make sure to handle ret value in test
- * [r2392] [trunk] Prefer the new style cmake: add_test command
-
- Fixes issues 258
- * [r2388] [trunk] Fix a warning about type conversion. Use a trick
- where unsigned wrapping is legal
-
-2014-02-12 Antonin Descampe
-
- * [r2375] [trunk] replaced fprintf with event_mgr in cinema-related
- stuff in j2k.c
- * [r2374] [trunk] moved logic related to cinema profiles in library
- (was in
- opj_compress.c). This enables one using the library with its own
- executable to easily ask for cinema profiles.
- * [r2373] [trunk] added a warning when tif conversion changes input
- image bitdepth
- * [r2372] [trunk]re-indenting convert.c
-
-2014-02-07 Mathieu Malaterre
-
- * [r2371] Update kakadu cmake module
-
-2014-01-23 Antonin Descampe
-
- * [r2369] [trunk] added some tests for Cinema2k 48fps and Cinema 4k
- 24 fps. Fixed
- a bug in comparePGXimages.c leading to huge Test.xml file
- uploaded to
- DashBoard
- * [r2367] [trunk] fixed another DCI compliance bug
-
-2014-01-22 Antonin Descampe
-
- * [r2366] [trunk] uncomment tests mistakenly commented in previous
- commit
- * [r2365] [trunk] fixed several bugs in cinema mode (2K 24/48 fps,
- and 4K). Trunk
- now produces compliant DCI code-streams.
-
-2014-01-16 Antonin Descampe
-
- * [r2364] [trunk] fixed indentation in opj_compress.c, renamed 2
- internal
- functions, added some comments
-
-2014-01-16 Antonin Descampe
-
- * [r2363] [trunk] fixed DCI-compliant codestream generation
- (-cinema2K and -
-
-2013-10-30 Antonin Descampe
-
- * [r2352] trunk: fixed cmake config so as to be able to link
- opj_jpip_server with FCGI.
- * [r2351] trunk: fixed cmake config so as to be able to link
- opj_jpip_server with FCGI.
-
-2013-10-28 Antonin Descampe
-
- * [r2350] trunk: disabling class-0 conformance tests for now (bad
- implentation of tests)
-
-2013-10-15 Rex Dieter
-
- * [r2348] complete openjpeg2 pkgconfig support, bug #68
-
-2013-09-26 Mathieu Malaterre
-
- * [r2347] [trunk] Import patch from bug #241
-
-2013-07-11 Antonin Descampe
-
- * [r2344] test: modified class-0 conformance testing to comply with
- constraints
-
-2013-03-25 Mickaël Savinaud
-
- * [r2322] [trunk] use the private version of opj_config to avoid
- compilation error into mj2
- * [r2321] [trunk] use opj_config_private.h into the opj_inttypes.h
- * [r2320] [trunk] separate the opj_config file between public and
- private part to avoid expose unused variables into the public
- API.
- * [r2319] [trunk] update test suite because now
- illegalcolortransform.j2k could be decoded
-
-2013-03-24 Mickaël Savinaud
-
- * [r2318] [trunk] enhance the support of sYCC into opj_decompress
- application (thanks winfried).
- * [r2317] [trunk] managed nicely the case where TPSot value is
- incorrect (thanks winfried). Update the test suite to check this
- case. Updates issue 202. Updates issue 206. Update issue 208
-
-2013-03-17 Mickaël Savinaud
-
- * [r2315] [trunk] add access to opj_apps_config.h to old
- applications
- * [r2314] [trunk] manage correctly the case where meth value is not
- correct (thanks winfried)
- * [r2313] [trunk] correct issue 188 (thanks winfried) and add test
- about it. Fixes issue 188
- * [r2308] [trunk] use OPJ_ prefix on HAVE variable also for tests
- * [r2307] [trunk]remove wrong code in mj2 library detected by
- winfried (thanks to you)
- * [r2306] [trunk] use everywhere the new opj_ prefix for HAVE
- variables and use the opj_apps_config file (thanks to winfried)
-
-2013-03-13 Mickaël Savinaud
-
- * [r2304] [trunk] use the home made macro to ensure the existence
- of some include file
- * [r2303] [trunk] use the opj_ prefix for the HAVE_FSEEKO variable
- * [r2302] [trunk] correct missing variable in openjpeg config file
-
-2013-03-03 Mickaël Savinaud
-
- * [r2301] [trunk] remove some unused variable from opj_config and
- rename other one with opj_ prefix
- * [r2300] [trunk] split into two config files config options
- related to the lib and to the application.
-
-2013-02-18 Mickaël Savinaud
-
- * [r2298] [trunk] add the prefix opj_ to deprecated everywhere
-
-2013-02-17 Mickaël Savinaud
-
- * [r2297] [trunk] update documentation of new functions _v3 and
- mark deprecated related functions
- * [r2296] [trunk] move to the new API for function
- opj_stream_create_default_file_stream. Use now
- opj_stream_create_default_file_stream_v3 (WIP)
-
-2013-02-16 Mickaël Savinaud
-
- * [r2295] [trunk] move to the new API for function
- opj_stream_destroy. Use now opj_stream_destroy_v3 (WIP)
- * [r2294] [trunk] rename deprecated macro with opj_ prefix and use
- it for opj_stream_destroy function
- * [r2293] [trunk] add functions to avoid to use FILE* into the API
- (thanks winfried).
- Update issue 120 and update issue 198
-
-2013-02-04 Mickaël Savinaud
-
- * [r2292] [trunk] add a test related to issue 202
-
-2013-02-03 Mickaël Savinaud
-
- * [r2290] [trunk] update convert about png writing with additional
- metadata (thanks winfried)
- * [r2287] [trunk] update test suite for issue 5 and 62
- * [r2285] [trunk] backout one part of the rev 2266
-
-2013-01-03 Mathieu Malaterre
-
- * [r2272] [trunk] JP3D: Fix issue with Z handling in packet
- iterator
- * [r2271] [trunk] JP3D: Handles errors properly
- * [r2270] [trunk] JP3D: remove old debug
-
-2013-01-02 Mathieu Malaterre
-
- * [r2269] [trunk] JP3D: convert from DOS to UNIX eol
- * [r2268] [trunk] JP3D: remove exe bit from source files
-
-2012-12-18 Mickaël Savinaud
-
- * [r2266] [trunk] merge from branch 1.5 a correction about large
- code-block data (decoding part) and add tests about issue 5 and
- issue 62
-
-2012-12-11 Mathieu Malaterre
-
- * [r2263] [trunk] remove left over from v2 transition
- * [r2262] [trunk] JP3D: completely redo the opj_tgt_create
- function. Take as input the initial opj_tgt_create as found in
- openjpeg 1.5, and extend with the 3rd dimension.
-
-2012-12-07 Rex Dieter
-
- * [r2259] Doxyfile: HTML_TIMESTAMP = NO
-
- helps when comparing the output of multiple runs,
- and distros will appreciate avoiding multilib conflicts.
-
-2012-12-04 Mickaël Savinaud
-
- * [r2255] [trunk] correct the new name of OPJ_HAVE_STDINT_H
- everywhere
- * [r2254] [trunk] remove SSIZE which is unused in openjpeg and
- rename HAVE_STDINT_H to OPJ_HAVE_STDINT_H
- * [r2253] [trunk] add openjpeg.h in some files of openjpip to use
- some opj type (thanks winfried)
-
-2012-12-03 Mickaël Savinaud
-
- * [r2252] [trunk] move typedef from opj_stdint.h to openjpeg.h and
- add an include of stdio.h in openjpeg.h. Fixes issue 197
- * [r2251] [trunk] correct the encoding of colr box information
- (thanks Winfried)
- * [r2250] [trunk]add the pkgconfig support for openjp2 (thanks
- Winfried)
-
-2012-11-28 Mathieu Malaterre
-
- * [r2249] [trunk] JP3D codec was trying to pull information from
- the registration parameter in COM. This is non-standard.
- * [r2248] [trunk] As per T.809 code block are not shifted in JP3D
-
- Table A.7
- 3D code-block width, height and depth exponent values xcb =
- value, ycb = value
- or zcb = value.
- NOTE – This redefines Rec. ITU-T T.800 | ISO/IEC 15444-1
- significantly! The 3D
- code-block width, height and depth are limited to powers of two
- with the minimum
- size being 20 and the maximum being 210.
- Further, the 3D code-block size is restricted so that 4 ≤
- xcb+ycb+zcb ≤ 18.
- * [r2247] [trunk] JP3D: this is safe to write comment using
- Registration: ISO-8859-15
- * [r2246] [trunk] JP3D fix issue with Registration value in COM
- marker. Move COM marker just before COD.
- * [r2245] [trunk] jp3d: fix command line parsing for subsampling
- * [r2244] [trunk] Fix issue with ITU-T T.809 (05/2011)
-
- - ZSI is now known as NSI (FF54)
- - NSI now stores Ndim (=3)
- - CAP extended marker was not set properly
- * [r2243] [trunk] Fix compilation issue where size_t would be
- undefined
-
-2012-11-27 Mickaël Savinaud
-
- * [r2242] [test] update the list of files which will be gracefully
- rejected when they are dump
- * [r2241] [trunk] add empty test about the issue 197. Updates issue
- 197
-
-2012-11-26 Mickaël Savinaud
-
- * [r2240] [trun[trunk] check if the dx and dy steps are not
- incorrect according to the JPEG2000 norm (thanks Even).
- Test associated to this issue should nicely fail. Fixes issue 194
- * [r2239] [trunk] check if the number of tiles is not incorrect
- regarding the JPEG2000 norm (thanks Even).
- Test associated to this issue should nicely fail. Fixes issue 163
- * [r2238] [trunk] test about issue 192 should nicely fail
- * [r2237] [trunk] check the index of the component in read_qcc
- (thanks Even). fixes issue 192
- * [r2235] [trunk] update test suite with issue 191 to 194 and
- update patch for 191 which should fail properly
-
diff --git a/openjpeg/NEWS b/openjpeg/NEWS
deleted file mode 100644
index 2fecd4ac2..000000000
--- a/openjpeg/NEWS
+++ /dev/null
@@ -1,61 +0,0 @@
-
-OpenJPEG NEWS - user visible changes
-====================================
-
-Changes from OpenJPEG 2.0.0 to OpenJPEG 2.X.X
-----------------------------------------------
-
-New Features:
-
- * Digital Cinema profiles have been fixed and updated
- * New option to disable MCT if needed
- * extended RAW support: it is now possible to input raw images
- with subsampled color components (422, 420, etc)
- * New way to deal with profiles
-
-API/ABI modifications: (see abi_compat_report in dev-utils/scripts)
-
- * Removed deprecated functions
- - opj_stream_create_default_file_stream(FILE*,...)
- - opj_stream_create_file_stream(FILE*,...)
- - opj_stream_set_user_data (opj_stream_t* p_stream, void * p_data)
- * Added
- - opj_stream_create_default_file_stream(char*,...)
- - opj_stream_create_file_stream(char*,...)
- - opj_stream_destroy(opj_stream_t*)
- - opj_stream_set_user_data (opj_stream_t* p_stream, void * p_data,
- ... opj_stream_free_user_data_fn p_function)
- - JPEG 2000 profiles and Part-2 extensions defined through '#define'
- * Changed
- - 'alpha' field added to 'opj_image_comp' structure
- - 'OPJ_CLRSPC_EYCC' added to enum COLOR_SPACE
- - 'OPJ_CLRSPC_CMYK' added to enum COLOR_SPACE
- - 'OPJ_CODEC_JPP' and 'OPJ_CODEC_JPX' added to CODEC_FORMAT
- (not yet used in use)
- - 'max_cs_size' and 'rsiz' fields added to opj_cparameters_t
-
-Misc:
-
- * OpenJPEG is now officialy conformant with JPEG 2000 Part-1
- and will soon become official reference software at the
- JPEG committee.
- * Huge amount of bug fixes. See CHANGES for details.
-
-
-Changes from OpenJPEG 1.5.x to OpenJPEG 2.0.0
-----------------------------------------------
-
-New Features:
-
- * streaming capabilities
- * merge JP3D
-
-API modifications:
-
- * Use a 64bits capable API
-
-Misc:
-
- * removed autotools build system
- * folders hierarchies reorganisation
- * Huge amount of bug fixes. See CHANGES for details.
diff --git a/openjpeg/NEWS.md b/openjpeg/NEWS.md
new file mode 100644
index 000000000..ce538f438
--- /dev/null
+++ b/openjpeg/NEWS.md
@@ -0,0 +1,67 @@
+# OpenJPEG NEWS
+
+More details in the [Changelog](https://github.com/uclouvain/openjpeg/blob/master/CHANGELOG.md)
+
+## OpenJPEG 2.1.1
+
+* Huge amount of critical bugfixes
+* Speed improvements
+* No API/ABI break compared to v2.1
+
+## OpenJPEG 2.1.0
+
+### New Features
+
+ * Digital Cinema profiles have been fixed and updated
+ * New option to disable MCT if needed
+ * extended RAW support: it is now possible to input raw images
+ with subsampled color components (422, 420, etc)
+ * New way to deal with profiles
+
+### API/ABI modifications
+(see [here](http://www.openjpeg.org/abi-check/timeline/openjpeg/) for details)
+
+ * Removed deprecated functions
+ * opj_stream_create_default_file_stream(FILE*,...)
+ * opj_stream_create_file_stream(FILE*,...)
+ * opj_stream_set_user_data (opj_stream_t* p_stream, void * p_data)
+ * Added
+ * opj_stream_create_default_file_stream(char*,...)
+ * opj_stream_create_file_stream(char*,...)
+ * opj_stream_destroy(opj_stream_t*)
+ * opj_stream_set_user_data (opj_stream_t* p_stream, void * p_data,
+ ... opj_stream_free_user_data_fn p_function)
+ * JPEG 2000 profiles and Part-2 extensions defined through '#define'
+ * Changed
+ * 'alpha' field added to 'opj_image_comp' structure
+ * 'OPJ_CLRSPC_EYCC' added to enum COLOR_SPACE
+ * 'OPJ_CLRSPC_CMYK' added to enum COLOR_SPACE
+ * 'OPJ_CODEC_JPP' and 'OPJ_CODEC_JPX' added to CODEC_FORMAT
+ (not yet used in use)
+ * 'max_cs_size' and 'rsiz' fields added to opj_cparameters_t
+
+### Misc
+
+ * OpenJPEG is now officially conformant with JPEG 2000 Part-1
+ and will soon become official reference software at the
+ JPEG committee.
+ * Huge amount of bug fixes. See CHANGES for details.
+
+
+## OpenJPEG 2.0.0
+
+### New Features
+
+ * streaming capabilities
+ * merge JP3D
+
+### API modifications
+(see [here](http://www.openjpeg.org/abi-check/timeline/openjpeg/) for details)
+
+ * Use a 64bits capable API
+
+### Misc
+
+ * removed autotools build system
+ * folders hierarchies reorganisation
+ * Huge amount of bug fixes. See CHANGES for details.
diff --git a/openjpeg/THANKS b/openjpeg/THANKS
deleted file mode 100644
index 27a35aa44..000000000
--- a/openjpeg/THANKS
+++ /dev/null
@@ -1,33 +0,0 @@
-OpenJPEG THANKS file
-
-Many people have contributed to OpenJPEG by reporting problems, suggesting various improvements,
-or submitting actual code. Here is a list of these people. Help me keep
-it complete and exempt of errors.
-
-Winfried Szukalski
-Vincent Torri
-Bob Friesenhahn
-Callum Lerwick
-Dzonatas Sol
-Julien Malik
-Jerôme Fimes
-Herve Drolon
-Yannick Verschueren
-Sebastien Lugan
-Kaori Hagihara
-Peter Wimmer
-Francois-Olivier Devaux
-Antonin Descampe
-David Janssens
-Pr. Benoit Macq
-Luis Ibanez
-Ben Boeckel
-Vincent Nicolas
-Glenn Pearson
-Giuseppe Baruffa
-Arnaud Maye
-Rex Dieter
-David Burken
-Parvatha Elangovan
-Hans Johnson
-Luc Hermitte \ No newline at end of file
diff --git a/openjpeg/THANKS.md b/openjpeg/THANKS.md
new file mode 100644
index 000000000..8e93d5904
--- /dev/null
+++ b/openjpeg/THANKS.md
@@ -0,0 +1,38 @@
+# OpenJPEG THANKS file
+
+Many people have contributed to OpenJPEG by reporting problems, suggesting various improvements,
+or submitting actual code. Here is a list of these people. Help me keep
+it complete and exempt of errors.
+
+* Giuseppe Baruffa
+* Ben Boeckel
+* Aaron Boxer
+* David Burken
+* Matthieu Darbois
+* Rex Dieter
+* Herve Drolon
+* Antonin Descampe
+* Francois-Olivier Devaux
+* Parvatha Elangovan
+* Jerôme Fimes
+* Bob Friesenhahn
+* Kaori Hagihara
+* Luc Hermitte
+* Luis Ibanez
+* David Janssens
+* Hans Johnson
+* Callum Lerwick
+* Ke Liu (Tencent's Xuanwu LAB)
+* Sebastien Lugan
+* Benoit Macq
+* Mathieu Malaterre
+* Julien Malik
+* Arnaud Maye
+* Vincent Nicolas
+* Glenn Pearson
+* Even Rouault
+* Dzonatas Sol
+* Winfried Szukalski
+* Vincent Torri
+* Yannick Verschueren
+* Peter Wimmer
diff --git a/openjpeg/src/lib/openjp2/CMakeLists.txt b/openjpeg/src/lib/openjp2/CMakeLists.txt
deleted file mode 100644
index fcf60ecf0..000000000
--- a/openjpeg/src/lib/openjp2/CMakeLists.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-include_regular_expression("^.*$")
-
-#
-install( FILES ${CMAKE_CURRENT_BINARY_DIR}/opj_config.h
- DESTINATION ${OPENJPEG_INSTALL_INCLUDE_DIR} COMPONENT Headers)
-
-include_directories(
- ${OPENJPEG_BINARY_DIR}/src/lib/openjp2 # opj_config.h and opj_config_private.h
-)
-# Defines the source code for the library
-set(OPENJPEG_SRCS
- ${CMAKE_CURRENT_SOURCE_DIR}/bio.c
- ${CMAKE_CURRENT_SOURCE_DIR}/cio.c
- ${CMAKE_CURRENT_SOURCE_DIR}/dwt.c
- ${CMAKE_CURRENT_SOURCE_DIR}/event.c
- ${CMAKE_CURRENT_SOURCE_DIR}/image.c
- ${CMAKE_CURRENT_SOURCE_DIR}/invert.c
- ${CMAKE_CURRENT_SOURCE_DIR}/j2k.c
- ${CMAKE_CURRENT_SOURCE_DIR}/jp2.c
- ${CMAKE_CURRENT_SOURCE_DIR}/mct.c
- ${CMAKE_CURRENT_SOURCE_DIR}/mqc.c
- ${CMAKE_CURRENT_SOURCE_DIR}/openjpeg.c
- ${CMAKE_CURRENT_SOURCE_DIR}/opj_clock.c
- ${CMAKE_CURRENT_SOURCE_DIR}/pi.c
- ${CMAKE_CURRENT_SOURCE_DIR}/raw.c
- ${CMAKE_CURRENT_SOURCE_DIR}/t1.c
- ${CMAKE_CURRENT_SOURCE_DIR}/t2.c
- ${CMAKE_CURRENT_SOURCE_DIR}/tcd.c
- ${CMAKE_CURRENT_SOURCE_DIR}/tgt.c
- ${CMAKE_CURRENT_SOURCE_DIR}/function_list.c
-)
-if(BUILD_JPIP)
- add_definitions(-DUSE_JPIP)
- set(OPENJPEG_SRCS
- ${OPENJPEG_SRCS}
- ${CMAKE_CURRENT_SOURCE_DIR}/cidx_manager.c
- ${CMAKE_CURRENT_SOURCE_DIR}/phix_manager.c
- ${CMAKE_CURRENT_SOURCE_DIR}/ppix_manager.c
- ${CMAKE_CURRENT_SOURCE_DIR}/thix_manager.c
- ${CMAKE_CURRENT_SOURCE_DIR}/tpix_manager.c
- )
-endif()
-
-# Build the library
-if(WIN32)
- if(BUILD_SHARED_LIBS)
- add_definitions(-DOPJ_EXPORTS)
- else()
- add_definitions(-DOPJ_STATIC)
- endif()
-endif()
-add_library(${OPENJPEG_LIBRARY_NAME} ${OPENJPEG_SRCS})
-if(UNIX)
- target_link_libraries(${OPENJPEG_LIBRARY_NAME} m)
-endif()
-set_target_properties(${OPENJPEG_LIBRARY_NAME} PROPERTIES ${OPENJPEG_LIBRARY_PROPERTIES})
-
-# Install library
-install(TARGETS ${OPENJPEG_LIBRARY_NAME}
- EXPORT OpenJPEGTargets
- RUNTIME DESTINATION ${OPENJPEG_INSTALL_BIN_DIR} COMPONENT Applications
- LIBRARY DESTINATION ${OPENJPEG_INSTALL_LIB_DIR} COMPONENT Libraries
- ARCHIVE DESTINATION ${OPENJPEG_INSTALL_LIB_DIR} COMPONENT Libraries
-)
-
-# Install includes files
-install(FILES openjpeg.h opj_stdint.h
- DESTINATION ${OPENJPEG_INSTALL_INCLUDE_DIR} COMPONENT Headers
-)
-
-if(BUILD_DOC)
-# install man page of the library
-install(
- FILES ${OPENJPEG_SOURCE_DIR}/doc/man/man3/libopenjp2.3
- DESTINATION ${OPENJPEG_INSTALL_MAN_DIR}/man3)
-endif()
-
-# internal utilities to generate t1_luts.h (part of the jp2 lib)
-# no need to install:
-add_executable(t1_generate_luts t1_generate_luts.c)
-if(UNIX)
- target_link_libraries(t1_generate_luts m)
-endif()
-
-# Experimental option; let's how cppcheck performs
-# Implementation details:
-# I could not figure out how to easily upload a file to CDash. Instead simply
-# pretend cppcheck is part of the Build step. Technically cppcheck can even
-# output gcc formatted error/warning report
-# Another implementation detail: I could not redirect error to the error
-# catching mechanism something is busted in cmake 2.8.5, I had to use the
-# warning regex to catch them.
-if(OPENJPEG_CPPCHECK)
- find_package(CPPCHECK REQUIRED)
- foreach(f ${OPENJPEG_SRCS})
- # cppcheck complains about too many configuration, pretend to be WIN32:
- add_custom_command(TARGET ${OPENJPEG_LIBRARY_NAME}
- COMMAND ${CPPCHECK_EXECUTABLE} -DWIN32 ${f})
- endforeach()
-endif()
diff --git a/openjpeg/src/lib/openjp2/bio.c b/openjpeg/src/lib/openjp2/bio.c
index 5d4958017..269769b45 100644
--- a/openjpeg/src/lib/openjp2/bio.c
+++ b/openjpeg/src/lib/openjp2/bio.c
@@ -78,27 +78,27 @@ static OPJ_BOOL opj_bio_bytein(opj_bio_t *bio);
==========================================================
*/
-OPJ_BOOL opj_bio_byteout(opj_bio_t *bio) {
+static OPJ_BOOL opj_bio_byteout(opj_bio_t *bio) {
bio->buf = (bio->buf << 8) & 0xffff;
bio->ct = bio->buf == 0xff00 ? 7 : 8;
- if (bio->bp >= bio->end) {
+ if ((OPJ_SIZE_T)bio->bp >= (OPJ_SIZE_T)bio->end) {
return OPJ_FALSE;
}
*bio->bp++ = (OPJ_BYTE)(bio->buf >> 8);
return OPJ_TRUE;
}
-OPJ_BOOL opj_bio_bytein(opj_bio_t *bio) {
+static OPJ_BOOL opj_bio_bytein(opj_bio_t *bio) {
bio->buf = (bio->buf << 8) & 0xffff;
bio->ct = bio->buf == 0xff00 ? 7 : 8;
- if (bio->bp >= bio->end) {
+ if ((OPJ_SIZE_T)bio->bp >= (OPJ_SIZE_T)bio->end) {
return OPJ_FALSE;
}
bio->buf |= *bio->bp++;
return OPJ_TRUE;
}
-void opj_bio_putbit(opj_bio_t *bio, OPJ_UINT32 b) {
+static void opj_bio_putbit(opj_bio_t *bio, OPJ_UINT32 b) {
if (bio->ct == 0) {
opj_bio_byteout(bio); /* MSD: why not check the return value of this function ? */
}
@@ -106,7 +106,7 @@ void opj_bio_putbit(opj_bio_t *bio, OPJ_UINT32 b) {
bio->buf |= b << bio->ct;
}
-OPJ_UINT32 opj_bio_getbit(opj_bio_t *bio) {
+static OPJ_UINT32 opj_bio_getbit(opj_bio_t *bio) {
if (bio->ct == 0) {
opj_bio_bytein(bio); /* MSD: why not check the return value of this function ? */
}
@@ -151,30 +151,40 @@ void opj_bio_init_dec(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len) {
bio->ct = 0;
}
+OPJ_NOSANITIZE("unsigned-integer-overflow")
void opj_bio_write(opj_bio_t *bio, OPJ_UINT32 v, OPJ_UINT32 n) {
OPJ_UINT32 i;
- for (i = n - 1; i < n; i--) {
+
+ assert((n > 0U) && (n <= 32U));
+ for (i = n - 1; i < n; i--) { /* overflow used for end-loop condition */
opj_bio_putbit(bio, (v >> i) & 1);
}
}
+OPJ_NOSANITIZE("unsigned-integer-overflow")
OPJ_UINT32 opj_bio_read(opj_bio_t *bio, OPJ_UINT32 n) {
OPJ_UINT32 i;
- OPJ_UINT32 v;
- v = 0;
- for (i = n - 1; i < n; i--) {
- v += opj_bio_getbit(bio) << i;
+ OPJ_UINT32 v;
+
+ assert((n > 0U) /* && (n <= 32U)*/);
+#ifdef OPJ_UBSAN_BUILD
+ /* This assert fails for some corrupted images which are gracefully rejected */
+ /* Add this assert only for ubsan build. */
+ /* This is the condition for overflow not to occur below which is needed because of OPJ_NOSANITIZE */
+ assert(n <= 32U);
+#endif
+ v = 0U;
+ for (i = n - 1; i < n; i--) { /* overflow used for end-loop condition */
+ v |= opj_bio_getbit(bio) << i; /* can't overflow, opj_bio_getbit returns 0 or 1 */
}
return v;
}
OPJ_BOOL opj_bio_flush(opj_bio_t *bio) {
- bio->ct = 0;
if (! opj_bio_byteout(bio)) {
return OPJ_FALSE;
}
if (bio->ct == 7) {
- bio->ct = 0;
if (! opj_bio_byteout(bio)) {
return OPJ_FALSE;
}
@@ -183,12 +193,11 @@ OPJ_BOOL opj_bio_flush(opj_bio_t *bio) {
}
OPJ_BOOL opj_bio_inalign(opj_bio_t *bio) {
- bio->ct = 0;
if ((bio->buf & 0xff) == 0xff) {
if (! opj_bio_bytein(bio)) {
return OPJ_FALSE;
}
- bio->ct = 0;
}
+ bio->ct = 0;
return OPJ_TRUE;
}
diff --git a/openjpeg/src/lib/openjp2/cidx_manager.c b/openjpeg/src/lib/openjp2/cidx_manager.c
index ff2dbdaa3..30561ed20 100644
--- a/openjpeg/src/lib/openjp2/cidx_manager.c
+++ b/openjpeg/src/lib/openjp2/cidx_manager.c
@@ -60,7 +60,9 @@ int opj_write_cidx( int offset, opj_stream_private_t *cio, opj_codestream_info_t
lenp = -1;
box = (opj_jp2_box_t *)opj_calloc( 32, sizeof(opj_jp2_box_t));
-
+ if(box == NULL){
+ return 0;
+ }
for (i=0;i<2;i++){
if(i)
diff --git a/openjpeg/src/lib/openjp2/cio.c b/openjpeg/src/lib/openjp2/cio.c
index 1fc239374..b115cf529 100644
--- a/openjpeg/src/lib/openjp2/cio.c
+++ b/openjpeg/src/lib/openjp2/cio.c
@@ -46,7 +46,7 @@
void opj_write_bytes_BE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes)
{
- const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes;
+ const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value)+sizeof(OPJ_UINT32)-p_nb_bytes;
assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
@@ -72,7 +72,7 @@ void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT
assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
*p_value = 0;
- memcpy(l_data_ptr+4-p_nb_bytes,p_buffer,p_nb_bytes);
+ memcpy(l_data_ptr+sizeof(OPJ_UINT32)-p_nb_bytes,p_buffer,p_nb_bytes);
}
void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes)
@@ -151,12 +151,11 @@ void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_SIZE_T p_buffer_size,OPJ_BOOL l_is_input)
{
opj_stream_private_t * l_stream = 00;
- l_stream = (opj_stream_private_t*) opj_malloc(sizeof(opj_stream_private_t));
+ l_stream = (opj_stream_private_t*) opj_calloc(1,sizeof(opj_stream_private_t));
if (! l_stream) {
return 00;
}
- memset(l_stream,0,sizeof(opj_stream_private_t));
l_stream->m_buffer_size = p_buffer_size;
l_stream->m_stored_data = (OPJ_BYTE *) opj_malloc(p_buffer_size);
if (! l_stream->m_stored_data) {
@@ -167,12 +166,12 @@ opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_SIZE_T p_buffer_size,OPJ_BOOL l
l_stream->m_current_data = l_stream->m_stored_data;
if (l_is_input) {
- l_stream->m_status |= opj_stream_e_input;
+ l_stream->m_status |= OPJ_STREAM_STATUS_INPUT;
l_stream->m_opj_skip = opj_stream_read_skip;
l_stream->m_opj_seek = opj_stream_read_seek;
}
else {
- l_stream->m_status |= opj_stream_e_output;
+ l_stream->m_status |= OPJ_STREAM_STATUS_OUTPUT;
l_stream->m_opj_skip = opj_stream_write_skip;
l_stream->m_opj_seek = opj_stream_write_seek;
}
@@ -208,7 +207,7 @@ void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream, opj_strea
{
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
- if ((!l_stream) || (! (l_stream->m_status & opj_stream_e_input))) {
+ if ((!l_stream) || (! (l_stream->m_status & OPJ_STREAM_STATUS_INPUT))) {
return;
}
@@ -229,7 +228,7 @@ void OPJ_CALLCONV opj_stream_set_write_function(opj_stream_t* p_stream, opj_stre
{
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
- if ((!l_stream )|| (! (l_stream->m_status & opj_stream_e_output))) {
+ if ((!l_stream )|| (! (l_stream->m_status & OPJ_STREAM_STATUS_OUTPUT))) {
return;
}
@@ -277,7 +276,7 @@ OPJ_SIZE_T opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_bu
}
/* we are now in the case when the remaining data if not sufficient */
- if (p_stream->m_status & opj_stream_e_end) {
+ if (p_stream->m_status & OPJ_STREAM_STATUS_END) {
l_read_nb_bytes += p_stream->m_bytes_in_buffer;
memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
p_stream->m_current_data += p_stream->m_bytes_in_buffer;
@@ -303,7 +302,7 @@ OPJ_SIZE_T opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_bu
p_stream->m_current_data = p_stream->m_stored_data;
}
- while(1){
+ for (;;) {
/* we should read less than a chunk -> read a chunk */
if (p_size < p_stream->m_buffer_size) {
/* we should do an actual read on the media */
@@ -314,7 +313,7 @@ OPJ_SIZE_T opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_bu
opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
p_stream->m_bytes_in_buffer = 0;
- p_stream->m_status |= opj_stream_e_end;
+ p_stream->m_status |= OPJ_STREAM_STATUS_END;
/* end of stream */
return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1;
}
@@ -346,7 +345,7 @@ OPJ_SIZE_T opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_bu
opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
p_stream->m_bytes_in_buffer = 0;
- p_stream->m_status |= opj_stream_e_end;
+ p_stream->m_status |= OPJ_STREAM_STATUS_END;
/* end of stream */
return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1;
}
@@ -379,11 +378,11 @@ OPJ_SIZE_T opj_stream_write_data (opj_stream_private_t * p_stream,
OPJ_SIZE_T l_remaining_bytes = 0;
OPJ_SIZE_T l_write_nb_bytes = 0;
- if (p_stream->m_status & opj_stream_e_error) {
+ if (p_stream->m_status & OPJ_STREAM_STATUS_ERROR) {
return (OPJ_SIZE_T)-1;
}
- while(1) {
+ for (;;) {
l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer;
/* we have more memory than required */
@@ -433,7 +432,7 @@ OPJ_BOOL opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_
p_stream->m_user_data);
if (l_current_write_nb_bytes == (OPJ_SIZE_T)-1) {
- p_stream->m_status |= opj_stream_e_error;
+ p_stream->m_status |= OPJ_STREAM_STATUS_ERROR;
opj_event_msg(p_event_mgr, EVT_INFO, "Error on writing stream!\n");
return OPJ_FALSE;
@@ -466,7 +465,7 @@ OPJ_OFF_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_siz
}
/* we are now in the case when the remaining data if not sufficient */
- if (p_stream->m_status & opj_stream_e_end) {
+ if (p_stream->m_status & OPJ_STREAM_STATUS_END) {
l_skip_nb_bytes += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
p_stream->m_current_data += p_stream->m_bytes_in_buffer;
p_stream->m_bytes_in_buffer = 0;
@@ -488,7 +487,7 @@ OPJ_OFF_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_siz
if (l_current_skip_nb_bytes == (OPJ_OFF_T) -1) {
opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
- p_stream->m_status |= opj_stream_e_end;
+ p_stream->m_status |= OPJ_STREAM_STATUS_END;
p_stream->m_byte_offset += l_skip_nb_bytes;
/* end if stream */
return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) -1;
@@ -508,14 +507,14 @@ OPJ_OFF_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_si
OPJ_OFF_T l_current_skip_nb_bytes = 0;
OPJ_OFF_T l_skip_nb_bytes = 0;
- if (p_stream->m_status & opj_stream_e_error) {
+ if (p_stream->m_status & OPJ_STREAM_STATUS_ERROR) {
return (OPJ_OFF_T) -1;
}
/* we should flush data */
l_is_written = opj_stream_flush (p_stream, p_event_mgr);
if (! l_is_written) {
- p_stream->m_status |= opj_stream_e_error;
+ p_stream->m_status |= OPJ_STREAM_STATUS_ERROR;
p_stream->m_bytes_in_buffer = 0;
return (OPJ_OFF_T) -1;
}
@@ -528,7 +527,7 @@ OPJ_OFF_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_si
if (l_current_skip_nb_bytes == (OPJ_OFF_T)-1) {
opj_event_msg(p_event_mgr, EVT_INFO, "Stream error!\n");
- p_stream->m_status |= opj_stream_e_error;
+ p_stream->m_status |= OPJ_STREAM_STATUS_ERROR;
p_stream->m_byte_offset += l_skip_nb_bytes;
/* end if stream */
return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T)-1;
@@ -569,12 +568,12 @@ OPJ_BOOL opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size
p_stream->m_bytes_in_buffer = 0;
if( !(p_stream->m_seek_fn(p_size,p_stream->m_user_data)) ) {
- p_stream->m_status |= opj_stream_e_end;
+ p_stream->m_status |= OPJ_STREAM_STATUS_END;
return OPJ_FALSE;
}
else {
/* reset stream status */
- p_stream->m_status &= (~opj_stream_e_end);
+ p_stream->m_status &= (~OPJ_STREAM_STATUS_END);
p_stream->m_byte_offset = p_size;
}
@@ -585,7 +584,7 @@ OPJ_BOOL opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size
OPJ_BOOL opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
{
if (! opj_stream_flush(p_stream,p_event_mgr)) {
- p_stream->m_status |= opj_stream_e_error;
+ p_stream->m_status |= OPJ_STREAM_STATUS_ERROR;
return OPJ_FALSE;
}
@@ -593,7 +592,7 @@ OPJ_BOOL opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_siz
p_stream->m_bytes_in_buffer = 0;
if (! p_stream->m_seek_fn(p_size,p_stream->m_user_data)) {
- p_stream->m_status |= opj_stream_e_error;
+ p_stream->m_status |= OPJ_STREAM_STATUS_ERROR;
return OPJ_FALSE;
}
else {
diff --git a/openjpeg/src/lib/openjp2/cio.h b/openjpeg/src/lib/openjp2/cio.h
index 6dfa5bb84..4ea03ff34 100644
--- a/openjpeg/src/lib/openjp2/cio.h
+++ b/openjpeg/src/lib/openjp2/cio.h
@@ -70,16 +70,10 @@ The functions in CIO.C have for goal to realize a byte input / output process.
#endif
-
-typedef enum
-{
- opj_signed_sentinel = -1, /* do not use in code */
- opj_stream_e_output = 0x1,
- opj_stream_e_input = 0x2,
- opj_stream_e_end = 0x4,
- opj_stream_e_error = 0x8
-}
-opj_stream_flag ;
+#define OPJ_STREAM_STATUS_OUTPUT 0x1U
+#define OPJ_STREAM_STATUS_INPUT 0x2U
+#define OPJ_STREAM_STATUS_END 0x4U
+#define OPJ_STREAM_STATUS_ERROR 0x8U
/**
Byte input-output stream.
@@ -162,8 +156,9 @@ typedef struct opj_stream_private
/**
* Flags to tell the status of the stream.
+ * Used with OPJ_STREAM_STATUS_* defines.
*/
- opj_stream_flag m_status;
+ OPJ_UINT32 m_status;
}
opj_stream_private_t;
@@ -184,7 +179,7 @@ void opj_write_bytes_BE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_n
* @param p_buffer pointer the data buffer to read data from.
* @param p_value pointer to the value that will store the data.
* @param p_nb_bytes the nb bytes to read.
- * @return the number of bytes read or -1 if an error occured.
+ * @return the number of bytes read or -1 if an error occurred.
*/
void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes);
@@ -193,7 +188,7 @@ void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT
* @param p_buffer pointer the data buffer to write data to.
* @param p_value the value to write
* @param p_nb_bytes the number of bytes to write
- * @return the number of bytes written or -1 if an error occured
+ * @return the number of bytes written or -1 if an error occurred
*/
void opj_write_bytes_LE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes);
@@ -202,7 +197,7 @@ void opj_write_bytes_LE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_n
* @param p_buffer pointer the data buffer to read data from.
* @param p_value pointer to the value that will store the data.
* @param p_nb_bytes the nb bytes to read.
- * @return the number of bytes read or -1 if an error occured.
+ * @return the number of bytes read or -1 if an error occurred.
*/
void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes);
@@ -269,7 +264,7 @@ void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value);
* @param p_buffer pointer to the data buffer that will receive the data.
* @param p_size number of bytes to read.
* @param p_event_mgr the user event manager to be notified of special events.
- * @return the number of bytes read, or -1 if an error occured or if the stream is at the end.
+ * @return the number of bytes read, or -1 if an error occurred or if the stream is at the end.
*/
OPJ_SIZE_T opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
@@ -279,7 +274,7 @@ OPJ_SIZE_T opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_bu
* @param p_buffer pointer to the data buffer holds the data to be writtent.
* @param p_size number of bytes to write.
* @param p_event_mgr the user event manager to be notified of special events.
- * @return the number of bytes writtent, or -1 if an error occured.
+ * @return the number of bytes writtent, or -1 if an error occurred.
*/
OPJ_SIZE_T opj_stream_write_data (opj_stream_private_t * p_stream,const OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
@@ -296,7 +291,7 @@ OPJ_BOOL opj_stream_flush (opj_stream_private_t * p_stream, struct opj_event_mgr
* @param p_stream the stream to skip data from.
* @param p_size the number of bytes to skip.
* @param p_event_mgr the user event manager to be notified of special events.
- * @return the number of bytes skipped, or -1 if an error occured.
+ * @return the number of bytes skipped, or -1 if an error occurred.
*/
OPJ_OFF_T opj_stream_skip (opj_stream_private_t * p_stream,OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
@@ -324,7 +319,7 @@ OPJ_OFF_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream
* @param p_stream the stream to skip data from.
* @param p_size the number of bytes to skip.
* @param p_event_mgr the user event manager to be notified of special events.
- * @return the number of bytes skipped, or -1 if an error occured.
+ * @return the number of bytes skipped, or -1 if an error occurred.
*/
OPJ_OFF_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
@@ -333,7 +328,7 @@ OPJ_OFF_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_si
* @param p_stream the stream to skip data from.
* @param p_size the number of bytes to skip.
* @param p_event_mgr the user event manager to be notified of special events.
- * @return the number of bytes skipped, or -1 if an error occured.
+ * @return the number of bytes skipped, or -1 if an error occurred.
*/
OPJ_OFF_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
@@ -342,7 +337,7 @@ OPJ_OFF_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_siz
* @param p_stream the stream to skip data from.
* @param p_size the number of bytes to skip.
* @param p_event_mgr the user event manager to be notified of special events.
- * @return OPJ_TRUE if success, or OPJ_FALSE if an error occured.
+ * @return OPJ_TRUE if success, or OPJ_FALSE if an error occurred.
*/
OPJ_BOOL opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
@@ -351,7 +346,7 @@ OPJ_BOOL opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size
* @param p_stream the stream to skip data from.
* @param p_size the number of bytes to skip.
* @param p_event_mgr the user event manager to be notified of special events.
- * @return the number of bytes skipped, or -1 if an error occured.
+ * @return the number of bytes skipped, or -1 if an error occurred.
*/
OPJ_BOOL opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
diff --git a/openjpeg/src/lib/openjp2/dwt.c b/openjpeg/src/lib/openjp2/dwt.c
index e1f8a337d..9e2a36158 100644
--- a/openjpeg/src/lib/openjp2/dwt.c
+++ b/openjpeg/src/lib/openjp2/dwt.c
@@ -124,21 +124,21 @@ static void opj_dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps, opj_st
/**
Inverse wavelet transform in 2-D.
*/
-static OPJ_BOOL opj_dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 i, DWT1DFN fn);
+static OPJ_BOOL opj_dwt_decode_tile(opj_thread_pool_t* tp, opj_tcd_tilecomp_t* tilec, OPJ_UINT32 i, DWT1DFN fn);
static OPJ_BOOL opj_dwt_encode_procedure( opj_tcd_tilecomp_t * tilec,
void (*p_function)(OPJ_INT32 *, OPJ_INT32,OPJ_INT32,OPJ_INT32) );
-static OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* restrict r, OPJ_UINT32 i);
+static OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* OPJ_RESTRICT r, OPJ_UINT32 i);
/* <summary> */
/* Inverse 9-7 wavelet transform in 1-D. */
/* </summary> */
-static void opj_v4dwt_decode(opj_v4dwt_t* restrict dwt);
+static void opj_v4dwt_decode(opj_v4dwt_t* OPJ_RESTRICT dwt);
-static void opj_v4dwt_interleave_h(opj_v4dwt_t* restrict w, OPJ_FLOAT32* restrict a, OPJ_INT32 x, OPJ_INT32 size);
+static void opj_v4dwt_interleave_h(opj_v4dwt_t* OPJ_RESTRICT w, OPJ_FLOAT32* OPJ_RESTRICT a, OPJ_INT32 x, OPJ_INT32 size);
-static void opj_v4dwt_interleave_v(opj_v4dwt_t* restrict v , OPJ_FLOAT32* restrict a , OPJ_INT32 x, OPJ_INT32 nb_elts_read);
+static void opj_v4dwt_interleave_v(opj_v4dwt_t* OPJ_RESTRICT v , OPJ_FLOAT32* OPJ_RESTRICT a , OPJ_INT32 x, OPJ_INT32 nb_elts_read);
#ifdef __SSE__
static void opj_v4dwt_decode_step1_sse(opj_v4_t* w, OPJ_INT32 count, const __m128 c);
@@ -193,7 +193,7 @@ static const OPJ_FLOAT64 opj_dwt_norms_real[4][10] = {
/* <summary> */
/* Forward lazy transform (horizontal). */
/* </summary> */
-void opj_dwt_deinterleave_h(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
+static void opj_dwt_deinterleave_h(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
OPJ_INT32 i;
OPJ_INT32 * l_dest = b;
OPJ_INT32 * l_src = a+cas;
@@ -215,7 +215,7 @@ void opj_dwt_deinterleave_h(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32
/* <summary> */
/* Forward lazy transform (vertical). */
/* </summary> */
-void opj_dwt_deinterleave_v(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 x, OPJ_INT32 cas) {
+static void opj_dwt_deinterleave_v(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 x, OPJ_INT32 cas) {
OPJ_INT32 i = sn;
OPJ_INT32 * l_dest = b;
OPJ_INT32 * l_src = a+cas;
@@ -240,7 +240,7 @@ void opj_dwt_deinterleave_v(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32
/* <summary> */
/* Inverse lazy transform (horizontal). */
/* </summary> */
-void opj_dwt_interleave_h(opj_dwt_t* h, OPJ_INT32 *a) {
+static void opj_dwt_interleave_h(opj_dwt_t* h, OPJ_INT32 *a) {
OPJ_INT32 *ai = a;
OPJ_INT32 *bi = h->mem + h->cas;
OPJ_INT32 i = h->sn;
@@ -260,7 +260,7 @@ void opj_dwt_interleave_h(opj_dwt_t* h, OPJ_INT32 *a) {
/* <summary> */
/* Inverse lazy transform (vertical). */
/* </summary> */
-void opj_dwt_interleave_v(opj_dwt_t* v, OPJ_INT32 *a, OPJ_INT32 x) {
+static void opj_dwt_interleave_v(opj_dwt_t* v, OPJ_INT32 *a, OPJ_INT32 x) {
OPJ_INT32 *ai = a;
OPJ_INT32 *bi = v->mem + v->cas;
OPJ_INT32 i = v->sn;
@@ -283,7 +283,7 @@ void opj_dwt_interleave_v(opj_dwt_t* v, OPJ_INT32 *a, OPJ_INT32 x) {
/* <summary> */
/* Forward 5-3 wavelet transform in 1-D. */
/* </summary> */
-void opj_dwt_encode_1(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
+static void opj_dwt_encode_1(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
OPJ_INT32 i;
if (!cas) {
@@ -304,7 +304,7 @@ void opj_dwt_encode_1(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
/* <summary> */
/* Inverse 5-3 wavelet transform in 1-D. */
/* </summary> */
-void opj_dwt_decode_1_(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
+static void opj_dwt_decode_1_(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
OPJ_INT32 i;
if (!cas) {
@@ -325,14 +325,14 @@ void opj_dwt_decode_1_(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas)
/* <summary> */
/* Inverse 5-3 wavelet transform in 1-D. */
/* </summary> */
-void opj_dwt_decode_1(opj_dwt_t *v) {
+static void opj_dwt_decode_1(opj_dwt_t *v) {
opj_dwt_decode_1_(v->mem, v->dn, v->sn, v->cas);
}
/* <summary> */
/* Forward 9-7 wavelet transform in 1-D. */
/* </summary> */
-void opj_dwt_encode_1_real(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
+static void opj_dwt_encode_1_real(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
OPJ_INT32 i;
if (!cas) {
if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */
@@ -367,7 +367,7 @@ void opj_dwt_encode_1_real(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 c
}
}
-void opj_dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps, opj_stepsize_t *bandno_stepsize) {
+static void opj_dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps, opj_stepsize_t *bandno_stepsize) {
OPJ_INT32 p, n;
p = opj_int_floorlog2(stepsize) - 13;
n = 11 - opj_int_floorlog2(stepsize);
@@ -385,7 +385,7 @@ void opj_dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps, opj_stepsize_
/* <summary> */
/* Forward 5-3 wavelet transform in 2-D. */
/* </summary> */
-INLINE OPJ_BOOL opj_dwt_encode_procedure(opj_tcd_tilecomp_t * tilec,void (*p_function)(OPJ_INT32 *, OPJ_INT32,OPJ_INT32,OPJ_INT32) )
+static INLINE OPJ_BOOL opj_dwt_encode_procedure(opj_tcd_tilecomp_t * tilec,void (*p_function)(OPJ_INT32 *, OPJ_INT32,OPJ_INT32,OPJ_INT32) )
{
OPJ_INT32 i, j, k;
OPJ_INT32 *a = 00;
@@ -395,7 +395,7 @@ INLINE OPJ_BOOL opj_dwt_encode_procedure(opj_tcd_tilecomp_t * tilec,void (*p_fun
OPJ_INT32 rw; /* width of the resolution level computed */
OPJ_INT32 rh; /* height of the resolution level computed */
- OPJ_UINT32 l_data_size;
+ size_t l_data_size;
opj_tcd_resolution_t * l_cur_res = 0;
opj_tcd_resolution_t * l_last_res = 0;
@@ -407,9 +407,17 @@ INLINE OPJ_BOOL opj_dwt_encode_procedure(opj_tcd_tilecomp_t * tilec,void (*p_fun
l_cur_res = tilec->resolutions + l;
l_last_res = l_cur_res - 1;
- l_data_size = opj_dwt_max_resolution( tilec->resolutions,tilec->numresolutions) * (OPJ_UINT32)sizeof(OPJ_INT32);
- bj = (OPJ_INT32*)opj_malloc((size_t)l_data_size);
- if (! bj) {
+ l_data_size = opj_dwt_max_resolution( tilec->resolutions,tilec->numresolutions);
+ /* overflow check */
+ if (l_data_size > (SIZE_MAX / sizeof(OPJ_INT32))) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+ l_data_size *= sizeof(OPJ_INT32);
+ bj = (OPJ_INT32*)opj_malloc(l_data_size);
+ /* l_data_size is equal to 0 when numresolutions == 1 but bj is not used */
+ /* in that case, so do not error out */
+ if (l_data_size != 0 && ! bj) {
return OPJ_FALSE;
}
i = l;
@@ -471,8 +479,8 @@ OPJ_BOOL opj_dwt_encode(opj_tcd_tilecomp_t * tilec)
/* <summary> */
/* Inverse 5-3 wavelet transform in 2-D. */
/* </summary> */
-OPJ_BOOL opj_dwt_decode(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres) {
- return opj_dwt_decode_tile(tilec, numres, &opj_dwt_decode_1);
+OPJ_BOOL opj_dwt_decode(opj_thread_pool_t* tp, opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres) {
+ return opj_dwt_decode_tile(tp, tilec, numres, &opj_dwt_decode_1);
}
@@ -541,7 +549,7 @@ void opj_dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, OPJ_UINT32 prec) {
/* <summary> */
/* Determine maximum computed resolution level for inverse wavelet transform */
/* </summary> */
-OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* restrict r, OPJ_UINT32 i) {
+static OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* OPJ_RESTRICT r, OPJ_UINT32 i) {
OPJ_UINT32 mr = 0;
OPJ_UINT32 w;
while( --i ) {
@@ -554,10 +562,73 @@ OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* restrict r, OPJ_UINT32 i
return mr ;
}
+typedef struct
+{
+ opj_dwt_t h;
+ DWT1DFN dwt_1D;
+ OPJ_UINT32 rw;
+ OPJ_UINT32 w;
+ OPJ_INT32 * OPJ_RESTRICT tiledp;
+ OPJ_UINT32 min_j;
+ OPJ_UINT32 max_j;
+} opj_dwd_decode_h_job_t;
+
+static void opj_dwt_decode_h_func(void* user_data, opj_tls_t* tls)
+{
+ OPJ_UINT32 j;
+ opj_dwd_decode_h_job_t* job;
+ (void)tls;
+
+ job = (opj_dwd_decode_h_job_t*)user_data;
+ for( j = job->min_j; j < job->max_j; j++ )
+ {
+ opj_dwt_interleave_h(&job->h, &job->tiledp[j*job->w]);
+ (job->dwt_1D)(&job->h);
+ memcpy(&job->tiledp[j*job->w], job->h.mem, job->rw * sizeof(OPJ_INT32));
+ }
+
+ opj_aligned_free(job->h.mem);
+ opj_free(job);
+}
+
+typedef struct
+{
+ opj_dwt_t v;
+ DWT1DFN dwt_1D;
+ OPJ_UINT32 rh;
+ OPJ_UINT32 w;
+ OPJ_INT32 * OPJ_RESTRICT tiledp;
+ OPJ_UINT32 min_j;
+ OPJ_UINT32 max_j;
+} opj_dwd_decode_v_job_t;
+
+static void opj_dwt_decode_v_func(void* user_data, opj_tls_t* tls)
+{
+ OPJ_UINT32 j;
+ opj_dwd_decode_v_job_t* job;
+ (void)tls;
+
+ job = (opj_dwd_decode_v_job_t*)user_data;
+ for( j = job->min_j; j < job->max_j; j++ )
+ {
+ OPJ_UINT32 k;
+ opj_dwt_interleave_v(&job->v, &job->tiledp[j], (OPJ_INT32)job->w);
+ (job->dwt_1D)(&job->v);
+ for(k = 0; k < job->rh; ++k) {
+ job->tiledp[k * job->w + j] = job->v.mem[k];
+ }
+ }
+
+ opj_aligned_free(job->v.mem);
+ opj_free(job);
+}
+
+
/* <summary> */
-/* Inverse wavelet transform in 2-D. */
+/* Inverse wavelet transform in 2-D. */
/* </summary> */
-OPJ_BOOL opj_dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres, DWT1DFN dwt_1D) {
+static OPJ_BOOL opj_dwt_decode_tile(opj_thread_pool_t* tp, opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres, DWT1DFN dwt_1D)
+{
opj_dwt_t h;
opj_dwt_t v;
@@ -567,17 +638,30 @@ OPJ_BOOL opj_dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres, DWT1D
OPJ_UINT32 rh = (OPJ_UINT32)(tr->y1 - tr->y0); /* height of the resolution level computed */
OPJ_UINT32 w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
-
- h.mem = (OPJ_INT32*)
- opj_aligned_malloc(opj_dwt_max_resolution(tr, numres) * sizeof(OPJ_INT32));
+ size_t h_mem_size;
+ int num_threads;
+
+ if (numres == 1U) {
+ return OPJ_TRUE;
+ }
+ num_threads = opj_thread_pool_get_thread_count(tp);
+ h_mem_size = opj_dwt_max_resolution(tr, numres);
+ /* overflow check */
+ if (h_mem_size > (SIZE_MAX / sizeof(OPJ_INT32))) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+ h_mem_size *= sizeof(OPJ_INT32);
+ h.mem = (OPJ_INT32*)opj_aligned_malloc(h_mem_size);
if (! h.mem){
+ /* FIXME event manager error callback */
return OPJ_FALSE;
}
v.mem = h.mem;
while( --numres) {
- OPJ_INT32 * restrict tiledp = tilec->data;
+ OPJ_INT32 * OPJ_RESTRICT tiledp = tilec->data;
OPJ_UINT32 j;
++tr;
@@ -590,30 +674,134 @@ OPJ_BOOL opj_dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres, DWT1D
h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn);
h.cas = tr->x0 % 2;
- for(j = 0; j < rh; ++j) {
- opj_dwt_interleave_h(&h, &tiledp[j*w]);
- (dwt_1D)(&h);
- memcpy(&tiledp[j*w], h.mem, rw * sizeof(OPJ_INT32));
+ if( num_threads <= 1 || rh <= 1 )
+ {
+ for(j = 0; j < rh; ++j) {
+ opj_dwt_interleave_h(&h, &tiledp[j*w]);
+ (dwt_1D)(&h);
+ memcpy(&tiledp[j*w], h.mem, rw * sizeof(OPJ_INT32));
+ }
+ }
+ else
+ {
+ OPJ_UINT32 num_jobs = (OPJ_UINT32)num_threads;
+ OPJ_UINT32 step_j;
+
+ if( rh < num_jobs ) {
+ num_jobs = rh;
+ }
+ step_j = (rh / num_jobs);
+
+ for(j = 0; j < num_jobs; j++)
+ {
+ opj_dwd_decode_h_job_t* job;
+
+ job = (opj_dwd_decode_h_job_t*) opj_malloc(sizeof(opj_dwd_decode_h_job_t));
+ if( !job )
+ {
+ /* It would be nice to fallback to single thread case, but */
+ /* unfortunately some jobs may be launched and have modified */
+ /* tiledp, so it is not practical to recover from that error */
+ /* FIXME event manager error callback */
+ opj_thread_pool_wait_completion(tp, 0);
+ opj_aligned_free(h.mem);
+ return OPJ_FALSE;
+ }
+ job->h = h;
+ job->dwt_1D = dwt_1D;
+ job->rw = rw;
+ job->w = w;
+ job->tiledp = tiledp;
+ job->min_j = j * step_j;
+ job->max_j = (j + 1U) * step_j; /* this can overflow */
+ if( j == (num_jobs - 1U) ) { /* this will take care of the overflow */
+ job->max_j = rh;
+ }
+ job->h.mem = (OPJ_INT32*)opj_aligned_malloc(h_mem_size);
+ if (!job->h.mem)
+ {
+ /* FIXME event manager error callback */
+ opj_thread_pool_wait_completion(tp, 0);
+ opj_free(job);
+ opj_aligned_free(h.mem);
+ return OPJ_FALSE;
+ }
+ opj_thread_pool_submit_job( tp, opj_dwt_decode_h_func, job );
+ }
+ opj_thread_pool_wait_completion(tp, 0);
}
v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn);
v.cas = tr->y0 % 2;
- for(j = 0; j < rw; ++j){
- OPJ_UINT32 k;
- opj_dwt_interleave_v(&v, &tiledp[j], (OPJ_INT32)w);
- (dwt_1D)(&v);
- for(k = 0; k < rh; ++k) {
- tiledp[k * w + j] = v.mem[k];
+ if( num_threads <= 1 || rw <= 1 )
+ {
+ for(j = 0; j < rw; ++j){
+ OPJ_UINT32 k;
+
+ opj_dwt_interleave_v(&v, &tiledp[j], (OPJ_INT32)w);
+ (dwt_1D)(&v);
+ for(k = 0; k < rh; ++k) {
+ tiledp[k * w + j] = v.mem[k];
+ }
}
}
+ else
+ {
+ OPJ_UINT32 num_jobs = (OPJ_UINT32)num_threads;
+ OPJ_UINT32 step_j;
+
+ if( rw < num_jobs ) {
+ num_jobs = rw;
+ }
+ step_j = (rw / num_jobs);
+
+ for( j = 0; j < num_jobs; j++ )
+ {
+ opj_dwd_decode_v_job_t* job;
+
+ job = (opj_dwd_decode_v_job_t*) opj_malloc(sizeof(opj_dwd_decode_v_job_t));
+ if( !job )
+ {
+ /* It would be nice to fallback to single thread case, but */
+ /* unfortunately some jobs may be launched and have modified */
+ /* tiledp, so it is not practical to recover from that error */
+ /* FIXME event manager error callback */
+ opj_thread_pool_wait_completion(tp, 0);
+ opj_aligned_free(v.mem);
+ return OPJ_FALSE;
+ }
+ job->v = v;
+ job->dwt_1D = dwt_1D;
+ job->rh = rh;
+ job->w = w;
+ job->tiledp = tiledp;
+ job->min_j = j * step_j;
+ job->max_j = (j + 1U) * step_j; /* this can overflow */
+ if( j == (num_jobs - 1U) ) { /* this will take care of the overflow */
+ job->max_j = rw;
+ }
+ job->v.mem = (OPJ_INT32*)opj_aligned_malloc(h_mem_size);
+ if (!job->v.mem)
+ {
+ /* FIXME event manager error callback */
+ opj_thread_pool_wait_completion(tp, 0);
+ opj_free(job);
+ opj_aligned_free(v.mem);
+ return OPJ_FALSE;
+ }
+ opj_thread_pool_submit_job( tp, opj_dwt_decode_v_func, job );
+ }
+ opj_thread_pool_wait_completion(tp, 0);
+ }
}
opj_aligned_free(h.mem);
return OPJ_TRUE;
}
-void opj_v4dwt_interleave_h(opj_v4dwt_t* restrict w, OPJ_FLOAT32* restrict a, OPJ_INT32 x, OPJ_INT32 size){
- OPJ_FLOAT32* restrict bi = (OPJ_FLOAT32*) (w->wavelet + w->cas);
+static void opj_v4dwt_interleave_h(opj_v4dwt_t* OPJ_RESTRICT w, OPJ_FLOAT32* OPJ_RESTRICT a, OPJ_INT32 x, OPJ_INT32 size)
+{
+ OPJ_FLOAT32* OPJ_RESTRICT bi = (OPJ_FLOAT32*) (w->wavelet + w->cas);
OPJ_INT32 count = w->sn;
OPJ_INT32 i, k;
@@ -655,8 +843,8 @@ void opj_v4dwt_interleave_h(opj_v4dwt_t* restrict w, OPJ_FLOAT32* restrict a, OP
}
}
-void opj_v4dwt_interleave_v(opj_v4dwt_t* restrict v , OPJ_FLOAT32* restrict a , OPJ_INT32 x, OPJ_INT32 nb_elts_read){
- opj_v4_t* restrict bi = v->wavelet + v->cas;
+static void opj_v4dwt_interleave_v(opj_v4dwt_t* OPJ_RESTRICT v , OPJ_FLOAT32* OPJ_RESTRICT a , OPJ_INT32 x, OPJ_INT32 nb_elts_read){
+ opj_v4_t* OPJ_RESTRICT bi = v->wavelet + v->cas;
OPJ_INT32 i;
for(i = 0; i < v->sn; ++i){
@@ -673,8 +861,8 @@ void opj_v4dwt_interleave_v(opj_v4dwt_t* restrict v , OPJ_FLOAT32* restrict a ,
#ifdef __SSE__
-void opj_v4dwt_decode_step1_sse(opj_v4_t* w, OPJ_INT32 count, const __m128 c){
- __m128* restrict vw = (__m128*) w;
+static void opj_v4dwt_decode_step1_sse(opj_v4_t* w, OPJ_INT32 count, const __m128 c){
+ __m128* OPJ_RESTRICT vw = (__m128*) w;
OPJ_INT32 i;
/* 4x unrolled loop */
for(i = 0; i < count >> 2; ++i){
@@ -695,8 +883,8 @@ void opj_v4dwt_decode_step1_sse(opj_v4_t* w, OPJ_INT32 count, const __m128 c){
}
void opj_v4dwt_decode_step2_sse(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k, OPJ_INT32 m, __m128 c){
- __m128* restrict vl = (__m128*) l;
- __m128* restrict vw = (__m128*) w;
+ __m128* OPJ_RESTRICT vl = (__m128*) l;
+ __m128* OPJ_RESTRICT vw = (__m128*) w;
OPJ_INT32 i;
__m128 tmp1, tmp2, tmp3;
tmp1 = vl[0];
@@ -722,9 +910,9 @@ void opj_v4dwt_decode_step2_sse(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k, OPJ_INT32
#else
-void opj_v4dwt_decode_step1(opj_v4_t* w, OPJ_INT32 count, const OPJ_FLOAT32 c)
+static void opj_v4dwt_decode_step1(opj_v4_t* w, OPJ_INT32 count, const OPJ_FLOAT32 c)
{
- OPJ_FLOAT32* restrict fw = (OPJ_FLOAT32*) w;
+ OPJ_FLOAT32* OPJ_RESTRICT fw = (OPJ_FLOAT32*) w;
OPJ_INT32 i;
for(i = 0; i < count; ++i){
OPJ_FLOAT32 tmp1 = fw[i*8 ];
@@ -738,10 +926,10 @@ void opj_v4dwt_decode_step1(opj_v4_t* w, OPJ_INT32 count, const OPJ_FLOAT32 c)
}
}
-void opj_v4dwt_decode_step2(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k, OPJ_INT32 m, OPJ_FLOAT32 c)
+static void opj_v4dwt_decode_step2(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k, OPJ_INT32 m, OPJ_FLOAT32 c)
{
- OPJ_FLOAT32* restrict fl = (OPJ_FLOAT32*) l;
- OPJ_FLOAT32* restrict fw = (OPJ_FLOAT32*) w;
+ OPJ_FLOAT32* fl = (OPJ_FLOAT32*) l;
+ OPJ_FLOAT32* fw = (OPJ_FLOAT32*) w;
OPJ_INT32 i;
for(i = 0; i < m; ++i){
OPJ_FLOAT32 tmp1_1 = fl[0];
@@ -792,7 +980,7 @@ void opj_v4dwt_decode_step2(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k, OPJ_INT32 m,
/* <summary> */
/* Inverse 9-7 wavelet transform in 1-D. */
/* </summary> */
-void opj_v4dwt_decode(opj_v4dwt_t* restrict dwt)
+static void opj_v4dwt_decode(opj_v4dwt_t* OPJ_RESTRICT dwt)
{
OPJ_INT32 a, b;
if(dwt->cas == 0) {
@@ -829,7 +1017,7 @@ void opj_v4dwt_decode(opj_v4dwt_t* restrict dwt)
/* <summary> */
/* Inverse 9-7 wavelet transform in 2-D. */
/* </summary> */
-OPJ_BOOL opj_dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, OPJ_UINT32 numres)
+OPJ_BOOL opj_dwt_decode_real(opj_tcd_tilecomp_t* OPJ_RESTRICT tilec, OPJ_UINT32 numres)
{
opj_v4dwt_t h;
opj_v4dwt_t v;
@@ -841,11 +1029,29 @@ OPJ_BOOL opj_dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, OPJ_UINT32 numr
OPJ_UINT32 w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
- h.wavelet = (opj_v4_t*) opj_aligned_malloc((opj_dwt_max_resolution(res, numres)+5) * sizeof(opj_v4_t));
+ size_t l_data_size;
+
+ l_data_size = opj_dwt_max_resolution(res, numres);
+ /* overflow check */
+ if (l_data_size > (SIZE_MAX - 5U)) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+ l_data_size += 5U;
+ /* overflow check */
+ if (l_data_size > (SIZE_MAX / sizeof(opj_v4_t))) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+ h.wavelet = (opj_v4_t*) opj_aligned_malloc(l_data_size * sizeof(opj_v4_t));
+ if (!h.wavelet) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
v.wavelet = h.wavelet;
while( --numres) {
- OPJ_FLOAT32 * restrict aj = (OPJ_FLOAT32*) tilec->data;
+ OPJ_FLOAT32 * OPJ_RESTRICT aj = (OPJ_FLOAT32*) tilec->data;
OPJ_UINT32 bufsize = (OPJ_UINT32)((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0));
OPJ_INT32 j;
diff --git a/openjpeg/src/lib/openjp2/dwt.h b/openjpeg/src/lib/openjp2/dwt.h
index f8b57bc0c..5321175b3 100644
--- a/openjpeg/src/lib/openjp2/dwt.h
+++ b/openjpeg/src/lib/openjp2/dwt.h
@@ -54,19 +54,20 @@ DWT.C are used by some function in TCD.C.
/*@{*/
/* ----------------------------------------------------------------------- */
/**
-Forward 5-3 wavelet tranform in 2-D.
+Forward 5-3 wavelet transform in 2-D.
Apply a reversible DWT transform to a component of an image.
@param tilec Tile component information (current tile)
*/
OPJ_BOOL opj_dwt_encode(opj_tcd_tilecomp_t * tilec);
/**
-Inverse 5-3 wavelet tranform in 2-D.
+Inverse 5-3 wavelet transform in 2-D.
Apply a reversible inverse DWT transform to a component of an image.
+@param tp Thread pool
@param tilec Tile component information (current tile)
@param numres Number of resolution levels to decode
*/
-OPJ_BOOL opj_dwt_decode(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres);
+OPJ_BOOL opj_dwt_decode(opj_thread_pool_t* tp, opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres);
/**
Get the gain of a subband for the reversible 5-3 DWT.
@@ -93,7 +94,7 @@ Apply an irreversible inverse DWT transform to a component of an image.
@param tilec Tile component information (current tile)
@param numres Number of resolution levels to decode
*/
-OPJ_BOOL opj_dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, OPJ_UINT32 numres);
+OPJ_BOOL opj_dwt_decode_real(opj_tcd_tilecomp_t* OPJ_RESTRICT tilec, OPJ_UINT32 numres);
/**
Get the gain of a subband for the irreversible 9-7 DWT.
diff --git a/openjpeg/src/lib/openjp2/event.h b/openjpeg/src/lib/openjp2/event.h
index 88e0395b4..fa8604ed0 100644
--- a/openjpeg/src/lib/openjp2/event.h
+++ b/openjpeg/src/lib/openjp2/event.h
@@ -95,6 +95,12 @@ OPJ_BOOL opj_event_msg(opj_event_mgr_t* event_mgr, OPJ_INT32 event_type, const c
*/
void opj_set_default_event_handler(opj_event_mgr_t * p_manager);
+/*
+#ifdef __GNUC__
+#pragma GCC poison printf fprintf
+#endif
+*/
+
/*@}*/
/*@}*/
diff --git a/openjpeg/src/lib/openjp2/function_list.c b/openjpeg/src/lib/openjp2/function_list.c
index 4c8aae621..a7ea11d59 100644
--- a/openjpeg/src/lib/openjp2/function_list.c
+++ b/openjpeg/src/lib/openjp2/function_list.c
@@ -39,22 +39,19 @@
opj_procedure_list_t * opj_procedure_list_create()
{
/* memory allocation */
- opj_procedure_list_t * l_validation = (opj_procedure_list_t *) opj_malloc(sizeof(opj_procedure_list_t));
+ opj_procedure_list_t * l_validation = (opj_procedure_list_t *) opj_calloc(1,sizeof(opj_procedure_list_t));
if (! l_validation)
{
return 00;
}
/* initialization */
- memset(l_validation,0,sizeof(opj_procedure_list_t));
l_validation->m_nb_max_procedures = OPJ_VALIDATION_SIZE;
- l_validation->m_procedures = (opj_procedure*)opj_malloc(
- OPJ_VALIDATION_SIZE * sizeof(opj_procedure));
+ l_validation->m_procedures = (opj_procedure*)opj_calloc(OPJ_VALIDATION_SIZE, sizeof(opj_procedure));
if (! l_validation->m_procedures)
{
opj_free(l_validation);
return 00;
}
- memset(l_validation->m_procedures,0,OPJ_VALIDATION_SIZE * sizeof(opj_procedure));
return l_validation;
}
@@ -72,8 +69,11 @@ void opj_procedure_list_destroy(opj_procedure_list_t * p_list)
opj_free(p_list);
}
-OPJ_BOOL opj_procedure_list_add_procedure (opj_procedure_list_t * p_validation_list, opj_procedure p_procedure)
+OPJ_BOOL opj_procedure_list_add_procedure (opj_procedure_list_t * p_validation_list, opj_procedure p_procedure, opj_event_mgr_t* p_manager )
{
+
+ assert(p_manager != NULL);
+
if (p_validation_list->m_nb_max_procedures == p_validation_list->m_nb_procedures)
{
opj_procedure * new_procedures;
@@ -87,9 +87,7 @@ OPJ_BOOL opj_procedure_list_add_procedure (opj_procedure_list_t * p_validation_l
opj_free(p_validation_list->m_procedures);
p_validation_list->m_nb_max_procedures = 0;
p_validation_list->m_nb_procedures = 0;
- /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add a new validation procedure\n"); */
- fprintf(stderr, "Not enough memory to add a new validation procedure\n");
-
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add a new validation procedure\n");
return OPJ_FALSE;
}
else
diff --git a/openjpeg/src/lib/openjp2/function_list.h b/openjpeg/src/lib/openjp2/function_list.h
index 749ad9e45..ab091b7be 100644
--- a/openjpeg/src/lib/openjp2/function_list.h
+++ b/openjpeg/src/lib/openjp2/function_list.h
@@ -95,7 +95,7 @@ void opj_procedure_list_destroy(opj_procedure_list_t * p_list);
*
* @return OPJ_TRUE if the procedure could be added.
*/
-OPJ_BOOL opj_procedure_list_add_procedure (opj_procedure_list_t * p_validation_list, opj_procedure p_procedure);
+OPJ_BOOL opj_procedure_list_add_procedure (opj_procedure_list_t * p_validation_list, opj_procedure p_procedure, opj_event_mgr_t* p_manager);
/**
* Gets the number of validation procedures.
diff --git a/openjpeg/src/lib/openjp2/image.c b/openjpeg/src/lib/openjp2/image.c
index 2c3540c51..23462f05f 100644
--- a/openjpeg/src/lib/openjp2/image.c
+++ b/openjpeg/src/lib/openjp2/image.c
@@ -47,7 +47,8 @@ opj_image_t* OPJ_CALLCONV opj_image_create(OPJ_UINT32 numcmpts, opj_image_cmptpa
/* allocate memory for the per-component information */
image->comps = (opj_image_comp_t*)opj_calloc(1,image->numcomps * sizeof(opj_image_comp_t));
if(!image->comps) {
- fprintf(stderr,"Unable to allocate memory for image.\n");
+ /* TODO replace with event manager, breaks API */
+ /* fprintf(stderr,"Unable to allocate memory for image.\n"); */
opj_image_destroy(image);
return NULL;
}
@@ -65,7 +66,8 @@ opj_image_t* OPJ_CALLCONV opj_image_create(OPJ_UINT32 numcmpts, opj_image_cmptpa
comp->sgnd = cmptparms[compno].sgnd;
comp->data = (OPJ_INT32*) opj_calloc(comp->w * comp->h, sizeof(OPJ_INT32));
if(!comp->data) {
- fprintf(stderr,"Unable to allocate memory for image.\n");
+ /* TODO replace with event manager, breaks API */
+ /* fprintf(stderr,"Unable to allocate memory for image.\n"); */
opj_image_destroy(image);
return NULL;
}
@@ -107,27 +109,29 @@ void OPJ_CALLCONV opj_image_destroy(opj_image_t *image) {
void opj_image_comp_header_update(opj_image_t * p_image_header, const struct opj_cp * p_cp)
{
OPJ_UINT32 i, l_width, l_height;
- OPJ_INT32 l_x0, l_y0, l_x1, l_y1;
- OPJ_INT32 l_comp_x0, l_comp_y0, l_comp_x1, l_comp_y1;
+ OPJ_UINT32 l_x0, l_y0, l_x1, l_y1;
+ OPJ_UINT32 l_comp_x0, l_comp_y0, l_comp_x1, l_comp_y1;
opj_image_comp_t* l_img_comp = NULL;
- l_x0 = opj_int_max((OPJ_INT32)p_cp->tx0 , (OPJ_INT32)p_image_header->x0);
- l_y0 = opj_int_max((OPJ_INT32)p_cp->ty0 , (OPJ_INT32)p_image_header->y0);
- l_x1 = opj_int_min((OPJ_INT32)(p_cp->tx0 + p_cp->tw * p_cp->tdx), (OPJ_INT32)p_image_header->x1);
- l_y1 = opj_int_min((OPJ_INT32)(p_cp->ty0 + p_cp->th * p_cp->tdy), (OPJ_INT32)p_image_header->y1);
+ l_x0 = opj_uint_max(p_cp->tx0 , p_image_header->x0);
+ l_y0 = opj_uint_max(p_cp->ty0 , p_image_header->y0);
+ l_x1 = p_cp->tx0 + (p_cp->tw - 1U) * p_cp->tdx; /* validity of p_cp members used here checked in opj_j2k_read_siz. Can't overflow. */
+ l_y1 = p_cp->ty0 + (p_cp->th - 1U) * p_cp->tdy; /* can't overflow */
+ l_x1 = opj_uint_min(opj_uint_adds(l_x1, p_cp->tdx), p_image_header->x1); /* use add saturated to prevent overflow */
+ l_y1 = opj_uint_min(opj_uint_adds(l_y1, p_cp->tdy), p_image_header->y1); /* use add saturated to prevent overflow */
l_img_comp = p_image_header->comps;
for (i = 0; i < p_image_header->numcomps; ++i) {
- l_comp_x0 = opj_int_ceildiv(l_x0, (OPJ_INT32)l_img_comp->dx);
- l_comp_y0 = opj_int_ceildiv(l_y0, (OPJ_INT32)l_img_comp->dy);
- l_comp_x1 = opj_int_ceildiv(l_x1, (OPJ_INT32)l_img_comp->dx);
- l_comp_y1 = opj_int_ceildiv(l_y1, (OPJ_INT32)l_img_comp->dy);
- l_width = (OPJ_UINT32)opj_int_ceildivpow2(l_comp_x1 - l_comp_x0, (OPJ_INT32)l_img_comp->factor);
- l_height = (OPJ_UINT32)opj_int_ceildivpow2(l_comp_y1 - l_comp_y0, (OPJ_INT32)l_img_comp->factor);
+ l_comp_x0 = opj_uint_ceildiv(l_x0, l_img_comp->dx);
+ l_comp_y0 = opj_uint_ceildiv(l_y0, l_img_comp->dy);
+ l_comp_x1 = opj_uint_ceildiv(l_x1, l_img_comp->dx);
+ l_comp_y1 = opj_uint_ceildiv(l_y1, l_img_comp->dy);
+ l_width = opj_uint_ceildivpow2(l_comp_x1 - l_comp_x0, l_img_comp->factor);
+ l_height = opj_uint_ceildivpow2(l_comp_y1 - l_comp_y0, l_img_comp->factor);
l_img_comp->w = l_width;
l_img_comp->h = l_height;
- l_img_comp->x0 = (OPJ_UINT32)l_comp_x0/*l_x0*/;
- l_img_comp->y0 = (OPJ_UINT32)l_comp_y0/*l_y0*/;
+ l_img_comp->x0 = l_comp_x0;
+ l_img_comp->y0 = l_comp_y0;
++l_img_comp;
}
}
@@ -205,21 +209,19 @@ opj_image_t* OPJ_CALLCONV opj_image_tile_create(OPJ_UINT32 numcmpts, opj_image_c
OPJ_UINT32 compno;
opj_image_t *image = 00;
- image = (opj_image_t*) opj_malloc(sizeof(opj_image_t));
+ image = (opj_image_t*) opj_calloc(1,sizeof(opj_image_t));
if (image)
{
- memset(image,0,sizeof(opj_image_t));
image->color_space = clrspc;
image->numcomps = numcmpts;
/* allocate memory for the per-component information */
- image->comps = (opj_image_comp_t*)opj_malloc(image->numcomps * sizeof(opj_image_comp_t));
+ image->comps = (opj_image_comp_t*)opj_calloc(image->numcomps, sizeof(opj_image_comp_t));
if (!image->comps) {
opj_image_destroy(image);
return 00;
}
- memset(image->comps,0,image->numcomps * sizeof(opj_image_comp_t));
/* create the individual image components */
for(compno = 0; compno < numcmpts; compno++) {
diff --git a/openjpeg/src/lib/openjp2/indexbox_manager.h b/openjpeg/src/lib/openjp2/indexbox_manager.h
index ec5525f53..ebcde8fec 100644
--- a/openjpeg/src/lib/openjp2/indexbox_manager.h
+++ b/openjpeg/src/lib/openjp2/indexbox_manager.h
@@ -108,7 +108,7 @@ int opj_write_phix( int coff, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused,
opj_event_mgr_t * p_manager );
/*
- * Wriet manifest box (box)
+ * Write manifest box (box)
*
* @param[in] second number to be visited
* @param[in] v number of boxes
diff --git a/openjpeg/src/lib/openjp2/invert.c b/openjpeg/src/lib/openjp2/invert.c
index 4c1ee780d..7efaf6eca 100644
--- a/openjpeg/src/lib/openjp2/invert.c
+++ b/openjpeg/src/lib/openjp2/invert.c
@@ -103,7 +103,7 @@ OPJ_BOOL opj_matrix_inversion_f(OPJ_FLOAT32 * pSrcMatrix,
Local functions
==========================================================
*/
-OPJ_BOOL opj_lupDecompose(OPJ_FLOAT32 * matrix,OPJ_UINT32 * permutations,
+static OPJ_BOOL opj_lupDecompose(OPJ_FLOAT32 * matrix,OPJ_UINT32 * permutations,
OPJ_FLOAT32 * p_swap_area,
OPJ_UINT32 nb_compo)
{
@@ -125,7 +125,7 @@ OPJ_BOOL opj_lupDecompose(OPJ_FLOAT32 * matrix,OPJ_UINT32 * permutations,
{
*tmpPermutations++ = i;
}
- /* now make a pivot with colum switch */
+ /* now make a pivot with column switch */
tmpPermutations = permutations;
for (k = 0; k < lLastColum; ++k) {
p = 0.0;
@@ -204,7 +204,7 @@ OPJ_BOOL opj_lupDecompose(OPJ_FLOAT32 * matrix,OPJ_UINT32 * permutations,
return OPJ_TRUE;
}
-void opj_lupSolve (OPJ_FLOAT32 * pResult,
+static void opj_lupSolve (OPJ_FLOAT32 * pResult,
OPJ_FLOAT32 * pMatrix,
OPJ_FLOAT32 * pVector,
OPJ_UINT32* pPermutations,
@@ -266,7 +266,7 @@ void opj_lupSolve (OPJ_FLOAT32 * pResult,
}
-void opj_lupInvert (OPJ_FLOAT32 * pSrcMatrix,
+static void opj_lupInvert (OPJ_FLOAT32 * pSrcMatrix,
OPJ_FLOAT32 * pDestMatrix,
OPJ_UINT32 nb_compo,
OPJ_UINT32 * pPermutations,
diff --git a/openjpeg/src/lib/openjp2/j2k.c b/openjpeg/src/lib/openjp2/j2k.c
index 3a223e152..0cceaef03 100644
--- a/openjpeg/src/lib/openjp2/j2k.c
+++ b/openjpeg/src/lib/openjp2/j2k.c
@@ -51,7 +51,7 @@
/**
* Sets up the procedures to do on reading header. Developpers wanting to extend the library can add their own reading procedures.
*/
-static void opj_j2k_setup_header_reading (opj_j2k_t *p_j2k);
+static OPJ_BOOL opj_j2k_setup_header_reading (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager);
/**
* The read header procedure.
@@ -90,19 +90,19 @@ static OPJ_BOOL opj_j2k_decoding_validation ( opj_j2k_t * p_j2k,
* Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
* are valid. Developpers wanting to extend the library can add their own validation procedures.
*/
-static void opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k);
+static OPJ_BOOL opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager);
/**
* Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
* are valid. Developpers wanting to extend the library can add their own validation procedures.
*/
-static void opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k);
+static OPJ_BOOL opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager);
/**
* Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
* are valid. Developpers wanting to extend the library can add their own validation procedures.
*/
-static void opj_j2k_setup_end_compress (opj_j2k_t *p_j2k);
+static OPJ_BOOL opj_j2k_setup_end_compress (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager);
/**
* The mct encoding validation procedure.
@@ -213,6 +213,18 @@ static void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp);
static void opj_j2k_cp_destroy (opj_cp_t *p_cp);
/**
+ * Compare 2 a SPCod/ SPCoc elements, i.e. the coding style of a given component of a tile.
+ *
+ * @param p_j2k J2K codec.
+ * @param p_tile_no Tile number
+ * @param p_first_comp_no The 1st component number to compare.
+ * @param p_second_comp_no The 1st component number to compare.
+ *
+ * @return OPJ_TRUE if SPCdod are equals.
+ */
+static OPJ_BOOL opj_j2k_compare_SPCod_SPCoc(opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no);
+
+/**
* Writes a SPCod or SPCoc element, i.e. the coding style of a given component of a tile.
*
* @param p_j2k J2K codec.
@@ -272,6 +284,19 @@ static OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size ( opj_j2k_t *p_j2k,
OPJ_UINT32 p_comp_no );
/**
+ * Compares 2 SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC.
+ *
+ * @param p_j2k J2K codec.
+ * @param p_tile_no the tile to output.
+ * @param p_first_comp_no the first component number to compare.
+ * @param p_second_comp_no the second component number to compare.
+ *
+ * @return OPJ_TRUE if equals.
+ */
+static OPJ_BOOL opj_j2k_compare_SQcd_SQcc(opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no);
+
+
+/**
* Writes a SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC.
*
* @param p_tile_no the tile to output.
@@ -338,11 +363,21 @@ static OPJ_BOOL opj_j2k_pre_write_tile ( opj_j2k_t * p_j2k,
static OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image);
+static void opj_get_tile_dimensions(opj_image_t * l_image,
+ opj_tcd_tilecomp_t * l_tilec,
+ opj_image_comp_t * l_img_comp,
+ OPJ_UINT32* l_size_comp,
+ OPJ_UINT32* l_width,
+ OPJ_UINT32* l_height,
+ OPJ_UINT32* l_offset_x,
+ OPJ_UINT32* l_offset_y,
+ OPJ_UINT32* l_image_width,
+ OPJ_UINT32* l_stride,
+ OPJ_UINT32* l_tile_offset);
+
static void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data);
static OPJ_BOOL opj_j2k_post_write_tile (opj_j2k_t * p_j2k,
- OPJ_BYTE * p_data,
- OPJ_UINT32 p_data_size,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager );
@@ -350,7 +385,7 @@ static OPJ_BOOL opj_j2k_post_write_tile (opj_j2k_t * p_j2k,
* Sets up the procedures to do on writing header.
* Developers wanting to extend the library can add their own writing procedures.
*/
-static void opj_j2k_setup_header_writing (opj_j2k_t *p_j2k);
+static OPJ_BOOL opj_j2k_setup_header_writing (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager);
static OPJ_BOOL opj_j2k_write_first_tile_part( opj_j2k_t *p_j2k,
OPJ_BYTE * p_data,
@@ -474,7 +509,17 @@ static OPJ_BOOL opj_j2k_read_cod ( opj_j2k_t *p_j2k,
OPJ_UINT32 p_header_size,
opj_event_mgr_t * p_manager);
-#if 0
+/**
+ * Compares 2 COC markers (Coding style component)
+ *
+ * @param p_j2k J2K codec.
+ * @param p_first_comp_no the index of the first component to compare.
+ * @param p_second_comp_no the index of the second component to compare.
+ *
+ * @return OPJ_TRUE if equals
+ */
+static OPJ_BOOL opj_j2k_compare_coc(opj_j2k_t *p_j2k, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no);
+
/**
* Writes the COC marker (Coding style component)
*
@@ -487,9 +532,7 @@ static OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_j2k,
OPJ_UINT32 p_comp_no,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager );
-#endif
-#if 0
/**
* Writes the COC marker (Coding style component)
*
@@ -504,7 +547,6 @@ static void opj_j2k_write_coc_in_memory(opj_j2k_t *p_j2k,
OPJ_BYTE * p_data,
OPJ_UINT32 * p_data_written,
opj_event_mgr_t * p_manager );
-#endif
/**
* Gets the maximum size taken by a coc.
@@ -547,7 +589,18 @@ static OPJ_BOOL opj_j2k_read_qcd ( opj_j2k_t *p_j2k,
OPJ_BYTE * p_header_data,
OPJ_UINT32 p_header_size,
opj_event_mgr_t * p_manager );
-#if 0
+
+/**
+ * Compare QCC markers (quantization component)
+ *
+ * @param p_j2k J2K codec.
+ * @param p_first_comp_no the index of the first component to compare.
+ * @param p_second_comp_no the index of the second component to compare.
+ *
+ * @return OPJ_TRUE if equals.
+ */
+static OPJ_BOOL opj_j2k_compare_qcc(opj_j2k_t *p_j2k, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no);
+
/**
* Writes the QCC marker (quantization component)
*
@@ -560,9 +613,7 @@ static OPJ_BOOL opj_j2k_write_qcc( opj_j2k_t *p_j2k,
OPJ_UINT32 p_comp_no,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager );
-#endif
-#if 0
/**
* Writes the QCC marker (quantization component)
*
@@ -577,7 +628,6 @@ static void opj_j2k_write_qcc_in_memory(opj_j2k_t *p_j2k,
OPJ_BYTE * p_data,
OPJ_UINT32 * p_data_written,
opj_event_mgr_t * p_manager );
-#endif
/**
* Gets the maximum size taken by a qcc.
@@ -708,28 +758,28 @@ static OPJ_BOOL opj_j2k_read_plt ( opj_j2k_t *p_j2k,
OPJ_UINT32 p_header_size,
opj_event_mgr_t * p_manager );
-#if 0
/**
- * Reads a PPM marker (Packed packet headers, main header)
+ * Reads a PPM marker (Packed headers, main header)
*
* @param p_header_data the data contained in the POC box.
* @param p_j2k the jpeg2000 codec.
* @param p_header_size the size of the data contained in the POC marker.
* @param p_manager the user event manager.
-*/
-static OPJ_BOOL j2k_read_ppm_v2 (
- opj_j2k_t *p_j2k,
- OPJ_BYTE * p_header_data,
- OPJ_UINT32 p_header_size,
- struct opj_event_mgr * p_manager
- );
-#endif
+ */
-static OPJ_BOOL j2k_read_ppm_v3 (
- opj_j2k_t *p_j2k,
- OPJ_BYTE * p_header_data,
- OPJ_UINT32 p_header_size,
- opj_event_mgr_t * p_manager );
+static OPJ_BOOL opj_j2k_read_ppm (
+ opj_j2k_t *p_j2k,
+ OPJ_BYTE * p_header_data,
+ OPJ_UINT32 p_header_size,
+ opj_event_mgr_t * p_manager );
+
+/**
+ * Merges all PPM markers read (Packed headers, main header)
+ *
+ * @param p_cp main coding parameters.
+ * @param p_manager the user event manager.
+ */
+static OPJ_BOOL opj_j2k_merge_ppm ( opj_cp_t *p_cp, opj_event_mgr_t * p_manager );
/**
* Reads a PPT marker (Packed packet headers, tile-part header)
@@ -743,6 +793,17 @@ static OPJ_BOOL opj_j2k_read_ppt ( opj_j2k_t *p_j2k,
OPJ_BYTE * p_header_data,
OPJ_UINT32 p_header_size,
opj_event_mgr_t * p_manager );
+
+/**
+ * Merges all PPT markers read (Packed headers, tile-part header)
+ *
+ * @param p_tcp the tile.
+ * @param p_manager the user event manager.
+ */
+static OPJ_BOOL opj_j2k_merge_ppt ( opj_tcp_t *p_tcp,
+ opj_event_mgr_t * p_manager );
+
+
/**
* Writes the TLM marker (Tile Length Marker)
*
@@ -770,12 +831,32 @@ static OPJ_BOOL opj_j2k_write_sot( opj_j2k_t *p_j2k,
opj_event_mgr_t * p_manager );
/**
- * Reads a PPT marker (Packed packet headers, tile-part header)
+ * Reads values from a SOT marker (Start of tile-part)
*
- * @param p_header_data the data contained in the PPT box.
- * @param p_j2k the jpeg2000 codec.
+ * the j2k decoder state is not affected. No side effects, no checks except for p_header_size.
+ *
+ * @param p_header_data the data contained in the SOT marker.
+ * @param p_header_size the size of the data contained in the SOT marker.
+ * @param p_tile_no Isot.
+ * @param p_tot_len Psot.
+ * @param p_current_part TPsot.
+ * @param p_num_parts TNsot.
+ * @param p_manager the user event manager.
+ */
+static OPJ_BOOL opj_j2k_get_sot_values(OPJ_BYTE * p_header_data,
+ OPJ_UINT32 p_header_size,
+ OPJ_UINT32* p_tile_no,
+ OPJ_UINT32* p_tot_len,
+ OPJ_UINT32* p_current_part,
+ OPJ_UINT32* p_num_parts,
+ opj_event_mgr_t * p_manager );
+/**
+ * Reads a SOT marker (Start of tile-part)
+ *
+ * @param p_header_data the data contained in the SOT marker.
+ * @param p_j2k the jpeg2000 codec.
* @param p_header_size the size of the data contained in the PPT marker.
- * @param p_manager the user event manager.
+ * @param p_manager the user event manager.
*/
static OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
OPJ_BYTE * p_header_data,
@@ -811,7 +892,7 @@ static OPJ_BOOL opj_j2k_read_sod( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager );
-void opj_j2k_update_tlm (opj_j2k_t * p_j2k, OPJ_UINT32 p_tile_part_size )
+static void opj_j2k_update_tlm (opj_j2k_t * p_j2k, OPJ_UINT32 p_tile_part_size )
{
opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current,p_j2k->m_current_tile_number,1); /* PSOT */
++p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current;
@@ -1056,7 +1137,7 @@ static OPJ_BOOL opj_j2k_read_cbd ( opj_j2k_t *p_j2k,
OPJ_UINT32 p_header_size,
opj_event_mgr_t * p_manager);
-#if 0
+
/**
* Writes COC marker for each component.
*
@@ -1067,9 +1148,7 @@ static OPJ_BOOL opj_j2k_read_cbd ( opj_j2k_t *p_j2k,
static OPJ_BOOL opj_j2k_write_all_coc( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager );
-#endif
-#if 0
/**
* Writes QCC marker for each component.
*
@@ -1080,7 +1159,6 @@ static OPJ_BOOL opj_j2k_write_all_coc( opj_j2k_t *p_j2k,
static OPJ_BOOL opj_j2k_write_all_qcc( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager );
-#endif
/**
* Writes regions of interests.
@@ -1169,6 +1247,18 @@ static void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_ima
static OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_UINT16 rsiz, opj_event_mgr_t *p_manager);
+/**
+ * Checks for invalid number of tile-parts in SOT marker (TPsot==TNsot). See issue 254.
+ *
+ * @param p_stream the stream to read data from.
+ * @param tile_no tile number we're looking for.
+ * @param p_correction_needed output value. if true, non conformant codestream needs TNsot correction.
+ * @param p_manager the user event manager.
+ *
+ * @return true if the function was successful, false else.
+ */
+static OPJ_BOOL opj_j2k_need_nb_tile_parts_correction(opj_stream_private_t *p_stream, OPJ_UINT32 tile_no, OPJ_BOOL* p_correction_needed, opj_event_mgr_t * p_manager );
+
/*@}*/
/*@}*/
@@ -1179,7 +1269,7 @@ typedef struct j2k_prog_order{
char str_prog[5];
}j2k_prog_order_t;
-j2k_prog_order_t j2k_prog_order_list[] = {
+static j2k_prog_order_t j2k_prog_order_list[] = {
{OPJ_CPRL, "CPRL"},
{OPJ_LRCP, "LRCP"},
{OPJ_PCRL, "PCRL"},
@@ -1201,7 +1291,7 @@ static const OPJ_UINT32 MCT_ELEMENT_SIZE [] =
typedef void (* opj_j2k_mct_function) (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
-const opj_j2k_mct_function j2k_mct_read_functions_to_float [] =
+static const opj_j2k_mct_function j2k_mct_read_functions_to_float [] =
{
opj_j2k_read_int16_to_float,
opj_j2k_read_int32_to_float,
@@ -1209,7 +1299,7 @@ const opj_j2k_mct_function j2k_mct_read_functions_to_float [] =
opj_j2k_read_float64_to_float
};
-const opj_j2k_mct_function j2k_mct_read_functions_to_int32 [] =
+static const opj_j2k_mct_function j2k_mct_read_functions_to_int32 [] =
{
opj_j2k_read_int16_to_int32,
opj_j2k_read_int32_to_int32,
@@ -1217,7 +1307,7 @@ const opj_j2k_mct_function j2k_mct_read_functions_to_int32 [] =
opj_j2k_read_float64_to_int32
};
-const opj_j2k_mct_function j2k_mct_write_functions_from_float [] =
+static const opj_j2k_mct_function j2k_mct_write_functions_from_float [] =
{
opj_j2k_write_float_to_int16,
opj_j2k_write_float_to_int32,
@@ -1239,7 +1329,7 @@ typedef struct opj_dec_memory_marker_handler
}
opj_dec_memory_marker_handler_t;
-const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] =
+static const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] =
{
{J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, opj_j2k_read_sot},
{J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_cod},
@@ -1252,7 +1342,7 @@ const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] =
{J2K_MS_TLM, J2K_STATE_MH, opj_j2k_read_tlm},
{J2K_MS_PLM, J2K_STATE_MH, opj_j2k_read_plm},
{J2K_MS_PLT, J2K_STATE_TPH, opj_j2k_read_plt},
- {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm_v3},
+ {J2K_MS_PPM, J2K_STATE_MH, opj_j2k_read_ppm},
{J2K_MS_PPT, J2K_STATE_TPH, opj_j2k_read_ppt},
{J2K_MS_SOP, 0, 0},
{J2K_MS_CRG, J2K_STATE_MH, opj_j2k_read_crg},
@@ -1276,7 +1366,7 @@ const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] =
{J2K_MS_UNK, J2K_STATE_MH | J2K_STATE_TPH, 0}/*opj_j2k_read_unk is directly used*/
};
-void opj_j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+static void opj_j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
{
OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
@@ -1292,7 +1382,7 @@ void opj_j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data,
}
}
-void opj_j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+static void opj_j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
{
OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
@@ -1308,7 +1398,7 @@ void opj_j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data,
}
}
-void opj_j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+static void opj_j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
{
OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
@@ -1324,7 +1414,7 @@ void opj_j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data
}
}
-void opj_j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+static void opj_j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
{
OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
@@ -1340,7 +1430,7 @@ void opj_j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data
}
}
-void opj_j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+static void opj_j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
{
OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
@@ -1356,7 +1446,7 @@ void opj_j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data,
}
}
-void opj_j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+static void opj_j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
{
OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
@@ -1372,7 +1462,7 @@ void opj_j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data,
}
}
-void opj_j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+static void opj_j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
{
OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
@@ -1388,7 +1478,7 @@ void opj_j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data
}
}
-void opj_j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+static void opj_j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
{
OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
@@ -1404,7 +1494,7 @@ void opj_j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data
}
}
-void opj_j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+static void opj_j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
{
OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
@@ -1420,7 +1510,7 @@ void opj_j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data,
}
}
-void opj_j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+static void opj_j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
{
OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
@@ -1436,7 +1526,7 @@ void opj_j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data,
}
}
-void opj_j2k_write_float_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+static void opj_j2k_write_float_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
{
OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
@@ -1452,7 +1542,7 @@ void opj_j2k_write_float_to_float (const void * p_src_data, void * p_dest_data,
}
}
-void opj_j2k_write_float_to_float64 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+static void opj_j2k_write_float_to_float64 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
{
OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
@@ -1478,7 +1568,7 @@ char *opj_j2k_convert_progression_order(OPJ_PROG_ORDER prg_order){
return po->str_prog;
}
-OPJ_BOOL opj_j2k_check_poc_val( const opj_poc_t *p_pocs,
+static OPJ_BOOL opj_j2k_check_poc_val( const opj_poc_t *p_pocs,
OPJ_UINT32 p_nb_pocs,
OPJ_UINT32 p_nb_resolutions,
OPJ_UINT32 p_num_comps,
@@ -1499,7 +1589,6 @@ OPJ_BOOL opj_j2k_check_poc_val( const opj_poc_t *p_pocs,
opj_event_msg(p_manager , EVT_ERROR, "Not enough memory for checking the poc values.\n");
return OPJ_FALSE;
}
- memset(packet_array,0,step_l * p_num_layers* sizeof(OPJ_UINT32));
if (p_nb_pocs == 0) {
opj_free(packet_array);
@@ -1583,7 +1672,7 @@ OPJ_BOOL opj_j2k_check_poc_val( const opj_poc_t *p_pocs,
/* ----------------------------------------------------------------------- */
-OPJ_UINT32 opj_j2k_get_num_tp(opj_cp_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno)
+static OPJ_UINT32 opj_j2k_get_num_tp(opj_cp_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno)
{
const OPJ_CHAR *prog = 00;
OPJ_INT32 i;
@@ -1641,7 +1730,7 @@ OPJ_UINT32 opj_j2k_get_num_tp(opj_cp_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno)
return tpnum;
}
-OPJ_BOOL opj_j2k_calculate_tp( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_calculate_tp( opj_j2k_t *p_j2k,
opj_cp_t *cp,
OPJ_UINT32 * p_nb_tiles,
opj_image_t *image,
@@ -1719,7 +1808,7 @@ OPJ_BOOL opj_j2k_calculate_tp( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_soc( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_soc( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
{
@@ -1797,7 +1886,7 @@ static OPJ_BOOL opj_j2k_read_soc( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_siz( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_siz( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
{
@@ -1910,7 +1999,7 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
OPJ_UINT32 l_nb_comp_remain;
OPJ_UINT32 l_remaining_size;
OPJ_UINT32 l_nb_tiles;
- OPJ_UINT32 l_tmp;
+ OPJ_UINT32 l_tmp, l_tx1, l_ty1;
opj_image_t *l_image = 00;
opj_cp_t *l_cp = 00;
opj_image_comp_t * l_img_comp = 00;
@@ -1972,22 +2061,31 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
}
/* testcase 4035.pdf.SIGSEGV.d8b.3375 */
- if (l_image->x0 > l_image->x1 || l_image->y0 > l_image->y1) {
- opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: negative image size (%d x %d)\n", l_image->x1 - l_image->x0, l_image->y1 - l_image->y0);
+ /* testcase issue427-null-image-size.jp2 */
+ if ((l_image->x0 >= l_image->x1) || (l_image->y0 >= l_image->y1)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: negative or zero image size (%" PRId64 " x %" PRId64 ")\n", (OPJ_INT64)l_image->x1 - l_image->x0, (OPJ_INT64)l_image->y1 - l_image->y0);
return OPJ_FALSE;
}
/* testcase 2539.pdf.SIGFPE.706.1712 (also 3622.pdf.SIGFPE.706.2916 and 4008.pdf.SIGFPE.706.3345 and maybe more) */
- if (!(l_cp->tdx * l_cp->tdy)) {
+ if ((l_cp->tdx == 0U) || (l_cp->tdy == 0U)) {
opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: invalid tile size (tdx: %d, tdy: %d)\n", l_cp->tdx, l_cp->tdy);
return OPJ_FALSE;
}
/* testcase 1610.pdf.SIGSEGV.59c.681 */
- if (((OPJ_UINT64)l_image->x1) * ((OPJ_UINT64)l_image->y1) != (l_image->x1 * l_image->y1)) {
+ if ((0xFFFFFFFFU / l_image->x1) < l_image->y1) {
opj_event_msg(p_manager, EVT_ERROR, "Prevent buffer overflow (x1: %d, y1: %d)\n", l_image->x1, l_image->y1);
return OPJ_FALSE;
}
+ /* testcase issue427-illegal-tile-offset.jp2 */
+ l_tx1 = opj_uint_adds(l_cp->tx0, l_cp->tdx); /* manage overflow */
+ l_ty1 = opj_uint_adds(l_cp->ty0, l_cp->tdy); /* manage overflow */
+ if ((l_cp->tx0 > l_image->x0) || (l_cp->ty0 > l_image->y0) || (l_tx1 <= l_image->x0) || (l_ty1 <= l_image->y0) ) {
+ opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: illegal tile offset\n");
+ return OPJ_FALSE;
+ }
+
#ifdef USE_JPWL
if (l_cp->correct) {
/* if JPWL is on, we check whether TX errors have damaged
@@ -1996,7 +2094,7 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
opj_event_msg(p_manager, EVT_ERROR,
"JPWL: bad image size (%d x %d)\n",
l_image->x1, l_image->y1);
- if (!JPWL_ASSUME || JPWL_ASSUME) {
+ if (!JPWL_ASSUME) {
opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
return OPJ_FALSE;
}
@@ -2038,7 +2136,6 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
return OPJ_FALSE;
}
- memset(l_image->comps,0,l_image->numcomps * sizeof(opj_image_comp_t));
l_img_comp = l_image->comps;
/* Read the component information */
@@ -2057,10 +2154,16 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
if( l_img_comp->dx < 1 || l_img_comp->dx > 255 ||
l_img_comp->dy < 1 || l_img_comp->dy > 255 ) {
opj_event_msg(p_manager, EVT_ERROR,
- "Invalid values for comp = %d : dx=%u dy=%u\n (should be between 1 and 255 according the JPEG2000 norm)",
+ "Invalid values for comp = %d : dx=%u dy=%u (should be between 1 and 255 according to the JPEG2000 norm)\n",
i, l_img_comp->dx, l_img_comp->dy);
return OPJ_FALSE;
}
+ if( l_img_comp->prec > 38) { /* TODO openjpeg won't handle more than ? */
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Invalid values for comp = %d : prec=%u (should be between 1 and 38 according to the JPEG2000 norm)\n",
+ i, l_img_comp->prec);
+ return OPJ_FALSE;
+ }
#ifdef USE_JPWL
if (l_cp->correct) {
@@ -2167,14 +2270,13 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
return OPJ_FALSE;
}
- memset(l_cp->tcps,0,l_nb_tiles*sizeof(opj_tcp_t));
#ifdef USE_JPWL
if (l_cp->correct) {
if (!l_cp->tcps) {
opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
"JPWL: could not alloc tcps field of cp\n");
- if (!JPWL_ASSUME || JPWL_ASSUME) {
+ if (!JPWL_ASSUME) {
opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
return OPJ_FALSE;
}
@@ -2188,27 +2290,24 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
return OPJ_FALSE;
}
- memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps ,0,l_image->numcomps*sizeof(opj_tccp_t));
p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records =
- (opj_mct_data_t*)opj_malloc(OPJ_J2K_MCT_DEFAULT_NB_RECORDS * sizeof(opj_mct_data_t));
+ (opj_mct_data_t*)opj_calloc(OPJ_J2K_MCT_DEFAULT_NB_RECORDS ,sizeof(opj_mct_data_t));
if (! p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
return OPJ_FALSE;
}
- memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records,0,OPJ_J2K_MCT_DEFAULT_NB_RECORDS * sizeof(opj_mct_data_t));
p_j2k->m_specific_param.m_decoder.m_default_tcp->m_nb_max_mct_records = OPJ_J2K_MCT_DEFAULT_NB_RECORDS;
p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records =
(opj_simple_mcc_decorrelation_data_t*)
- opj_malloc(OPJ_J2K_MCC_DEFAULT_NB_RECORDS * sizeof(opj_simple_mcc_decorrelation_data_t));
+ opj_calloc(OPJ_J2K_MCC_DEFAULT_NB_RECORDS, sizeof(opj_simple_mcc_decorrelation_data_t));
if (! p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
return OPJ_FALSE;
}
- memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records,0,OPJ_J2K_MCC_DEFAULT_NB_RECORDS * sizeof(opj_simple_mcc_decorrelation_data_t));
p_j2k->m_specific_param.m_decoder.m_default_tcp->m_nb_max_mcc_records = OPJ_J2K_MCC_DEFAULT_NB_RECORDS;
/* set up default dc level shift */
@@ -2220,12 +2319,11 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
l_current_tile_param = l_cp->tcps;
for (i = 0; i < l_nb_tiles; ++i) {
- l_current_tile_param->tccps = (opj_tccp_t*) opj_malloc(l_image->numcomps * sizeof(opj_tccp_t));
+ l_current_tile_param->tccps = (opj_tccp_t*) opj_calloc(l_image->numcomps, sizeof(opj_tccp_t));
if (l_current_tile_param->tccps == 00) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
return OPJ_FALSE;
}
- memset(l_current_tile_param->tccps,0,l_image->numcomps * sizeof(opj_tccp_t));
++l_current_tile_param;
}
@@ -2236,7 +2334,7 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_com( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_com( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager
)
@@ -2310,7 +2408,7 @@ static OPJ_BOOL opj_j2k_read_com ( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_cod( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_cod( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
{
@@ -2344,22 +2442,22 @@ OPJ_BOOL opj_j2k_write_cod( opj_j2k_t *p_j2k,
l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
- opj_write_bytes(l_current_data,J2K_MS_COD,2); /* COD */
+ opj_write_bytes(l_current_data,J2K_MS_COD,2); /* COD */
l_current_data += 2;
- opj_write_bytes(l_current_data,l_code_size-2,2); /* L_COD */
+ opj_write_bytes(l_current_data,l_code_size-2,2); /* L_COD */
l_current_data += 2;
- opj_write_bytes(l_current_data,l_tcp->csty,1); /* Scod */
+ opj_write_bytes(l_current_data,l_tcp->csty,1); /* Scod */
++l_current_data;
- opj_write_bytes(l_current_data,l_tcp->prg,1); /* SGcod (A) */
+ opj_write_bytes(l_current_data,(OPJ_UINT32)l_tcp->prg,1); /* SGcod (A) */
++l_current_data;
- opj_write_bytes(l_current_data,l_tcp->numlayers,2); /* SGcod (B) */
+ opj_write_bytes(l_current_data,l_tcp->numlayers,2); /* SGcod (B) */
l_current_data+=2;
- opj_write_bytes(l_current_data,l_tcp->mct,1); /* SGcod (C) */
+ opj_write_bytes(l_current_data,l_tcp->mct,1); /* SGcod (C) */
++l_current_data;
l_remaining_size -= 9;
@@ -2413,7 +2511,14 @@ static OPJ_BOOL opj_j2k_read_cod ( opj_j2k_t *p_j2k,
l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ?
&l_cp->tcps[p_j2k->m_current_tile_number] :
p_j2k->m_specific_param.m_decoder.m_default_tcp;
-
+
+ /* Only one COD per tile */
+ if (l_tcp->cod) {
+ opj_event_msg(p_manager, EVT_ERROR, "COD marker already read. No more than one COD marker per tile.\n");
+ return OPJ_FALSE;
+ }
+ l_tcp->cod = 1;
+
/* Make sure room is sufficient */
if (p_header_size < 5) {
opj_event_msg(p_manager, EVT_ERROR, "Error reading COD marker\n");
@@ -2422,11 +2527,26 @@ static OPJ_BOOL opj_j2k_read_cod ( opj_j2k_t *p_j2k,
opj_read_bytes(p_header_data,&l_tcp->csty,1); /* Scod */
++p_header_data;
+ /* Make sure we know how to decode this */
+ if ((l_tcp->csty & ~(OPJ_UINT32)(J2K_CP_CSTY_PRT | J2K_CP_CSTY_SOP | J2K_CP_CSTY_EPH)) != 0U) {
+ opj_event_msg(p_manager, EVT_ERROR, "Unknown Scod value in COD marker\n");
+ return OPJ_FALSE;
+ }
opj_read_bytes(p_header_data,&l_tmp,1); /* SGcod (A) */
++p_header_data;
l_tcp->prg = (OPJ_PROG_ORDER) l_tmp;
+ /* Make sure progression order is valid */
+ if (l_tcp->prg > OPJ_CPRL ) {
+ opj_event_msg(p_manager, EVT_ERROR, "Unknown progression order in COD marker\n");
+ l_tcp->prg = OPJ_PROG_UNKNOWN;
+ }
opj_read_bytes(p_header_data,&l_tcp->numlayers,2); /* SGcod (B) */
p_header_data+=2;
+
+ if ((l_tcp->numlayers < 1U) || (l_tcp->numlayers > 65535U)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Invalid number of layers in COD marker : %d not in range [1-65535]\n", l_tcp->numlayers);
+ return OPJ_FALSE;
+ }
/* If user didn't set a number layer to decode take the max specify in the codestream. */
if (l_cp->m_specific_param.m_dec.m_layer) {
@@ -2464,6 +2584,9 @@ static OPJ_BOOL opj_j2k_read_cod ( opj_j2k_t *p_j2k,
p_j2k->cstr_info->prog = l_tcp->prg;
p_j2k->cstr_info->numlayers = l_tcp->numlayers;
p_j2k->cstr_info->numdecompos = (OPJ_INT32*) opj_malloc(l_image->numcomps * sizeof(OPJ_UINT32));
+ if(!p_j2k->cstr_info->numdecompos){
+ return OPJ_FALSE;
+ }
for (i = 0; i < l_image->numcomps; ++i) {
p_j2k->cstr_info->numdecompos[i] = l_tcp->tccps[i].numresolutions - 1;
}
@@ -2473,8 +2596,7 @@ static OPJ_BOOL opj_j2k_read_cod ( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-#if 0
-OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_j2k,
OPJ_UINT32 p_comp_no,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
@@ -2518,10 +2640,27 @@ OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-#endif
-#if 0
-void opj_j2k_write_coc_in_memory( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_compare_coc(opj_j2k_t *p_j2k, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no)
+{
+ opj_cp_t *l_cp = NULL;
+ opj_tcp_t *l_tcp = NULL;
+
+ /* preconditions */
+ assert(p_j2k != 00);
+
+ l_cp = &(p_j2k->m_cp);
+ l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number];
+
+ if (l_tcp->tccps[p_first_comp_no].csty != l_tcp->tccps[p_second_comp_no].csty) {
+ return OPJ_FALSE;
+ }
+
+
+ return opj_j2k_compare_SPCod_SPCoc(p_j2k, p_j2k->m_current_tile_number, p_first_comp_no, p_second_comp_no);
+}
+
+static void opj_j2k_write_coc_in_memory( opj_j2k_t *p_j2k,
OPJ_UINT32 p_comp_no,
OPJ_BYTE * p_data,
OPJ_UINT32 * p_data_written,
@@ -2565,9 +2704,8 @@ void opj_j2k_write_coc_in_memory( opj_j2k_t *p_j2k,
opj_j2k_write_SPCod_SPCoc(p_j2k,p_j2k->m_current_tile_number,0,l_current_data,&l_remaining_size,p_manager);
* p_data_written = l_coc_size;
}
-#endif
-OPJ_UINT32 opj_j2k_get_max_coc_size(opj_j2k_t *p_j2k)
+static OPJ_UINT32 opj_j2k_get_max_coc_size(opj_j2k_t *p_j2k)
{
OPJ_UINT32 i,j;
OPJ_UINT32 l_nb_comp;
@@ -2649,7 +2787,7 @@ static OPJ_BOOL opj_j2k_read_coc ( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_qcd( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_qcd( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager
)
@@ -2739,8 +2877,7 @@ static OPJ_BOOL opj_j2k_read_qcd ( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-#if 0
-OPJ_BOOL opj_j2k_write_qcc( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_qcc( opj_j2k_t *p_j2k,
OPJ_UINT32 p_comp_no,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager
@@ -2778,10 +2915,13 @@ OPJ_BOOL opj_j2k_write_qcc( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-#endif
-#if 0
-void opj_j2k_write_qcc_in_memory( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_compare_qcc(opj_j2k_t *p_j2k, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no)
+{
+ return opj_j2k_compare_SQcd_SQcc(p_j2k,p_j2k->m_current_tile_number,p_first_comp_no, p_second_comp_no);
+}
+
+static void opj_j2k_write_qcc_in_memory( opj_j2k_t *p_j2k,
OPJ_UINT32 p_comp_no,
OPJ_BYTE * p_data,
OPJ_UINT32 * p_data_written,
@@ -2829,9 +2969,8 @@ void opj_j2k_write_qcc_in_memory( opj_j2k_t *p_j2k,
*p_data_written = l_qcc_size;
}
-#endif
-OPJ_UINT32 opj_j2k_get_max_qcc_size (opj_j2k_t *p_j2k)
+static OPJ_UINT32 opj_j2k_get_max_qcc_size (opj_j2k_t *p_j2k)
{
return opj_j2k_get_max_coc_size(p_j2k);
}
@@ -2923,7 +3062,7 @@ static OPJ_BOOL opj_j2k_read_qcc( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_poc( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_poc( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager
)
@@ -2974,7 +3113,7 @@ OPJ_BOOL opj_j2k_write_poc( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-void opj_j2k_write_poc_in_memory( opj_j2k_t *p_j2k,
+static void opj_j2k_write_poc_in_memory( opj_j2k_t *p_j2k,
OPJ_BYTE * p_data,
OPJ_UINT32 * p_data_written,
opj_event_mgr_t * p_manager
@@ -3035,7 +3174,7 @@ void opj_j2k_write_poc_in_memory( opj_j2k_t *p_j2k,
opj_write_bytes(l_current_data,l_current_poc->compno1,l_poc_room); /* CEpoc_i */
l_current_data+=l_poc_room;
- opj_write_bytes(l_current_data,l_current_poc->prg,1); /* Ppoc_i */
+ opj_write_bytes(l_current_data, (OPJ_UINT32)l_current_poc->prg,1); /* Ppoc_i */
++l_current_data;
/* change the value of the max layer according to the actual number of layers in the file, components and resolutions*/
@@ -3049,7 +3188,7 @@ void opj_j2k_write_poc_in_memory( opj_j2k_t *p_j2k,
*p_data_written = l_poc_size;
}
-OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k)
+static OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k)
{
opj_tcp_t * l_tcp = 00;
OPJ_UINT32 l_nb_tiles = 0;
@@ -3069,7 +3208,7 @@ OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k)
return 4 + 9 * l_max_poc;
}
-OPJ_UINT32 opj_j2k_get_max_toc_size (opj_j2k_t *p_j2k)
+static OPJ_UINT32 opj_j2k_get_max_toc_size (opj_j2k_t *p_j2k)
{
OPJ_UINT32 i;
OPJ_UINT32 l_nb_tiles;
@@ -3088,7 +3227,7 @@ OPJ_UINT32 opj_j2k_get_max_toc_size (opj_j2k_t *p_j2k)
return 12 * l_max;
}
-OPJ_UINT32 opj_j2k_get_specific_header_sizes(opj_j2k_t *p_j2k)
+static OPJ_UINT32 opj_j2k_get_specific_header_sizes(opj_j2k_t *p_j2k)
{
OPJ_UINT32 l_nb_bytes = 0;
OPJ_UINT32 l_nb_comps;
@@ -3418,347 +3557,220 @@ static OPJ_BOOL opj_j2k_read_plt ( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-#if 0
-OPJ_BOOL j2k_read_ppm_v2 (
- opj_j2k_t *p_j2k,
- OPJ_BYTE * p_header_data,
- OPJ_UINT32 p_header_size,
- struct opj_event_mgr * p_manager
- )
-{
-
- opj_cp_t *l_cp = 00;
- OPJ_UINT32 l_remaining_data, l_Z_ppm, l_N_ppm;
-
- /* preconditions */
- assert(p_header_data != 00);
- assert(p_j2k != 00);
- assert(p_manager != 00);
-
- if (p_header_size < 1) {
- opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
- return OPJ_FALSE;
- }
-
- l_cp = &(p_j2k->m_cp);
- l_cp->ppm = 1;
-
- opj_read_bytes(p_header_data,&l_Z_ppm,1); /* Z_ppm */
- ++p_header_data;
- --p_header_size;
-
- /* First PPM marker */
- if (l_Z_ppm == 0) {
- if (p_header_size < 4) {
- opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
- return OPJ_FALSE;
- }
-
- opj_read_bytes(p_header_data,&l_N_ppm,4); /* N_ppm */
- p_header_data+=4;
- p_header_size-=4;
-
- /* First PPM marker: Initialization */
- l_cp->ppm_len = l_N_ppm;
- l_cp->ppm_data_size = 0;
-
- l_cp->ppm_buffer = (OPJ_BYTE *) opj_malloc(l_cp->ppm_len);
- if (l_cp->ppm_buffer == 00) {
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n");
- return OPJ_FALSE;
- }
- memset(l_cp->ppm_buffer,0,l_cp->ppm_len);
-
- l_cp->ppm_data = l_cp->ppm_buffer;
- }
-
- while (1) {
- if (l_cp->ppm_data_size == l_cp->ppm_len) {
- if (p_header_size >= 4) {
- /* read a N_ppm */
- opj_read_bytes(p_header_data,&l_N_ppm,4); /* N_ppm */
- p_header_data+=4;
- p_header_size-=4;
- l_cp->ppm_len += l_N_ppm ;
-
- OPJ_BYTE *new_ppm_buffer = (OPJ_BYTE *) opj_realloc(l_cp->ppm_buffer, l_cp->ppm_len);
- if (! new_ppm_buffer) {
- opj_free(l_cp->ppm_buffer);
- l_cp->ppm_buffer = NULL;
- l_cp->ppm_len = 0;
- l_cp->ppm_data = NULL;
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n");
- return OPJ_FALSE;
- }
- l_cp->ppm_buffer = new_ppm_buffer;
- memset(l_cp->ppm_buffer+l_cp->ppm_data_size,0,l_N_ppm);
- l_cp->ppm_data = l_cp->ppm_buffer;
- }
- else {
- return OPJ_FALSE;
- }
- }
-
- l_remaining_data = l_cp->ppm_len - l_cp->ppm_data_size;
-
- if (l_remaining_data <= p_header_size) {
- /* we must store less information than available in the packet */
- memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , l_remaining_data);
- l_cp->ppm_data_size = l_cp->ppm_len;
- p_header_size -= l_remaining_data;
- p_header_data += l_remaining_data;
- }
- else {
- memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , p_header_size);
- l_cp->ppm_data_size += p_header_size;
- p_header_data += p_header_size;
- p_header_size = 0;
- break;
- }
- }
+/**
+ * Reads a PPM marker (Packed packet headers, main header)
+ *
+ * @param p_header_data the data contained in the POC box.
+ * @param p_j2k the jpeg2000 codec.
+ * @param p_header_size the size of the data contained in the POC marker.
+ * @param p_manager the user event manager.
+ */
- return OPJ_TRUE;
+static OPJ_BOOL opj_j2k_read_ppm (
+ opj_j2k_t *p_j2k,
+ OPJ_BYTE * p_header_data,
+ OPJ_UINT32 p_header_size,
+ opj_event_mgr_t * p_manager )
+{
+ opj_cp_t *l_cp = 00;
+ OPJ_UINT32 l_Z_ppm;
+
+ /* preconditions */
+ assert(p_header_data != 00);
+ assert(p_j2k != 00);
+ assert(p_manager != 00);
+
+ /* We need to have the Z_ppm element + 1 byte of Nppm/Ippm at minimum */
+ if (p_header_size < 2) {
+ opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
+ return OPJ_FALSE;
+ }
+
+ l_cp = &(p_j2k->m_cp);
+ l_cp->ppm = 1;
+
+ opj_read_bytes(p_header_data,&l_Z_ppm,1); /* Z_ppm */
+ ++p_header_data;
+ --p_header_size;
+
+ /* check allocation needed */
+ if (l_cp->ppm_markers == NULL) { /* first PPM marker */
+ OPJ_UINT32 l_newCount = l_Z_ppm + 1U; /* can't overflow, l_Z_ppm is UINT8 */
+ assert(l_cp->ppm_markers_count == 0U);
+
+ l_cp->ppm_markers = (opj_ppx *) opj_calloc(l_newCount, sizeof(opj_ppx));
+ if (l_cp->ppm_markers == NULL) {
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n");
+ return OPJ_FALSE;
+ }
+ l_cp->ppm_markers_count = l_newCount;
+ } else if (l_cp->ppm_markers_count <= l_Z_ppm) {
+ OPJ_UINT32 l_newCount = l_Z_ppm + 1U; /* can't overflow, l_Z_ppm is UINT8 */
+ opj_ppx *new_ppm_markers;
+ new_ppm_markers = (opj_ppx *) opj_realloc(l_cp->ppm_markers, l_newCount * sizeof(opj_ppx));
+ if (new_ppm_markers == NULL) {
+ /* clean up to be done on l_cp destruction */
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n");
+ return OPJ_FALSE;
+ }
+ l_cp->ppm_markers = new_ppm_markers;
+ memset(l_cp->ppm_markers + l_cp->ppm_markers_count, 0, (l_newCount - l_cp->ppm_markers_count) * sizeof(opj_ppx));
+ l_cp->ppm_markers_count = l_newCount;
+ }
+
+ if (l_cp->ppm_markers[l_Z_ppm].m_data != NULL) {
+ /* clean up to be done on l_cp destruction */
+ opj_event_msg(p_manager, EVT_ERROR, "Zppm %u already read\n", l_Z_ppm);
+ return OPJ_FALSE;
+ }
+
+ l_cp->ppm_markers[l_Z_ppm].m_data = (OPJ_BYTE *) opj_malloc(p_header_size);
+ if (l_cp->ppm_markers[l_Z_ppm].m_data == NULL) {
+ /* clean up to be done on l_cp destruction */
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n");
+ return OPJ_FALSE;
+ }
+ l_cp->ppm_markers[l_Z_ppm].m_data_size = p_header_size;
+ memcpy(l_cp->ppm_markers[l_Z_ppm].m_data, p_header_data, p_header_size);
+
+ return OPJ_TRUE;
}
-#endif
-OPJ_BOOL j2k_read_ppm_v3 (
- opj_j2k_t *p_j2k,
- OPJ_BYTE * p_header_data,
- OPJ_UINT32 p_header_size,
- struct opj_event_mgr * p_manager
- )
-{
- opj_cp_t *l_cp = 00;
- OPJ_UINT32 l_remaining_data, l_Z_ppm, l_N_ppm;
-
- /* preconditions */
- assert(p_header_data != 00);
- assert(p_j2k != 00);
- assert(p_manager != 00);
-
- /* Minimum size of PPM marker is equal to the size of Zppm element */
- if (p_header_size < 1) {
- opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
- return OPJ_FALSE;
- }
-
- l_cp = &(p_j2k->m_cp);
- l_cp->ppm = 1;
-
- opj_read_bytes(p_header_data,&l_Z_ppm,1); /* Z_ppm */
- ++p_header_data;
- --p_header_size;
-
- /* First PPM marker */
- if (l_Z_ppm == 0) {
- /* We need now at least the Nppm^0 element */
- if (p_header_size < 4) {
- opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
- return OPJ_FALSE;
- }
-
- opj_read_bytes(p_header_data,&l_N_ppm,4); /* First N_ppm */
- p_header_data+=4;
- p_header_size-=4;
-
- /* sanity check: how much bytes is left for Ippm */
- if( p_header_size < l_N_ppm )
- {
- opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes (%u) to hold Ippm series (%u), Index (%d)\n", p_header_size, l_N_ppm, l_Z_ppm );
- opj_free(l_cp->ppm_data);
- l_cp->ppm_data = NULL;
- l_cp->ppm_buffer = NULL;
- l_cp->ppm = 0; /* do not use PPM */
- return OPJ_FALSE;
- }
-
- /* First PPM marker: Initialization */
- l_cp->ppm_len = l_N_ppm;
- l_cp->ppm_data_read = 0;
-
- l_cp->ppm_data = (OPJ_BYTE *) opj_malloc(l_cp->ppm_len);
- l_cp->ppm_buffer = l_cp->ppm_data;
- if (l_cp->ppm_data == 00) {
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read ppm marker\n");
- return OPJ_FALSE;
- }
- memset(l_cp->ppm_data,0,l_cp->ppm_len);
-
- l_cp->ppm_data_current = l_cp->ppm_data;
-
- /*l_cp->ppm_data = l_cp->ppm_buffer;*/
- }
- else {
- if (p_header_size < 4) {
- opj_event_msg(p_manager, EVT_WARNING, "Empty PPM marker\n");
- return OPJ_TRUE;
- }
- else {
- /* Uncompleted Ippm series in the previous PPM marker?*/
- if (l_cp->ppm_data_read < l_cp->ppm_len) {
- /* Get the place where add the remaining Ippm series*/
- l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_data_read]);
- l_N_ppm = l_cp->ppm_len - l_cp->ppm_data_read;
- }
- else {
- OPJ_BYTE *new_ppm_data;
- opj_read_bytes(p_header_data,&l_N_ppm,4); /* First N_ppm */
- p_header_data+=4;
- p_header_size-=4;
-
- /* sanity check: how much bytes is left for Ippm */
- if( p_header_size < l_N_ppm )
- {
- opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes (%u) to hold Ippm series (%u), Index (%d)\n", p_header_size, l_N_ppm, l_Z_ppm );
- opj_free(l_cp->ppm_data);
- l_cp->ppm_data = NULL;
- l_cp->ppm_buffer = NULL;
- l_cp->ppm = 0; /* do not use PPM */
- return OPJ_FALSE;
- }
- /* Increase the size of ppm_data to add the new Ippm series*/
- assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating");
- new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm);
- if (! new_ppm_data) {
- opj_free(l_cp->ppm_data);
- l_cp->ppm_data = NULL;
- l_cp->ppm_buffer = NULL; /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */
- l_cp->ppm_len = 0;
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new Ippm series\n");
- return OPJ_FALSE;
- }
- l_cp->ppm_data = new_ppm_data;
- l_cp->ppm_buffer = l_cp->ppm_data;
-
- /* Keep the position of the place where concatenate the new series*/
- l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]);
- l_cp->ppm_len += l_N_ppm;
- }
- }
- }
-
- l_remaining_data = p_header_size;
-
- while (l_remaining_data >= l_N_ppm) {
- /* read a complete Ippm series*/
- memcpy(l_cp->ppm_data_current, p_header_data, l_N_ppm);
- p_header_size -= l_N_ppm;
- p_header_data += l_N_ppm;
-
- l_cp->ppm_data_read += l_N_ppm; /* Increase the number of data read*/
-
- if (p_header_size)
- {
- opj_read_bytes(p_header_data,&l_N_ppm,4); /* N_ppm^i */
- p_header_data+=4;
- p_header_size-=4;
- }
- else {
- l_remaining_data = p_header_size;
- break;
- }
-
- l_remaining_data = p_header_size;
-
- /* Next Ippm series is a complete series ?*/
- if (l_remaining_data >= l_N_ppm) {
- OPJ_BYTE *new_ppm_data;
- /* Increase the size of ppm_data to add the new Ippm series*/
- assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating");
- new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm);
- if (! new_ppm_data) {
- opj_free(l_cp->ppm_data);
- l_cp->ppm_data = NULL;
- l_cp->ppm_buffer = NULL; /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */
- l_cp->ppm_len = 0;
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new (complete) Ippm series\n");
- return OPJ_FALSE;
- }
- l_cp->ppm_data = new_ppm_data;
- l_cp->ppm_buffer = l_cp->ppm_data;
-
- /* Keep the position of the place where concatenate the new series */
- l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]);
- l_cp->ppm_len += l_N_ppm;
- }
-
- }
-
- /* Need to read an incomplete Ippm series*/
- if (l_remaining_data) {
- OPJ_BYTE *new_ppm_data;
- assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating");
- new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm);
- if (! new_ppm_data) {
- opj_free(l_cp->ppm_data);
- l_cp->ppm_data = NULL;
- l_cp->ppm_buffer = NULL; /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */
- l_cp->ppm_len = 0;
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new (incomplete) Ippm series\n");
- return OPJ_FALSE;
- }
- l_cp->ppm_data = new_ppm_data;
- l_cp->ppm_buffer = l_cp->ppm_data;
-
- /* Keep the position of the place where concatenate the new series*/
- l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]);
- l_cp->ppm_len += l_N_ppm;
-
- /* Read incomplete Ippm series*/
- memcpy(l_cp->ppm_data_current, p_header_data, l_remaining_data);
- p_header_size -= l_remaining_data;
- p_header_data += l_remaining_data;
-
- l_cp->ppm_data_read += l_remaining_data; /* Increase the number of data read*/
- }
-
-#ifdef CLEAN_MSD
-
- if (l_cp->ppm_data_size == l_cp->ppm_len) {
- if (p_header_size >= 4) {
- /* read a N_ppm*/
- opj_read_bytes(p_header_data,&l_N_ppm,4); /* N_ppm */
- p_header_data+=4;
- p_header_size-=4;
- l_cp->ppm_len += l_N_ppm ;
-
- OPJ_BYTE *new_ppm_buffer = (OPJ_BYTE *) opj_realloc(l_cp->ppm_buffer, l_cp->ppm_len);
- if (! new_ppm_buffer) {
- opj_free(l_cp->ppm_buffer);
- l_cp->ppm_buffer = NULL;
- l_cp->ppm_len = 0;
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read ppm marker\n");
- return OPJ_FALSE;
- }
- l_cp->ppm_buffer = new_ppm_buffer;
- memset(l_cp->ppm_buffer+l_cp->ppm_data_size,0,l_N_ppm);
-
- l_cp->ppm_data = l_cp->ppm_buffer;
- }
- else {
- return OPJ_FALSE;
- }
- }
-
- l_remaining_data = l_cp->ppm_len - l_cp->ppm_data_size;
-
- if (l_remaining_data <= p_header_size) {
- /* we must store less information than available in the packet */
- memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , l_remaining_data);
- l_cp->ppm_data_size = l_cp->ppm_len;
- p_header_size -= l_remaining_data;
- p_header_data += l_remaining_data;
- }
- else {
- memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , p_header_size);
- l_cp->ppm_data_size += p_header_size;
- p_header_data += p_header_size;
- p_header_size = 0;
- break;
- }
- }
-#endif
- return OPJ_TRUE;
+/**
+ * Merges all PPM markers read (Packed headers, main header)
+ *
+ * @param p_cp main coding parameters.
+ * @param p_manager the user event manager.
+ */
+static OPJ_BOOL opj_j2k_merge_ppm ( opj_cp_t *p_cp, opj_event_mgr_t * p_manager )
+{
+ OPJ_UINT32 i, l_ppm_data_size, l_N_ppm_remaining;
+
+ /* preconditions */
+ assert(p_cp != 00);
+ assert(p_manager != 00);
+ assert(p_cp->ppm_buffer == NULL);
+
+ if (p_cp->ppm == 0U) {
+ return OPJ_TRUE;
+ }
+
+ l_ppm_data_size = 0U;
+ l_N_ppm_remaining = 0U;
+ for (i = 0U; i < p_cp->ppm_markers_count; ++i) {
+ if (p_cp->ppm_markers[i].m_data != NULL) { /* standard doesn't seem to require contiguous Zppm */
+ OPJ_UINT32 l_N_ppm;
+ OPJ_UINT32 l_data_size = p_cp->ppm_markers[i].m_data_size;
+ const OPJ_BYTE* l_data = p_cp->ppm_markers[i].m_data;
+
+ if (l_N_ppm_remaining >= l_data_size) {
+ l_N_ppm_remaining -= l_data_size;
+ l_data_size = 0U;
+ } else {
+ l_data += l_N_ppm_remaining;
+ l_data_size -= l_N_ppm_remaining;
+ l_N_ppm_remaining = 0U;
+ }
+
+ if (l_data_size > 0U) {
+ do
+ {
+ /* read Nppm */
+ if (l_data_size < 4U) {
+ /* clean up to be done on l_cp destruction */
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes to read Nppm\n");
+ return OPJ_FALSE;
+ }
+ opj_read_bytes(l_data, &l_N_ppm, 4);
+ l_data+=4;
+ l_data_size-=4;
+ l_ppm_data_size += l_N_ppm; /* can't overflow, max 256 markers of max 65536 bytes, that is when PPM markers are not corrupted which is checked elsewhere */
+
+ if (l_data_size >= l_N_ppm) {
+ l_data_size -= l_N_ppm;
+ l_data += l_N_ppm;
+ } else {
+ l_N_ppm_remaining = l_N_ppm - l_data_size;
+ l_data_size = 0U;
+ }
+ } while (l_data_size > 0U);
+ }
+ }
+ }
+
+ if (l_N_ppm_remaining != 0U) {
+ /* clean up to be done on l_cp destruction */
+ opj_event_msg(p_manager, EVT_ERROR, "Corrupted PPM markers\n");
+ return OPJ_FALSE;
+ }
+
+ p_cp->ppm_buffer = (OPJ_BYTE *) opj_malloc(l_ppm_data_size);
+ if (p_cp->ppm_buffer == 00) {
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n");
+ return OPJ_FALSE;
+ }
+ p_cp->ppm_len = l_ppm_data_size;
+ l_ppm_data_size = 0U;
+ l_N_ppm_remaining = 0U;
+ for (i = 0U; i < p_cp->ppm_markers_count; ++i) {
+ if (p_cp->ppm_markers[i].m_data != NULL) { /* standard doesn't seem to require contiguous Zppm */
+ OPJ_UINT32 l_N_ppm;
+ OPJ_UINT32 l_data_size = p_cp->ppm_markers[i].m_data_size;
+ const OPJ_BYTE* l_data = p_cp->ppm_markers[i].m_data;
+
+ if (l_N_ppm_remaining >= l_data_size) {
+ memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_data_size);
+ l_ppm_data_size += l_data_size;
+ l_N_ppm_remaining -= l_data_size;
+ l_data_size = 0U;
+ } else {
+ memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_N_ppm_remaining);
+ l_ppm_data_size += l_N_ppm_remaining;
+ l_data += l_N_ppm_remaining;
+ l_data_size -= l_N_ppm_remaining;
+ l_N_ppm_remaining = 0U;
+ }
+
+ if (l_data_size > 0U) {
+ do
+ {
+ /* read Nppm */
+ if (l_data_size < 4U) {
+ /* clean up to be done on l_cp destruction */
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes to read Nppm\n");
+ return OPJ_FALSE;
+ }
+ opj_read_bytes(l_data, &l_N_ppm, 4);
+ l_data+=4;
+ l_data_size-=4;
+
+ if (l_data_size >= l_N_ppm) {
+ memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_N_ppm);
+ l_ppm_data_size += l_N_ppm;
+ l_data_size -= l_N_ppm;
+ l_data += l_N_ppm;
+ } else {
+ memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_data_size);
+ l_ppm_data_size += l_data_size;
+ l_N_ppm_remaining = l_N_ppm - l_data_size;
+ l_data_size = 0U;
+ }
+ } while (l_data_size > 0U);
+ }
+ opj_free(p_cp->ppm_markers[i].m_data);
+ p_cp->ppm_markers[i].m_data = NULL;
+ p_cp->ppm_markers[i].m_data_size = 0U;
+ }
+ }
+
+ p_cp->ppm_data = p_cp->ppm_buffer;
+ p_cp->ppm_data_size = p_cp->ppm_len;
+
+ p_cp->ppm_markers_count = 0U;
+ opj_free(p_cp->ppm_markers);
+ p_cp->ppm_markers = NULL;
+
+ return OPJ_TRUE;
}
/**
@@ -3775,77 +3787,127 @@ static OPJ_BOOL opj_j2k_read_ppt ( opj_j2k_t *p_j2k,
opj_event_mgr_t * p_manager
)
{
- opj_cp_t *l_cp = 00;
- opj_tcp_t *l_tcp = 00;
- OPJ_UINT32 l_Z_ppt;
-
- /* preconditions */
- assert(p_header_data != 00);
- assert(p_j2k != 00);
- assert(p_manager != 00);
-
- /* We need to have the Z_ppt element at minimum */
- if (p_header_size < 1) {
- opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker\n");
- return OPJ_FALSE;
- }
-
- l_cp = &(p_j2k->m_cp);
- if (l_cp->ppm){
- opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker: packet header have been previously found in the main header (PPM marker).\n");
- return OPJ_FALSE;
- }
-
- l_tcp = &(l_cp->tcps[p_j2k->m_current_tile_number]);
- l_tcp->ppt = 1;
-
- opj_read_bytes(p_header_data,&l_Z_ppt,1); /* Z_ppt */
- ++p_header_data;
- --p_header_size;
-
- /* Allocate buffer to read the packet header */
- if (l_Z_ppt == 0) {
- /* First PPT marker */
- l_tcp->ppt_data_size = 0;
- l_tcp->ppt_len = p_header_size;
-
- opj_free(l_tcp->ppt_buffer);
- l_tcp->ppt_buffer = (OPJ_BYTE *) opj_calloc(l_tcp->ppt_len, sizeof(OPJ_BYTE) );
- if (l_tcp->ppt_buffer == 00) {
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
- return OPJ_FALSE;
- }
- l_tcp->ppt_data = l_tcp->ppt_buffer;
-
- /* memset(l_tcp->ppt_buffer,0,l_tcp->ppt_len); */
- }
- else {
- OPJ_BYTE *new_ppt_buffer;
- l_tcp->ppt_len += p_header_size;
-
- new_ppt_buffer = (OPJ_BYTE *) opj_realloc(l_tcp->ppt_buffer, l_tcp->ppt_len);
- if (! new_ppt_buffer) {
- opj_free(l_tcp->ppt_buffer);
- l_tcp->ppt_buffer = NULL;
- l_tcp->ppt_len = 0;
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
- return OPJ_FALSE;
- }
- l_tcp->ppt_buffer = new_ppt_buffer;
- l_tcp->ppt_data = l_tcp->ppt_buffer;
-
- memset(l_tcp->ppt_buffer+l_tcp->ppt_data_size,0,p_header_size);
- }
-
- /* Read packet header from buffer */
- memcpy(l_tcp->ppt_buffer+l_tcp->ppt_data_size,p_header_data,p_header_size);
-
- l_tcp->ppt_data_size += p_header_size;
-
- return OPJ_TRUE;
+ opj_cp_t *l_cp = 00;
+ opj_tcp_t *l_tcp = 00;
+ OPJ_UINT32 l_Z_ppt;
+
+ /* preconditions */
+ assert(p_header_data != 00);
+ assert(p_j2k != 00);
+ assert(p_manager != 00);
+
+ /* We need to have the Z_ppt element + 1 byte of Ippt at minimum */
+ if (p_header_size < 2) {
+ opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker\n");
+ return OPJ_FALSE;
+ }
+
+ l_cp = &(p_j2k->m_cp);
+ if (l_cp->ppm){
+ opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker: packet header have been previously found in the main header (PPM marker).\n");
+ return OPJ_FALSE;
+ }
+
+ l_tcp = &(l_cp->tcps[p_j2k->m_current_tile_number]);
+ l_tcp->ppt = 1;
+
+ opj_read_bytes(p_header_data,&l_Z_ppt,1); /* Z_ppt */
+ ++p_header_data;
+ --p_header_size;
+
+ /* check allocation needed */
+ if (l_tcp->ppt_markers == NULL) { /* first PPT marker */
+ OPJ_UINT32 l_newCount = l_Z_ppt + 1U; /* can't overflow, l_Z_ppt is UINT8 */
+ assert(l_tcp->ppt_markers_count == 0U);
+
+ l_tcp->ppt_markers = (opj_ppx *) opj_calloc(l_newCount, sizeof(opj_ppx));
+ if (l_tcp->ppt_markers == NULL) {
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+ return OPJ_FALSE;
+ }
+ l_tcp->ppt_markers_count = l_newCount;
+ } else if (l_tcp->ppt_markers_count <= l_Z_ppt) {
+ OPJ_UINT32 l_newCount = l_Z_ppt + 1U; /* can't overflow, l_Z_ppt is UINT8 */
+ opj_ppx *new_ppt_markers;
+ new_ppt_markers = (opj_ppx *) opj_realloc(l_tcp->ppt_markers, l_newCount * sizeof(opj_ppx));
+ if (new_ppt_markers == NULL) {
+ /* clean up to be done on l_tcp destruction */
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+ return OPJ_FALSE;
+ }
+ l_tcp->ppt_markers = new_ppt_markers;
+ memset(l_tcp->ppt_markers + l_tcp->ppt_markers_count, 0, (l_newCount - l_tcp->ppt_markers_count) * sizeof(opj_ppx));
+ l_tcp->ppt_markers_count = l_newCount;
+ }
+
+ if (l_tcp->ppt_markers[l_Z_ppt].m_data != NULL) {
+ /* clean up to be done on l_tcp destruction */
+ opj_event_msg(p_manager, EVT_ERROR, "Zppt %u already read\n", l_Z_ppt);
+ return OPJ_FALSE;
+ }
+
+ l_tcp->ppt_markers[l_Z_ppt].m_data = (OPJ_BYTE *) opj_malloc(p_header_size);
+ if (l_tcp->ppt_markers[l_Z_ppt].m_data == NULL) {
+ /* clean up to be done on l_tcp destruction */
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+ return OPJ_FALSE;
+ }
+ l_tcp->ppt_markers[l_Z_ppt].m_data_size = p_header_size;
+ memcpy(l_tcp->ppt_markers[l_Z_ppt].m_data, p_header_data, p_header_size);
+ return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_tlm( opj_j2k_t *p_j2k,
+/**
+ * Merges all PPT markers read (Packed packet headers, tile-part header)
+ *
+ * @param p_tcp the tile.
+ * @param p_manager the user event manager.
+ */
+static OPJ_BOOL opj_j2k_merge_ppt(opj_tcp_t *p_tcp, opj_event_mgr_t * p_manager)
+{
+ OPJ_UINT32 i, l_ppt_data_size;
+ /* preconditions */
+ assert(p_tcp != 00);
+ assert(p_manager != 00);
+ assert(p_tcp->ppt_buffer == NULL);
+
+ if (p_tcp->ppt == 0U) {
+ return OPJ_TRUE;
+ }
+
+ l_ppt_data_size = 0U;
+ for (i = 0U; i < p_tcp->ppt_markers_count; ++i) {
+ l_ppt_data_size += p_tcp->ppt_markers[i].m_data_size; /* can't overflow, max 256 markers of max 65536 bytes */
+ }
+
+ p_tcp->ppt_buffer = (OPJ_BYTE *) opj_malloc(l_ppt_data_size);
+ if (p_tcp->ppt_buffer == 00) {
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+ return OPJ_FALSE;
+ }
+ p_tcp->ppt_len = l_ppt_data_size;
+ l_ppt_data_size = 0U;
+ for (i = 0U; i < p_tcp->ppt_markers_count; ++i) {
+ if (p_tcp->ppt_markers[i].m_data != NULL) { /* standard doesn't seem to require contiguous Zppt */
+ memcpy(p_tcp->ppt_buffer + l_ppt_data_size, p_tcp->ppt_markers[i].m_data, p_tcp->ppt_markers[i].m_data_size);
+ l_ppt_data_size += p_tcp->ppt_markers[i].m_data_size; /* can't overflow, max 256 markers of max 65536 bytes */
+
+ opj_free(p_tcp->ppt_markers[i].m_data);
+ p_tcp->ppt_markers[i].m_data = NULL;
+ p_tcp->ppt_markers[i].m_data_size = 0U;
+ }
+ }
+
+ p_tcp->ppt_markers_count = 0U;
+ opj_free(p_tcp->ppt_markers);
+ p_tcp->ppt_markers = NULL;
+
+ p_tcp->ppt_data = p_tcp->ppt_buffer;
+ p_tcp->ppt_data_size = p_tcp->ppt_len;
+ return OPJ_TRUE;
+}
+
+static OPJ_BOOL opj_j2k_write_tlm( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager
)
@@ -3899,7 +3961,7 @@ OPJ_BOOL opj_j2k_write_tlm( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_sot( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_sot( opj_j2k_t *p_j2k,
OPJ_BYTE * p_data,
OPJ_UINT32 * p_data_written,
const opj_stream_private_t *p_stream,
@@ -3943,7 +4005,36 @@ OPJ_BOOL opj_j2k_write_sot( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_get_sot_values(OPJ_BYTE * p_header_data,
+ OPJ_UINT32 p_header_size,
+ OPJ_UINT32* p_tile_no,
+ OPJ_UINT32* p_tot_len,
+ OPJ_UINT32* p_current_part,
+ OPJ_UINT32* p_num_parts,
+ opj_event_mgr_t * p_manager )
+{
+ /* preconditions */
+ assert(p_header_data != 00);
+ assert(p_manager != 00);
+
+ /* Size of this marker is fixed = 12 (we have already read marker and its size)*/
+ if (p_header_size != 8) {
+ opj_event_msg(p_manager, EVT_ERROR, "Error reading SOT marker\n");
+ return OPJ_FALSE;
+ }
+
+ opj_read_bytes(p_header_data,p_tile_no,2); /* Isot */
+ p_header_data+=2;
+ opj_read_bytes(p_header_data,p_tot_len,4); /* Psot */
+ p_header_data+=4;
+ opj_read_bytes(p_header_data,p_current_part,1); /* TPsot */
+ ++p_header_data;
+ opj_read_bytes(p_header_data,p_num_parts ,1); /* TNsot */
+ ++p_header_data;
+ return OPJ_TRUE;
+}
+
+static OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
OPJ_BYTE * p_header_data,
OPJ_UINT32 p_header_size,
opj_event_mgr_t * p_manager )
@@ -3955,19 +4046,16 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
OPJ_UINT32 l_tile_x,l_tile_y;
/* preconditions */
- assert(p_header_data != 00);
+
assert(p_j2k != 00);
assert(p_manager != 00);
-
- /* Size of this marker is fixed = 12 (we have already read marker and its size)*/
- if (p_header_size != 8) {
+
+ if (! opj_j2k_get_sot_values(p_header_data, p_header_size, &(p_j2k->m_current_tile_number), &l_tot_len, &l_current_part, &l_num_parts, p_manager)) {
opj_event_msg(p_manager, EVT_ERROR, "Error reading SOT marker\n");
return OPJ_FALSE;
}
l_cp = &(p_j2k->m_cp);
- opj_read_bytes(p_header_data,&(p_j2k->m_current_tile_number),2); /* Isot */
- p_header_data+=2;
/* testcase 2.pdf.SIGFPE.706.1112 */
if (p_j2k->m_current_tile_number >= l_cp->tw * l_cp->th) {
@@ -4010,9 +4098,6 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
/* Optimization possible here with a more complex data structure and with the removing of tiles */
/* since the time taken by this function can only grow at the time */
- opj_read_bytes(p_header_data,&l_tot_len,4); /* Psot */
- p_header_data+=4;
-
/* PSot should be equal to zero or >=14 or <= 2^32-1 */
if ((l_tot_len !=0 ) && (l_tot_len < 14) )
{
@@ -4055,13 +4140,8 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1;
}
- opj_read_bytes(p_header_data,&l_current_part ,1); /* TPsot */
- ++p_header_data;
-
- opj_read_bytes(p_header_data,&l_num_parts ,1); /* TNsot */
- ++p_header_data;
-
if (l_num_parts != 0) { /* Number of tile-part header is provided by this tile-part header */
+ l_num_parts += p_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction;
/* Useful to manage the case of textGBR.jp2 file because two values of TNSot are allowed: the correct numbers of
* tile-parts for that tile and zero (A.4.2 of 15444-1 : 2002). */
if (l_tcp->m_nb_tile_parts) {
@@ -4132,6 +4212,10 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index) {
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index =
(opj_tp_index_t*)opj_calloc(l_num_parts, sizeof(opj_tp_index_t));
+ if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index) {
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read SOT marker. Tile index allocation failed\n");
+ return OPJ_FALSE;
+ }
}
else {
opj_tp_index_t *new_tp_index = (opj_tp_index_t *) opj_realloc(
@@ -4139,7 +4223,7 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
if (! new_tp_index) {
opj_free(p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index);
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = NULL;
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read SOT marker. Tile index allocation failed\n");
return OPJ_FALSE;
}
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = new_tp_index;
@@ -4153,6 +4237,11 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index =
(opj_tp_index_t*)opj_calloc( p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps,
sizeof(opj_tp_index_t));
+ if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index) {
+ p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = 0;
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read SOT marker. Tile index allocation failed\n");
+ return OPJ_FALSE;
+ }
}
if ( l_current_part >= p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps ){
@@ -4165,7 +4254,7 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
opj_free(p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index);
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = NULL;
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = 0;
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read SOT marker. Tile index allocation failed\n");
return OPJ_FALSE;
}
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = new_tp_index;
@@ -4206,7 +4295,7 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_sod( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_sod( opj_j2k_t *p_j2k,
opj_tcd_t * p_tile_coder,
OPJ_BYTE * p_data,
OPJ_UINT32 * p_data_written,
@@ -4280,7 +4369,7 @@ OPJ_BOOL opj_j2k_write_sod( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager
)
@@ -4320,15 +4409,15 @@ OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k,
/* Patch to support new PHR data */
if (p_j2k->m_specific_param.m_decoder.m_sot_length) {
- /* cf. https://code.google.com/p/openjpeg/issues/detail?id=348 */
- if (p_j2k->m_specific_param.m_decoder.m_sot_length > opj_stream_get_number_byte_left(p_stream)) {
- opj_event_msg(p_manager, EVT_ERROR, "Not enough data to decode tile\n");
+ /* If we are here, we'll try to read the data after allocation */
+ /* Check enough bytes left in stream before allocation */
+ if ((OPJ_OFF_T)p_j2k->m_specific_param.m_decoder.m_sot_length > opj_stream_get_number_byte_left(p_stream)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Tile part length size inconsistent with stream length\n");
return OPJ_FALSE;
}
-
- if (! *l_current_data) {
+ if (! *l_current_data) {
/* LH: oddly enough, in this path, l_tile_len!=0.
- * TODO: If this was consistant, we could simplify the code to only use realloc(), as realloc(0,...) default to malloc(0,...).
+ * TODO: If this was consistent, we could simplify the code to only use realloc(), as realloc(0,...) default to malloc(0,...).
*/
*l_current_data = (OPJ_BYTE*) opj_malloc(p_j2k->m_specific_param.m_decoder.m_sot_length);
}
@@ -4401,7 +4490,7 @@ OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
- OPJ_BOOL opj_j2k_write_rgn(opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_rgn(opj_j2k_t *p_j2k,
OPJ_UINT32 p_tile_no,
OPJ_UINT32 p_comp_no,
OPJ_UINT32 nb_comps,
@@ -4458,7 +4547,7 @@ OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_eoc( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_eoc( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager
)
@@ -4545,7 +4634,7 @@ static OPJ_BOOL opj_j2k_read_rgn (opj_j2k_t *p_j2k,
opj_event_msg(p_manager, EVT_ERROR,
"JPWL: bad component number in RGN (%d when there are only %d)\n",
l_comp_room, l_nb_comp);
- if (!JPWL_ASSUME || JPWL_ASSUME) {
+ if (!JPWL_ASSUME) {
opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
return OPJ_FALSE;
}
@@ -4568,18 +4657,18 @@ static OPJ_BOOL opj_j2k_read_rgn (opj_j2k_t *p_j2k,
}
-OPJ_FLOAT32 opj_j2k_get_tp_stride (opj_tcp_t * p_tcp)
+static OPJ_FLOAT32 opj_j2k_get_tp_stride (opj_tcp_t * p_tcp)
{
return (OPJ_FLOAT32) ((p_tcp->m_nb_tile_parts - 1) * 14);
}
-OPJ_FLOAT32 opj_j2k_get_default_stride (opj_tcp_t * p_tcp)
+static OPJ_FLOAT32 opj_j2k_get_default_stride (opj_tcp_t * p_tcp)
{
(void)p_tcp;
return 0;
}
-OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
{
@@ -4630,7 +4719,7 @@ OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k,
l_rates = l_tcp->rates;
/* Modification of the RATE >> */
- if (*l_rates) {
+ if (*l_rates > 0.0f) {
*l_rates = (( (OPJ_FLOAT32) (l_size_pixel * (OPJ_UINT32)(l_x1 - l_x0) * (OPJ_UINT32)(l_y1 - l_y0)))
/
((*l_rates) * (OPJ_FLOAT32)l_bits_empty)
@@ -4642,7 +4731,7 @@ OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k,
++l_rates;
for (k = 1; k < l_tcp->numlayers; ++k) {
- if (*l_rates) {
+ if (*l_rates > 0.0f) {
*l_rates = (( (OPJ_FLOAT32) (l_size_pixel * (OPJ_UINT32)(l_x1 - l_x0) * (OPJ_UINT32)(l_y1 - l_y0)))
/
((*l_rates) * (OPJ_FLOAT32)l_bits_empty)
@@ -4665,11 +4754,11 @@ OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k,
for (j=0;j<l_cp->tw;++j) {
l_rates = l_tcp->rates;
- if (*l_rates) {
+ if (*l_rates > 0.0f) {
*l_rates -= l_sot_remove;
- if (*l_rates < 30) {
- *l_rates = 30;
+ if (*l_rates < 30.0f) {
+ *l_rates = 30.0f;
}
}
@@ -4679,22 +4768,22 @@ OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k,
for (k = 1; k < l_last_res; ++k) {
- if (*l_rates) {
+ if (*l_rates > 0.0f) {
*l_rates -= l_sot_remove;
- if (*l_rates < *(l_rates - 1) + 10) {
- *l_rates = (*(l_rates - 1)) + 20;
+ if (*l_rates < *(l_rates - 1) + 10.0f) {
+ *l_rates = (*(l_rates - 1)) + 20.0f;
}
}
++l_rates;
}
- if (*l_rates) {
+ if (*l_rates > 0.0f) {
*l_rates -= (l_sot_remove + 2.f);
- if (*l_rates < *(l_rates - 1) + 10) {
- *l_rates = (*(l_rates - 1)) + 20;
+ if (*l_rates < *(l_rates - 1) + 10.0f) {
+ *l_rates = (*(l_rates - 1)) + 20.0f;
}
}
@@ -4742,7 +4831,7 @@ OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k,
}
#if 0
-OPJ_BOOL opj_j2k_read_eoc ( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_read_eoc ( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
{
@@ -4792,7 +4881,7 @@ OPJ_BOOL opj_j2k_read_eoc ( opj_j2k_t *p_j2k,
}
#endif
-OPJ_BOOL opj_j2k_get_end_header(opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_get_end_header(opj_j2k_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager )
{
@@ -4806,7 +4895,7 @@ OPJ_BOOL opj_j2k_get_end_header(opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_mct_data_group( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_mct_data_group( opj_j2k_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager )
{
@@ -4854,54 +4943,56 @@ OPJ_BOOL opj_j2k_write_mct_data_group( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-#if 0
-OPJ_BOOL opj_j2k_write_all_coc(opj_j2k_t *p_j2k,
- struct opj_stream_private *p_stream,
- struct opj_event_mgr * p_manager )
-{
- OPJ_UINT32 compno;
-
- /* preconditions */
- assert(p_j2k != 00);
- assert(p_manager != 00);
- assert(p_stream != 00);
-
- for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno)
- {
- if (! opj_j2k_write_coc(p_j2k,compno,p_stream, p_manager)) {
- return OPJ_FALSE;
- }
- }
-
- return OPJ_TRUE;
-}
-#endif
-
-#if 0
-OPJ_BOOL opj_j2k_write_all_qcc(opj_j2k_t *p_j2k,
- struct opj_stream_private *p_stream,
- struct opj_event_mgr * p_manager )
-{
- OPJ_UINT32 compno;
-
- /* preconditions */
- assert(p_j2k != 00);
- assert(p_manager != 00);
- assert(p_stream != 00);
-
- for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno)
- {
- if (! opj_j2k_write_qcc(p_j2k,compno,p_stream, p_manager)) {
- return OPJ_FALSE;
- }
- }
-
- return OPJ_TRUE;
+static OPJ_BOOL opj_j2k_write_all_coc(
+ opj_j2k_t *p_j2k,
+ struct opj_stream_private *p_stream,
+ struct opj_event_mgr * p_manager )
+{
+ OPJ_UINT32 compno;
+
+ /* preconditions */
+ assert(p_j2k != 00);
+ assert(p_manager != 00);
+ assert(p_stream != 00);
+
+ for (compno = 1; compno < p_j2k->m_private_image->numcomps; ++compno)
+ {
+ /* cod is first component of first tile */
+ if (! opj_j2k_compare_coc(p_j2k, 0, compno)) {
+ if (! opj_j2k_write_coc(p_j2k,compno,p_stream, p_manager)) {
+ return OPJ_FALSE;
+ }
+ }
+ }
+
+ return OPJ_TRUE;
+}
+
+static OPJ_BOOL opj_j2k_write_all_qcc(
+ opj_j2k_t *p_j2k,
+ struct opj_stream_private *p_stream,
+ struct opj_event_mgr * p_manager )
+{
+ OPJ_UINT32 compno;
+
+ /* preconditions */
+ assert(p_j2k != 00);
+ assert(p_manager != 00);
+ assert(p_stream != 00);
+
+ for (compno = 1; compno < p_j2k->m_private_image->numcomps; ++compno)
+ {
+ /* qcd is first component of first tile */
+ if (! opj_j2k_compare_qcc(p_j2k, 0, compno)) {
+ if (! opj_j2k_write_qcc(p_j2k,compno,p_stream, p_manager)) {
+ return OPJ_FALSE;
+ }
+ }
+ }
+ return OPJ_TRUE;
}
-#endif
-
-OPJ_BOOL opj_j2k_write_regions( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_regions( opj_j2k_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager )
{
@@ -4915,7 +5006,7 @@ OPJ_BOOL opj_j2k_write_regions( opj_j2k_t *p_j2k,
l_tccp = p_j2k->m_cp.tcps->tccps;
- for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno) {
+ for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno) {
if (l_tccp->roishift) {
if (! opj_j2k_write_rgn(p_j2k,0,compno,p_j2k->m_private_image->numcomps,p_stream,p_manager)) {
@@ -4929,7 +5020,7 @@ OPJ_BOOL opj_j2k_write_regions( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_epc( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_epc( opj_j2k_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager )
{
@@ -4967,7 +5058,7 @@ OPJ_BOOL opj_j2k_write_epc( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_read_unk ( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_read_unk ( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
OPJ_UINT32 *output_marker,
opj_event_mgr_t * p_manager
@@ -4984,7 +5075,7 @@ OPJ_BOOL opj_j2k_read_unk ( opj_j2k_t *p_j2k,
opj_event_msg(p_manager, EVT_WARNING, "Unknown marker\n");
- while(1) {
+ for (;;) {
/* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer*/
if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
@@ -5029,7 +5120,7 @@ OPJ_BOOL opj_j2k_read_unk ( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_mct_record( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_mct_record( opj_j2k_t *p_j2k,
opj_mct_data_t * p_mct_record,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager )
@@ -5168,6 +5259,7 @@ static OPJ_BOOL opj_j2k_read_mct ( opj_j2k_t *p_j2k,
}
l_mct_data = l_tcp->m_mct_records + l_tcp->m_nb_mct_records;
+ ++l_tcp->m_nb_mct_records;
}
if (l_mct_data->m_data) {
@@ -5196,12 +5288,11 @@ static OPJ_BOOL opj_j2k_read_mct ( opj_j2k_t *p_j2k,
memcpy(l_mct_data->m_data,p_header_data,p_header_size);
l_mct_data->m_data_size = p_header_size;
- ++l_tcp->m_nb_mct_records;
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_mcc_record( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_mcc_record( opj_j2k_t *p_j2k,
struct opj_simple_mcc_decorrelation_data * p_mcc_record,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager )
@@ -5284,7 +5375,7 @@ OPJ_BOOL opj_j2k_write_mcc_record( opj_j2k_t *p_j2k,
l_current_data+=l_nb_bytes_for_comp;
}
- l_tmcc = ((!p_mcc_record->m_is_irreversible)&1)<<16;
+ l_tmcc = ((!p_mcc_record->m_is_irreversible) & 1U) << 16;
if (p_mcc_record->m_decorrelation_array) {
l_tmcc |= p_mcc_record->m_decorrelation_array->m_index;
@@ -5304,7 +5395,7 @@ OPJ_BOOL opj_j2k_write_mcc_record( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_read_mcc ( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_read_mcc ( opj_j2k_t *p_j2k,
OPJ_BYTE * p_header_data,
OPJ_UINT32 p_header_size,
opj_event_mgr_t * p_manager )
@@ -5318,6 +5409,7 @@ OPJ_BOOL opj_j2k_read_mcc ( opj_j2k_t *p_j2k,
OPJ_UINT32 l_nb_collections;
OPJ_UINT32 l_nb_comps;
OPJ_UINT32 l_nb_bytes_by_comp;
+ OPJ_BOOL l_new_mcc = OPJ_FALSE;
/* preconditions */
assert(p_header_data != 00);
@@ -5379,6 +5471,7 @@ OPJ_BOOL opj_j2k_read_mcc ( opj_j2k_t *p_j2k,
memset(l_mcc_record,0,(l_tcp->m_nb_max_mcc_records-l_tcp->m_nb_mcc_records) * sizeof(opj_simple_mcc_decorrelation_data_t));
}
l_mcc_record = l_tcp->m_mcc_records + l_tcp->m_nb_mcc_records;
+ l_new_mcc = OPJ_TRUE;
}
l_mcc_record->m_index = l_indix;
@@ -5514,12 +5607,14 @@ OPJ_BOOL opj_j2k_read_mcc ( opj_j2k_t *p_j2k,
return OPJ_FALSE;
}
- ++l_tcp->m_nb_mcc_records;
+ if (l_new_mcc) {
+ ++l_tcp->m_nb_mcc_records;
+ }
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_mco( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_mco( opj_j2k_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager
)
@@ -5536,8 +5631,7 @@ OPJ_BOOL opj_j2k_write_mco( opj_j2k_t *p_j2k,
assert(p_stream != 00);
l_tcp =&(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]);
- l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
-
+
l_mco_size = 5 + l_tcp->m_nb_mcc_records;
if (l_mco_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
@@ -5552,6 +5646,8 @@ OPJ_BOOL opj_j2k_write_mco( opj_j2k_t *p_j2k,
p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mco_size;
}
+ l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
opj_write_bytes(l_current_data,J2K_MS_MCO,2); /* MCO */
l_current_data += 2;
@@ -5559,14 +5655,13 @@ OPJ_BOOL opj_j2k_write_mco( opj_j2k_t *p_j2k,
opj_write_bytes(l_current_data,l_mco_size-2,2); /* Lmco */
l_current_data += 2;
- opj_write_bytes(l_current_data,l_tcp->m_nb_mcc_records,1); /* Nmco : only one tranform stage*/
+ opj_write_bytes(l_current_data,l_tcp->m_nb_mcc_records,1); /* Nmco : only one transform stage*/
++l_current_data;
l_mcc_record = l_tcp->m_mcc_records;
- for (i=0;i<l_tcp->m_nb_mcc_records;++i) {
+ for (i=0;i<l_tcp->m_nb_mcc_records;++i) {
opj_write_bytes(l_current_data,l_mcc_record->m_index,1);/* Imco -> use the mcc indicated by 1*/
++l_current_data;
-
++l_mcc_record;
}
@@ -5612,7 +5707,7 @@ static OPJ_BOOL opj_j2k_read_mco ( opj_j2k_t *p_j2k,
return OPJ_FALSE;
}
- opj_read_bytes(p_header_data,&l_nb_stages,1); /* Nmco : only one tranform stage*/
+ opj_read_bytes(p_header_data,&l_nb_stages,1); /* Nmco : only one transform stage*/
++p_header_data;
if (l_nb_stages > 1) {
@@ -5649,7 +5744,7 @@ static OPJ_BOOL opj_j2k_read_mco ( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_index)
+static OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_index)
{
OPJ_UINT32 i;
opj_simple_mcc_decorrelation_data_t * l_mcc_record;
@@ -5731,7 +5826,7 @@ OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_cbd( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_cbd( opj_j2k_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager )
{
@@ -5857,18 +5952,46 @@ void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters)
}
}
+OPJ_BOOL opj_j2k_set_threads(opj_j2k_t *j2k, OPJ_UINT32 num_threads)
+{
+ if( opj_has_thread_support() )
+ {
+ opj_thread_pool_destroy(j2k->m_tp);
+ j2k->m_tp = NULL;
+ if (num_threads <= (OPJ_UINT32)INT_MAX ) {
+ j2k->m_tp = opj_thread_pool_create((int)num_threads);
+ }
+ if( j2k->m_tp == NULL )
+ {
+ j2k->m_tp = opj_thread_pool_create(0);
+ return OPJ_FALSE;
+ }
+ return OPJ_TRUE;
+ }
+ return OPJ_FALSE;
+}
+
+static int opj_j2k_get_default_thread_count()
+{
+ const char* num_threads = getenv("OPJ_NUM_THREADS");
+ if( num_threads == NULL || !opj_has_thread_support() )
+ return 0;
+ if( strcmp(num_threads, "ALL_CPUS") == 0 )
+ return opj_get_num_cpus();
+ return atoi(num_threads);
+}
+
/* ----------------------------------------------------------------------- */
/* J2K encoder interface */
/* ----------------------------------------------------------------------- */
opj_j2k_t* opj_j2k_create_compress(void)
{
- opj_j2k_t *l_j2k = (opj_j2k_t*) opj_malloc(sizeof(opj_j2k_t));
+ opj_j2k_t *l_j2k = (opj_j2k_t*) opj_calloc(1,sizeof(opj_j2k_t));
if (!l_j2k) {
return NULL;
}
- memset(l_j2k,0,sizeof(opj_j2k_t));
l_j2k->m_is_decoder = 0;
l_j2k->m_cp.m_is_decoder = 0;
@@ -5895,10 +6018,21 @@ opj_j2k_t* opj_j2k_create_compress(void)
return NULL;
}
+ l_j2k->m_tp = opj_thread_pool_create(opj_j2k_get_default_thread_count());
+ if( !l_j2k->m_tp )
+ {
+ l_j2k->m_tp = opj_thread_pool_create(0);
+ }
+ if( !l_j2k->m_tp )
+ {
+ opj_j2k_destroy(l_j2k);
+ return NULL;
+ }
+
return l_j2k;
}
-int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres){
+static int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres){
POC[0].tile = 1;
POC[0].resno0 = 0;
POC[0].compno0 = 0;
@@ -5916,7 +6050,7 @@ int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres){
return 2;
}
-void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *image, opj_event_mgr_t *p_manager)
+static void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *image, opj_event_mgr_t *p_manager)
{
/* Configure cinema parameters */
int i;
@@ -6053,7 +6187,7 @@ void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *i
}
-OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_UINT16 rsiz, opj_event_mgr_t *p_manager)
+static OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_UINT16 rsiz, opj_event_mgr_t *p_manager)
{
OPJ_UINT32 i;
@@ -6115,7 +6249,7 @@ OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_UINT16 rsiz, opj_ev
return OPJ_TRUE;
}
-void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
+OPJ_BOOL opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
opj_cparameters_t *parameters,
opj_image_t *image,
opj_event_mgr_t * p_manager)
@@ -6124,7 +6258,12 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
opj_cp_t *cp = 00;
if(!p_j2k || !parameters || ! image) {
- return;
+ return OPJ_FALSE;
+ }
+
+ if ((parameters->numresolution <= 0) || (parameters->numresolution > OPJ_J2K_MAXRLVLS)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Invalid number of resolutions : %d not in range [1,%d]\n", parameters->numresolution, OPJ_J2K_MAXRLVLS);
+ return OPJ_FALSE;
}
/* keep a link to cp so that we can destroy it later in j2k_destroy_compress */
@@ -6266,6 +6405,10 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
if (parameters->cp_fixed_alloc && parameters->cp_matrice) {
size_t array_size = (size_t)parameters->tcp_numlayers * (size_t)parameters->numresolution * 3 * sizeof(OPJ_INT32);
cp->m_specific_param.m_enc.m_matrice = (OPJ_INT32 *) opj_malloc(array_size);
+ if (!cp->m_specific_param.m_enc.m_matrice) {
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate copy of user encoding parameters matrix \n");
+ return OPJ_FALSE;
+ }
memcpy(cp->m_specific_param.m_enc.m_matrice, parameters->cp_matrice, array_size);
}
@@ -6279,11 +6422,36 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
/* comment string */
if(parameters->cp_comment) {
- cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1);
- if(cp->comment) {
- strcpy(cp->comment, parameters->cp_comment);
- }
- }
+ cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1U);
+ if(!cp->comment) {
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate copy of comment string\n");
+ return OPJ_FALSE;
+ }
+ strcpy(cp->comment, parameters->cp_comment);
+ } else {
+ /* Create default comment for codestream */
+ const char comment[] = "Created by OpenJPEG version ";
+ const size_t clen = strlen(comment);
+ const char *version = opj_version();
+
+ /* UniPG>> */
+#ifdef USE_JPWL
+ cp->comment = (char*)opj_malloc(clen+strlen(version)+11);
+ if(!cp->comment) {
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate comment string\n");
+ return OPJ_FALSE;
+ }
+ sprintf(cp->comment,"%s%s with JPWL", comment, version);
+#else
+ cp->comment = (char*)opj_malloc(clen+strlen(version)+1);
+ if(!cp->comment) {
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate comment string\n");
+ return OPJ_FALSE;
+ }
+ sprintf(cp->comment,"%s%s", comment, version);
+#endif
+ /* <<UniPG */
+ }
/*
calculate other encoding parameters
@@ -6361,6 +6529,10 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
/* initialize the mutiple tiles */
/* ---------------------------- */
cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t));
+ if (!cp->tcps) {
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate tile coding parameters\n");
+ return OPJ_FALSE;
+ }
if (parameters->numpocs) {
/* initialisation of POC */
opj_j2k_check_poc_val(parameters->POC,parameters->numpocs, (OPJ_UINT32)parameters->numresolution, image->numcomps, (OPJ_UINT32)parameters->tcp_numlayers, p_manager);
@@ -6418,24 +6590,54 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
}
tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t));
-
+ if (!tcp->tccps) {
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate tile component coding parameters\n");
+ return OPJ_FALSE;
+ }
if (parameters->mct_data) {
OPJ_UINT32 lMctSize = image->numcomps * image->numcomps * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
OPJ_FLOAT32 * lTmpBuf = (OPJ_FLOAT32*)opj_malloc(lMctSize);
OPJ_INT32 * l_dc_shift = (OPJ_INT32 *) ((OPJ_BYTE *) parameters->mct_data + lMctSize);
+ if (!lTmpBuf) {
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate temp buffer\n");
+ return OPJ_FALSE;
+ }
+
tcp->mct = 2;
tcp->m_mct_coding_matrix = (OPJ_FLOAT32*)opj_malloc(lMctSize);
+ if (! tcp->m_mct_coding_matrix) {
+ opj_free(lTmpBuf);
+ lTmpBuf = NULL;
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate encoder MCT coding matrix \n");
+ return OPJ_FALSE;
+ }
memcpy(tcp->m_mct_coding_matrix,parameters->mct_data,lMctSize);
memcpy(lTmpBuf,parameters->mct_data,lMctSize);
tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(lMctSize);
- assert(opj_matrix_inversion_f(lTmpBuf,(tcp->m_mct_decoding_matrix),image->numcomps));
+ if (! tcp->m_mct_decoding_matrix) {
+ opj_free(lTmpBuf);
+ lTmpBuf = NULL;
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate encoder MCT decoding matrix \n");
+ return OPJ_FALSE;
+ }
+ if(opj_matrix_inversion_f(lTmpBuf,(tcp->m_mct_decoding_matrix),image->numcomps) == OPJ_FALSE) {
+ opj_free(lTmpBuf);
+ lTmpBuf = NULL;
+ opj_event_msg(p_manager, EVT_ERROR, "Failed to inverse encoder MCT decoding matrix \n");
+ return OPJ_FALSE;
+ }
tcp->mct_norms = (OPJ_FLOAT64*)
opj_malloc(image->numcomps * sizeof(OPJ_FLOAT64));
-
+ if (! tcp->mct_norms) {
+ opj_free(lTmpBuf);
+ lTmpBuf = NULL;
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate encoder MCT norms \n");
+ return OPJ_FALSE;
+ }
opj_calculate_norms(tcp->mct_norms,image->numcomps,tcp->m_mct_decoding_matrix);
opj_free(lTmpBuf);
@@ -6444,9 +6646,22 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
tccp->m_dc_level_shift = l_dc_shift[i];
}
- opj_j2k_setup_mct_encoding(tcp,image);
+ if (opj_j2k_setup_mct_encoding(tcp,image) == OPJ_FALSE) {
+ /* free will be handled by opj_j2k_destroy */
+ opj_event_msg(p_manager, EVT_ERROR, "Failed to setup j2k mct encoding\n");
+ return OPJ_FALSE;
+ }
}
else {
+ if(tcp->mct==1 && image->numcomps >= 3) { /* RGB->YCC MCT is enabled */
+ if ((image->comps[0].dx != image->comps[1].dx) ||
+ (image->comps[0].dx != image->comps[2].dx) ||
+ (image->comps[0].dy != image->comps[1].dy) ||
+ (image->comps[0].dy != image->comps[2].dy)) {
+ opj_event_msg(p_manager, EVT_WARNING, "Cannot perform MCT on components with different sizes. Disabling MCT.\n");
+ tcp->mct = 0;
+ }
+ }
for (i = 0; i < image->numcomps; i++) {
opj_tccp_t *tccp = &tcp->tccps[i];
opj_image_comp_t * l_comp = &(image->comps[i]);
@@ -6533,6 +6748,7 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
opj_free(parameters->mct_data);
parameters->mct_data = 00;
}
+ return OPJ_TRUE;
}
static OPJ_BOOL opj_j2k_add_mhmarker(opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len)
@@ -6636,7 +6852,11 @@ OPJ_BOOL opj_j2k_read_header( opj_stream_private_t *p_stream,
}
/* customization of the validation */
- opj_j2k_setup_decoding_validation(p_j2k);
+ if (! opj_j2k_setup_decoding_validation(p_j2k, p_manager)) {
+ opj_image_destroy(p_j2k->m_private_image);
+ p_j2k->m_private_image = NULL;
+ return OPJ_FALSE;
+ }
/* validation of the parameters codec */
if (! opj_j2k_exec(p_j2k, p_j2k->m_validation_list, p_stream,p_manager)) {
@@ -6646,7 +6866,11 @@ OPJ_BOOL opj_j2k_read_header( opj_stream_private_t *p_stream,
}
/* customization of the encoding */
- opj_j2k_setup_header_reading(p_j2k);
+ if (! opj_j2k_setup_header_reading(p_j2k, p_manager)) {
+ opj_image_destroy(p_j2k->m_private_image);
+ p_j2k->m_private_image = NULL;
+ return OPJ_FALSE;
+ }
/* read header */
if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
@@ -6671,30 +6895,42 @@ OPJ_BOOL opj_j2k_read_header( opj_stream_private_t *p_stream,
return OPJ_TRUE;
}
-void opj_j2k_setup_header_reading (opj_j2k_t *p_j2k)
+static OPJ_BOOL opj_j2k_setup_header_reading (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager)
{
/* preconditions*/
assert(p_j2k != 00);
+ assert(p_manager != 00);
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_read_header_procedure);
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_read_header_procedure, p_manager)) {
+ return OPJ_FALSE;
+ }
/* DEVELOPER CORNER, add your custom procedures */
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_copy_default_tcp_and_create_tcd);
-
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_copy_default_tcp_and_create_tcd, p_manager)) {
+ return OPJ_FALSE;
+ }
+
+ return OPJ_TRUE;
}
-void opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k)
+static OPJ_BOOL opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager)
{
/* preconditions*/
assert(p_j2k != 00);
+ assert(p_manager != 00);
- opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_build_decoder);
- opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_decoding_validation);
- /* DEVELOPER CORNER, add your custom validation procedure */
+ if (! opj_procedure_list_add_procedure(p_j2k->m_validation_list,(opj_procedure)opj_j2k_build_decoder, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if (! opj_procedure_list_add_procedure(p_j2k->m_validation_list,(opj_procedure)opj_j2k_decoding_validation, p_manager)) {
+ return OPJ_FALSE;
+ }
+ /* DEVELOPER CORNER, add your custom validation procedure */
+ return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_mct_validation ( opj_j2k_t * p_j2k,
+static OPJ_BOOL opj_j2k_mct_validation ( opj_j2k_t * p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
{
@@ -6880,7 +7116,7 @@ OPJ_BOOL opj_j2k_setup_mct_encoding(opj_tcp_t * p_tcp, opj_image_t * p_image)
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_build_decoder (opj_j2k_t * p_j2k,
+static OPJ_BOOL opj_j2k_build_decoder (opj_j2k_t * p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
{
@@ -6892,7 +7128,7 @@ OPJ_BOOL opj_j2k_build_decoder (opj_j2k_t * p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_build_encoder (opj_j2k_t * p_j2k,
+static OPJ_BOOL opj_j2k_build_encoder (opj_j2k_t * p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
{
@@ -6904,7 +7140,7 @@ OPJ_BOOL opj_j2k_build_encoder (opj_j2k_t * p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_encoding_validation ( opj_j2k_t * p_j2k,
+static OPJ_BOOL opj_j2k_encoding_validation ( opj_j2k_t * p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
{
@@ -6925,12 +7161,20 @@ OPJ_BOOL opj_j2k_encoding_validation ( opj_j2k_t * p_j2k,
/* make sure a validation list is present */
l_is_valid &= (p_j2k->m_validation_list != 00);
- if ((p_j2k->m_cp.tdx) < (OPJ_UINT32) (1 << p_j2k->m_cp.tcps->tccps->numresolutions)) {
+ /* ISO 15444-1:2004 states between 1 & 33 (0 -> 32) */
+ /* 33 (32) would always fail the check below (if a cast to 64bits was done) */
+ /* FIXME Shall we change OPJ_J2K_MAXRLVLS to 32 ? */
+ if ((p_j2k->m_cp.tcps->tccps->numresolutions <= 0) || (p_j2k->m_cp.tcps->tccps->numresolutions > 32)) {
opj_event_msg(p_manager, EVT_ERROR, "Number of resolutions is too high in comparison to the size of tiles\n");
return OPJ_FALSE;
}
- if ((p_j2k->m_cp.tdy) < (OPJ_UINT32) (1 << p_j2k->m_cp.tcps->tccps->numresolutions)) {
+ if ((p_j2k->m_cp.tdx) < (OPJ_UINT32) (1 << (p_j2k->m_cp.tcps->tccps->numresolutions - 1U))) {
+ opj_event_msg(p_manager, EVT_ERROR, "Number of resolutions is too high in comparison to the size of tiles\n");
+ return OPJ_FALSE;
+ }
+
+ if ((p_j2k->m_cp.tdy) < (OPJ_UINT32) (1 << (p_j2k->m_cp.tcps->tccps->numresolutions - 1U))) {
opj_event_msg(p_manager, EVT_ERROR, "Number of resolutions is too high in comparison to the size of tiles\n");
return OPJ_FALSE;
}
@@ -6939,7 +7183,7 @@ OPJ_BOOL opj_j2k_encoding_validation ( opj_j2k_t * p_j2k,
return l_is_valid;
}
-OPJ_BOOL opj_j2k_decoding_validation ( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_decoding_validation ( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager
)
@@ -6969,13 +7213,16 @@ OPJ_BOOL opj_j2k_decoding_validation ( opj_j2k_t *p_j2k,
return l_is_valid;
}
-OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager)
{
OPJ_UINT32 l_current_marker;
OPJ_UINT32 l_marker_size;
const opj_dec_memory_marker_handler_t * l_marker_handler = 00;
+ OPJ_BOOL l_has_siz = 0;
+ OPJ_BOOL l_has_cod = 0;
+ OPJ_BOOL l_has_qcd = 0;
/* preconditions */
assert(p_stream != 00);
@@ -7005,7 +7252,7 @@ OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k,
/* Check if the current marker ID is valid */
if (l_current_marker < 0xff00) {
- opj_event_msg(p_manager, EVT_ERROR, "We expected read a marker ID (0xff--) instead of %.8x\n", l_current_marker);
+ opj_event_msg(p_manager, EVT_ERROR, "A marker ID was expected (0xff--) instead of %.8x\n", l_current_marker);
return OPJ_FALSE;
}
@@ -7025,6 +7272,19 @@ OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k,
l_marker_handler = opj_j2k_get_marker_handler(l_current_marker);
}
+ if (l_marker_handler->id == J2K_MS_SIZ) {
+ /* Mark required SIZ marker as found */
+ l_has_siz = 1;
+ }
+ if (l_marker_handler->id == J2K_MS_COD) {
+ /* Mark required COD marker as found */
+ l_has_cod = 1;
+ }
+ if (l_marker_handler->id == J2K_MS_QCD) {
+ /* Mark required QCD marker as found */
+ l_has_qcd = 1;
+ }
+
/* Check if the marker is known and if it is the right place to find it */
if (! (p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states) ) {
opj_event_msg(p_manager, EVT_ERROR, "Marker is not compliant with its position\n");
@@ -7087,6 +7347,24 @@ OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k,
opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2);
}
+ if (l_has_siz == 0) {
+ opj_event_msg(p_manager, EVT_ERROR, "required SIZ marker not found in main header\n");
+ return OPJ_FALSE;
+ }
+ if (l_has_cod == 0) {
+ opj_event_msg(p_manager, EVT_ERROR, "required COD marker not found in main header\n");
+ return OPJ_FALSE;
+ }
+ if (l_has_qcd == 0) {
+ opj_event_msg(p_manager, EVT_ERROR, "required QCD marker not found in main header\n");
+ return OPJ_FALSE;
+ }
+
+ if (! opj_j2k_merge_ppm(&(p_j2k->m_cp), p_manager)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Failed to merge PPM data\n");
+ return OPJ_FALSE;
+ }
+
opj_event_msg(p_manager, EVT_INFO, "Main header has been correctly decoded.\n");
/* Position of the last element if the main header */
@@ -7098,7 +7376,7 @@ OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_exec ( opj_j2k_t * p_j2k,
+static OPJ_BOOL opj_j2k_exec ( opj_j2k_t * p_j2k,
opj_procedure_list_t * p_procedure_list,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
@@ -7164,8 +7442,15 @@ static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd ( opj_j2k_t * p_j2
/*Copy default coding parameters into the current tile coding parameters*/
memcpy(l_tcp, l_default_tcp, sizeof(opj_tcp_t));
/* Initialize some values of the current tile coding parameters*/
+ l_tcp->cod = 0;
l_tcp->ppt = 0;
l_tcp->ppt_data = 00;
+ /* Remove memory not owned by this tile in case of early error return. */
+ l_tcp->m_mct_decoding_matrix = 00;
+ l_tcp->m_nb_max_mct_records = 0;
+ l_tcp->m_mct_records = 00;
+ l_tcp->m_nb_max_mcc_records = 0;
+ l_tcp->m_mcc_records = 00;
/* Reconnect the tile-compo coding parameters pointer to the current tile coding parameters*/
l_tcp->tccps = l_current_tccp;
@@ -7203,6 +7488,8 @@ static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd ( opj_j2k_t * p_j2
++l_src_mct_rec;
++l_dest_mct_rec;
+ /* Update with each pass to free exactly what has been allocated on early return. */
+ l_tcp->m_nb_max_mct_records += 1;
}
/* Get the mcc_record of the dflt_tile_cp and copy them into the current tile cp*/
@@ -7212,6 +7499,7 @@ static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd ( opj_j2k_t * p_j2
return OPJ_FALSE;
}
memcpy(l_tcp->m_mcc_records,l_default_tcp->m_mcc_records,l_mcc_records_size);
+ l_tcp->m_nb_max_mcc_records = l_default_tcp->m_nb_max_mcc_records;
/* Copy the mcc record data from dflt_tile_cp to the current tile*/
l_src_mcc_rec = l_default_tcp->m_mcc_records;
@@ -7246,7 +7534,7 @@ static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd ( opj_j2k_t * p_j2
return OPJ_FALSE;
}
- if ( !opj_tcd_init(p_j2k->m_tcd, l_image, &(p_j2k->m_cp)) ) {
+ if ( !opj_tcd_init(p_j2k->m_tcd, l_image, &(p_j2k->m_cp), p_j2k->m_tp) ) {
opj_tcd_destroy(p_j2k->m_tcd);
p_j2k->m_tcd = 00;
opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
@@ -7256,7 +7544,7 @@ static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd ( opj_j2k_t * p_j2
return OPJ_TRUE;
}
-const opj_dec_memory_marker_handler_t * opj_j2k_get_marker_handler (OPJ_UINT32 p_id)
+static const opj_dec_memory_marker_handler_t * opj_j2k_get_marker_handler (OPJ_UINT32 p_id)
{
const opj_dec_memory_marker_handler_t *e;
for (e = j2k_memory_marker_handler_tab; e->id != 0; ++e) {
@@ -7327,6 +7615,9 @@ void opj_j2k_destroy (opj_j2k_t *p_j2k)
opj_image_destroy(p_j2k->m_output_image);
p_j2k->m_output_image = NULL;
+ opj_thread_pool_destroy(p_j2k->m_tp);
+ p_j2k->m_tp = NULL;
+
opj_free(p_j2k);
}
@@ -7369,66 +7660,78 @@ void j2k_destroy_cstr_index (opj_codestream_index_t *p_cstr_ind)
}
}
-void opj_j2k_tcp_destroy (opj_tcp_t *p_tcp)
+static void opj_j2k_tcp_destroy (opj_tcp_t *p_tcp)
{
- if (p_tcp == 00) {
- return;
- }
-
- if (p_tcp->ppt_buffer != 00) {
- opj_free(p_tcp->ppt_buffer);
- p_tcp->ppt_buffer = 00;
- }
-
- if (p_tcp->tccps != 00) {
- opj_free(p_tcp->tccps);
- p_tcp->tccps = 00;
- }
-
- if (p_tcp->m_mct_coding_matrix != 00) {
- opj_free(p_tcp->m_mct_coding_matrix);
- p_tcp->m_mct_coding_matrix = 00;
- }
-
- if (p_tcp->m_mct_decoding_matrix != 00) {
- opj_free(p_tcp->m_mct_decoding_matrix);
- p_tcp->m_mct_decoding_matrix = 00;
- }
-
- if (p_tcp->m_mcc_records) {
- opj_free(p_tcp->m_mcc_records);
- p_tcp->m_mcc_records = 00;
- p_tcp->m_nb_max_mcc_records = 0;
- p_tcp->m_nb_mcc_records = 0;
- }
-
- if (p_tcp->m_mct_records) {
- opj_mct_data_t * l_mct_data = p_tcp->m_mct_records;
- OPJ_UINT32 i;
-
- for (i=0;i<p_tcp->m_nb_mct_records;++i) {
- if (l_mct_data->m_data) {
- opj_free(l_mct_data->m_data);
- l_mct_data->m_data = 00;
- }
-
- ++l_mct_data;
- }
-
- opj_free(p_tcp->m_mct_records);
- p_tcp->m_mct_records = 00;
- }
+ if (p_tcp == 00) {
+ return;
+ }
+
+ if (p_tcp->ppt_markers != 00) {
+ OPJ_UINT32 i;
+ for (i = 0U; i < p_tcp->ppt_markers_count; ++i) {
+ if (p_tcp->ppt_markers[i].m_data != NULL) {
+ opj_free(p_tcp->ppt_markers[i].m_data);
+ }
+ }
+ p_tcp->ppt_markers_count = 0U;
+ opj_free(p_tcp->ppt_markers);
+ p_tcp->ppt_markers = NULL;
+ }
+
+ if (p_tcp->ppt_buffer != 00) {
+ opj_free(p_tcp->ppt_buffer);
+ p_tcp->ppt_buffer = 00;
+ }
+
+ if (p_tcp->tccps != 00) {
+ opj_free(p_tcp->tccps);
+ p_tcp->tccps = 00;
+ }
+
+ if (p_tcp->m_mct_coding_matrix != 00) {
+ opj_free(p_tcp->m_mct_coding_matrix);
+ p_tcp->m_mct_coding_matrix = 00;
+ }
+
+ if (p_tcp->m_mct_decoding_matrix != 00) {
+ opj_free(p_tcp->m_mct_decoding_matrix);
+ p_tcp->m_mct_decoding_matrix = 00;
+ }
+
+ if (p_tcp->m_mcc_records) {
+ opj_free(p_tcp->m_mcc_records);
+ p_tcp->m_mcc_records = 00;
+ p_tcp->m_nb_max_mcc_records = 0;
+ p_tcp->m_nb_mcc_records = 0;
+ }
+
+ if (p_tcp->m_mct_records) {
+ opj_mct_data_t * l_mct_data = p_tcp->m_mct_records;
+ OPJ_UINT32 i;
+
+ for (i=0;i<p_tcp->m_nb_mct_records;++i) {
+ if (l_mct_data->m_data) {
+ opj_free(l_mct_data->m_data);
+ l_mct_data->m_data = 00;
+ }
+
+ ++l_mct_data;
+ }
+
+ opj_free(p_tcp->m_mct_records);
+ p_tcp->m_mct_records = 00;
+ }
- if (p_tcp->mct_norms != 00) {
- opj_free(p_tcp->mct_norms);
- p_tcp->mct_norms = 00;
- }
+ if (p_tcp->mct_norms != 00) {
+ opj_free(p_tcp->mct_norms);
+ p_tcp->mct_norms = 00;
+ }
- opj_j2k_tcp_data_destroy(p_tcp);
+ opj_j2k_tcp_data_destroy(p_tcp);
}
-void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp)
+static void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp)
{
if (p_tcp->m_data) {
opj_free(p_tcp->m_data);
@@ -7437,39 +7740,153 @@ void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp)
}
}
-void opj_j2k_cp_destroy (opj_cp_t *p_cp)
+static void opj_j2k_cp_destroy (opj_cp_t *p_cp)
{
- OPJ_UINT32 l_nb_tiles;
- opj_tcp_t * l_current_tile = 00;
- OPJ_UINT32 i;
-
- if (p_cp == 00)
- {
- return;
- }
- if (p_cp->tcps != 00)
- {
- l_current_tile = p_cp->tcps;
- l_nb_tiles = p_cp->th * p_cp->tw;
+ OPJ_UINT32 l_nb_tiles;
+ opj_tcp_t * l_current_tile = 00;
- for (i = 0; i < l_nb_tiles; ++i)
- {
- opj_j2k_tcp_destroy(l_current_tile);
- ++l_current_tile;
- }
- opj_free(p_cp->tcps);
- p_cp->tcps = 00;
- }
- opj_free(p_cp->ppm_buffer);
- p_cp->ppm_buffer = 00;
- p_cp->ppm_data = NULL; /* ppm_data belongs to the allocated buffer pointed by ppm_buffer */
- opj_free(p_cp->comment);
- p_cp->comment = 00;
- if (! p_cp->m_is_decoder)
- {
- opj_free(p_cp->m_specific_param.m_enc.m_matrice);
- p_cp->m_specific_param.m_enc.m_matrice = 00;
- }
+ if (p_cp == 00)
+ {
+ return;
+ }
+ if (p_cp->tcps != 00)
+ {
+ OPJ_UINT32 i;
+ l_current_tile = p_cp->tcps;
+ l_nb_tiles = p_cp->th * p_cp->tw;
+
+ for (i = 0U; i < l_nb_tiles; ++i)
+ {
+ opj_j2k_tcp_destroy(l_current_tile);
+ ++l_current_tile;
+ }
+ opj_free(p_cp->tcps);
+ p_cp->tcps = 00;
+ }
+ if (p_cp->ppm_markers != 00) {
+ OPJ_UINT32 i;
+ for (i = 0U; i < p_cp->ppm_markers_count; ++i) {
+ if (p_cp->ppm_markers[i].m_data != NULL) {
+ opj_free(p_cp->ppm_markers[i].m_data);
+ }
+ }
+ p_cp->ppm_markers_count = 0U;
+ opj_free(p_cp->ppm_markers);
+ p_cp->ppm_markers = NULL;
+ }
+ opj_free(p_cp->ppm_buffer);
+ p_cp->ppm_buffer = 00;
+ p_cp->ppm_data = NULL; /* ppm_data belongs to the allocated buffer pointed by ppm_buffer */
+ opj_free(p_cp->comment);
+ p_cp->comment = 00;
+ if (! p_cp->m_is_decoder)
+ {
+ opj_free(p_cp->m_specific_param.m_enc.m_matrice);
+ p_cp->m_specific_param.m_enc.m_matrice = 00;
+ }
+}
+
+static OPJ_BOOL opj_j2k_need_nb_tile_parts_correction(opj_stream_private_t *p_stream, OPJ_UINT32 tile_no, OPJ_BOOL* p_correction_needed, opj_event_mgr_t * p_manager )
+{
+ OPJ_BYTE l_header_data[10];
+ OPJ_OFF_T l_stream_pos_backup;
+ OPJ_UINT32 l_current_marker;
+ OPJ_UINT32 l_marker_size;
+ OPJ_UINT32 l_tile_no, l_tot_len, l_current_part, l_num_parts;
+
+ /* initialize to no correction needed */
+ *p_correction_needed = OPJ_FALSE;
+
+ if (!opj_stream_has_seek(p_stream)) {
+ /* We can't do much in this case, seek is needed */
+ return OPJ_TRUE;
+ }
+
+ l_stream_pos_backup = opj_stream_tell(p_stream);
+ if (l_stream_pos_backup == -1) {
+ /* let's do nothing */
+ return OPJ_TRUE;
+ }
+
+ for (;;) {
+ /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */
+ if (opj_stream_read_data(p_stream,l_header_data, 2, p_manager) != 2) {
+ /* assume all is OK */
+ if (! opj_stream_seek(p_stream, l_stream_pos_backup, p_manager)) {
+ return OPJ_FALSE;
+ }
+ return OPJ_TRUE;
+ }
+
+ /* Read 2 bytes from buffer as the new marker ID */
+ opj_read_bytes(l_header_data, &l_current_marker, 2);
+
+ if (l_current_marker != J2K_MS_SOT) {
+ /* assume all is OK */
+ if (! opj_stream_seek(p_stream, l_stream_pos_backup, p_manager)) {
+ return OPJ_FALSE;
+ }
+ return OPJ_TRUE;
+ }
+
+ /* Try to read 2 bytes (the marker size) from stream and copy them into the buffer */
+ if (opj_stream_read_data(p_stream, l_header_data, 2, p_manager) != 2) {
+ opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
+ return OPJ_FALSE;
+ }
+
+ /* Read 2 bytes from the buffer as the marker size */
+ opj_read_bytes(l_header_data, &l_marker_size, 2);
+
+ /* Check marker size for SOT Marker */
+ if (l_marker_size != 10) {
+ opj_event_msg(p_manager, EVT_ERROR, "Inconsistent marker size\n");
+ return OPJ_FALSE;
+ }
+ l_marker_size -= 2;
+
+ if (opj_stream_read_data(p_stream, l_header_data, l_marker_size, p_manager) != l_marker_size) {
+ opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
+ return OPJ_FALSE;
+ }
+
+ if (! opj_j2k_get_sot_values(l_header_data, l_marker_size, &l_tile_no, &l_tot_len, &l_current_part, &l_num_parts, p_manager)) {
+ return OPJ_FALSE;
+ }
+
+ if (l_tile_no == tile_no) {
+ /* we found what we were looking for */
+ break;
+ }
+
+ if ((l_tot_len == 0U) || (l_tot_len < 14U)) {
+ /* last SOT until EOC or invalid Psot value */
+ /* assume all is OK */
+ if (! opj_stream_seek(p_stream, l_stream_pos_backup, p_manager)) {
+ return OPJ_FALSE;
+ }
+ return OPJ_TRUE;
+ }
+ l_tot_len -= 12U;
+ /* look for next SOT marker */
+ if (opj_stream_skip(p_stream, (OPJ_OFF_T)(l_tot_len), p_manager) != (OPJ_OFF_T)(l_tot_len)) {
+ /* assume all is OK */
+ if (! opj_stream_seek(p_stream, l_stream_pos_backup, p_manager)) {
+ return OPJ_FALSE;
+ }
+ return OPJ_TRUE;
+ }
+ }
+
+ /* check for correction */
+ if (l_current_part == l_num_parts) {
+ *p_correction_needed = OPJ_TRUE;
+ }
+
+ if (! opj_stream_seek(p_stream, l_stream_pos_backup, p_manager)) {
+ return OPJ_FALSE;
+ }
+ return OPJ_TRUE;
}
OPJ_BOOL opj_j2k_read_tile_header( opj_j2k_t * p_j2k,
@@ -7486,7 +7903,6 @@ OPJ_BOOL opj_j2k_read_tile_header( opj_j2k_t * p_j2k,
OPJ_UINT32 l_marker_size;
const opj_dec_memory_marker_handler_t * l_marker_handler = 00;
opj_tcp_t * l_tcp = NULL;
- OPJ_UINT32 l_nb_tiles;
/* preconditions */
assert(p_stream != 00);
@@ -7523,6 +7939,12 @@ OPJ_BOOL opj_j2k_read_tile_header( opj_j2k_t * p_j2k,
/* Read 2 bytes from the buffer as the marker size */
opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_marker_size,2);
+ /* Check marker size (does not include marker ID but includes marker size) */
+ if (l_marker_size < 2) {
+ opj_event_msg(p_manager, EVT_ERROR, "Inconsistent marker size\n");
+ return OPJ_FALSE;
+ }
+
/* cf. https://code.google.com/p/openjpeg/issues/detail?id=226 */
if (l_current_marker == 0x8080 && opj_stream_get_number_byte_left(p_stream) == 0) {
p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
@@ -7547,7 +7969,14 @@ OPJ_BOOL opj_j2k_read_tile_header( opj_j2k_t * p_j2k,
/* Check if the marker size is compatible with the header data size */
if (l_marker_size > p_j2k->m_specific_param.m_decoder.m_header_data_size) {
- OPJ_BYTE *new_header_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_decoder.m_header_data, l_marker_size);
+ OPJ_BYTE *new_header_data = NULL;
+ /* If we are here, this means we consider this marker as known & we will read it */
+ /* Check enough bytes left in stream before allocation */
+ if ((OPJ_OFF_T)l_marker_size > opj_stream_get_number_byte_left(p_stream)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Marker size inconsistent with stream length\n");
+ return OPJ_FALSE;
+ }
+ new_header_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_decoder.m_header_data, l_marker_size);
if (! new_header_data) {
opj_free(p_j2k->m_specific_param.m_decoder.m_header_data);
p_j2k->m_specific_param.m_decoder.m_header_data = NULL;
@@ -7623,7 +8052,30 @@ OPJ_BOOL opj_j2k_read_tile_header( opj_j2k_t * p_j2k,
if (! opj_j2k_read_sod(p_j2k, p_stream, p_manager)) {
return OPJ_FALSE;
}
-
+ if (p_j2k->m_specific_param.m_decoder.m_can_decode && !p_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction_checked) {
+ /* Issue 254 */
+ OPJ_BOOL l_correction_needed;
+
+ p_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction_checked = 1;
+ if(!opj_j2k_need_nb_tile_parts_correction(p_stream, p_j2k->m_current_tile_number, &l_correction_needed, p_manager)) {
+ opj_event_msg(p_manager, EVT_ERROR, "opj_j2k_apply_nb_tile_parts_correction error\n");
+ return OPJ_FALSE;
+ }
+ if (l_correction_needed) {
+ OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th;
+ OPJ_UINT32 l_tile_no;
+
+ p_j2k->m_specific_param.m_decoder.m_can_decode = 0;
+ p_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction = 1;
+ /* correct tiles */
+ for (l_tile_no = 0U; l_tile_no < l_nb_tiles; ++l_tile_no) {
+ if (p_j2k->m_cp.tcps[l_tile_no].m_nb_tile_parts != 0U) {
+ p_j2k->m_cp.tcps[l_tile_no].m_nb_tile_parts+=1;
+ }
+ }
+ opj_event_msg(p_manager, EVT_WARNING, "Non conformant codestream TPsot==TNsot.\n");
+ }
+ }
if (! p_j2k->m_specific_param.m_decoder.m_can_decode){
/* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer */
if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
@@ -7662,8 +8114,8 @@ OPJ_BOOL opj_j2k_read_tile_header( opj_j2k_t * p_j2k,
/* FIXME DOC ???*/
if ( ! p_j2k->m_specific_param.m_decoder.m_can_decode) {
+ OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
l_tcp = p_j2k->m_cp.tcps + p_j2k->m_current_tile_number;
- l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
while( (p_j2k->m_current_tile_number < l_nb_tiles) && (l_tcp->m_data == 00) ) {
++p_j2k->m_current_tile_number;
@@ -7676,14 +8128,18 @@ OPJ_BOOL opj_j2k_read_tile_header( opj_j2k_t * p_j2k,
}
}
+ if (! opj_j2k_merge_ppt(p_j2k->m_cp.tcps + p_j2k->m_current_tile_number, p_manager)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Failed to merge PPT data\n");
+ return OPJ_FALSE;
+ }
/*FIXME ???*/
- if (! opj_tcd_init_decode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number)) {
+ if (! opj_tcd_init_decode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number, p_manager)) {
opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
return OPJ_FALSE;
}
opj_event_msg(p_manager, EVT_INFO, "Header of tile %d / %d has been read.\n",
- p_j2k->m_current_tile_number, (p_j2k->m_cp.th * p_j2k->m_cp.tw) - 1);
+ p_j2k->m_current_tile_number+1, (p_j2k->m_cp.th * p_j2k->m_cp.tw));
*p_tile_index = p_j2k->m_current_tile_number;
*p_go_on = OPJ_TRUE;
@@ -7730,7 +8186,7 @@ OPJ_BOOL opj_j2k_decode_tile ( opj_j2k_t * p_j2k,
l_tcp->m_data,
l_tcp->m_data_size,
p_tile_index,
- p_j2k->cstr_index) ) {
+ p_j2k->cstr_index, p_manager) ) {
opj_j2k_tcp_destroy(l_tcp);
p_j2k->m_specific_param.m_decoder.m_state |= 0x8000;/*FIXME J2K_DEC_STATE_ERR;*/
opj_event_msg(p_manager, EVT_ERROR, "Failed to decode.\n");
@@ -7768,13 +8224,13 @@ OPJ_BOOL opj_j2k_decode_tile ( opj_j2k_t * p_j2k,
p_j2k->m_specific_param.m_decoder.m_state = 0x0100;/*FIXME J2K_DEC_STATE_EOC;*/
}
else if (l_current_marker != J2K_MS_SOT)
- {
- opj_event_msg(p_manager, EVT_ERROR, "Stream too short, expected SOT\n");
-
+ {
if(opj_stream_get_number_byte_left(p_stream) == 0) {
p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
+ opj_event_msg(p_manager, EVT_WARNING, "Stream does not end with EOC\n");
return OPJ_TRUE;
}
+ opj_event_msg(p_manager, EVT_ERROR, "Stream too short, expected SOT\n");
return OPJ_FALSE;
}
}
@@ -7782,16 +8238,16 @@ OPJ_BOOL opj_j2k_decode_tile ( opj_j2k_t * p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image)
+static OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image)
{
OPJ_UINT32 i,j,k = 0;
OPJ_UINT32 l_width_src,l_height_src;
OPJ_UINT32 l_width_dest,l_height_dest;
OPJ_INT32 l_offset_x0_src, l_offset_y0_src, l_offset_x1_src, l_offset_y1_src;
- OPJ_INT32 l_start_offset_src, l_line_offset_src, l_end_offset_src ;
+ OPJ_SIZE_T l_start_offset_src, l_line_offset_src, l_end_offset_src ;
OPJ_UINT32 l_start_x_dest , l_start_y_dest;
OPJ_UINT32 l_x0_dest, l_y0_dest, l_x1_dest, l_y1_dest;
- OPJ_INT32 l_start_offset_dest, l_line_offset_dest;
+ OPJ_SIZE_T l_start_offset_dest, l_line_offset_dest;
opj_image_comp_t * l_img_comp_src = 00;
opj_image_comp_t * l_img_comp_dest = 00;
@@ -7812,8 +8268,14 @@ OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_im
/* Allocate output component buffer if necessary */
if (!l_img_comp_dest->data) {
+ OPJ_SIZE_T l_width = l_img_comp_dest->w;
+ OPJ_SIZE_T l_height = l_img_comp_dest->h;
- l_img_comp_dest->data = (OPJ_INT32*) opj_calloc(l_img_comp_dest->w * l_img_comp_dest->h, sizeof(OPJ_INT32));
+ if ((l_height == 0U) || (l_width > (SIZE_MAX / l_height))) {
+ /* would overflow */
+ return OPJ_FALSE;
+ }
+ l_img_comp_dest->data = (OPJ_INT32*) opj_calloc(l_width * l_height, sizeof(OPJ_INT32));
if (! l_img_comp_dest->data) {
return OPJ_FALSE;
}
@@ -7847,9 +8309,9 @@ OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_im
l_height_src = (OPJ_UINT32)(l_res->y1 - l_res->y0);
/* Border of the current output component*/
- l_x0_dest = (OPJ_UINT32)opj_int_ceildivpow2((OPJ_INT32)l_img_comp_dest->x0, (OPJ_INT32)l_img_comp_dest->factor);
- l_y0_dest = (OPJ_UINT32)opj_int_ceildivpow2((OPJ_INT32)l_img_comp_dest->y0, (OPJ_INT32)l_img_comp_dest->factor);
- l_x1_dest = l_x0_dest + l_img_comp_dest->w;
+ l_x0_dest = opj_uint_ceildivpow2(l_img_comp_dest->x0, l_img_comp_dest->factor);
+ l_y0_dest = opj_uint_ceildivpow2(l_img_comp_dest->y0, l_img_comp_dest->factor);
+ l_x1_dest = l_x0_dest + l_img_comp_dest->w; /* can't overflow given that image->x1 is uint32 */
l_y1_dest = l_y0_dest + l_img_comp_dest->h;
/*if (i == 0) {
@@ -7880,7 +8342,7 @@ OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_im
}
}
else {
- l_start_x_dest = 0 ;
+ l_start_x_dest = 0U;
l_offset_x0_src = (OPJ_INT32)l_x0_dest - l_res->x0;
if ( l_x1_dest >= (OPJ_UINT32)l_res->x1 ) {
@@ -7907,7 +8369,7 @@ OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_im
}
}
else {
- l_start_y_dest = 0 ;
+ l_start_y_dest = 0U;
l_offset_y0_src = (OPJ_INT32)l_y0_dest - l_res->y0;
if ( l_y1_dest >= (OPJ_UINT32)l_res->y1 ) {
@@ -7930,13 +8392,13 @@ OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_im
/*-----*/
/* Compute the input buffer offset */
- l_start_offset_src = l_offset_x0_src + l_offset_y0_src * (OPJ_INT32)l_width_src;
- l_line_offset_src = l_offset_x1_src + l_offset_x0_src;
- l_end_offset_src = l_offset_y1_src * (OPJ_INT32)l_width_src - l_offset_x0_src;
+ l_start_offset_src = (OPJ_SIZE_T)l_offset_x0_src + (OPJ_SIZE_T)l_offset_y0_src * (OPJ_SIZE_T)l_width_src;
+ l_line_offset_src = (OPJ_SIZE_T)l_offset_x1_src + (OPJ_SIZE_T)l_offset_x0_src;
+ l_end_offset_src = (OPJ_SIZE_T)l_offset_y1_src * (OPJ_SIZE_T)l_width_src - (OPJ_SIZE_T)l_offset_x0_src;
/* Compute the output buffer offset */
- l_start_offset_dest = (OPJ_INT32)(l_start_x_dest + l_start_y_dest * l_img_comp_dest->w);
- l_line_offset_dest = (OPJ_INT32)(l_img_comp_dest->w - l_width_dest);
+ l_start_offset_dest = (OPJ_SIZE_T)l_start_x_dest + (OPJ_SIZE_T)l_start_y_dest * (OPJ_SIZE_T)l_img_comp_dest->w;
+ l_line_offset_dest = (OPJ_SIZE_T)l_img_comp_dest->w - (OPJ_SIZE_T)l_width_dest;
/* Move the output buffer to the first place where we will write*/
l_dest_ptr = l_img_comp_dest->data + l_start_offset_dest;
@@ -8202,23 +8664,25 @@ OPJ_BOOL opj_j2k_set_decode_area( opj_j2k_t *p_j2k,
opj_j2k_t* opj_j2k_create_decompress(void)
{
- opj_j2k_t *l_j2k = (opj_j2k_t*) opj_malloc(sizeof(opj_j2k_t));
+ opj_j2k_t *l_j2k = (opj_j2k_t*) opj_calloc(1,sizeof(opj_j2k_t));
if (!l_j2k) {
return 00;
}
- memset(l_j2k,0,sizeof(opj_j2k_t));
l_j2k->m_is_decoder = 1;
l_j2k->m_cp.m_is_decoder = 1;
- l_j2k->m_specific_param.m_decoder.m_default_tcp = (opj_tcp_t*) opj_malloc(sizeof(opj_tcp_t));
+#ifdef OPJ_DISABLE_TPSOT_FIX
+ l_j2k->m_specific_param.m_decoder.m_nb_tile_parts_correction_checked = 1;
+#endif
+
+ l_j2k->m_specific_param.m_decoder.m_default_tcp = (opj_tcp_t*) opj_calloc(1,sizeof(opj_tcp_t));
if (!l_j2k->m_specific_param.m_decoder.m_default_tcp) {
opj_j2k_destroy(l_j2k);
return 00;
}
- memset(l_j2k->m_specific_param.m_decoder.m_default_tcp,0,sizeof(opj_tcp_t));
- l_j2k->m_specific_param.m_decoder.m_header_data = (OPJ_BYTE *) opj_malloc(OPJ_J2K_DEFAULT_HEADER_SIZE);
+ l_j2k->m_specific_param.m_decoder.m_header_data = (OPJ_BYTE *) opj_calloc(1,OPJ_J2K_DEFAULT_HEADER_SIZE);
if (! l_j2k->m_specific_param.m_decoder.m_header_data) {
opj_j2k_destroy(l_j2k);
return 00;
@@ -8232,16 +8696,11 @@ opj_j2k_t* opj_j2k_create_decompress(void)
/* codestream index creation */
l_j2k->cstr_index = opj_j2k_create_cstr_index();
-
- /*(opj_codestream_index_t*) opj_malloc(sizeof(opj_codestream_index_t));
if (!l_j2k->cstr_index){
opj_j2k_destroy(l_j2k);
- return NULL;
+ return 00;
}
- l_j2k->cstr_index->marker = (opj_marker_info_t*) opj_malloc(100 * sizeof(opj_marker_info_t));
-*/
-
/* validation list creation */
l_j2k->m_validation_list = opj_procedure_list_create();
if (! l_j2k->m_validation_list) {
@@ -8256,10 +8715,21 @@ opj_j2k_t* opj_j2k_create_decompress(void)
return 00;
}
+ l_j2k->m_tp = opj_thread_pool_create(opj_j2k_get_default_thread_count());
+ if( !l_j2k->m_tp )
+ {
+ l_j2k->m_tp = opj_thread_pool_create(0);
+ }
+ if( !l_j2k->m_tp )
+ {
+ opj_j2k_destroy(l_j2k);
+ return NULL;
+ }
+
return l_j2k;
}
-opj_codestream_index_t* opj_j2k_create_cstr_index(void)
+static opj_codestream_index_t* opj_j2k_create_cstr_index(void)
{
opj_codestream_index_t* cstr_index = (opj_codestream_index_t*)
opj_calloc(1,sizeof(opj_codestream_index_t));
@@ -8270,15 +8740,17 @@ opj_codestream_index_t* opj_j2k_create_cstr_index(void)
cstr_index->marknum = 0;
cstr_index->marker = (opj_marker_info_t*)
opj_calloc(cstr_index->maxmarknum, sizeof(opj_marker_info_t));
- if (!cstr_index-> marker)
+ if (!cstr_index-> marker) {
+ opj_free(cstr_index);
return NULL;
+ }
cstr_index->tile_index = NULL;
return cstr_index;
}
-OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size ( opj_j2k_t *p_j2k,
+static OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size ( opj_j2k_t *p_j2k,
OPJ_UINT32 p_tile_no,
OPJ_UINT32 p_comp_no )
{
@@ -8305,7 +8777,53 @@ OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size ( opj_j2k_t *p_j2k,
}
}
-OPJ_BOOL opj_j2k_write_SPCod_SPCoc( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_compare_SPCod_SPCoc(opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no)
+{
+ OPJ_UINT32 i;
+ opj_cp_t *l_cp = NULL;
+ opj_tcp_t *l_tcp = NULL;
+ opj_tccp_t *l_tccp0 = NULL;
+ opj_tccp_t *l_tccp1 = NULL;
+
+ /* preconditions */
+ assert(p_j2k != 00);
+
+ l_cp = &(p_j2k->m_cp);
+ l_tcp = &l_cp->tcps[p_tile_no];
+ l_tccp0 = &l_tcp->tccps[p_first_comp_no];
+ l_tccp1 = &l_tcp->tccps[p_second_comp_no];
+
+ if (l_tccp0->numresolutions != l_tccp1->numresolutions) {
+ return OPJ_FALSE;
+ }
+ if (l_tccp0->cblkw != l_tccp1->cblkw) {
+ return OPJ_FALSE;
+ }
+ if (l_tccp0->cblkh != l_tccp1->cblkh) {
+ return OPJ_FALSE;
+ }
+ if (l_tccp0->cblksty != l_tccp1->cblksty) {
+ return OPJ_FALSE;
+ }
+ if (l_tccp0->qmfbid != l_tccp1->qmfbid) {
+ return OPJ_FALSE;
+ }
+ if ((l_tccp0->csty & J2K_CCP_CSTY_PRT) != (l_tccp1->csty & J2K_CCP_CSTY_PRT)) {
+ return OPJ_FALSE;
+ }
+
+ for (i = 0U; i < l_tccp0->numresolutions; ++i) {
+ if (l_tccp0->prcw[i] != l_tccp1->prcw[i]) {
+ return OPJ_FALSE;
+ }
+ if (l_tccp0->prch[i] != l_tccp1->prch[i]) {
+ return OPJ_FALSE;
+ }
+ }
+ return OPJ_TRUE;
+}
+
+static OPJ_BOOL opj_j2k_write_SPCod_SPCoc( opj_j2k_t *p_j2k,
OPJ_UINT32 p_tile_no,
OPJ_UINT32 p_comp_no,
OPJ_BYTE * p_data,
@@ -8371,7 +8889,7 @@ OPJ_BOOL opj_j2k_write_SPCod_SPCoc( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_read_SPCod_SPCoc( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_read_SPCod_SPCoc( opj_j2k_t *p_j2k,
OPJ_UINT32 compno,
OPJ_BYTE * p_header_data,
OPJ_UINT32 * p_header_size,
@@ -8431,8 +8949,18 @@ OPJ_BOOL opj_j2k_read_SPCod_SPCoc( opj_j2k_t *p_j2k,
++l_current_ptr;
l_tccp->cblkh += 2;
+ if ((l_tccp->cblkw > 10) || (l_tccp->cblkh > 10) || ((l_tccp->cblkw + l_tccp->cblkh) > 12)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Error reading SPCod SPCoc element, Invalid cblkw/cblkh combination\n");
+ return OPJ_FALSE;
+ }
+
+
opj_read_bytes(l_current_ptr,&l_tccp->cblksty ,1); /* SPcoc (G) */
++l_current_ptr;
+ if (l_tccp->cblksty & 0xC0U) { /* 2 msb are reserved, assume we can't read */
+ opj_event_msg(p_manager, EVT_ERROR, "Error reading SPCod SPCoc element, Invalid code-block style found\n");
+ return OPJ_FALSE;
+ }
opj_read_bytes(l_current_ptr,&l_tccp->qmfbid ,1); /* SPcoc (H) */
++l_current_ptr;
@@ -8449,6 +8977,11 @@ OPJ_BOOL opj_j2k_read_SPCod_SPCoc( opj_j2k_t *p_j2k,
for (i = 0; i < l_tccp->numresolutions; ++i) {
opj_read_bytes(l_current_ptr,&l_tmp ,1); /* SPcoc (I_i) */
++l_current_ptr;
+ /* Precinct exponent 0 is only allowed for lowest resolution level (Table A.21) */
+ if ((i != 0) && (((l_tmp & 0xf) == 0) || ((l_tmp >> 4) == 0))) {
+ opj_event_msg(p_manager, EVT_ERROR, "Invalid precinct size\n");
+ return OPJ_FALSE;
+ }
l_tccp->prcw[i] = l_tmp & 0xf;
l_tccp->prch[i] = l_tmp >> 4;
}
@@ -8483,7 +9016,7 @@ OPJ_BOOL opj_j2k_read_SPCod_SPCoc( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-void opj_j2k_copy_tile_component_parameters( opj_j2k_t *p_j2k )
+static void opj_j2k_copy_tile_component_parameters( opj_j2k_t *p_j2k )
{
/* loop */
OPJ_UINT32 i;
@@ -8516,7 +9049,7 @@ void opj_j2k_copy_tile_component_parameters( opj_j2k_t *p_j2k )
}
}
-OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size ( opj_j2k_t *p_j2k,
+static OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size ( opj_j2k_t *p_j2k,
OPJ_UINT32 p_tile_no,
OPJ_UINT32 p_comp_no )
{
@@ -8547,7 +9080,55 @@ OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size ( opj_j2k_t *p_j2k,
}
}
-OPJ_BOOL opj_j2k_write_SQcd_SQcc( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_compare_SQcd_SQcc(opj_j2k_t *p_j2k, OPJ_UINT32 p_tile_no, OPJ_UINT32 p_first_comp_no, OPJ_UINT32 p_second_comp_no)
+{
+ opj_cp_t *l_cp = NULL;
+ opj_tcp_t *l_tcp = NULL;
+ opj_tccp_t *l_tccp0 = NULL;
+ opj_tccp_t *l_tccp1 = NULL;
+ OPJ_UINT32 l_band_no, l_num_bands;
+
+ /* preconditions */
+ assert(p_j2k != 00);
+
+ l_cp = &(p_j2k->m_cp);
+ l_tcp = &l_cp->tcps[p_tile_no];
+ l_tccp0 = &l_tcp->tccps[p_first_comp_no];
+ l_tccp1 = &l_tcp->tccps[p_second_comp_no];
+
+ if (l_tccp0->qntsty != l_tccp1->qntsty ) {
+ return OPJ_FALSE;
+ }
+ if (l_tccp0->numgbits != l_tccp1->numgbits ) {
+ return OPJ_FALSE;
+ }
+ if (l_tccp0->qntsty == J2K_CCP_QNTSTY_SIQNT) {
+ l_num_bands = 1U;
+ } else {
+ l_num_bands = l_tccp0->numresolutions * 3U - 2U;
+ if (l_num_bands != (l_tccp1->numresolutions * 3U - 2U)) {
+ return OPJ_FALSE;
+ }
+ }
+
+ for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) {
+ if (l_tccp0->stepsizes[l_band_no].expn != l_tccp1->stepsizes[l_band_no].expn ) {
+ return OPJ_FALSE;
+ }
+ }
+ if (l_tccp0->qntsty != J2K_CCP_QNTSTY_NOQNT)
+ {
+ for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) {
+ if (l_tccp0->stepsizes[l_band_no].mant != l_tccp1->stepsizes[l_band_no].mant ) {
+ return OPJ_FALSE;
+ }
+ }
+ }
+ return OPJ_TRUE;
+}
+
+
+static OPJ_BOOL opj_j2k_write_SQcd_SQcc( opj_j2k_t *p_j2k,
OPJ_UINT32 p_tile_no,
OPJ_UINT32 p_comp_no,
OPJ_BYTE * p_data,
@@ -8620,7 +9201,7 @@ OPJ_BOOL opj_j2k_write_SQcd_SQcc( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k,
OPJ_UINT32 p_comp_no,
OPJ_BYTE* p_header_data,
OPJ_UINT32 * p_header_size,
@@ -8737,7 +9318,7 @@ OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-void opj_j2k_copy_tile_quantization_parameters( opj_j2k_t *p_j2k )
+static void opj_j2k_copy_tile_quantization_parameters( opj_j2k_t *p_j2k )
{
OPJ_UINT32 i;
opj_cp_t *l_cp = NULL;
@@ -8834,16 +9415,19 @@ void j2k_dump (opj_j2k_t* p_j2k, OPJ_INT32 flag, FILE* out_stream)
/* Dump the codestream info from main header */
if (flag & OPJ_J2K_MH_INFO){
- opj_j2k_dump_MH_info(p_j2k, out_stream);
+ if (p_j2k->m_private_image)
+ opj_j2k_dump_MH_info(p_j2k, out_stream);
}
/* Dump all tile/codestream info */
if (flag & OPJ_J2K_TCH_INFO){
OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
OPJ_UINT32 i;
opj_tcp_t * l_tcp = p_j2k->m_cp.tcps;
- for (i=0;i<l_nb_tiles;++i) {
- opj_j2k_dump_tile_info( l_tcp,(OPJ_INT32)p_j2k->m_private_image->numcomps, out_stream);
- ++l_tcp;
+ if (p_j2k->m_private_image) {
+ for (i=0;i<l_nb_tiles;++i) {
+ opj_j2k_dump_tile_info( l_tcp,(OPJ_INT32)p_j2k->m_private_image->numcomps, out_stream);
+ ++l_tcp;
+ }
}
}
@@ -8864,7 +9448,7 @@ void j2k_dump (opj_j2k_t* p_j2k, OPJ_INT32 flag, FILE* out_stream)
}
-void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream)
+static void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream)
{
opj_codestream_index_t* cstr_index = p_j2k->cstr_index;
OPJ_UINT32 it_marker, it_tile, it_tile_part;
@@ -8933,7 +9517,7 @@ void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream)
}
-void opj_j2k_dump_MH_info(opj_j2k_t* p_j2k, FILE* out_stream)
+static void opj_j2k_dump_MH_info(opj_j2k_t* p_j2k, FILE* out_stream)
{
fprintf(out_stream, "Codestream info from main header: {\n");
@@ -9173,7 +9757,7 @@ opj_codestream_index_t* j2k_get_cstr_index(opj_j2k_t* p_j2k)
return l_cstr_index;
}
-OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k)
+static OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k)
{
OPJ_UINT32 it_tile=0;
@@ -9194,7 +9778,7 @@ OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k)
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager)
{
@@ -9213,7 +9797,7 @@ OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k,
}
l_max_data_size = 1000;
- while (OPJ_TRUE) {
+ for (;;) {
if (! opj_j2k_read_tile_header( p_j2k,
&l_current_tile_no,
&l_data_size,
@@ -9270,14 +9854,18 @@ OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k,
/**
* Sets up the procedures to do on decoding data. Developpers wanting to extend the library can add their own reading procedures.
*/
-static void opj_j2k_setup_decoding (opj_j2k_t *p_j2k)
+static OPJ_BOOL opj_j2k_setup_decoding (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager)
{
/* preconditions*/
assert(p_j2k != 00);
+ assert(p_manager != 00);
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_decode_tiles);
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_decode_tiles, p_manager)) {
+ return OPJ_FALSE;
+ }
/* DEVELOPER CORNER, add your custom procedures */
+ return OPJ_TRUE;
}
/*
@@ -9320,14 +9908,14 @@ static OPJ_BOOL opj_j2k_decode_one_tile ( opj_j2k_t *p_j2k,
* so move to the last SOT read */
if ( !(opj_stream_read_seek(p_stream, p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos+2, p_manager)) ){
opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n");
- opj_free(l_current_data);
+ opj_free(l_current_data);
return OPJ_FALSE;
}
}
else{
if ( !(opj_stream_read_seek(p_stream, p_j2k->cstr_index->tile_index[l_tile_no_to_dec].tp_index[0].start_pos+2, p_manager)) ) {
opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n");
- opj_free(l_current_data);
+ opj_free(l_current_data);
return OPJ_FALSE;
}
}
@@ -9336,7 +9924,7 @@ static OPJ_BOOL opj_j2k_decode_one_tile ( opj_j2k_t *p_j2k,
p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;
}
- while (OPJ_TRUE) {
+ for (;;) {
if (! opj_j2k_read_tile_header( p_j2k,
&l_current_tile_no,
&l_data_size,
@@ -9359,9 +9947,7 @@ static OPJ_BOOL opj_j2k_decode_one_tile ( opj_j2k_t *p_j2k,
if (! l_new_current_data) {
opj_free(l_current_data);
l_current_data = NULL;
- /* TODO: LH: why tile numbering policy used in messages differs from
- the one used in opj_j2k_decode_tiles() ? */
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode tile %d/%d\n", l_current_tile_no, (p_j2k->m_cp.th * p_j2k->m_cp.tw) - 1);
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode tile %d/%d\n", l_current_tile_no+1, p_j2k->m_cp.th * p_j2k->m_cp.tw);
return OPJ_FALSE;
}
l_current_data = l_new_current_data;
@@ -9372,25 +9958,26 @@ static OPJ_BOOL opj_j2k_decode_one_tile ( opj_j2k_t *p_j2k,
opj_free(l_current_data);
return OPJ_FALSE;
}
- opj_event_msg(p_manager, EVT_INFO, "Tile %d/%d has been decoded.\n", l_current_tile_no, (p_j2k->m_cp.th * p_j2k->m_cp.tw) - 1);
+ opj_event_msg(p_manager, EVT_INFO, "Tile %d/%d has been decoded.\n", l_current_tile_no+1, p_j2k->m_cp.th * p_j2k->m_cp.tw);
if (! opj_j2k_update_image_data(p_j2k->m_tcd,l_current_data, p_j2k->m_output_image)) {
opj_free(l_current_data);
return OPJ_FALSE;
}
- opj_event_msg(p_manager, EVT_INFO, "Image data has been updated with tile %d.\n\n", l_current_tile_no);
+ opj_event_msg(p_manager, EVT_INFO, "Image data has been updated with tile %d.\n\n", l_current_tile_no+1);
if(l_current_tile_no == l_tile_no_to_dec)
{
- /* move into the codestream to the the first SOT (FIXME or not move?)*/
+ /* move into the codestream to the first SOT (FIXME or not move?)*/
if (!(opj_stream_read_seek(p_stream, p_j2k->cstr_index->main_head_end + 2, p_manager) ) ) {
opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n");
+ opj_free(l_current_data);
return OPJ_FALSE;
}
break;
}
else {
- opj_event_msg(p_manager, EVT_WARNING, "Tile read, decode and updated is not the desired (%d vs %d).\n", l_current_tile_no, l_tile_no_to_dec);
+ opj_event_msg(p_manager, EVT_WARNING, "Tile read, decoded and updated is not the desired one (%d vs %d).\n", l_current_tile_no+1, l_tile_no_to_dec+1);
}
}
@@ -9403,14 +9990,18 @@ static OPJ_BOOL opj_j2k_decode_one_tile ( opj_j2k_t *p_j2k,
/**
* Sets up the procedures to do on decoding one tile. Developpers wanting to extend the library can add their own reading procedures.
*/
-static void opj_j2k_setup_decoding_tile (opj_j2k_t *p_j2k)
+static OPJ_BOOL opj_j2k_setup_decoding_tile (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager)
{
/* preconditions*/
assert(p_j2k != 00);
+ assert(p_manager != 00);
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_decode_one_tile);
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_decode_one_tile, p_manager)) {
+ return OPJ_FALSE;
+ }
/* DEVELOPER CORNER, add your custom procedures */
+ return OPJ_TRUE;
}
OPJ_BOOL opj_j2k_decode(opj_j2k_t * p_j2k,
@@ -9422,7 +10013,7 @@ OPJ_BOOL opj_j2k_decode(opj_j2k_t * p_j2k,
if (!p_image)
return OPJ_FALSE;
-
+
p_j2k->m_output_image = opj_image_create0();
if (! (p_j2k->m_output_image)) {
return OPJ_FALSE;
@@ -9430,7 +10021,7 @@ OPJ_BOOL opj_j2k_decode(opj_j2k_t * p_j2k,
opj_copy_image_header(p_image, p_j2k->m_output_image);
/* customization of the decoding */
- opj_j2k_setup_decoding(p_j2k);
+ opj_j2k_setup_decoding(p_j2k, p_manager);
/* Decode the codestream */
if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
@@ -9526,7 +10117,7 @@ OPJ_BOOL opj_j2k_get_tile( opj_j2k_t *p_j2k,
p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec = (OPJ_INT32)tile_index;
/* customization of the decoding */
- opj_j2k_setup_decoding_tile(p_j2k);
+ opj_j2k_setup_decoding_tile(p_j2k, p_manager);
/* Decode the codestream */
if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
@@ -9583,50 +10174,97 @@ OPJ_BOOL opj_j2k_encode(opj_j2k_t * p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
{
- OPJ_UINT32 i;
+ OPJ_UINT32 i, j;
OPJ_UINT32 l_nb_tiles;
- OPJ_UINT32 l_max_tile_size, l_current_tile_size;
- OPJ_BYTE * l_current_data;
+ OPJ_UINT32 l_max_tile_size = 0, l_current_tile_size;
+ OPJ_BYTE * l_current_data = 00;
+ OPJ_BOOL l_reuse_data = OPJ_FALSE;
+ opj_tcd_t* p_tcd = 00;
/* preconditions */
assert(p_j2k != 00);
assert(p_stream != 00);
assert(p_manager != 00);
-
- l_current_data = (OPJ_BYTE*)opj_malloc(1000);
- if (! l_current_data) {
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to encode all tiles\n");
- return OPJ_FALSE;
- }
- l_max_tile_size = 1000;
+
+ p_tcd = p_j2k->m_tcd;
l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
+ if (l_nb_tiles == 1) {
+ l_reuse_data = OPJ_TRUE;
+#ifdef __SSE__
+ for (j=0;j<p_j2k->m_tcd->image->numcomps;++j) {
+ opj_image_comp_t * l_img_comp = p_tcd->image->comps + j;
+ if (((size_t)l_img_comp->data & 0xFU) != 0U) { /* tile data shall be aligned on 16 bytes */
+ l_reuse_data = OPJ_FALSE;
+ }
+ }
+#endif
+ }
for (i=0;i<l_nb_tiles;++i) {
if (! opj_j2k_pre_write_tile(p_j2k,i,p_stream,p_manager)) {
- opj_free(l_current_data);
+ if (l_current_data) {
+ opj_free(l_current_data);
+ }
return OPJ_FALSE;
}
- l_current_tile_size = opj_tcd_get_encoded_tile_size(p_j2k->m_tcd);
- if (l_current_tile_size > l_max_tile_size) {
- OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(l_current_data, l_current_tile_size);
- if (! l_new_current_data) {
- opj_free(l_current_data);
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to encode all tiles\n");
- return OPJ_FALSE;
+ /* if we only have one tile, then simply set tile component data equal to image component data */
+ /* otherwise, allocate the data */
+ for (j=0;j<p_j2k->m_tcd->image->numcomps;++j) {
+ opj_tcd_tilecomp_t* l_tilec = p_tcd->tcd_image->tiles->comps + j;
+ if (l_reuse_data) {
+ opj_image_comp_t * l_img_comp = p_tcd->image->comps + j;
+ l_tilec->data = l_img_comp->data;
+ l_tilec->ownsData = OPJ_FALSE;
+ } else {
+ if(! opj_alloc_tile_component_data(l_tilec)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Error allocating tile component data." );
+ if (l_current_data) {
+ opj_free(l_current_data);
+ }
+ return OPJ_FALSE;
+ }
}
- l_current_data = l_new_current_data;
- l_max_tile_size = l_current_tile_size;
}
+ l_current_tile_size = opj_tcd_get_encoded_tile_size(p_j2k->m_tcd);
+ if (!l_reuse_data) {
+ if (l_current_tile_size > l_max_tile_size) {
+ OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(l_current_data, l_current_tile_size);
+ if (! l_new_current_data) {
+ if (l_current_data) {
+ opj_free(l_current_data);
+ }
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to encode all tiles\n");
+ return OPJ_FALSE;
+ }
+ l_current_data = l_new_current_data;
+ l_max_tile_size = l_current_tile_size;
+ }
- opj_j2k_get_tile_data(p_j2k->m_tcd,l_current_data);
+ /* copy image data (32 bit) to l_current_data as contiguous, all-component, zero offset buffer */
+ /* 32 bit components @ 8 bit precision get converted to 8 bit */
+ /* 32 bit components @ 16 bit precision get converted to 16 bit */
+ opj_j2k_get_tile_data(p_j2k->m_tcd,l_current_data);
- if (! opj_j2k_post_write_tile (p_j2k,l_current_data,l_current_tile_size,p_stream,p_manager)) {
+ /* now copy this data into the tile component */
+ if (! opj_tcd_copy_tile_data(p_j2k->m_tcd,l_current_data,l_current_tile_size)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Size mismatch between tile data and sent data." );
+ opj_free(l_current_data);
+ return OPJ_FALSE;
+ }
+ }
+
+ if (! opj_j2k_post_write_tile (p_j2k,p_stream,p_manager)) {
+ if (l_current_data) {
+ opj_free(l_current_data);
+ }
return OPJ_FALSE;
}
}
- opj_free(l_current_data);
+ if (l_current_data) {
+ opj_free(l_current_data);
+ }
return OPJ_TRUE;
}
@@ -9635,7 +10273,9 @@ OPJ_BOOL opj_j2k_end_compress( opj_j2k_t *p_j2k,
opj_event_mgr_t * p_manager)
{
/* customization of the encoding */
- opj_j2k_setup_end_compress(p_j2k);
+ if (! opj_j2k_setup_end_compress(p_j2k, p_manager)) {
+ return OPJ_FALSE;
+ }
if (! opj_j2k_exec (p_j2k, p_j2k->m_procedure_list, p_stream, p_manager))
{
@@ -9656,6 +10296,10 @@ OPJ_BOOL opj_j2k_start_compress(opj_j2k_t *p_j2k,
assert(p_manager != 00);
p_j2k->m_private_image = opj_image_create0();
+ if (! p_j2k->m_private_image) {
+ opj_event_msg(p_manager, EVT_ERROR, "Failed to allocate image header." );
+ return OPJ_FALSE;
+ }
opj_copy_image_header(p_image, p_j2k->m_private_image);
/* TODO_MSD: Find a better way */
@@ -9671,7 +10315,9 @@ OPJ_BOOL opj_j2k_start_compress(opj_j2k_t *p_j2k,
}
/* customization of the validation */
- opj_j2k_setup_encoding_validation (p_j2k);
+ if (! opj_j2k_setup_encoding_validation (p_j2k, p_manager)) {
+ return OPJ_FALSE;
+ }
/* validation of the parameters codec */
if (! opj_j2k_exec(p_j2k,p_j2k->m_validation_list,p_stream,p_manager)) {
@@ -9679,7 +10325,9 @@ OPJ_BOOL opj_j2k_start_compress(opj_j2k_t *p_j2k,
}
/* customization of the encoding */
- opj_j2k_setup_header_writing(p_j2k);
+ if (! opj_j2k_setup_header_writing(p_j2k, p_manager)) {
+ return OPJ_FALSE;
+ }
/* write header */
if (! opj_j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) {
@@ -9689,7 +10337,7 @@ OPJ_BOOL opj_j2k_start_compress(opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_pre_write_tile ( opj_j2k_t * p_j2k,
+static OPJ_BOOL opj_j2k_pre_write_tile ( opj_j2k_t * p_j2k,
OPJ_UINT32 p_tile_index,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
@@ -9707,44 +10355,68 @@ OPJ_BOOL opj_j2k_pre_write_tile ( opj_j2k_t * p_j2k,
p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = 0;
/* initialisation before tile encoding */
- if (! opj_tcd_init_encode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number)) {
+ if (! opj_tcd_init_encode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number, p_manager)) {
return OPJ_FALSE;
}
return OPJ_TRUE;
}
-void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data)
+static void opj_get_tile_dimensions(opj_image_t * l_image,
+ opj_tcd_tilecomp_t * l_tilec,
+ opj_image_comp_t * l_img_comp,
+ OPJ_UINT32* l_size_comp,
+ OPJ_UINT32* l_width,
+ OPJ_UINT32* l_height,
+ OPJ_UINT32* l_offset_x,
+ OPJ_UINT32* l_offset_y,
+ OPJ_UINT32* l_image_width,
+ OPJ_UINT32* l_stride,
+ OPJ_UINT32* l_tile_offset) {
+ OPJ_UINT32 l_remaining;
+ *l_size_comp = l_img_comp->prec >> 3; /* (/8) */
+ l_remaining = l_img_comp->prec & 7; /* (%8) */
+ if (l_remaining) {
+ *l_size_comp += 1;
+ }
+
+ if (*l_size_comp == 3) {
+ *l_size_comp = 4;
+ }
+
+ *l_width = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0);
+ *l_height = (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0);
+ *l_offset_x = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx);
+ *l_offset_y = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->y0, (OPJ_INT32)l_img_comp->dy);
+ *l_image_width = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x1 - (OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx);
+ *l_stride = *l_image_width - *l_width;
+ *l_tile_offset = ((OPJ_UINT32)l_tilec->x0 - *l_offset_x) + ((OPJ_UINT32)l_tilec->y0 - *l_offset_y) * *l_image_width;
+}
+
+static void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data)
{
OPJ_UINT32 i,j,k = 0;
- OPJ_UINT32 l_width,l_height,l_stride, l_offset_x,l_offset_y, l_image_width;
- opj_image_comp_t * l_img_comp = 00;
- opj_tcd_tilecomp_t * l_tilec = 00;
- opj_image_t * l_image = 00;
- OPJ_UINT32 l_size_comp, l_remaining;
- OPJ_INT32 * l_src_ptr;
- l_tilec = p_tcd->tcd_image->tiles->comps;
- l_image = p_tcd->image;
- l_img_comp = l_image->comps;
for (i=0;i<p_tcd->image->numcomps;++i) {
- l_size_comp = l_img_comp->prec >> 3; /* (/8) */
- l_remaining = l_img_comp->prec & 7; /* (%8) */
- if (l_remaining) {
- ++l_size_comp;
- }
-
- if (l_size_comp == 3) {
- l_size_comp = 4;
- }
-
- l_width = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0);
- l_height = (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0);
- l_offset_x = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx);
- l_offset_y = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->y0, (OPJ_INT32)l_img_comp->dy);
- l_image_width = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x1 - (OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx);
- l_stride = l_image_width - l_width;
- l_src_ptr = l_img_comp->data + ((OPJ_UINT32)l_tilec->x0 - l_offset_x) + ((OPJ_UINT32)l_tilec->y0 - l_offset_y) * l_image_width;
+ opj_image_t * l_image = p_tcd->image;
+ OPJ_INT32 * l_src_ptr;
+ opj_tcd_tilecomp_t * l_tilec = p_tcd->tcd_image->tiles->comps + i;
+ opj_image_comp_t * l_img_comp = l_image->comps + i;
+ OPJ_UINT32 l_size_comp,l_width,l_height,l_offset_x,l_offset_y, l_image_width,l_stride,l_tile_offset;
+
+ opj_get_tile_dimensions(l_image,
+ l_tilec,
+ l_img_comp,
+ &l_size_comp,
+ &l_width,
+ &l_height,
+ &l_offset_x,
+ &l_offset_y,
+ &l_image_width,
+ &l_stride,
+ &l_tile_offset);
+
+ l_src_ptr = l_img_comp->data + l_tile_offset;
switch (l_size_comp) {
case 1:
@@ -9811,19 +10483,13 @@ void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data)
}
break;
}
-
- ++l_img_comp;
- ++l_tilec;
}
}
-OPJ_BOOL opj_j2k_post_write_tile ( opj_j2k_t * p_j2k,
- OPJ_BYTE * p_data,
- OPJ_UINT32 p_data_size,
+static OPJ_BOOL opj_j2k_post_write_tile ( opj_j2k_t * p_j2k,
opj_stream_private_t *p_stream,
opj_event_mgr_t * p_manager )
{
- opj_tcd_t * l_tcd = 00;
OPJ_UINT32 l_nb_bytes_written;
OPJ_BYTE * l_current_data = 00;
OPJ_UINT32 l_tile_size = 0;
@@ -9832,17 +10498,10 @@ OPJ_BOOL opj_j2k_post_write_tile ( opj_j2k_t * p_j2k,
/* preconditions */
assert(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data);
- l_tcd = p_j2k->m_tcd;
-
l_tile_size = p_j2k->m_specific_param.m_encoder.m_encoded_tile_size;
l_available_data = l_tile_size;
l_current_data = p_j2k->m_specific_param.m_encoder.m_encoded_tile_data;
- if (! opj_tcd_copy_tile_data(l_tcd,p_data,p_data_size)) {
- opj_event_msg(p_manager, EVT_ERROR, "Size mismatch between tile data and sent data." );
- return OPJ_FALSE;
- }
-
l_nb_bytes_written = 0;
if (! opj_j2k_write_first_tile_part(p_j2k,l_current_data,&l_nb_bytes_written,l_available_data,p_stream,p_manager)) {
return OPJ_FALSE;
@@ -9869,79 +10528,131 @@ OPJ_BOOL opj_j2k_post_write_tile ( opj_j2k_t * p_j2k,
return OPJ_TRUE;
}
-void opj_j2k_setup_end_compress (opj_j2k_t *p_j2k)
+static OPJ_BOOL opj_j2k_setup_end_compress (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager)
{
/* preconditions */
assert(p_j2k != 00);
+ assert(p_manager != 00);
/* DEVELOPER CORNER, insert your custom procedures */
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_eoc );
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_eoc, p_manager)) {
+ return OPJ_FALSE;
+ }
if (OPJ_IS_CINEMA(p_j2k->m_cp.rsiz)) {
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_updated_tlm);
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_updated_tlm, p_manager)) {
+ return OPJ_FALSE;
+ }
}
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_epc );
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_end_encoding );
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_destroy_header_memory);
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_epc, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_end_encoding, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_destroy_header_memory, p_manager)) {
+ return OPJ_FALSE;
+ }
+ return OPJ_TRUE;
}
-void opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k)
+static OPJ_BOOL opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager)
{
/* preconditions */
assert(p_j2k != 00);
+ assert(p_manager != 00);
- opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_build_encoder);
- opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_encoding_validation);
+ if (! opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_build_encoder, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if (! opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_encoding_validation, p_manager)) {
+ return OPJ_FALSE;
+ }
/* DEVELOPER CORNER, add your custom validation procedure */
- opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_mct_validation);
+ if (! opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_mct_validation, p_manager)) {
+ return OPJ_FALSE;
+ }
+
+ return OPJ_TRUE;
}
-void opj_j2k_setup_header_writing (opj_j2k_t *p_j2k)
+static OPJ_BOOL opj_j2k_setup_header_writing (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager)
{
/* preconditions */
assert(p_j2k != 00);
+ assert(p_manager != 00);
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_init_info );
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_soc );
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_siz );
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_cod );
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_qcd );
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_init_info, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_soc, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_siz, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_cod, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_qcd, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_all_coc, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_all_qcc, p_manager)) {
+ return OPJ_FALSE;
+ }
if (OPJ_IS_CINEMA(p_j2k->m_cp.rsiz)) {
- /* No need for COC or QCC, QCD and COD are used
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_all_coc );
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_all_qcc );
- */
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_tlm );
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_tlm, p_manager)) {
+ return OPJ_FALSE;
+ }
if (p_j2k->m_cp.rsiz == OPJ_PROFILE_CINEMA_4K) {
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_poc );
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_poc, p_manager)) {
+ return OPJ_FALSE;
+ }
}
}
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_regions);
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_regions, p_manager)) {
+ return OPJ_FALSE;
+ }
if (p_j2k->m_cp.comment != 00) {
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_com);
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_com, p_manager)) {
+ return OPJ_FALSE;
+ }
}
/* DEVELOPER CORNER, insert your custom procedures */
if (p_j2k->m_cp.rsiz & OPJ_EXTENSION_MCT) {
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_mct_data_group );
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_mct_data_group, p_manager)) {
+ return OPJ_FALSE;
+ }
}
/* End of Developer Corner */
if (p_j2k->cstr_index) {
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_get_end_header );
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_get_end_header, p_manager)) {
+ return OPJ_FALSE;
+ }
}
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_create_tcd);
- opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_update_rates);
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_create_tcd, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_update_rates, p_manager)) {
+ return OPJ_FALSE;
+ }
+
+ return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_first_tile_part (opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_first_tile_part (opj_j2k_t *p_j2k,
OPJ_BYTE * p_data,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 p_total_data_size,
@@ -9993,7 +10704,6 @@ OPJ_BOOL opj_j2k_write_first_tile_part (opj_j2k_t *p_j2k,
p_total_data_size -= l_current_nb_bytes_written;
}
#endif
-
if (l_cp->tcps[p_j2k->m_current_tile_number].numpocs) {
l_current_nb_bytes_written = 0;
opj_j2k_write_poc_in_memory(p_j2k,p_data,&l_current_nb_bytes_written,p_manager);
@@ -10021,7 +10731,7 @@ OPJ_BOOL opj_j2k_write_first_tile_part (opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_all_tile_parts( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_all_tile_parts( opj_j2k_t *p_j2k,
OPJ_BYTE * p_data,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 p_total_data_size,
@@ -10132,7 +10842,7 @@ OPJ_BOOL opj_j2k_write_all_tile_parts( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_write_updated_tlm( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_updated_tlm( opj_j2k_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager )
{
@@ -10163,7 +10873,7 @@ OPJ_BOOL opj_j2k_write_updated_tlm( opj_j2k_t *p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_end_encoding( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_end_encoding( opj_j2k_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager )
{
@@ -10214,7 +10924,7 @@ static OPJ_BOOL opj_j2k_destroy_header_memory ( opj_j2k_t * p_j2k,
return OPJ_TRUE;
}
-OPJ_BOOL opj_j2k_init_info( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_init_info( opj_j2k_t *p_j2k,
struct opj_stream_private *p_stream,
struct opj_event_mgr * p_manager )
{
@@ -10292,7 +11002,7 @@ static OPJ_BOOL opj_j2k_create_tcd( opj_j2k_t *p_j2k,
return OPJ_FALSE;
}
- if (!opj_tcd_init(p_j2k->m_tcd,p_j2k->m_private_image,&p_j2k->m_cp)) {
+ if (!opj_tcd_init(p_j2k->m_tcd,p_j2k->m_private_image,&p_j2k->m_cp, p_j2k->m_tp)) {
opj_tcd_destroy(p_j2k->m_tcd);
p_j2k->m_tcd = 00;
return OPJ_FALSE;
@@ -10313,7 +11023,23 @@ OPJ_BOOL opj_j2k_write_tile (opj_j2k_t * p_j2k,
return OPJ_FALSE;
}
else {
- if (! opj_j2k_post_write_tile(p_j2k,p_data,p_data_size,p_stream,p_manager)) {
+ OPJ_UINT32 j;
+ /* Allocate data */
+ for (j=0;j<p_j2k->m_tcd->image->numcomps;++j) {
+ opj_tcd_tilecomp_t* l_tilec = p_j2k->m_tcd->tcd_image->tiles->comps + j;
+
+ if(! opj_alloc_tile_component_data(l_tilec)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Error allocating tile component data." );
+ return OPJ_FALSE;
+ }
+ }
+
+ /* now copy data into the tile component */
+ if (! opj_tcd_copy_tile_data(p_j2k->m_tcd,p_data,p_data_size)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Size mismatch between tile data and sent data." );
+ return OPJ_FALSE;
+ }
+ if (! opj_j2k_post_write_tile(p_j2k,p_stream,p_manager)) {
opj_event_msg(p_manager, EVT_ERROR, "Error while opj_j2k_post_write_tile with tile index = %d\n", p_tile_index);
return OPJ_FALSE;
}
diff --git a/openjpeg/src/lib/openjp2/j2k.h b/openjpeg/src/lib/openjp2/j2k.h
index d0f59d727..7e68b3af8 100644
--- a/openjpeg/src/lib/openjp2/j2k.h
+++ b/openjpeg/src/lib/openjp2/j2k.h
@@ -228,10 +228,16 @@ typedef struct opj_simple_mcc_decorrelation_data
OPJ_UINT32 m_nb_comps;
opj_mct_data_t * m_decorrelation_array;
opj_mct_data_t * m_offset_array;
- OPJ_UINT32 m_is_irreversible : 1;
+ OPJ_BITFIELD m_is_irreversible : 1;
}
opj_simple_mcc_decorrelation_data_t;
+typedef struct opj_ppx_struct
+{
+ OPJ_BYTE* m_data; /* m_data == NULL => Zppx not read yet */
+ OPJ_UINT32 m_data_size;
+} opj_ppx;
+
/**
Tile coding parameters :
this structure is used to store coding/decoding parameters common to all
@@ -254,7 +260,13 @@ typedef struct opj_tcp
OPJ_UINT32 numpocs;
/** progression order changes */
opj_poc_t pocs[32];
- /** packet header store there for futur use in t2_decode_packet */
+
+ /** number of ppt markers (reserved size) */
+ OPJ_UINT32 ppt_markers_count;
+ /** ppt markers data (table indexed by Zppt) */
+ opj_ppx* ppt_markers;
+
+ /** packet header store there for future use in t2_decode_packet */
OPJ_BYTE *ppt_data;
/** used to keep a track of the allocated memory */
OPJ_BYTE *ppt_buffer;
@@ -293,10 +305,12 @@ typedef struct opj_tcp
/***** FLAGS *******/
+ /** If cod == 1 --> there was a COD marker for the present tile */
+ OPJ_BITFIELD cod : 1;
/** If ppt == 1 --> there was a PPT marker for the present tile */
- OPJ_UINT32 ppt : 1;
+ OPJ_BITFIELD ppt : 1;
/** indicates if a POC marker has been used O:NO, 1:YES */
- OPJ_UINT32 POC : 1;
+ OPJ_BITFIELD POC : 1;
} opj_tcp_t;
@@ -313,13 +327,13 @@ typedef struct opj_encoding_param
/** Flag determining tile part generation*/
OPJ_BYTE m_tp_flag;
/** allocation by rate/distortion */
- OPJ_UINT32 m_disto_alloc : 1;
+ OPJ_BITFIELD m_disto_alloc : 1;
/** allocation by fixed layer */
- OPJ_UINT32 m_fixed_alloc : 1;
+ OPJ_BITFIELD m_fixed_alloc : 1;
/** add fixed_quality */
- OPJ_UINT32 m_fixed_quality : 1;
+ OPJ_BITFIELD m_fixed_quality : 1;
/** Enabling Tile part generation*/
- OPJ_UINT32 m_tp_on : 1;
+ OPJ_BITFIELD m_tp_on : 1;
}
opj_encoding_param_t;
@@ -357,7 +371,12 @@ typedef struct opj_cp
/** number of tiles in heigth */
OPJ_UINT32 th;
- /** packet header store there for futur use in t2_decode_packet */
+ /** number of ppm markers (reserved size) */
+ OPJ_UINT32 ppm_markers_count;
+ /** ppm markers data (table indexed by Zppm) */
+ opj_ppx* ppm_markers;
+
+ /** packet header store there for future use in t2_decode_packet */
OPJ_BYTE *ppm_data;
/** size of the ppm_data*/
OPJ_UINT32 ppm_len;
@@ -434,9 +453,9 @@ typedef struct opj_cp
/******** FLAGS *********/
/** if ppm == 1 --> there was a PPM marker*/
- OPJ_UINT32 ppm : 1;
+ OPJ_BITFIELD ppm : 1;
/** tells if the parameter is a coding or decoding one */
- OPJ_UINT32 m_is_decoder : 1;
+ OPJ_BITFIELD m_is_decoder : 1;
/* <<UniPG */
} opj_cp_t;
@@ -478,9 +497,12 @@ typedef struct opj_j2k_dec
*/
OPJ_BOOL m_last_tile_part;
/** to tell that a tile can be decoded. */
- OPJ_UINT32 m_can_decode : 1;
- OPJ_UINT32 m_discard_tiles : 1;
- OPJ_UINT32 m_skip_data : 1;
+ OPJ_BITFIELD m_can_decode : 1;
+ OPJ_BITFIELD m_discard_tiles : 1;
+ OPJ_BITFIELD m_skip_data : 1;
+ /** TNsot correction : see issue 254 **/
+ OPJ_BITFIELD m_nb_tile_parts_correction_checked : 1;
+ OPJ_BITFIELD m_nb_tile_parts_correction : 1;
} opj_j2k_dec_t;
@@ -568,6 +590,11 @@ 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;
}
opj_j2k_t;
@@ -586,6 +613,8 @@ Decoding parameters are returned in j2k->cp.
*/
void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters);
+OPJ_BOOL opj_j2k_set_threads(opj_j2k_t *j2k, OPJ_UINT32 num_threads);
+
/**
* Creates a J2K compression structure
*
@@ -594,7 +623,7 @@ void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters);
opj_j2k_t* opj_j2k_create_compress(void);
-void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
+OPJ_BOOL opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
opj_cparameters_t *parameters,
opj_image_t *image,
opj_event_mgr_t * p_manager);
diff --git a/openjpeg/src/lib/openjp2/jp2.c b/openjpeg/src/lib/openjp2/jp2.c
index 5c88c4d74..ea81d0f5d 100644
--- a/openjpeg/src/lib/openjp2/jp2.c
+++ b/openjpeg/src/lib/openjp2/jp2.c
@@ -94,7 +94,7 @@ static OPJ_BYTE * opj_jp2_write_bpcc( opj_jp2_t *jp2,
* @param p_bpc_header_size the size of the bpc header
* @param p_manager the user event manager.
*
- * @return true if the bpc header is valid, fale else.
+ * @return true if the bpc header is valid, false else.
*/
static OPJ_BOOL opj_jp2_read_bpcc( opj_jp2_t *jp2,
OPJ_BYTE * p_bpc_header_data,
@@ -106,7 +106,18 @@ static OPJ_BOOL opj_jp2_read_cdef( opj_jp2_t * jp2,
OPJ_UINT32 p_cdef_header_size,
opj_event_mgr_t * p_manager );
-static void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color);
+static void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color, opj_event_mgr_t *);
+
+/**
+ * Writes the Channel Definition box.
+ *
+ * @param jp2 jpeg2000 file codec.
+ * @param p_nb_bytes_written pointer to store the nb of bytes written by the function.
+ *
+ * @return the data being copied.
+ */
+static OPJ_BYTE * opj_jp2_write_cdef( opj_jp2_t *jp2,
+ OPJ_UINT32 * p_nb_bytes_written );
/**
* Writes the Colour Specification box.
@@ -147,7 +158,7 @@ static OPJ_BOOL opj_jp2_read_ftyp( opj_jp2_t *jp2,
OPJ_UINT32 p_header_size,
opj_event_mgr_t * p_manager );
-OPJ_BOOL opj_jp2_skip_jp2c( opj_jp2_t *jp2,
+static OPJ_BOOL opj_jp2_skip_jp2c( opj_jp2_t *jp2,
opj_stream_private_t *cio,
opj_event_mgr_t * p_manager );
@@ -159,7 +170,7 @@ OPJ_BOOL opj_jp2_skip_jp2c( opj_jp2_t *jp2,
* @param p_header_size the size of the data contained in the file header box.
* @param p_manager the user event manager.
*
- * @return true if the JP2 Header box was successfully reconized.
+ * @return true if the JP2 Header box was successfully recognized.
*/
static OPJ_BOOL opj_jp2_read_jp2h( opj_jp2_t *jp2,
OPJ_BYTE *p_header_data,
@@ -167,6 +178,19 @@ static OPJ_BOOL opj_jp2_read_jp2h( opj_jp2_t *jp2,
opj_event_mgr_t * p_manager );
/**
+ * Writes the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box).
+ *
+ * @param jp2 the jpeg2000 file codec.
+ * @param stream the stream to write data to.
+ * @param p_manager user event manager.
+ *
+ * @return true if writing was successful.
+ */
+static OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2,
+ opj_stream_private_t *stream,
+ opj_event_mgr_t * p_manager );
+
+/**
* Writes the Jpeg2000 codestream Header box - JP2C Header box. This function must be called AFTER the coding has been done.
*
* @param cio the stream to write data to.
@@ -287,7 +311,7 @@ static OPJ_BOOL opj_jp2_read_cmap( opj_jp2_t * jp2,
* @param p_colr_header_size the size of the color header
* @param p_manager the user event manager.
*
- * @return true if the bpc header is valid, fale else.
+ * @return true if the bpc header is valid, false else.
*/
static OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2,
OPJ_BYTE * p_colr_header_data,
@@ -302,13 +326,13 @@ static OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2,
* Sets up the procedures to do on writing header after the codestream.
* Developpers wanting to extend the library can add their own writing procedures.
*/
-static void opj_jp2_setup_end_header_writing (opj_jp2_t *jp2);
+static OPJ_BOOL opj_jp2_setup_end_header_writing (opj_jp2_t *jp2, opj_event_mgr_t * p_manager);
/**
* Sets up the procedures to do on reading header after the codestream.
* Developpers wanting to extend the library can add their own writing procedures.
*/
-static void opj_jp2_setup_end_header_reading (opj_jp2_t *jp2);
+static OPJ_BOOL opj_jp2_setup_end_header_reading (opj_jp2_t *jp2, opj_event_mgr_t * p_manager);
/**
* Reads a jpeg2000 file header structure.
@@ -346,7 +370,7 @@ static OPJ_BOOL opj_jp2_exec ( opj_jp2_t * jp2,
* @param p_number_bytes_read pointer to an int that will store the number of bytes read from the stream (shoul usually be 2).
* @param p_manager user event manager.
*
- * @return true if the box is reconized, false otherwise
+ * @return true if the box is recognized, false otherwise
*/
static OPJ_BOOL opj_jp2_read_boxhdr(opj_jp2_box_t *box,
OPJ_UINT32 * p_number_bytes_read,
@@ -357,14 +381,14 @@ static OPJ_BOOL opj_jp2_read_boxhdr(opj_jp2_box_t *box,
* Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
* are valid. Developpers wanting to extend the library can add their own validation procedures.
*/
-static void opj_jp2_setup_encoding_validation (opj_jp2_t *jp2);
+static OPJ_BOOL opj_jp2_setup_encoding_validation (opj_jp2_t *jp2, opj_event_mgr_t * p_manager);
/**
* Sets up the procedures to do on writing header. Developpers wanting to extend the library can add their own writing procedures.
*/
-static void opj_jp2_setup_header_writing (opj_jp2_t *jp2);
+static OPJ_BOOL opj_jp2_setup_header_writing (opj_jp2_t *jp2, opj_event_mgr_t * p_manager);
-OPJ_BOOL opj_jp2_default_validation ( opj_jp2_t * jp2,
+static OPJ_BOOL opj_jp2_default_validation ( opj_jp2_t * jp2,
opj_stream_private_t *cio,
opj_event_mgr_t * p_manager );
@@ -386,14 +410,14 @@ static const opj_jp2_header_handler_t * opj_jp2_img_find_handler (OPJ_UINT32 p_i
*/
static const opj_jp2_header_handler_t * opj_jp2_find_handler (OPJ_UINT32 p_id );
-const opj_jp2_header_handler_t jp2_header [] =
+static const opj_jp2_header_handler_t jp2_header [] =
{
{JP2_JP,opj_jp2_read_jp},
{JP2_FTYP,opj_jp2_read_ftyp},
{JP2_JP2H,opj_jp2_read_jp2h}
};
-const opj_jp2_header_handler_t jp2_img_header [] =
+static const opj_jp2_header_handler_t jp2_img_header [] =
{
{JP2_IHDR,opj_jp2_read_ihdr},
{JP2_COLR,opj_jp2_read_colr},
@@ -413,7 +437,7 @@ const opj_jp2_header_handler_t jp2_img_header [] =
* @param p_box_max_size the maximum number of bytes in the box.
* @param p_manager FIXME DOC
*
- * @return true if the box is reconized, false otherwise
+ * @return true if the box is recognized, false otherwise
*/
static OPJ_BOOL opj_jp2_read_boxhdr_char( opj_jp2_box_t *box,
OPJ_BYTE * p_data,
@@ -425,16 +449,16 @@ static OPJ_BOOL opj_jp2_read_boxhdr_char( opj_jp2_box_t *box,
* Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
* are valid. Developpers wanting to extend the library can add their own validation procedures.
*/
-static void opj_jp2_setup_decoding_validation (opj_jp2_t *jp2);
+static OPJ_BOOL opj_jp2_setup_decoding_validation (opj_jp2_t *jp2, opj_event_mgr_t * p_manager);
/**
* Sets up the procedures to do on reading header.
* Developpers wanting to extend the library can add their own writing procedures.
*/
-static void opj_jp2_setup_header_reading (opj_jp2_t *jp2);
+static OPJ_BOOL opj_jp2_setup_header_reading (opj_jp2_t *jp2, opj_event_mgr_t * p_manager);
/* ----------------------------------------------------------------------- */
- OPJ_BOOL opj_jp2_read_boxhdr(opj_jp2_box_t *box,
+static OPJ_BOOL opj_jp2_read_boxhdr(opj_jp2_box_t *box,
OPJ_UINT32 * p_number_bytes_read,
opj_stream_private_t *cio,
opj_event_mgr_t * p_manager )
@@ -458,12 +482,16 @@ static void opj_jp2_setup_header_reading (opj_jp2_t *jp2);
opj_read_bytes(l_data_header+4,&(box->type), 4);
if(box->length == 0)/* last box */
- {
+ {
const OPJ_OFF_T bleft = opj_stream_get_number_byte_left(cio);
- box->length = (OPJ_UINT32)bleft;
- assert( (OPJ_OFF_T)box->length == bleft );
- return OPJ_TRUE;
+ if (bleft > (OPJ_OFF_T)(0xFFFFFFFFU - 8U)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
+ return OPJ_FALSE;
}
+ box->length = (OPJ_UINT32)bleft + 8U;
+ assert( (OPJ_OFF_T)box->length == bleft + 8 );
+ return OPJ_TRUE;
+ }
/* do we have a "special very large box ?" */
/* read then the XLBox */
@@ -514,7 +542,7 @@ static void jp2_write_url(opj_cio_t *cio, char *Idx_file) {
}
#endif
-OPJ_BOOL opj_jp2_read_ihdr( opj_jp2_t *jp2,
+static OPJ_BOOL opj_jp2_read_ihdr( opj_jp2_t *jp2,
OPJ_BYTE *p_image_header_data,
OPJ_UINT32 p_image_header_size,
opj_event_mgr_t * p_manager )
@@ -524,6 +552,11 @@ OPJ_BOOL opj_jp2_read_ihdr( opj_jp2_t *jp2,
assert(jp2 != 00);
assert(p_manager != 00);
+ if (jp2->comps != NULL) {
+ opj_event_msg(p_manager, EVT_WARNING, "Ignoring ihdr box. First ihdr box already read\n");
+ return OPJ_TRUE;
+ }
+
if (p_image_header_size != 14) {
opj_event_msg(p_manager, EVT_ERROR, "Bad image header box (bad size)\n");
return OPJ_FALSE;
@@ -535,14 +568,18 @@ OPJ_BOOL opj_jp2_read_ihdr( opj_jp2_t *jp2,
p_image_header_data += 4;
opj_read_bytes(p_image_header_data,&(jp2->numcomps),2); /* NC */
p_image_header_data += 2;
+
+ 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");
+ return OPJ_FALSE;
+ }
/* allocate memory for components */
- jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
+ jp2->comps = (opj_jp2_comps_t*) opj_calloc(jp2->numcomps, sizeof(opj_jp2_comps_t));
if (jp2->comps == 0) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle image header (ihdr)\n");
return OPJ_FALSE;
}
- memset(jp2->comps,0,jp2->numcomps * sizeof(opj_jp2_comps_t));
opj_read_bytes(p_image_header_data,&(jp2->bpc),1); /* BPC */
++ p_image_header_data;
@@ -563,7 +600,7 @@ OPJ_BOOL opj_jp2_read_ihdr( opj_jp2_t *jp2,
return OPJ_TRUE;
}
-OPJ_BYTE * opj_jp2_write_ihdr(opj_jp2_t *jp2,
+static OPJ_BYTE * opj_jp2_write_ihdr(opj_jp2_t *jp2,
OPJ_UINT32 * p_nb_bytes_written
)
{
@@ -574,11 +611,10 @@ OPJ_BYTE * opj_jp2_write_ihdr(opj_jp2_t *jp2,
assert(p_nb_bytes_written != 00);
/* default image header is 22 bytes wide */
- l_ihdr_data = (OPJ_BYTE *) opj_malloc(22);
+ l_ihdr_data = (OPJ_BYTE *) opj_calloc(1,22);
if (l_ihdr_data == 00) {
return 00;
}
- memset(l_ihdr_data,0,22);
l_current_ihdr_ptr = l_ihdr_data;
@@ -614,24 +650,24 @@ OPJ_BYTE * opj_jp2_write_ihdr(opj_jp2_t *jp2,
return l_ihdr_data;
}
-OPJ_BYTE * opj_jp2_write_bpcc( opj_jp2_t *jp2,
+static OPJ_BYTE * opj_jp2_write_bpcc( opj_jp2_t *jp2,
OPJ_UINT32 * p_nb_bytes_written
)
{
OPJ_UINT32 i;
/* room for 8 bytes for box and 1 byte for each component */
- OPJ_UINT32 l_bpcc_size = 8 + jp2->numcomps;
+ OPJ_UINT32 l_bpcc_size;
OPJ_BYTE * l_bpcc_data,* l_current_bpcc_ptr;
/* preconditions */
assert(jp2 != 00);
assert(p_nb_bytes_written != 00);
+ l_bpcc_size = 8 + jp2->numcomps;
- l_bpcc_data = (OPJ_BYTE *) opj_malloc(l_bpcc_size);
+ l_bpcc_data = (OPJ_BYTE *) opj_calloc(1,l_bpcc_size);
if (l_bpcc_data == 00) {
return 00;
}
- memset(l_bpcc_data,0,l_bpcc_size);
l_current_bpcc_ptr = l_bpcc_data;
@@ -651,7 +687,7 @@ OPJ_BYTE * opj_jp2_write_bpcc( opj_jp2_t *jp2,
return l_bpcc_data;
}
-OPJ_BOOL opj_jp2_read_bpcc( opj_jp2_t *jp2,
+static OPJ_BOOL opj_jp2_read_bpcc( opj_jp2_t *jp2,
OPJ_BYTE * p_bpc_header_data,
OPJ_UINT32 p_bpc_header_size,
opj_event_mgr_t * p_manager
@@ -683,15 +719,64 @@ OPJ_BOOL opj_jp2_read_bpcc( opj_jp2_t *jp2,
return OPJ_TRUE;
}
+static OPJ_BYTE * opj_jp2_write_cdef(opj_jp2_t *jp2, OPJ_UINT32 * p_nb_bytes_written)
+{
+ /* room for 8 bytes for box, 2 for n */
+ OPJ_UINT32 l_cdef_size = 10;
+ OPJ_BYTE * l_cdef_data,* l_current_cdef_ptr;
+ OPJ_UINT32 l_value;
+ OPJ_UINT16 i;
+
+ /* preconditions */
+ assert(jp2 != 00);
+ assert(p_nb_bytes_written != 00);
+ assert(jp2->color.jp2_cdef != 00);
+ assert(jp2->color.jp2_cdef->info != 00);
+ assert(jp2->color.jp2_cdef->n > 0U);
-OPJ_BYTE * opj_jp2_write_colr( opj_jp2_t *jp2,
+ l_cdef_size += 6U * jp2->color.jp2_cdef->n;
+
+ l_cdef_data = (OPJ_BYTE *) opj_malloc(l_cdef_size);
+ if (l_cdef_data == 00) {
+ return 00;
+ }
+
+ l_current_cdef_ptr = l_cdef_data;
+
+ opj_write_bytes(l_current_cdef_ptr,l_cdef_size,4); /* write box size */
+ l_current_cdef_ptr += 4;
+
+ opj_write_bytes(l_current_cdef_ptr,JP2_CDEF,4); /* BPCC */
+ l_current_cdef_ptr += 4;
+
+ l_value = jp2->color.jp2_cdef->n;
+ opj_write_bytes(l_current_cdef_ptr,l_value,2); /* N */
+ l_current_cdef_ptr += 2;
+
+ for (i = 0U; i < jp2->color.jp2_cdef->n; ++i) {
+ l_value = jp2->color.jp2_cdef->info[i].cn;
+ opj_write_bytes(l_current_cdef_ptr,l_value,2); /* Cni */
+ l_current_cdef_ptr += 2;
+ l_value = jp2->color.jp2_cdef->info[i].typ;
+ opj_write_bytes(l_current_cdef_ptr,l_value,2); /* Typi */
+ l_current_cdef_ptr += 2;
+ l_value = jp2->color.jp2_cdef->info[i].asoc;
+ opj_write_bytes(l_current_cdef_ptr,l_value,2); /* Asoci */
+ l_current_cdef_ptr += 2;
+ }
+ *p_nb_bytes_written = l_cdef_size;
+
+ return l_cdef_data;
+}
+
+static OPJ_BYTE * opj_jp2_write_colr( opj_jp2_t *jp2,
OPJ_UINT32 * p_nb_bytes_written
)
{
/* room for 8 bytes for box 3 for common data and variable upon profile*/
OPJ_UINT32 l_colr_size = 11;
OPJ_BYTE * l_colr_data,* l_current_colr_ptr;
-
+
/* preconditions */
assert(jp2 != 00);
assert(p_nb_bytes_written != 00);
@@ -709,11 +794,10 @@ OPJ_BYTE * opj_jp2_write_colr( opj_jp2_t *jp2,
return 00;
}
- l_colr_data = (OPJ_BYTE *) opj_malloc(l_colr_size);
+ l_colr_data = (OPJ_BYTE *) opj_calloc(1,l_colr_size);
if (l_colr_data == 00) {
return 00;
}
- memset(l_colr_data,0,l_colr_size);
l_current_colr_ptr = l_colr_data;
@@ -749,7 +833,7 @@ OPJ_BYTE * opj_jp2_write_colr( opj_jp2_t *jp2,
return l_colr_data;
}
-void opj_jp2_free_pclr(opj_jp2_color_t *color)
+static void opj_jp2_free_pclr(opj_jp2_color_t *color)
{
opj_free(color->jp2_pclr->channel_sign);
opj_free(color->jp2_pclr->channel_size);
@@ -768,16 +852,40 @@ static OPJ_BOOL opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color,
if (color->jp2_cdef) {
opj_jp2_cdef_info_t *info = color->jp2_cdef->info;
OPJ_UINT16 n = color->jp2_cdef->n;
+ OPJ_UINT32 nr_channels = image->numcomps; /* FIXME image->numcomps == jp2->numcomps before color is applied ??? */
+
+ /* cdef applies to cmap channels if any */
+ if (color->jp2_pclr && color->jp2_pclr->cmap) {
+ nr_channels = (OPJ_UINT32)color->jp2_pclr->nr_channels;
+ }
for (i = 0; i < n; i++) {
- if (info[i].cn >= image->numcomps) {
- opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].cn, image->numcomps);
+ if (info[i].cn >= nr_channels) {
+ opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].cn, nr_channels);
+ return OPJ_FALSE;
+ }
+ if (info[i].asoc == 65535U) continue;
+
+ if (info[i].asoc > 0 && (OPJ_UINT32)(info[i].asoc - 1) >= nr_channels) {
+ opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].asoc - 1, nr_channels);
return OPJ_FALSE;
}
- if (info[i].asoc > 0 && (OPJ_UINT32)(info[i].asoc - 1) >= image->numcomps) {
- opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].asoc - 1, image->numcomps);
+ }
+
+ /* issue 397 */
+ /* ISO 15444-1 states that if cdef is present, it shall contain a complete list of channel definitions. */
+ while (nr_channels > 0)
+ {
+ for(i = 0; i < n; ++i) {
+ if ((OPJ_UINT32)info[i].cn == (nr_channels - 1U)) {
+ break;
+ }
+ }
+ if (i == n) {
+ opj_event_msg(p_manager, EVT_ERROR, "Incomplete channel definitions.\n");
return OPJ_FALSE;
}
+ --nr_channels;
}
}
@@ -796,7 +904,7 @@ static OPJ_BOOL opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color,
}
}
- pcol_usage = opj_calloc(nr_channels, sizeof(OPJ_BOOL));
+ pcol_usage = (OPJ_BOOL *) opj_calloc(nr_channels, sizeof(OPJ_BOOL));
if (!pcol_usage) {
opj_event_msg(p_manager, EVT_ERROR, "Unexpected OOM.\n");
return OPJ_FALSE;
@@ -829,6 +937,23 @@ static OPJ_BOOL opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color,
is_sane = OPJ_FALSE;
}
}
+ /* Issue 235/447 weird cmap */
+ if (1 && is_sane && (image->numcomps==1U)) {
+ for (i = 0; i < nr_channels; i++) {
+ if (!pcol_usage[i]) {
+ is_sane = 0U;
+ opj_event_msg(p_manager, EVT_WARNING, "Component mapping seems wrong. Trying to correct.\n", i);
+ break;
+ }
+ }
+ if (!is_sane) {
+ is_sane = OPJ_TRUE;
+ for (i = 0; i < nr_channels; i++) {
+ cmap[i].mtyp = 1U;
+ cmap[i].pcol = (OPJ_BYTE) i;
+ }
+ }
+ }
opj_free(pcol_usage);
if (!is_sane) {
return OPJ_FALSE;
@@ -839,7 +964,7 @@ static OPJ_BOOL opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color,
}
/* file9.jp2 */
-void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color)
+static void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color)
{
opj_image_comp_t *old_comps, *new_comps;
OPJ_BYTE *channel_size, *channel_sign;
@@ -859,7 +984,11 @@ void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color)
old_comps = image->comps;
new_comps = (opj_image_comp_t*)
opj_malloc(nr_channels * sizeof(opj_image_comp_t));
-
+ if (!new_comps) {
+ /* FIXME no error code for opj_jp2_apply_pclr */
+ /* FIXME event manager error callback */
+ return;
+ }
for(i = 0; i < nr_channels; ++i) {
pcol = cmap[i].pcol; cmp = cmap[i].cmp;
@@ -875,6 +1004,13 @@ void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color)
/* Palette mapping: */
new_comps[i].data = (OPJ_INT32*)
opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(OPJ_INT32));
+ if (!new_comps[i].data) {
+ opj_free(new_comps);
+ new_comps = NULL;
+ /* FIXME no error code for opj_jp2_apply_pclr */
+ /* FIXME event manager error callback */
+ return;
+ }
new_comps[i].prec = channel_size[i];
new_comps[i].sgnd = channel_sign[i];
}
@@ -924,7 +1060,7 @@ void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color)
}/* apply_pclr() */
-OPJ_BOOL opj_jp2_read_pclr( opj_jp2_t *jp2,
+static OPJ_BOOL opj_jp2_read_pclr( opj_jp2_t *jp2,
OPJ_BYTE * p_pclr_header_data,
OPJ_UINT32 p_pclr_header_size,
opj_event_mgr_t * p_manager
@@ -953,12 +1089,20 @@ OPJ_BOOL opj_jp2_read_pclr( opj_jp2_t *jp2,
opj_read_bytes(p_pclr_header_data, &l_value , 2); /* NE */
p_pclr_header_data += 2;
nr_entries = (OPJ_UINT16) l_value;
+ if ((nr_entries == 0U) || (nr_entries > 1024U)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Invalid PCLR box. Reports %d entries\n", (int)nr_entries);
+ return OPJ_FALSE;
+ }
opj_read_bytes(p_pclr_header_data, &l_value , 1); /* NPC */
++p_pclr_header_data;
nr_channels = (OPJ_UINT16) l_value;
+ if (nr_channels == 0U) {
+ opj_event_msg(p_manager, EVT_ERROR, "Invalid PCLR box. Reports 0 palette columns\n");
+ return OPJ_FALSE;
+ }
- if (p_pclr_header_size < 3 + (OPJ_UINT32)nr_channels || nr_channels == 0 || nr_entries >= (OPJ_UINT32)-1 / nr_channels)
+ if (p_pclr_header_size < 3 + (OPJ_UINT32)nr_channels)
return OPJ_FALSE;
entries = (OPJ_UINT32*) opj_malloc((size_t)nr_channels * nr_entries * sizeof(OPJ_UINT32));
@@ -1010,7 +1154,7 @@ OPJ_BOOL opj_jp2_read_pclr( opj_jp2_t *jp2,
if (bytes_to_read > sizeof(OPJ_UINT32))
bytes_to_read = sizeof(OPJ_UINT32);
- if ((ptrdiff_t)p_pclr_header_size < p_pclr_header_data - orig_header_data + (ptrdiff_t)bytes_to_read)
+ if ((ptrdiff_t)p_pclr_header_size < (ptrdiff_t)(p_pclr_header_data - orig_header_data) + (ptrdiff_t)bytes_to_read)
return OPJ_FALSE;
opj_read_bytes(p_pclr_header_data, &l_value , bytes_to_read); /* Cji */
@@ -1023,7 +1167,7 @@ OPJ_BOOL opj_jp2_read_pclr( opj_jp2_t *jp2,
return OPJ_TRUE;
}
-OPJ_BOOL opj_jp2_read_cmap( opj_jp2_t * jp2,
+static OPJ_BOOL opj_jp2_read_cmap( opj_jp2_t * jp2,
OPJ_BYTE * p_cmap_header_data,
OPJ_UINT32 p_cmap_header_size,
opj_event_mgr_t * p_manager
@@ -1083,55 +1227,71 @@ OPJ_BOOL opj_jp2_read_cmap( opj_jp2_t * jp2,
return OPJ_TRUE;
}
-void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color)
+static void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color, opj_event_mgr_t *manager)
{
opj_jp2_cdef_info_t *info;
OPJ_UINT16 i, n, cn, asoc, acn;
-
+
info = color->jp2_cdef->info;
n = color->jp2_cdef->n;
-
- for(i = 0; i < n; ++i)
- {
- /* WATCH: acn = asoc - 1 ! */
- asoc = info[i].asoc;
- if(asoc == 0 || asoc == 65535)
- {
- if (i < image->numcomps)
- image->comps[i].alpha = info[i].typ;
- continue;
- }
-
- cn = info[i].cn;
- acn = (OPJ_UINT16)(asoc - 1);
- if( cn >= image->numcomps || acn >= image->numcomps )
- {
- fprintf(stderr, "cn=%d, acn=%d, numcomps=%d\n", cn, acn, image->numcomps);
- continue;
- }
-
- if(cn != acn)
+
+ for(i = 0; i < n; ++i)
+ {
+ /* WATCH: acn = asoc - 1 ! */
+ asoc = info[i].asoc;
+ cn = info[i].cn;
+
+ if( cn >= image->numcomps)
+ {
+ opj_event_msg(manager, EVT_WARNING, "opj_jp2_apply_cdef: cn=%d, numcomps=%d\n", cn, image->numcomps);
+ continue;
+ }
+ if(asoc == 0 || asoc == 65535)
+ {
+ image->comps[cn].alpha = info[i].typ;
+ continue;
+ }
+
+ acn = (OPJ_UINT16)(asoc - 1);
+ if( acn >= image->numcomps )
+ {
+ opj_event_msg(manager, EVT_WARNING, "opj_jp2_apply_cdef: acn=%d, numcomps=%d\n", acn, image->numcomps);
+ continue;
+ }
+
+ /* Swap only if color channel */
+ if((cn != acn) && (info[i].typ == 0))
{
opj_image_comp_t saved;
-
+ OPJ_UINT16 j;
+
memcpy(&saved, &image->comps[cn], sizeof(opj_image_comp_t));
memcpy(&image->comps[cn], &image->comps[acn], sizeof(opj_image_comp_t));
memcpy(&image->comps[acn], &saved, sizeof(opj_image_comp_t));
-
- info[i].asoc = (OPJ_UINT16)(cn + 1);
- info[acn].asoc = (OPJ_UINT16)(info[acn].cn + 1);
+
+ /* Swap channels in following channel definitions, don't bother with j <= i that are already processed */
+ for (j = (OPJ_UINT16)(i + 1U); j < n ; ++j)
+ {
+ if (info[j].cn == cn) {
+ info[j].cn = acn;
+ }
+ else if (info[j].cn == acn) {
+ info[j].cn = cn;
+ }
+ /* asoc is related to color index. Do not update. */
+ }
}
-
+
image->comps[cn].alpha = info[i].typ;
}
-
+
if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
-
+
opj_free(color->jp2_cdef); color->jp2_cdef = NULL;
-
+
}/* jp2_apply_cdef() */
-OPJ_BOOL opj_jp2_read_cdef( opj_jp2_t * jp2,
+static OPJ_BOOL opj_jp2_read_cdef( opj_jp2_t * jp2,
OPJ_BYTE * p_cdef_header_data,
OPJ_UINT32 p_cdef_header_size,
opj_event_mgr_t * p_manager
@@ -1170,15 +1330,15 @@ OPJ_BOOL opj_jp2_read_cdef( opj_jp2_t * jp2,
}
cdef_info = (opj_jp2_cdef_info_t*) opj_malloc(l_value * sizeof(opj_jp2_cdef_info_t));
- if (!cdef_info)
- return OPJ_FALSE;
+ if (!cdef_info)
+ return OPJ_FALSE;
jp2->color.jp2_cdef = (opj_jp2_cdef_t*)opj_malloc(sizeof(opj_jp2_cdef_t));
- if(!jp2->color.jp2_cdef)
- {
- opj_free(cdef_info);
- return OPJ_FALSE;
- }
+ if(!jp2->color.jp2_cdef)
+ {
+ opj_free(cdef_info);
+ return OPJ_FALSE;
+ }
jp2->color.jp2_cdef->info = cdef_info;
jp2->color.jp2_cdef->n = (OPJ_UINT16) l_value;
@@ -1199,7 +1359,7 @@ OPJ_BOOL opj_jp2_read_cdef( opj_jp2_t * jp2,
return OPJ_TRUE;
}
-OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2,
+static OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2,
OPJ_BYTE * p_colr_header_data,
OPJ_UINT32 p_colr_header_size,
opj_event_mgr_t * p_manager
@@ -1240,14 +1400,63 @@ OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2,
opj_event_msg(p_manager, EVT_ERROR, "Bad COLR header box (bad size: %d)\n", p_colr_header_size);
return OPJ_FALSE;
}
- if (p_colr_header_size > 7) {
+ if ((p_colr_header_size > 7) && (jp2->enumcs != 14)) { /* handled below for CIELab) */
/* testcase Altona_Technical_v20_x4.pdf */
opj_event_msg(p_manager, EVT_WARNING, "Bad COLR header box (bad size: %d)\n", p_colr_header_size);
}
opj_read_bytes(p_colr_header_data,&jp2->enumcs ,4); /* EnumCS */
-
- jp2->color.jp2_has_colr = 1;
+
+ p_colr_header_data += 4;
+
+ if(jp2->enumcs == 14)/* CIELab */
+ {
+ OPJ_UINT32 *cielab;
+ OPJ_UINT32 rl, ol, ra, oa, rb, ob, il;
+
+ cielab = (OPJ_UINT32*)opj_malloc(9 * sizeof(OPJ_UINT32));
+ if(cielab == NULL){
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory for cielab\n");
+ return OPJ_FALSE;
+ }
+ cielab[0] = 14; /* enumcs */
+
+ /* default values */
+ rl = ra = rb = ol = oa = ob = 0;
+ il = 0x00443530; /* D50 */
+ cielab[1] = 0x44454600;/* DEF */
+
+ if(p_colr_header_size == 35)
+ {
+ opj_read_bytes(p_colr_header_data, &rl, 4);
+ p_colr_header_data += 4;
+ opj_read_bytes(p_colr_header_data, &ol, 4);
+ p_colr_header_data += 4;
+ opj_read_bytes(p_colr_header_data, &ra, 4);
+ p_colr_header_data += 4;
+ opj_read_bytes(p_colr_header_data, &oa, 4);
+ p_colr_header_data += 4;
+ opj_read_bytes(p_colr_header_data, &rb, 4);
+ p_colr_header_data += 4;
+ opj_read_bytes(p_colr_header_data, &ob, 4);
+ p_colr_header_data += 4;
+ opj_read_bytes(p_colr_header_data, &il, 4);
+ p_colr_header_data += 4;
+
+ cielab[1] = 0;
+ }
+ else if(p_colr_header_size != 7)
+ {
+ opj_event_msg(p_manager, EVT_WARNING, "Bad COLR header box (CIELab, bad size: %d)\n", p_colr_header_size);
+ }
+ cielab[2] = rl; cielab[4] = ra; cielab[6] = rb;
+ cielab[3] = ol; cielab[5] = oa; cielab[7] = ob;
+ cielab[8] = il;
+
+ jp2->color.icc_profile_buf = (OPJ_BYTE*)cielab;
+ jp2->color.icc_profile_len = 0;
+ }
+ jp2->color.jp2_has_colr = 1;
}
else if (jp2->meth == 2) {
/* ICC profile */
@@ -1255,13 +1464,12 @@ OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2,
OPJ_INT32 icc_len = (OPJ_INT32)p_colr_header_size - 3;
jp2->color.icc_profile_len = (OPJ_UINT32)icc_len;
- jp2->color.icc_profile_buf = (OPJ_BYTE*) opj_malloc((size_t)icc_len);
- if (!jp2->color.icc_profile_buf)
- {
- jp2->color.icc_profile_len = 0;
- return OPJ_FALSE;
- }
- memset(jp2->color.icc_profile_buf, 0, (size_t)icc_len * sizeof(OPJ_BYTE));
+ jp2->color.icc_profile_buf = (OPJ_BYTE*) opj_calloc(1,(size_t)icc_len);
+ if (!jp2->color.icc_profile_buf)
+ {
+ jp2->color.icc_profile_len = 0;
+ return OPJ_FALSE;
+ }
for (it_icc_value = 0; it_icc_value < icc_len; ++it_icc_value)
{
@@ -1270,16 +1478,16 @@ OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2,
jp2->color.icc_profile_buf[it_icc_value] = (OPJ_BYTE) l_value;
}
- jp2->color.jp2_has_colr = 1;
+ jp2->color.jp2_has_colr = 1;
}
else if (jp2->meth > 2)
- {
- /* ISO/IEC 15444-1:2004 (E), Table I.9 ­ Legal METH values:
- conforming JP2 reader shall ignore the entire Colour Specification box.*/
- opj_event_msg(p_manager, EVT_INFO, "COLR BOX meth value is not a regular value (%d), "
- "so we will ignore the entire Colour Specification box. \n", jp2->meth);
- }
- return OPJ_TRUE;
+ {
+ /* ISO/IEC 15444-1:2004 (E), Table I.9 Legal METH values:
+ conforming JP2 reader shall ignore the entire Colour Specification box.*/
+ opj_event_msg(p_manager, EVT_INFO, "COLR BOX meth value is not a regular value (%d), "
+ "so we will ignore the entire Colour Specification box. \n", jp2->meth);
+ }
+ return OPJ_TRUE;
}
OPJ_BOOL opj_jp2_decode(opj_jp2_t *jp2,
@@ -1296,52 +1504,54 @@ OPJ_BOOL opj_jp2_decode(opj_jp2_t *jp2,
return OPJ_FALSE;
}
- if (!jp2->ignore_pclr_cmap_cdef){
- if (!opj_jp2_check_color(p_image, &(jp2->color), p_manager)) {
- return OPJ_FALSE;
- }
-
- /* Set Image Color Space */
- if (jp2->enumcs == 16)
- p_image->color_space = OPJ_CLRSPC_SRGB;
- else if (jp2->enumcs == 17)
- p_image->color_space = OPJ_CLRSPC_GRAY;
- else if (jp2->enumcs == 18)
- p_image->color_space = OPJ_CLRSPC_SYCC;
- else if (jp2->enumcs == 24)
- p_image->color_space = OPJ_CLRSPC_EYCC;
- else
- p_image->color_space = OPJ_CLRSPC_UNKNOWN;
-
- /* Apply the color space if needed */
- if(jp2->color.jp2_cdef) {
- opj_jp2_apply_cdef(p_image, &(jp2->color));
- }
-
- if(jp2->color.jp2_pclr) {
- /* Part 1, I.5.3.4: Either both or none : */
- if( !jp2->color.jp2_pclr->cmap)
- opj_jp2_free_pclr(&(jp2->color));
- else
- opj_jp2_apply_pclr(p_image, &(jp2->color));
- }
-
- if(jp2->color.icc_profile_buf) {
- p_image->icc_profile_buf = jp2->color.icc_profile_buf;
- p_image->icc_profile_len = jp2->color.icc_profile_len;
- jp2->color.icc_profile_buf = NULL;
- }
- }
+ if (!jp2->ignore_pclr_cmap_cdef){
+ if (!opj_jp2_check_color(p_image, &(jp2->color), p_manager)) {
+ return OPJ_FALSE;
+ }
+
+ /* Set Image Color Space */
+ if (jp2->enumcs == 16)
+ p_image->color_space = OPJ_CLRSPC_SRGB;
+ else if (jp2->enumcs == 17)
+ p_image->color_space = OPJ_CLRSPC_GRAY;
+ else if (jp2->enumcs == 18)
+ p_image->color_space = OPJ_CLRSPC_SYCC;
+ else if (jp2->enumcs == 24)
+ p_image->color_space = OPJ_CLRSPC_EYCC;
+ else if (jp2->enumcs == 12)
+ p_image->color_space = OPJ_CLRSPC_CMYK;
+ else
+ p_image->color_space = OPJ_CLRSPC_UNKNOWN;
+
+ if(jp2->color.jp2_pclr) {
+ /* Part 1, I.5.3.4: Either both or none : */
+ if( !jp2->color.jp2_pclr->cmap)
+ opj_jp2_free_pclr(&(jp2->color));
+ else
+ opj_jp2_apply_pclr(p_image, &(jp2->color));
+ }
+
+ /* Apply the color space if needed */
+ if(jp2->color.jp2_cdef) {
+ opj_jp2_apply_cdef(p_image, &(jp2->color), p_manager);
+ }
+
+ if(jp2->color.icc_profile_buf) {
+ p_image->icc_profile_buf = jp2->color.icc_profile_buf;
+ p_image->icc_profile_len = jp2->color.icc_profile_len;
+ jp2->color.icc_profile_buf = NULL;
+ }
+ }
return OPJ_TRUE;
}
-OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2,
+static OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2,
opj_stream_private_t *stream,
opj_event_mgr_t * p_manager
)
{
- opj_jp2_img_header_writer_handler_t l_writers [3];
+ opj_jp2_img_header_writer_handler_t l_writers [4];
opj_jp2_img_header_writer_handler_t * l_current_writer;
OPJ_INT32 i, l_nb_pass;
@@ -1371,6 +1581,11 @@ OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2,
l_writers[1].handler = opj_jp2_write_colr;
}
+ if (jp2->color.jp2_cdef != NULL) {
+ l_writers[l_nb_pass].handler = opj_jp2_write_cdef;
+ l_nb_pass++;
+ }
+
/* write box header */
/* write JP2H type */
opj_write_bytes(l_jp2h_data+4,JP2_JP2H,4);
@@ -1434,12 +1649,12 @@ OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2,
return l_result;
}
-OPJ_BOOL opj_jp2_write_ftyp(opj_jp2_t *jp2,
+static OPJ_BOOL opj_jp2_write_ftyp(opj_jp2_t *jp2,
opj_stream_private_t *cio,
opj_event_mgr_t * p_manager )
{
OPJ_UINT32 i;
- OPJ_UINT32 l_ftyp_size = 16 + 4 * jp2->numcl;
+ OPJ_UINT32 l_ftyp_size;
OPJ_BYTE * l_ftyp_data, * l_current_data_ptr;
OPJ_BOOL l_result;
@@ -1447,16 +1662,15 @@ OPJ_BOOL opj_jp2_write_ftyp(opj_jp2_t *jp2,
assert(cio != 00);
assert(jp2 != 00);
assert(p_manager != 00);
+ l_ftyp_size = 16 + 4 * jp2->numcl;
- l_ftyp_data = (OPJ_BYTE *) opj_malloc(l_ftyp_size);
+ l_ftyp_data = (OPJ_BYTE *) opj_calloc(1,l_ftyp_size);
if (l_ftyp_data == 00) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle ftyp data\n");
return OPJ_FALSE;
}
- memset(l_ftyp_data,0,l_ftyp_size);
-
l_current_data_ptr = l_ftyp_data;
opj_write_bytes(l_current_data_ptr, l_ftyp_size,4); /* box size */
@@ -1486,7 +1700,7 @@ OPJ_BOOL opj_jp2_write_ftyp(opj_jp2_t *jp2,
return l_result;
}
-OPJ_BOOL opj_jp2_write_jp2c(opj_jp2_t *jp2,
+static OPJ_BOOL opj_jp2_write_jp2c(opj_jp2_t *jp2,
opj_stream_private_t *cio,
opj_event_mgr_t * p_manager )
{
@@ -1523,7 +1737,7 @@ OPJ_BOOL opj_jp2_write_jp2c(opj_jp2_t *jp2,
return OPJ_TRUE;
}
-OPJ_BOOL opj_jp2_write_jp( opj_jp2_t *jp2,
+static OPJ_BOOL opj_jp2_write_jp( opj_jp2_t *jp2,
opj_stream_private_t *cio,
opj_event_mgr_t * p_manager )
{
@@ -1560,24 +1774,33 @@ void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters)
/* further JP2 initializations go here */
jp2->color.jp2_has_colr = 0;
- jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
+ jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
+}
+
+OPJ_BOOL opj_jp2_set_threads(opj_jp2_t *jp2, OPJ_UINT32 num_threads)
+{
+ return opj_j2k_set_threads(jp2->j2k, num_threads);
}
/* ----------------------------------------------------------------------- */
/* JP2 encoder interface */
/* ----------------------------------------------------------------------- */
-void opj_jp2_setup_encoder( opj_jp2_t *jp2,
+OPJ_BOOL opj_jp2_setup_encoder( opj_jp2_t *jp2,
opj_cparameters_t *parameters,
opj_image_t *image,
opj_event_mgr_t * p_manager)
{
- OPJ_UINT32 i;
+ OPJ_UINT32 i;
OPJ_UINT32 depth_0;
OPJ_UINT32 sign;
+ OPJ_UINT32 alpha_count;
+ OPJ_UINT32 color_channels = 0U;
+ OPJ_UINT32 alpha_channel = 0U;
+
if(!jp2 || !parameters || !image)
- return;
+ return OPJ_FALSE;
/* setup the J2K codec */
/* ------------------- */
@@ -1585,10 +1808,12 @@ void opj_jp2_setup_encoder( opj_jp2_t *jp2,
/* Check if number of components respects standard */
if (image->numcomps < 1 || image->numcomps > 16384) {
opj_event_msg(p_manager, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n");
- return;
+ return OPJ_FALSE;
}
- opj_j2k_setup_encoder(jp2->j2k, parameters, image, p_manager );
+ if (opj_j2k_setup_encoder(jp2->j2k, parameters, image, p_manager ) == OPJ_FALSE) {
+ return OPJ_FALSE;
+ }
/* setup the JP2 codec */
/* ------------------- */
@@ -1599,22 +1824,21 @@ void opj_jp2_setup_encoder( opj_jp2_t *jp2,
jp2->minversion = 0; /* MinV */
jp2->numcl = 1;
jp2->cl = (OPJ_UINT32*) opj_malloc(jp2->numcl * sizeof(OPJ_UINT32));
- if (!jp2->cl){
- jp2->cl = NULL;
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
- return;
- }
+ if (!jp2->cl){
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
+ return OPJ_FALSE;
+ }
jp2->cl[0] = JP2_JP2; /* CL0 : JP2 */
/* Image Header box */
jp2->numcomps = image->numcomps; /* NC */
jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
- if (!jp2->comps) {
- jp2->comps = NULL;
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
- return;
- }
+ if (!jp2->comps) {
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
+ /* Memory of jp2->cl will be freed by opj_jp2_destroy */
+ return OPJ_FALSE;
+ }
jp2->h = image->y1 - image->y0; /* HEIGHT */
jp2->w = image->x1 - image->x0; /* WIDTH */
@@ -1652,11 +1876,81 @@ void opj_jp2_setup_encoder( opj_jp2_t *jp2,
jp2->enumcs = 18; /* YUV */
}
+ /* Channel Definition box */
+ /* FIXME not provided by parameters */
+ /* We try to do what we can... */
+ alpha_count = 0U;
+ for (i = 0; i < image->numcomps; i++) {
+ if (image->comps[i].alpha != 0) {
+ alpha_count++;
+ alpha_channel = i;
+ }
+ }
+ if (alpha_count == 1U) { /* no way to deal with more than 1 alpha channel */
+ switch (jp2->enumcs) {
+ case 16:
+ case 18:
+ color_channels = 3;
+ break;
+ case 17:
+ color_channels = 1;
+ break;
+ default:
+ alpha_count = 0U;
+ break;
+ }
+ if (alpha_count == 0U) {
+ opj_event_msg(p_manager, EVT_WARNING, "Alpha channel specified but unknown enumcs. No cdef box will be created.\n");
+ } else if (image->numcomps < (color_channels+1)) {
+ opj_event_msg(p_manager, EVT_WARNING, "Alpha channel specified but not enough image components for an automatic cdef box creation.\n");
+ alpha_count = 0U;
+ } else if ((OPJ_UINT32)alpha_channel < color_channels) {
+ opj_event_msg(p_manager, EVT_WARNING, "Alpha channel position conflicts with color channel. No cdef box will be created.\n");
+ alpha_count = 0U;
+ }
+ } else if (alpha_count > 1) {
+ opj_event_msg(p_manager, EVT_WARNING, "Multiple alpha channels specified. No cdef box will be created.\n");
+ }
+ if (alpha_count == 1U) { /* if here, we know what we can do */
+ jp2->color.jp2_cdef = (opj_jp2_cdef_t*)opj_malloc(sizeof(opj_jp2_cdef_t));
+ if(!jp2->color.jp2_cdef) {
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup the JP2 encoder\n");
+ return OPJ_FALSE;
+ }
+ /* no memset needed, all values will be overwritten except if jp2->color.jp2_cdef->info allocation fails, */
+ /* in which case jp2->color.jp2_cdef->info will be NULL => valid for destruction */
+ jp2->color.jp2_cdef->info = (opj_jp2_cdef_info_t*) opj_malloc(image->numcomps * sizeof(opj_jp2_cdef_info_t));
+ if (!jp2->color.jp2_cdef->info) {
+ /* memory will be freed by opj_jp2_destroy */
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup the JP2 encoder\n");
+ return OPJ_FALSE;
+ }
+ jp2->color.jp2_cdef->n = (OPJ_UINT16) image->numcomps; /* cast is valid : image->numcomps [1,16384] */
+ for (i = 0U; i < color_channels; i++) {
+ jp2->color.jp2_cdef->info[i].cn = (OPJ_UINT16)i; /* cast is valid : image->numcomps [1,16384] */
+ jp2->color.jp2_cdef->info[i].typ = 0U;
+ jp2->color.jp2_cdef->info[i].asoc = (OPJ_UINT16)(i+1U); /* No overflow + cast is valid : image->numcomps [1,16384] */
+ }
+ for (; i < image->numcomps; i++) {
+ if (image->comps[i].alpha != 0) { /* we'll be here exactly once */
+ jp2->color.jp2_cdef->info[i].cn = (OPJ_UINT16)i; /* cast is valid : image->numcomps [1,16384] */
+ jp2->color.jp2_cdef->info[i].typ = 1U; /* Opacity channel */
+ jp2->color.jp2_cdef->info[i].asoc = 0U; /* Apply alpha channel to the whole image */
+ } else {
+ /* Unknown channel */
+ jp2->color.jp2_cdef->info[i].cn = (OPJ_UINT16)i; /* cast is valid : image->numcomps [1,16384] */
+ jp2->color.jp2_cdef->info[i].typ = 65535U;
+ jp2->color.jp2_cdef->info[i].asoc = 65535U;
+ }
+ }
+ }
jp2->precedence = 0; /* PRECEDENCE */
jp2->approx = 0; /* APPROX */
jp2->jpip_on = parameters->jpip_on;
+
+ return OPJ_TRUE;
}
OPJ_BOOL opj_jp2_encode(opj_jp2_t *jp2,
@@ -1677,7 +1971,9 @@ OPJ_BOOL opj_jp2_end_decompress(opj_jp2_t *jp2,
assert(p_manager != 00);
/* customization of the end encoding */
- opj_jp2_setup_end_header_reading(jp2);
+ if (! opj_jp2_setup_end_header_reading(jp2, p_manager)) {
+ return OPJ_FALSE;
+ }
/* write header */
if (! opj_jp2_exec (jp2,jp2->m_procedure_list,cio,p_manager)) {
@@ -1698,7 +1994,9 @@ OPJ_BOOL opj_jp2_end_compress( opj_jp2_t *jp2,
assert(p_manager != 00);
/* customization of the end encoding */
- opj_jp2_setup_end_header_writing(jp2);
+ if (! opj_jp2_setup_end_header_writing(jp2, p_manager)) {
+ return OPJ_FALSE;
+ }
if (! opj_j2k_end_compress(jp2->j2k,cio,p_manager)) {
return OPJ_FALSE;
@@ -1708,35 +2006,52 @@ OPJ_BOOL opj_jp2_end_compress( opj_jp2_t *jp2,
return opj_jp2_exec(jp2,jp2->m_procedure_list,cio,p_manager);
}
-void opj_jp2_setup_end_header_writing (opj_jp2_t *jp2)
+static OPJ_BOOL opj_jp2_setup_end_header_writing (opj_jp2_t *jp2, opj_event_mgr_t * p_manager)
{
/* preconditions */
assert(jp2 != 00);
+ assert(p_manager != 00);
#ifdef USE_JPIP
- if( jp2->jpip_on )
- opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_iptr );
+ if( jp2->jpip_on ) {
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_iptr, p_manager)) {
+ return OPJ_FALSE;
+ }
+ }
#endif
- opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp2c );
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp2c, p_manager)) {
+ return OPJ_FALSE;
+ }
/* DEVELOPER CORNER, add your custom procedures */
#ifdef USE_JPIP
if( jp2->jpip_on )
- {
- opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_cidx );
- opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_fidx );
- }
+ {
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_cidx, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_fidx, p_manager)) {
+ return OPJ_FALSE;
+ }
+ }
#endif
+ return OPJ_TRUE;
}
-void opj_jp2_setup_end_header_reading (opj_jp2_t *jp2)
+static OPJ_BOOL opj_jp2_setup_end_header_reading (opj_jp2_t *jp2, opj_event_mgr_t * p_manager)
{
/* preconditions */
assert(jp2 != 00);
- opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_read_header_procedure );
+ assert(p_manager != 00);
+
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_read_header_procedure, p_manager)) {
+ return OPJ_FALSE;
+ }
/* DEVELOPER CORNER, add your custom procedures */
+
+ return OPJ_TRUE;
}
-OPJ_BOOL opj_jp2_default_validation ( opj_jp2_t * jp2,
+static OPJ_BOOL opj_jp2_default_validation ( opj_jp2_t * jp2,
opj_stream_private_t *cio,
opj_event_mgr_t * p_manager
)
@@ -1777,7 +2092,7 @@ OPJ_BOOL opj_jp2_default_validation ( opj_jp2_t * jp2,
l_is_valid &= (jp2->w > 0);
/* precision */
for (i = 0; i < jp2->numcomps; ++i) {
- l_is_valid &= (jp2->comps[i].bpcc > 0);
+ l_is_valid &= ((jp2->comps[i].bpcc & 0x7FU) < 38U); /* 0 is valid, ignore sign for check */
}
/* METH */
@@ -1790,7 +2105,7 @@ OPJ_BOOL opj_jp2_default_validation ( opj_jp2_t * jp2,
return l_is_valid;
}
-OPJ_BOOL opj_jp2_read_header_procedure( opj_jp2_t *jp2,
+static OPJ_BOOL opj_jp2_read_header_procedure( opj_jp2_t *jp2,
opj_stream_private_t *stream,
opj_event_mgr_t * p_manager
)
@@ -1798,6 +2113,7 @@ OPJ_BOOL opj_jp2_read_header_procedure( opj_jp2_t *jp2,
opj_jp2_box_t box;
OPJ_UINT32 l_nb_bytes_read;
const opj_jp2_header_handler_t * l_current_handler;
+ const opj_jp2_header_handler_t * l_current_handler_misplaced;
OPJ_UINT32 l_last_data_size = OPJ_BOX_SIZE;
OPJ_UINT32 l_current_data_size;
OPJ_BYTE * l_current_data = 00;
@@ -1807,20 +2123,19 @@ OPJ_BOOL opj_jp2_read_header_procedure( opj_jp2_t *jp2,
assert(jp2 != 00);
assert(p_manager != 00);
- l_current_data = (OPJ_BYTE*)opj_malloc(l_last_data_size);
+ l_current_data = (OPJ_BYTE*)opj_calloc(1,l_last_data_size);
if (l_current_data == 00) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle jpeg2000 file header\n");
return OPJ_FALSE;
}
- memset(l_current_data, 0 , l_last_data_size);
while (opj_jp2_read_boxhdr(&box,&l_nb_bytes_read,stream,p_manager)) {
/* is it the codestream box ? */
if (box.type == JP2_JP2C) {
if (jp2->jp2_state & JP2_STATE_HEADER) {
jp2->jp2_state |= JP2_STATE_CODESTREAM;
- opj_free(l_current_data);
+ opj_free(l_current_data);
return OPJ_TRUE;
}
else {
@@ -1835,16 +2150,39 @@ OPJ_BOOL opj_jp2_read_header_procedure( opj_jp2_t *jp2,
return OPJ_FALSE;
}
/* testcase 1851.pdf.SIGSEGV.ce9.948 */
- else if (box.length < l_nb_bytes_read) {
+ else if (box.length < l_nb_bytes_read) {
opj_event_msg(p_manager, EVT_ERROR, "invalid box size %d (%x)\n", box.length, box.type);
opj_free(l_current_data);
return OPJ_FALSE;
}
l_current_handler = opj_jp2_find_handler(box.type);
+ l_current_handler_misplaced = opj_jp2_img_find_handler(box.type);
l_current_data_size = box.length - l_nb_bytes_read;
- if (l_current_handler != 00) {
+ if ((l_current_handler != 00) || (l_current_handler_misplaced != 00)) {
+ if (l_current_handler == 00) {
+ opj_event_msg(p_manager, EVT_WARNING, "Found a misplaced '%c%c%c%c' box outside jp2h box\n", (OPJ_BYTE)(box.type>>24), (OPJ_BYTE)(box.type>>16), (OPJ_BYTE)(box.type>>8), (OPJ_BYTE)(box.type>>0));
+ if (jp2->jp2_state & JP2_STATE_HEADER) {
+ /* read anyway, we already have jp2h */
+ l_current_handler = l_current_handler_misplaced;
+ } else {
+ opj_event_msg(p_manager, EVT_WARNING, "JPEG2000 Header box not read yet, '%c%c%c%c' box will be ignored\n", (OPJ_BYTE)(box.type>>24), (OPJ_BYTE)(box.type>>16), (OPJ_BYTE)(box.type>>8), (OPJ_BYTE)(box.type>>0));
+ jp2->jp2_state |= JP2_STATE_UNKNOWN;
+ if (opj_stream_skip(stream,l_current_data_size,p_manager) != l_current_data_size) {
+ opj_event_msg(p_manager, EVT_ERROR, "Problem with skipping JPEG2000 box, stream error\n");
+ opj_free(l_current_data);
+ return OPJ_FALSE;
+ }
+ continue;
+ }
+ }
+ if ((OPJ_OFF_T)l_current_data_size > opj_stream_get_number_byte_left(stream)) {
+ /* do not even try to malloc if we can't read */
+ opj_event_msg(p_manager, EVT_ERROR, "Invalid box size %d for box '%c%c%c%c'. Need %d bytes, %d bytes remaining \n", box.length, (OPJ_BYTE)(box.type>>24), (OPJ_BYTE)(box.type>>16), (OPJ_BYTE)(box.type>>8), (OPJ_BYTE)(box.type>>0), l_current_data_size, (OPJ_UINT32)opj_stream_get_number_byte_left(stream));
+ opj_free(l_current_data);
+ return OPJ_FALSE;
+ }
if (l_current_data_size > l_last_data_size) {
OPJ_BYTE* new_current_data = (OPJ_BYTE*)opj_realloc(l_current_data,l_current_data_size);
if (!new_current_data) {
@@ -1869,6 +2207,16 @@ OPJ_BOOL opj_jp2_read_header_procedure( opj_jp2_t *jp2,
}
}
else {
+ if (!(jp2->jp2_state & JP2_STATE_SIGNATURE)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Malformed JP2 file format: first box must be JPEG 2000 signature box\n");
+ opj_free(l_current_data);
+ return OPJ_FALSE;
+ }
+ if (!(jp2->jp2_state & JP2_STATE_FILE_TYPE)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Malformed JP2 file format: second box must be file type box\n");
+ opj_free(l_current_data);
+ return OPJ_FALSE;
+ }
jp2->jp2_state |= JP2_STATE_UNKNOWN;
if (opj_stream_skip(stream,l_current_data_size,p_manager) != l_current_data_size) {
opj_event_msg(p_manager, EVT_ERROR, "Problem with skipping JPEG2000 box, stream error\n");
@@ -1935,7 +2283,9 @@ OPJ_BOOL opj_jp2_start_compress(opj_jp2_t *jp2,
assert(p_manager != 00);
/* customization of the validation */
- opj_jp2_setup_encoding_validation (jp2);
+ if (! opj_jp2_setup_encoding_validation (jp2, p_manager)) {
+ return OPJ_FALSE;
+ }
/* validation of the parameters codec */
if (! opj_jp2_exec(jp2,jp2->m_validation_list,stream,p_manager)) {
@@ -1943,7 +2293,9 @@ OPJ_BOOL opj_jp2_start_compress(opj_jp2_t *jp2,
}
/* customization of the encoding */
- opj_jp2_setup_header_writing(jp2);
+ if (! opj_jp2_setup_header_writing(jp2, p_manager)) {
+ return OPJ_FALSE;
+ }
/* write header */
if (! opj_jp2_exec (jp2,jp2->m_procedure_list,stream,p_manager)) {
@@ -1953,7 +2305,7 @@ OPJ_BOOL opj_jp2_start_compress(opj_jp2_t *jp2,
return opj_j2k_start_compress(jp2->j2k,stream,p_image,p_manager);
}
-const opj_jp2_header_handler_t * opj_jp2_find_handler (OPJ_UINT32 p_id)
+static const opj_jp2_header_handler_t * opj_jp2_find_handler (OPJ_UINT32 p_id)
{
OPJ_UINT32 i, l_handler_size = sizeof(jp2_header) / sizeof(opj_jp2_header_handler_t);
@@ -2083,12 +2435,11 @@ static OPJ_BOOL opj_jp2_read_ftyp( opj_jp2_t *jp2,
/* div by 4 */
jp2->numcl = l_remaining_bytes >> 2;
if (jp2->numcl) {
- jp2->cl = (OPJ_UINT32 *) opj_malloc(jp2->numcl * sizeof(OPJ_UINT32));
+ jp2->cl = (OPJ_UINT32 *) opj_calloc(jp2->numcl, sizeof(OPJ_UINT32));
if (jp2->cl == 00) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory with FTYP Box\n");
return OPJ_FALSE;
}
- memset(jp2->cl,0,jp2->numcl * sizeof(OPJ_UINT32));
}
for (i = 0; i < jp2->numcl; ++i)
@@ -2102,7 +2453,7 @@ static OPJ_BOOL opj_jp2_read_ftyp( opj_jp2_t *jp2,
return OPJ_TRUE;
}
-OPJ_BOOL opj_jp2_skip_jp2c( opj_jp2_t *jp2,
+static OPJ_BOOL opj_jp2_skip_jp2c( opj_jp2_t *jp2,
opj_stream_private_t *stream,
opj_event_mgr_t * p_manager )
{
@@ -2146,7 +2497,7 @@ static OPJ_BOOL opj_jpip_skip_iptr( opj_jp2_t *jp2,
* @param p_header_size the size of the data contained in the file header box.
* @param p_manager the user event manager.
*
- * @return true if the JP2 Header box was successfully reconized.
+ * @return true if the JP2 Header box was successfully recognized.
*/
static OPJ_BOOL opj_jp2_read_jp2h( opj_jp2_t *jp2,
OPJ_BYTE *p_header_data,
@@ -2157,6 +2508,7 @@ static OPJ_BOOL opj_jp2_read_jp2h( opj_jp2_t *jp2,
OPJ_UINT32 l_box_size=0, l_current_data_size = 0;
opj_jp2_box_t box;
const opj_jp2_header_handler_t * l_current_handler;
+ OPJ_BOOL l_has_ihdr = 0;
/* preconditions */
assert(p_header_data != 00);
@@ -2197,16 +2549,25 @@ static OPJ_BOOL opj_jp2_read_jp2h( opj_jp2_t *jp2,
jp2->jp2_img_state |= JP2_IMG_STATE_UNKNOWN;
}
+ if (box.type == JP2_IHDR) {
+ l_has_ihdr = 1;
+ }
+
p_header_data += l_current_data_size;
p_header_size -= box.length;
}
+ if (l_has_ihdr == 0) {
+ opj_event_msg(p_manager, EVT_ERROR, "Stream error while reading JP2 Header box: no 'ihdr' box.\n");
+ return OPJ_FALSE;
+ }
+
jp2->jp2_state |= JP2_STATE_HEADER;
return OPJ_TRUE;
}
-OPJ_BOOL opj_jp2_read_boxhdr_char( opj_jp2_box_t *box,
+static OPJ_BOOL opj_jp2_read_boxhdr_char( opj_jp2_box_t *box,
OPJ_BYTE * p_data,
OPJ_UINT32 * p_number_bytes_read,
OPJ_UINT32 p_box_max_size,
@@ -2269,7 +2630,10 @@ OPJ_BOOL opj_jp2_read_boxhdr_char( opj_jp2_box_t *box,
opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n");
return OPJ_FALSE;
}
-
+ if (box->length < *p_number_bytes_read) {
+ opj_event_msg(p_manager, EVT_ERROR, "Box length is inconsistent.\n");
+ return OPJ_FALSE;
+ }
return OPJ_TRUE;
}
@@ -2285,10 +2649,14 @@ OPJ_BOOL opj_jp2_read_header( opj_stream_private_t *p_stream,
assert(p_manager != 00);
/* customization of the validation */
- opj_jp2_setup_decoding_validation (jp2);
+ if (! opj_jp2_setup_decoding_validation (jp2, p_manager)) {
+ return OPJ_FALSE;
+ }
/* customization of the encoding */
- opj_jp2_setup_header_reading(jp2);
+ if (! opj_jp2_setup_header_reading(jp2, p_manager)) {
+ return OPJ_FALSE;
+ }
/* validation of the parameters codec */
if (! opj_jp2_exec(jp2,jp2->m_validation_list,p_stream,p_manager)) {
@@ -2306,45 +2674,73 @@ OPJ_BOOL opj_jp2_read_header( opj_stream_private_t *p_stream,
p_manager);
}
-void opj_jp2_setup_encoding_validation (opj_jp2_t *jp2)
+static OPJ_BOOL opj_jp2_setup_encoding_validation (opj_jp2_t *jp2, opj_event_mgr_t * p_manager)
{
/* preconditions */
assert(jp2 != 00);
+ assert(p_manager != 00);
- opj_procedure_list_add_procedure(jp2->m_validation_list, (opj_procedure)opj_jp2_default_validation);
+ if (! opj_procedure_list_add_procedure(jp2->m_validation_list, (opj_procedure)opj_jp2_default_validation, p_manager)) {
+ return OPJ_FALSE;
+ }
/* DEVELOPER CORNER, add your custom validation procedure */
+
+ return OPJ_TRUE;
}
-void opj_jp2_setup_decoding_validation (opj_jp2_t *jp2)
+static OPJ_BOOL opj_jp2_setup_decoding_validation (opj_jp2_t *jp2, opj_event_mgr_t * p_manager)
{
/* preconditions */
assert(jp2 != 00);
+ assert(p_manager != 00);
+
/* DEVELOPER CORNER, add your custom validation procedure */
+
+ return OPJ_TRUE;
}
-void opj_jp2_setup_header_writing (opj_jp2_t *jp2)
+static OPJ_BOOL opj_jp2_setup_header_writing (opj_jp2_t *jp2, opj_event_mgr_t * p_manager)
{
/* preconditions */
assert(jp2 != 00);
+ assert(p_manager != 00);
- opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp );
- opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_ftyp );
- opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp2h );
- if( jp2->jpip_on )
- opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_skip_iptr );
- opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_skip_jp2c );
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_ftyp, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp2h, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if( jp2->jpip_on ) {
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_skip_iptr, p_manager)) {
+ return OPJ_FALSE;
+ }
+ }
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_skip_jp2c,p_manager)) {
+ return OPJ_FALSE;
+ }
/* DEVELOPER CORNER, insert your custom procedures */
+ return OPJ_TRUE;
}
-void opj_jp2_setup_header_reading (opj_jp2_t *jp2)
+static OPJ_BOOL opj_jp2_setup_header_reading (opj_jp2_t *jp2, opj_event_mgr_t * p_manager)
{
/* preconditions */
assert(jp2 != 00);
+ assert(p_manager != 00);
- opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_read_header_procedure );
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_read_header_procedure, p_manager)) {
+ return OPJ_FALSE;
+ }
+
/* DEVELOPER CORNER, add your custom procedures */
+
+ return OPJ_TRUE;
}
OPJ_BOOL opj_jp2_read_tile_header ( opj_jp2_t * p_jp2,
@@ -2500,14 +2896,13 @@ OPJ_BOOL opj_jp2_get_tile( opj_jp2_t *p_jp2,
p_image->color_space = OPJ_CLRSPC_GRAY;
else if (p_jp2->enumcs == 18)
p_image->color_space = OPJ_CLRSPC_SYCC;
+ else if (p_jp2->enumcs == 24)
+ p_image->color_space = OPJ_CLRSPC_EYCC;
+ else if (p_jp2->enumcs == 12)
+ p_image->color_space = OPJ_CLRSPC_CMYK;
else
p_image->color_space = OPJ_CLRSPC_UNKNOWN;
- /* Apply the color space if needed */
- if(p_jp2->color.jp2_cdef) {
- opj_jp2_apply_cdef(p_image, &(p_jp2->color));
- }
-
if(p_jp2->color.jp2_pclr) {
/* Part 1, I.5.3.4: Either both or none : */
if( !p_jp2->color.jp2_pclr->cmap)
@@ -2515,6 +2910,11 @@ OPJ_BOOL opj_jp2_get_tile( opj_jp2_t *p_jp2,
else
opj_jp2_apply_pclr(p_image, &(p_jp2->color));
}
+
+ /* Apply the color space if needed */
+ if(p_jp2->color.jp2_cdef) {
+ opj_jp2_apply_cdef(p_image, &(p_jp2->color), p_manager);
+ }
if(p_jp2->color.icc_profile_buf) {
p_image->icc_profile_buf = p_jp2->color.icc_profile_buf;
@@ -2531,9 +2931,8 @@ OPJ_BOOL opj_jp2_get_tile( opj_jp2_t *p_jp2,
opj_jp2_t* opj_jp2_create(OPJ_BOOL p_is_decoder)
{
- opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t));
+ opj_jp2_t *jp2 = (opj_jp2_t*)opj_calloc(1,sizeof(opj_jp2_t));
if (jp2) {
- memset(jp2,0,sizeof(opj_jp2_t));
/* create the J2K codec */
if (! p_is_decoder) {
diff --git a/openjpeg/src/lib/openjp2/jp2.h b/openjpeg/src/lib/openjp2/jp2.h
index c11d2f313..b54d0bfd5 100644
--- a/openjpeg/src/lib/openjp2/jp2.h
+++ b/openjpeg/src/lib/openjp2/jp2.h
@@ -90,7 +90,7 @@ typedef enum
JP2_IMG_STATE;
/**
-Channel description: channel index, type, assocation
+Channel description: channel index, type, association
*/
typedef struct opj_jp2_cdef_info
{
@@ -236,19 +236,6 @@ opj_jp2_img_header_writer_handler_t;
/* ----------------------------------------------------------------------- */
/**
- * Writes the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box).
- *
- * @param jp2 the jpeg2000 file codec.
- * @param stream the stream to write data to.
- * @param p_manager user event manager.
- *
- * @return true if writing was successful.
-*/
-OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2,
- opj_stream_private_t *stream,
- opj_event_mgr_t * p_manager );
-
-/**
Setup the decoder decoding parameters using user parameters.
Decoding parameters are returned in jp2->j2k->cp.
@param jp2 JP2 decompressor handle
@@ -256,6 +243,8 @@ Decoding parameters are returned in jp2->j2k->cp.
*/
void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters);
+OPJ_BOOL opj_jp2_set_threads(opj_jp2_t *jp2, OPJ_UINT32 num_threads);
+
/**
* Decode an image from a JPEG-2000 file stream
* @param jp2 JP2 decompressor handle
@@ -278,8 +267,9 @@ OPJ_BOOL opj_jp2_decode(opj_jp2_t *jp2,
* @param parameters compression parameters
* @param image input filled image
* @param p_manager FIXME DOC
+ * @return OPJ_TRUE if successful, OPJ_FALSE otherwise
*/
-void opj_jp2_setup_encoder( opj_jp2_t *jp2,
+OPJ_BOOL opj_jp2_setup_encoder( opj_jp2_t *jp2,
opj_cparameters_t *parameters,
opj_image_t *image,
opj_event_mgr_t * p_manager);
diff --git a/openjpeg/src/lib/openjp2/libopenjp2.pc.cmake.in b/openjpeg/src/lib/openjp2/libopenjp2.pc.cmake.in
deleted file mode 100644
index 62159b00a..000000000
--- a/openjpeg/src/lib/openjp2/libopenjp2.pc.cmake.in
+++ /dev/null
@@ -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}
diff --git a/openjpeg/src/lib/openjp2/mct.c b/openjpeg/src/lib/openjp2/mct.c
index 60ee0969d..e1f2f50dd 100644
--- a/openjpeg/src/lib/openjp2/mct.c
+++ b/openjpeg/src/lib/openjp2/mct.c
@@ -40,6 +40,12 @@
#ifdef __SSE__
#include <xmmintrin.h>
#endif
+#ifdef __SSE2__
+#include <emmintrin.h>
+#endif
+#ifdef __SSE4_1__
+#include <smmintrin.h>
+#endif
#include "opj_includes.h"
@@ -64,16 +70,61 @@ const OPJ_FLOAT64 * opj_mct_get_mct_norms_real ()
}
/* <summary> */
-/* Foward reversible MCT. */
+/* Forward reversible MCT. */
/* </summary> */
+#ifdef __SSE2__
void opj_mct_encode(
- OPJ_INT32* restrict c0,
- OPJ_INT32* restrict c1,
- OPJ_INT32* restrict c2,
+ OPJ_INT32* OPJ_RESTRICT c0,
+ OPJ_INT32* OPJ_RESTRICT c1,
+ OPJ_INT32* OPJ_RESTRICT c2,
OPJ_UINT32 n)
{
- OPJ_UINT32 i;
- for(i = 0; i < n; ++i) {
+ OPJ_SIZE_T i;
+ const OPJ_SIZE_T len = n;
+ /* buffer are aligned on 16 bytes */
+ assert( ((size_t)c0 & 0xf) == 0 );
+ assert( ((size_t)c1 & 0xf) == 0 );
+ assert( ((size_t)c2 & 0xf) == 0 );
+
+ for(i = 0; i < (len & ~3U); i += 4) {
+ __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]));
+ y = _mm_add_epi32(g, g);
+ y = _mm_add_epi32(y, b);
+ y = _mm_add_epi32(y, r);
+ y = _mm_srai_epi32(y, 2);
+ u = _mm_sub_epi32(b, g);
+ v = _mm_sub_epi32(r, g);
+ _mm_store_si128((__m128i *)&(c0[i]), y);
+ _mm_store_si128((__m128i *)&(c1[i]), u);
+ _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 = (r + (g * 2) + b) >> 2;
+ OPJ_INT32 u = b - g;
+ OPJ_INT32 v = r - g;
+ c0[i] = y;
+ c1[i] = u;
+ c2[i] = v;
+ }
+}
+#else
+void opj_mct_encode(
+ OPJ_INT32* OPJ_RESTRICT c0,
+ OPJ_INT32* OPJ_RESTRICT c1,
+ OPJ_INT32* OPJ_RESTRICT c2,
+ OPJ_UINT32 n)
+{
+ OPJ_SIZE_T i;
+ const OPJ_SIZE_T len = n;
+
+ for(i = 0; i < len; ++i) {
OPJ_INT32 r = c0[i];
OPJ_INT32 g = c1[i];
OPJ_INT32 b = c2[i];
@@ -85,14 +136,51 @@ void opj_mct_encode(
c2[i] = v;
}
}
+#endif
/* <summary> */
/* Inverse reversible MCT. */
/* </summary> */
+#ifdef __SSE2__
void opj_mct_decode(
- OPJ_INT32* restrict c0,
- OPJ_INT32* restrict c1,
- OPJ_INT32* restrict c2,
+ OPJ_INT32* OPJ_RESTRICT c0,
+ OPJ_INT32* OPJ_RESTRICT c1,
+ OPJ_INT32* OPJ_RESTRICT c2,
+ OPJ_UINT32 n)
+{
+ OPJ_SIZE_T i;
+ const OPJ_SIZE_T len = n;
+
+ for(i = 0; i < (len & ~3U); i += 4) {
+ __m128i r, g, b;
+ __m128i y = _mm_load_si128((const __m128i *)&(c0[i]));
+ __m128i u = _mm_load_si128((const __m128i *)&(c1[i]));
+ __m128i v = _mm_load_si128((const __m128i *)&(c2[i]));
+ g = y;
+ g = _mm_sub_epi32(g, _mm_srai_epi32(_mm_add_epi32(u, v), 2));
+ r = _mm_add_epi32(v, g);
+ b = _mm_add_epi32(u, g);
+ _mm_store_si128((__m128i *)&(c0[i]), r);
+ _mm_store_si128((__m128i *)&(c1[i]), g);
+ _mm_store_si128((__m128i *)&(c2[i]), b);
+ }
+ for (; i < len; ++i) {
+ OPJ_INT32 y = c0[i];
+ OPJ_INT32 u = c1[i];
+ OPJ_INT32 v = c2[i];
+ OPJ_INT32 g = y - ((u + v) >> 2);
+ OPJ_INT32 r = v + g;
+ OPJ_INT32 b = u + g;
+ c0[i] = r;
+ c1[i] = g;
+ c2[i] = b;
+ }
+}
+#else
+void opj_mct_decode(
+ OPJ_INT32* OPJ_RESTRICT c0,
+ OPJ_INT32* OPJ_RESTRICT c1,
+ OPJ_INT32* OPJ_RESTRICT c2,
OPJ_UINT32 n)
{
OPJ_UINT32 i;
@@ -108,6 +196,7 @@ void opj_mct_decode(
c2[i] = b;
}
}
+#endif
/* <summary> */
/* Get norm of basis function of reversible MCT. */
@@ -117,12 +206,154 @@ OPJ_FLOAT64 opj_mct_getnorm(OPJ_UINT32 compno) {
}
/* <summary> */
-/* Foward irreversible MCT. */
+/* Forward irreversible MCT. */
/* </summary> */
+#ifdef __SSE4_1__
void opj_mct_encode_real(
- OPJ_INT32* restrict c0,
- OPJ_INT32* restrict c1,
- OPJ_INT32* restrict c2,
+ OPJ_INT32* OPJ_RESTRICT c0,
+ OPJ_INT32* OPJ_RESTRICT c1,
+ OPJ_INT32* OPJ_RESTRICT c2,
+ OPJ_UINT32 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);
+
+ /*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;
+ }
+}
+#else
+void opj_mct_encode_real(
+ OPJ_INT32* OPJ_RESTRICT c0,
+ OPJ_INT32* OPJ_RESTRICT c1,
+ OPJ_INT32* OPJ_RESTRICT c2,
OPJ_UINT32 n)
{
OPJ_UINT32 i;
@@ -138,14 +369,15 @@ void opj_mct_encode_real(
c2[i] = v;
}
}
+#endif
/* <summary> */
/* Inverse irreversible MCT. */
/* </summary> */
void opj_mct_decode_real(
- OPJ_FLOAT32* restrict c0,
- OPJ_FLOAT32* restrict c1,
- OPJ_FLOAT32* restrict c2,
+ OPJ_FLOAT32* OPJ_RESTRICT c0,
+ OPJ_FLOAT32* OPJ_RESTRICT c1,
+ OPJ_FLOAT32* OPJ_RESTRICT c2,
OPJ_UINT32 n)
{
OPJ_UINT32 i;
diff --git a/openjpeg/src/lib/openjp2/mct.h b/openjpeg/src/lib/openjp2/mct.h
index 1c1f4d0c4..1bc722e39 100644
--- a/openjpeg/src/lib/openjp2/mct.h
+++ b/openjpeg/src/lib/openjp2/mct.h
@@ -60,7 +60,7 @@ Apply a reversible multi-component transform to an image
@param c2 Samples blue component
@param n Number of samples for each component
*/
-void opj_mct_encode(OPJ_INT32 *c0, OPJ_INT32 *c1, OPJ_INT32 *c2, OPJ_UINT32 n);
+void opj_mct_encode(OPJ_INT32* OPJ_RESTRICT c0, OPJ_INT32* OPJ_RESTRICT c1, OPJ_INT32* OPJ_RESTRICT c2, OPJ_UINT32 n);
/**
Apply a reversible multi-component inverse transform to an image
@param c0 Samples for luminance component
@@ -68,7 +68,7 @@ Apply a reversible multi-component inverse transform to an image
@param c2 Samples for blue chrominance component
@param n Number of samples for each component
*/
-void opj_mct_decode(OPJ_INT32 *c0, OPJ_INT32 *c1, OPJ_INT32 *c2, OPJ_UINT32 n);
+void opj_mct_decode(OPJ_INT32* OPJ_RESTRICT c0, OPJ_INT32* OPJ_RESTRICT c1, OPJ_INT32* OPJ_RESTRICT c2, OPJ_UINT32 n);
/**
Get norm of the basis function used for the reversible multi-component transform
@param compno Number of the component (0->Y, 1->U, 2->V)
@@ -83,7 +83,7 @@ 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 *c0, OPJ_INT32 *c1, OPJ_INT32 *c2, OPJ_UINT32 n);
+void opj_mct_encode_real(OPJ_INT32* OPJ_RESTRICT c0, OPJ_INT32* OPJ_RESTRICT c1, OPJ_INT32* OPJ_RESTRICT c2, OPJ_UINT32 n);
/**
Apply an irreversible multi-component inverse transform to an image
@param c0 Samples for luminance component
@@ -91,7 +91,7 @@ Apply an irreversible multi-component inverse transform to an image
@param c2 Samples for blue chrominance component
@param n Number of samples for each component
*/
-void opj_mct_decode_real(OPJ_FLOAT32* c0, OPJ_FLOAT32* c1, OPJ_FLOAT32* c2, OPJ_UINT32 n);
+void opj_mct_decode_real(OPJ_FLOAT32* OPJ_RESTRICT c0, OPJ_FLOAT32* OPJ_RESTRICT c1, OPJ_FLOAT32* OPJ_RESTRICT c2, OPJ_UINT32 n);
/**
Get norm of the basis function used for the irreversible multi-component transform
@param compno Number of the component (0->Y, 1->U, 2->V)
diff --git a/openjpeg/src/lib/openjp2/mqc.c b/openjpeg/src/lib/openjp2/mqc.c
index 18fcc4760..7119c3a5e 100644
--- a/openjpeg/src/lib/openjp2/mqc.c
+++ b/openjpeg/src/lib/openjp2/mqc.c
@@ -70,28 +70,6 @@ Fill mqc->c with 1's for flushing
@param mqc MQC handle
*/
static void opj_mqc_setbits(opj_mqc_t *mqc);
-/**
-FIXME DOC
-@param mqc MQC handle
-@return
-*/
-static INLINE OPJ_INT32 opj_mqc_mpsexchange(opj_mqc_t *const mqc);
-/**
-FIXME DOC
-@param mqc MQC handle
-@return
-*/
-static INLINE OPJ_INT32 opj_mqc_lpsexchange(opj_mqc_t *const mqc);
-/**
-Input a byte
-@param mqc MQC handle
-*/
-static INLINE void opj_mqc_bytein(opj_mqc_t *const mqc);
-/**
-Renormalize mqc->a and mqc->c while decoding
-@param mqc MQC handle
-*/
-static INLINE void opj_mqc_renormd(opj_mqc_t *const mqc);
/*@}*/
/*@}*/
@@ -202,14 +180,21 @@ static opj_mqc_state_t mqc_states[47 * 2] = {
==========================================================
*/
-void opj_mqc_byteout(opj_mqc_t *mqc) {
- if (*mqc->bp == 0xff) {
+static void opj_mqc_byteout(opj_mqc_t *mqc) {
+ /* avoid accessing uninitialized memory*/
+ if (mqc->bp == mqc->start-1) {
+ mqc->bp++;
+ *mqc->bp = (OPJ_BYTE)(mqc->c >> 19);
+ mqc->c &= 0x7ffff;
+ mqc->ct = 8;
+ }
+ else 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->c&0x8000000)==0) CHANGE */
+ if ((mqc->c & 0x8000000) == 0) {
mqc->bp++;
*mqc->bp = (OPJ_BYTE)(mqc->c >> 19);
mqc->c &= 0x7ffff;
@@ -232,7 +217,7 @@ void opj_mqc_byteout(opj_mqc_t *mqc) {
}
}
-void opj_mqc_renorme(opj_mqc_t *mqc) {
+static void opj_mqc_renorme(opj_mqc_t *mqc) {
do {
mqc->a <<= 1;
mqc->c <<= 1;
@@ -243,7 +228,7 @@ void opj_mqc_renorme(opj_mqc_t *mqc) {
} while ((mqc->a & 0x8000) == 0);
}
-void opj_mqc_codemps(opj_mqc_t *mqc) {
+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) {
@@ -258,7 +243,7 @@ void opj_mqc_codemps(opj_mqc_t *mqc) {
}
}
-void opj_mqc_codelps(opj_mqc_t *mqc) {
+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;
@@ -269,7 +254,7 @@ void opj_mqc_codelps(opj_mqc_t *mqc) {
opj_mqc_renorme(mqc);
}
-void opj_mqc_setbits(opj_mqc_t *mqc) {
+static void opj_mqc_setbits(opj_mqc_t *mqc) {
OPJ_UINT32 tempc = mqc->c + mqc->a;
mqc->c |= 0xffff;
if (mqc->c >= tempc) {
@@ -277,82 +262,6 @@ void opj_mqc_setbits(opj_mqc_t *mqc) {
}
}
-static INLINE OPJ_INT32 opj_mqc_mpsexchange(opj_mqc_t *const mqc) {
- OPJ_INT32 d;
- if (mqc->a < (*mqc->curctx)->qeval) {
- d = (OPJ_INT32)(1 - (*mqc->curctx)->mps);
- *mqc->curctx = (*mqc->curctx)->nlps;
- } else {
- d = (OPJ_INT32)(*mqc->curctx)->mps;
- *mqc->curctx = (*mqc->curctx)->nmps;
- }
-
- return d;
-}
-
-static INLINE OPJ_INT32 opj_mqc_lpsexchange(opj_mqc_t *const mqc) {
- OPJ_INT32 d;
- if (mqc->a < (*mqc->curctx)->qeval) {
- mqc->a = (*mqc->curctx)->qeval;
- d = (OPJ_INT32)(*mqc->curctx)->mps;
- *mqc->curctx = (*mqc->curctx)->nmps;
- } else {
- mqc->a = (*mqc->curctx)->qeval;
- d = (OPJ_INT32)(1 - (*mqc->curctx)->mps);
- *mqc->curctx = (*mqc->curctx)->nlps;
- }
-
- return d;
-}
-
-#ifdef MQC_PERF_OPT
-static INLINE void opj_mqc_bytein(opj_mqc_t *const mqc) {
- unsigned int i = *((unsigned int *) mqc->bp);
- mqc->c += i & 0xffff00;
- mqc->ct = i & 0x0f;
- mqc->bp += (i >> 2) & 0x04;
-}
-#else
-static void opj_mqc_bytein(opj_mqc_t *const mqc) {
- if (mqc->bp != mqc->end) {
- OPJ_UINT32 c;
- if (mqc->bp + 1 != mqc->end) {
- c = *(mqc->bp + 1);
- } else {
- c = 0xff;
- }
- if (*mqc->bp == 0xff) {
- if (c > 0x8f) {
- mqc->c += 0xff00;
- mqc->ct = 8;
- } else {
- mqc->bp++;
- mqc->c += c << 9;
- mqc->ct = 7;
- }
- } else {
- mqc->bp++;
- mqc->c += c << 8;
- mqc->ct = 8;
- }
- } else {
- mqc->c += 0xff00;
- mqc->ct = 8;
- }
-}
-#endif
-
-static INLINE void opj_mqc_renormd(opj_mqc_t *const mqc) {
- do {
- if (mqc->ct == 0) {
- opj_mqc_bytein(mqc);
- }
- mqc->a <<= 1;
- mqc->c <<= 1;
- mqc->ct--;
- } while (mqc->a < 0x8000);
-}
-
/*
==========================================================
MQ-Coder interface
@@ -362,7 +271,9 @@ static INLINE void opj_mqc_renormd(opj_mqc_t *const mqc) {
opj_mqc_t* opj_mqc_create(void) {
opj_mqc_t *mqc = (opj_mqc_t*)opj_malloc(sizeof(opj_mqc_t));
#ifdef MQC_PERF_OPT
- mqc->buffer = NULL;
+ if (mqc) {
+ mqc->buffer = NULL;
+ }
#endif
return mqc;
}
@@ -370,7 +281,9 @@ opj_mqc_t* opj_mqc_create(void) {
void opj_mqc_destroy(opj_mqc_t *mqc) {
if(mqc) {
#ifdef MQC_PERF_OPT
- opj_free(mqc->buffer);
+ if (mqc->buffer) {
+ opj_free(mqc->buffer);
+ }
#endif
opj_free(mqc);
}
@@ -391,9 +304,6 @@ void opj_mqc_init_enc(opj_mqc_t *mqc, OPJ_BYTE *bp) {
mqc->c = 0;
mqc->bp = bp - 1;
mqc->ct = 12;
- if (*mqc->bp == 0xff) {
- mqc->ct = 13;
- }
mqc->start = bp;
}
@@ -577,25 +487,6 @@ OPJ_BOOL opj_mqc_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len) {
return OPJ_TRUE;
}
-OPJ_INT32 opj_mqc_decode(opj_mqc_t *const mqc) {
- OPJ_INT32 d;
- mqc->a -= (*mqc->curctx)->qeval;
- if ((mqc->c >> 16) < (*mqc->curctx)->qeval) {
- d = opj_mqc_lpsexchange(mqc);
- opj_mqc_renormd(mqc);
- } else {
- mqc->c -= (*mqc->curctx)->qeval << 16;
- if ((mqc->a & 0x8000) == 0) {
- d = opj_mqc_mpsexchange(mqc);
- opj_mqc_renormd(mqc);
- } else {
- d = (OPJ_INT32)(*mqc->curctx)->mps;
- }
- }
-
- return d;
-}
-
void opj_mqc_resetstates(opj_mqc_t *mqc) {
OPJ_UINT32 i;
for (i = 0; i < MQC_NUMCTXS; i++) {
diff --git a/openjpeg/src/lib/openjp2/mqc.h b/openjpeg/src/lib/openjp2/mqc.h
index 69a2d4602..491ee50ee 100644
--- a/openjpeg/src/lib/openjp2/mqc.h
+++ b/openjpeg/src/lib/openjp2/mqc.h
@@ -77,11 +77,14 @@ typedef struct opj_mqc {
OPJ_BYTE *end;
opj_mqc_state_t *ctxs[MQC_NUMCTXS];
opj_mqc_state_t **curctx;
+ const OPJ_BYTE *lut_ctxno_zc_orient; /* lut_ctxno_zc shifted by 256 * bandno */
#ifdef MQC_PERF_OPT
unsigned char *buffer;
#endif
} opj_mqc_t;
+#include "mqc_inl.h"
+
/** @name Exported functions */
/*@{*/
/* ----------------------------------------------------------------------- */
@@ -198,7 +201,7 @@ Decode a symbol
@param mqc MQC handle
@return Returns the decoded symbol (0 or 1)
*/
-OPJ_INT32 opj_mqc_decode(opj_mqc_t * const mqc);
+static INLINE OPJ_INT32 opj_mqc_decode(opj_mqc_t * const mqc);
/* ----------------------------------------------------------------------- */
/*@}*/
diff --git a/openjpeg/src/lib/openjp2/mqc_inl.h b/openjpeg/src/lib/openjp2/mqc_inl.h
new file mode 100644
index 000000000..882b59f4c
--- /dev/null
+++ b/openjpeg/src/lib/openjp2/mqc_inl.h
@@ -0,0 +1,159 @@
+/*
+ * The copyright in this software is being made available under the 2-clauses
+ * BSD License, included below. This software may be subject to other third
+ * party and contributor rights, including patent rights, and no such rights
+ * are granted under this license.
+ *
+ * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2014, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux
+ * Copyright (c) 2003-2014, Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MQC_INL_H
+#define __MQC_INL_H
+/**
+FIXME DOC
+@param mqc MQC handle
+@return
+*/
+static INLINE OPJ_INT32 opj_mqc_mpsexchange(opj_mqc_t *const mqc) {
+ OPJ_INT32 d;
+ if (mqc->a < (*mqc->curctx)->qeval) {
+ d = (OPJ_INT32)(1 - (*mqc->curctx)->mps);
+ *mqc->curctx = (*mqc->curctx)->nlps;
+ } else {
+ d = (OPJ_INT32)(*mqc->curctx)->mps;
+ *mqc->curctx = (*mqc->curctx)->nmps;
+ }
+
+ return d;
+}
+
+/**
+FIXME DOC
+@param mqc MQC handle
+@return
+*/
+static INLINE OPJ_INT32 opj_mqc_lpsexchange(opj_mqc_t *const mqc) {
+ OPJ_INT32 d;
+ if (mqc->a < (*mqc->curctx)->qeval) {
+ mqc->a = (*mqc->curctx)->qeval;
+ d = (OPJ_INT32)(*mqc->curctx)->mps;
+ *mqc->curctx = (*mqc->curctx)->nmps;
+ } else {
+ mqc->a = (*mqc->curctx)->qeval;
+ d = (OPJ_INT32)(1 - (*mqc->curctx)->mps);
+ *mqc->curctx = (*mqc->curctx)->nlps;
+ }
+
+ return d;
+}
+
+/**
+Input a byte
+@param mqc MQC handle
+*/
+#ifdef MQC_PERF_OPT
+static INLINE void opj_mqc_bytein(opj_mqc_t *const mqc) {
+ unsigned int i = *((unsigned int *) mqc->bp);
+ mqc->c += i & 0xffff00;
+ mqc->ct = i & 0x0f;
+ mqc->bp += (i >> 2) & 0x04;
+}
+#else
+static INLINE void opj_mqc_bytein(opj_mqc_t *const mqc) {
+ if (mqc->bp != mqc->end) {
+ OPJ_UINT32 c;
+ if (mqc->bp + 1 != mqc->end) {
+ c = *(mqc->bp + 1);
+ } else {
+ c = 0xff;
+ }
+ if (*mqc->bp == 0xff) {
+ if (c > 0x8f) {
+ mqc->c += 0xff00;
+ mqc->ct = 8;
+ } else {
+ mqc->bp++;
+ mqc->c += c << 9;
+ mqc->ct = 7;
+ }
+ } else {
+ mqc->bp++;
+ mqc->c += c << 8;
+ mqc->ct = 8;
+ }
+ } else {
+ mqc->c += 0xff00;
+ mqc->ct = 8;
+ }
+}
+#endif
+
+/**
+Renormalize mqc->a and mqc->c while decoding
+@param mqc MQC handle
+*/
+static INLINE void opj_mqc_renormd(opj_mqc_t *const mqc) {
+ do {
+ if (mqc->ct == 0) {
+ opj_mqc_bytein(mqc);
+ }
+ mqc->a <<= 1;
+ mqc->c <<= 1;
+ mqc->ct--;
+ } while (mqc->a < 0x8000);
+}
+
+/**
+Decode a symbol
+@param mqc MQC handle
+@return Returns the decoded symbol (0 or 1)
+*/
+static INLINE OPJ_INT32 opj_mqc_decode(opj_mqc_t *const mqc) {
+ OPJ_INT32 d;
+ mqc->a -= (*mqc->curctx)->qeval;
+ if ((mqc->c >> 16) < (*mqc->curctx)->qeval) {
+ d = opj_mqc_lpsexchange(mqc);
+ opj_mqc_renormd(mqc);
+ } else {
+ mqc->c -= (*mqc->curctx)->qeval << 16;
+ if ((mqc->a & 0x8000) == 0) {
+ d = opj_mqc_mpsexchange(mqc);
+ opj_mqc_renormd(mqc);
+ } else {
+ d = (OPJ_INT32)(*mqc->curctx)->mps;
+ }
+ }
+
+ return d;
+}
+
+#endif /* __MQC_INL_H */
diff --git a/openjpeg/src/lib/openjp2/openjpeg.c b/openjpeg/src/lib/openjp2/openjpeg.c
index 4665d906e..4d12540e3 100644
--- a/openjpeg/src/lib/openjp2/openjpeg.c
+++ b/openjpeg/src/lib/openjp2/openjpeg.c
@@ -132,7 +132,7 @@ static OPJ_BOOL opj_seek_from_file (OPJ_OFF_T p_nb_bytes, FILE * p_user_data)
#ifdef _WIN32
#ifndef OPJ_STATIC
BOOL APIENTRY
-DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
+DllMain(HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
OPJ_ARG_NOT_USED(lpReserved);
OPJ_ARG_NOT_USED(hModule);
@@ -169,7 +169,6 @@ opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format)
if (!l_codec){
return 00;
}
- memset(l_codec, 0, sizeof(opj_codec_private_t));
l_codec->is_decompressor = 1;
@@ -240,6 +239,9 @@ opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format)
OPJ_UINT32 res_factor,
struct opj_event_mgr * p_manager)) opj_j2k_set_decoded_resolution_factor;
+ 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_decompress();
if (! l_codec->m_codec) {
@@ -316,6 +318,9 @@ opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format)
OPJ_UINT32 res_factor,
opj_event_mgr_t * p_manager)) opj_jp2_set_decoded_resolution_factor;
+ 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_TRUE);
if (! l_codec->m_codec) {
@@ -355,6 +360,18 @@ void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *paramete
}
}
+
+OPJ_BOOL OPJ_CALLCONV opj_codec_set_threads(opj_codec_t *p_codec,
+ int num_threads)
+{
+ if (p_codec && (num_threads >= 0)) {
+ opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+
+ return l_codec->opj_set_threads(l_codec->m_codec, (OPJ_UINT32)num_threads);
+ }
+ return OPJ_FALSE;
+}
+
OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec,
opj_dparameters_t *parameters
)
@@ -525,14 +542,12 @@ OPJ_BOOL OPJ_CALLCONV opj_set_decoded_resolution_factor(opj_codec_t *p_codec,
opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
if ( !l_codec ){
- fprintf(stderr, "[ERROR] Input parameters of the setup_decoder function are incorrect.\n");
return OPJ_FALSE;
}
- l_codec->m_codec_data.m_decompression.opj_set_decoded_resolution_factor(l_codec->m_codec,
+ return l_codec->m_codec_data.m_decompression.opj_set_decoded_resolution_factor(l_codec->m_codec,
res_factor,
&(l_codec->m_event_mgr) );
- return OPJ_TRUE;
}
/* ---------------------------------------------------------------------- */
@@ -546,7 +561,6 @@ opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format)
if (!l_codec) {
return 00;
}
- memset(l_codec, 0, sizeof(opj_codec_private_t));
l_codec->is_decompressor = 0;
@@ -574,7 +588,7 @@ opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format)
l_codec->m_codec_data.m_compression.opj_destroy = (void (*) (void *)) opj_j2k_destroy;
- l_codec->m_codec_data.m_compression.opj_setup_encoder = (void (*) ( void *,
+ l_codec->m_codec_data.m_compression.opj_setup_encoder = (OPJ_BOOL (*) ( void *,
opj_cparameters_t *,
struct opj_image *,
struct opj_event_mgr * )) opj_j2k_setup_encoder;
@@ -611,7 +625,7 @@ opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format)
l_codec->m_codec_data.m_compression.opj_destroy = (void (*) (void *)) opj_jp2_destroy;
- l_codec->m_codec_data.m_compression.opj_setup_encoder = (void (*) ( void *,
+ l_codec->m_codec_data.m_compression.opj_setup_encoder = (OPJ_BOOL (*) ( void *,
opj_cparameters_t *,
struct opj_image *,
struct opj_event_mgr * )) opj_jp2_setup_encoder;
@@ -702,11 +716,10 @@ OPJ_BOOL OPJ_CALLCONV opj_setup_encoder(opj_codec_t *p_codec,
opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
if (! l_codec->is_decompressor) {
- l_codec->m_codec_data.m_compression.opj_setup_encoder( l_codec->m_codec,
+ return l_codec->m_codec_data.m_compression.opj_setup_encoder( l_codec->m_codec,
parameters,
p_image,
&(l_codec->m_event_mgr) );
- return OPJ_TRUE;
}
}
@@ -871,7 +884,8 @@ void OPJ_CALLCONV opj_dump_codec( opj_codec_t *p_codec,
return;
}
- fprintf(stderr, "[ERROR] Input parameter of the dump_codec function are incorrect.\n");
+ /* TODO return error */
+ /* fprintf(stderr, "[ERROR] Input parameter of the dump_codec function are incorrect.\n"); */
return;
}
diff --git a/openjpeg/src/lib/openjp2/openjpeg.h b/openjpeg/src/lib/openjp2/openjpeg.h
index 988db7200..7912c236a 100644
--- a/openjpeg/src/lib/openjp2/openjpeg.h
+++ b/openjpeg/src/lib/openjp2/openjpeg.h
@@ -78,29 +78,33 @@ Most compilers implement their own version of this keyword ...
#if defined(OPJ_STATIC) || !defined(_WIN32)
/* http://gcc.gnu.org/wiki/Visibility */
-#if __GNUC__ >= 4
-#define OPJ_API __attribute__ ((visibility ("default")))
-#define OPJ_LOCAL __attribute__ ((visibility ("hidden")))
+# if __GNUC__ >= 4
+# if defined(OPJ_STATIC) /* static library uses "hidden" */
+# define OPJ_API __attribute__ ((visibility ("hidden")))
+# else
+# define OPJ_API __attribute__ ((visibility ("default")))
+# endif
+# define OPJ_LOCAL __attribute__ ((visibility ("hidden")))
+# else
+# define OPJ_API
+# define OPJ_LOCAL
+# endif
+# define OPJ_CALLCONV
#else
-#define OPJ_API
-#define OPJ_LOCAL
-#endif
-#define OPJ_CALLCONV
-#else
-#define OPJ_CALLCONV __stdcall
+# define OPJ_CALLCONV __stdcall
/*
The following ifdef block is the standard way of creating macros which make exporting
from a DLL simpler. All files within this DLL are compiled with the OPJ_EXPORTS
symbol defined on the command line. this symbol should not be defined on any project
that uses this DLL. This way any other project whose source files include this file see
-OPJ_API functions as being imported from a DLL, wheras this DLL sees symbols
+OPJ_API functions as being imported from a DLL, whereas this DLL sees symbols
defined with this macro as being exported.
*/
-#if defined(OPJ_EXPORTS) || defined(DLL_EXPORT)
-#define OPJ_API __declspec(dllexport)
-#else
-#define OPJ_API __declspec(dllimport)
-#endif /* OPJ_EXPORTS */
+# if defined(OPJ_EXPORTS) || defined(DLL_EXPORT)
+# define OPJ_API __declspec(dllexport)
+# else
+# define OPJ_API __declspec(dllimport)
+# endif /* OPJ_EXPORTS */
#endif /* !OPJ_STATIC || !_WIN32 */
typedef int OPJ_BOOL;
@@ -846,7 +850,7 @@ typedef struct opj_codestream_info {
} opj_codestream_info_t;
/* <----------------------------------------------------------- */
-/* new output managment of the codestream information and index */
+/* new output management of the codestream information and index */
/**
* Tile-component coding parameters information
@@ -1259,6 +1263,25 @@ OPJ_API OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec,
opj_dparameters_t *parameters );
/**
+ * Allocates worker threads for the compressor/decompressor.
+ *
+ * By default, only the main thread is used. If this function is not used,
+ * but the OPJ_NUM_THREADS environment variable is set, its value will be
+ * used to initialize the number of threads. The value can be either an integer
+ * 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.
+ *
+ * Note: currently only has effect on the decompressor.
+ *
+ * @param p_codec decompressor handler
+ * @param num_threads number of threads.
+ *
+ * @return OPJ_TRUE if the decoder is correctly set
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_codec_set_threads(opj_codec_t *p_codec,
+ int num_threads);
+
+/**
* Decodes an image header.
*
* @param p_stream the jpeg2000 stream.
@@ -1343,7 +1366,7 @@ OPJ_API OPJ_BOOL OPJ_CALLCONV opj_write_tile ( opj_codec_t *p_codec,
opj_stream_t *p_stream );
/**
- * Reads a tile header. This function is compulsory and allows one to know the size of the tile thta will be decoded.
+ * Reads a tile header. This function is compulsory and allows one to know the size of the tile that will be decoded.
* The user may need to refer to the image got by opj_read_header to understand the size being taken by the tile.
*
* @param p_codec the jpeg2000 codec.
@@ -1550,6 +1573,19 @@ OPJ_API OPJ_BOOL OPJ_CALLCONV opj_set_MCT( opj_cparameters_t *parameters,
OPJ_INT32 * p_dc_shift,
OPJ_UINT32 pNbComp);
+/*
+==========================================================
+ Thread functions
+==========================================================
+*/
+
+/** Returns if the library is built with thread support.
+ * OPJ_TRUE if mutex, condition, thread, thread pool are available.
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_has_thread_support(void);
+
+/** Return the number of virtual CPUs */
+OPJ_API int OPJ_CALLCONV opj_get_num_cpus(void);
#ifdef __cplusplus
diff --git a/openjpeg/src/lib/openjp2/opj_clock.c b/openjpeg/src/lib/openjp2/opj_clock.c
index 0df99ef04..bb4cae734 100644
--- a/openjpeg/src/lib/openjp2/opj_clock.c
+++ b/openjpeg/src/lib/openjp2/opj_clock.c
@@ -29,6 +29,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include "opj_includes.h"
+
#ifdef _WIN32
#include <windows.h>
#else
@@ -36,7 +38,6 @@
#include <sys/resource.h>
#include <sys/times.h>
#endif /* _WIN32 */
-#include "opj_includes.h"
OPJ_FLOAT64 opj_clock(void) {
#ifdef _WIN32
diff --git a/openjpeg/src/lib/openjp2/opj_codec.h b/openjpeg/src/lib/openjp2/opj_codec.h
index 4fdfa7d8b..c88005d7d 100644
--- a/openjpeg/src/lib/openjp2/opj_codec.h
+++ b/openjpeg/src/lib/openjp2/opj_codec.h
@@ -113,6 +113,7 @@ typedef struct opj_codec_private
OPJ_BOOL (*opj_set_decoded_resolution_factor) ( void * p_codec,
OPJ_UINT32 res_factor,
opj_event_mgr_t * p_manager);
+
} m_decompression;
/**
@@ -142,10 +143,10 @@ typedef struct opj_codec_private
void (* opj_destroy) (void * p_codec);
- void (* opj_setup_encoder) ( void * p_codec,
- opj_cparameters_t * p_param,
- struct opj_image * p_image,
- struct opj_event_mgr * p_manager);
+ OPJ_BOOL (* opj_setup_encoder) ( void * p_codec,
+ opj_cparameters_t * p_param,
+ struct opj_image * p_image,
+ struct opj_event_mgr * p_manager);
} m_compression;
} m_codec_data;
/** FIXME DOC*/
@@ -157,6 +158,9 @@ typedef struct opj_codec_private
void (*opj_dump_codec) (void * p_codec, OPJ_INT32 info_flag, FILE* output_stream);
opj_codestream_info_v2_t* (*opj_get_codec_info)(void* p_codec);
opj_codestream_index_t* (*opj_get_codec_index)(void* p_codec);
+
+ /** Set number of threads */
+ OPJ_BOOL (*opj_set_threads) ( void * p_codec, OPJ_UINT32 num_threads );
}
opj_codec_private_t;
diff --git a/openjpeg/src/lib/openjp2/opj_config.h.cmake.in b/openjpeg/src/lib/openjp2/opj_config.h.cmake.in
deleted file mode 100644
index 5f762ca3d..000000000
--- a/openjpeg/src/lib/openjp2/opj_config.h.cmake.in
+++ /dev/null
@@ -1,10 +0,0 @@
-/* create opj_config.h for CMake */
-#cmakedefine OPJ_HAVE_STDINT_H @OPJ_HAVE_STDINT_H@
-
-/*--------------------------------------------------------------------------*/
-/* OpenJPEG Versioning */
-
-/* Version number. */
-#define OPJ_VERSION_MAJOR @OPENJPEG_VERSION_MAJOR@
-#define OPJ_VERSION_MINOR @OPENJPEG_VERSION_MINOR@
-#define OPJ_VERSION_BUILD @OPENJPEG_VERSION_BUILD@
diff --git a/openjpeg/src/lib/openjp2/opj_config_private.h.cmake.in b/openjpeg/src/lib/openjp2/opj_config_private.h.cmake.in
deleted file mode 100644
index 8a02c79d9..000000000
--- a/openjpeg/src/lib/openjp2/opj_config_private.h.cmake.in
+++ /dev/null
@@ -1,31 +0,0 @@
-/* create opj_config_private.h for CMake */
-#cmakedefine OPJ_HAVE_INTTYPES_H @OPJ_HAVE_INTTYPES_H@
-
-#define OPJ_PACKAGE_VERSION "@PACKAGE_VERSION@"
-
-/* Not used by openjp2*/
-/*#cmakedefine HAVE_MEMORY_H @HAVE_MEMORY_H@*/
-/*#cmakedefine HAVE_STDLIB_H @HAVE_STDLIB_H@*/
-/*#cmakedefine HAVE_STRINGS_H @HAVE_STRINGS_H@*/
-/*#cmakedefine HAVE_STRING_H @HAVE_STRING_H@*/
-/*#cmakedefine HAVE_SYS_STAT_H @HAVE_SYS_STAT_H@*/
-/*#cmakedefine HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@ */
-/*#cmakedefine HAVE_UNISTD_H @HAVE_UNISTD_H@*/
-
-#cmakedefine _LARGEFILE_SOURCE
-#cmakedefine _LARGE_FILES
-#cmakedefine _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@
-#cmakedefine OPJ_HAVE_FSEEKO @OPJ_HAVE_FSEEKO@
-
-/* Byte order. */
-/* All compilers that support Mac OS X define either __BIG_ENDIAN__ or
-__LITTLE_ENDIAN__ to match the endianness of the architecture being
-compiled for. This is not necessarily the same as the architecture of the
-machine doing the building. In order to support Universal Binaries on
-Mac OS X, we prefer those defines to decide the endianness.
-On other platforms we use the result of the TRY_RUN. */
-#if !defined(__APPLE__)
-#cmakedefine OPJ_BIG_ENDIAN
-#elif defined(__BIG_ENDIAN__)
-# define OPJ_BIG_ENDIAN
-#endif \ No newline at end of file
diff --git a/openjpeg/src/lib/openjp2/opj_includes.h b/openjpeg/src/lib/openjp2/opj_includes.h
index d9238b1bf..e3de42dae 100644
--- a/openjpeg/src/lib/openjp2/opj_includes.h
+++ b/openjpeg/src/lib/openjp2/opj_includes.h
@@ -54,6 +54,7 @@
#include <stdarg.h>
#include <ctype.h>
#include <assert.h>
+#include <limits.h>
/*
Use fseeko() and ftello() if they are available since they use
@@ -102,48 +103,101 @@
==========================================================
*/
-/* Ignore GCC attributes if this is not GCC */
-#ifndef __GNUC__
- #define __attribute__(x) /* __attribute__(x) */
-#endif
-
-
/* Are restricted pointers available? (C99) */
-#if (__STDC_VERSION__ != 199901L)
+#if (__STDC_VERSION__ >= 199901L)
+ #define OPJ_RESTRICT restrict
+#else
/* Not a C99 compiler */
- #ifdef __GNUC__
- #define restrict __restrict__
+ #if defined(__GNUC__)
+ #define OPJ_RESTRICT __restrict__
+
+/*
+ vc14 (2015) outputs wrong results.
+ Need to check OPJ_RESTRICT usage (or a bug in vc14)
+ #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
+ #define OPJ_RESTRICT __restrict
+*/
#else
- #define restrict /* restrict */
+ #define OPJ_RESTRICT /* restrict */
+ #endif
+#endif
+
+#ifdef __has_attribute
+ #if __has_attribute(no_sanitize)
+ #define OPJ_NOSANITIZE(kind) __attribute__((no_sanitize(kind)))
#endif
#endif
+#ifndef OPJ_NOSANITIZE
+ #define OPJ_NOSANITIZE(kind)
+#endif
+
/* MSVC before 2013 and Borland C do not have lrintf */
-#if defined(_MSC_VER) && (_MSC_VER < 1800) || defined(__BORLANDC__)
-static INLINE long lrintf(float f){
+#if defined(_MSC_VER)
+#include <intrin.h>
+static INLINE long opj_lrintf(float f){
#ifdef _M_X64
- return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f));
-#else
+ return _mm_cvt_ss2si(_mm_load_ss(&f));
+
+ /* commented out line breaks many tests */
+ /* return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f)); */
+#elif defined(_M_IX86)
int i;
-
- _asm{
+ _asm{
fld f
fistp i
};
return i;
+#else
+ return (long)((f>0.0f) ? (f + 0.5f) : (f - 0.5f));
#endif
}
+#elif defined(__BORLANDC__)
+static INLINE long opj_lrintf(float f) {
+#ifdef _M_X64
+ return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f));
+#else
+ int i;
+
+ _asm {
+ fld f
+ fistp i
+ };
+
+ return i;
+#endif
+}
+#else
+static INLINE long opj_lrintf(float f) {
+ return lrintf(f);
+}
#endif
+#if defined(_MSC_VER) && (_MSC_VER < 1400)
+ #define vsnprintf _vsnprintf
+#endif
+
+/* MSVC x86 is really bad at doing int64 = int32 * int32 on its own. Use intrinsic. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER) && defined(_M_IX86)
+# include <intrin.h>
+# pragma intrinsic(__emul)
+#endif
+
+/* Type to use for bit-fields in internal headers */
+typedef unsigned int OPJ_BITFIELD;
+
#include "opj_inttypes.h"
#include "opj_clock.h"
#include "opj_malloc.h"
-#include "function_list.h"
#include "event.h"
+#include "function_list.h"
#include "bio.h"
#include "cio.h"
+#include "thread.h"
+#include "tls_keys.h"
+
#include "image.h"
#include "invert.h"
#include "j2k.h"
diff --git a/openjpeg/src/lib/openjp2/opj_intmath.h b/openjpeg/src/lib/openjp2/opj_intmath.h
index dc8989530..3f7934c47 100644
--- a/openjpeg/src/lib/openjp2/opj_intmath.h
+++ b/openjpeg/src/lib/openjp2/opj_intmath.h
@@ -82,6 +82,15 @@ static INLINE OPJ_UINT32 opj_uint_max(OPJ_UINT32 a, OPJ_UINT32 b) {
}
/**
+ Get the saturated sum of two unsigned integers
+ @return Returns saturated sum of a+b
+ */
+static INLINE OPJ_UINT32 opj_uint_adds(OPJ_UINT32 a, OPJ_UINT32 b) {
+ OPJ_UINT64 sum = (OPJ_UINT64)a + (OPJ_UINT64)b;
+ return (OPJ_UINT32)(-(OPJ_INT32)(sum >> 32)) | (OPJ_UINT32)sum;
+}
+
+/**
Clamp an integer inside an interval
@return
<ul>
@@ -108,7 +117,7 @@ Divide an integer and round upwards
@return Returns a divided by b
*/
static INLINE OPJ_INT32 opj_int_ceildiv(OPJ_INT32 a, OPJ_INT32 b) {
- assert(b);
+ assert(b);
return (a + b - 1) / b;
}
@@ -117,6 +126,7 @@ Divide an integer and round upwards
@return Returns a divided by b
*/
static INLINE OPJ_UINT32 opj_uint_ceildiv(OPJ_UINT32 a, OPJ_UINT32 b) {
+ assert(b);
return (a + b - 1) / b;
}
@@ -125,8 +135,25 @@ Divide an integer by a power of 2 and round upwards
@return Returns a divided by 2^b
*/
static INLINE OPJ_INT32 opj_int_ceildivpow2(OPJ_INT32 a, OPJ_INT32 b) {
- return (OPJ_INT32)((a + (OPJ_INT64)(1 << b) - 1) >> b);
+ return (OPJ_INT32)((a + ((OPJ_INT64)1 << b) - 1) >> b);
}
+
+/**
+ Divide a 64bits integer by a power of 2 and round upwards
+ @return Returns a divided by 2^b
+ */
+static INLINE OPJ_INT32 opj_int64_ceildivpow2(OPJ_INT64 a, OPJ_INT32 b) {
+ return (OPJ_INT32)((a + ((OPJ_INT64)1 << b) - 1) >> b);
+}
+
+/**
+ Divide an integer by a power of 2 and round upwards
+ @return Returns a divided by 2^b
+ */
+static INLINE OPJ_UINT32 opj_uint_ceildivpow2(OPJ_UINT32 a, OPJ_UINT32 b) {
+ return (OPJ_UINT32)((a + ((OPJ_UINT64)1U << b) - 1U) >> b);
+}
+
/**
Divide an integer by a power of 2 and round downwards
@return Returns a divided by 2^b
@@ -165,9 +192,27 @@ Multiply two fixed-precision rational numbers.
@return Returns a * b
*/
static INLINE OPJ_INT32 opj_int_fix_mul(OPJ_INT32 a, OPJ_INT32 b) {
- OPJ_INT64 temp = (OPJ_INT64) a * (OPJ_INT64) b ;
- temp += temp & 4096;
- return (OPJ_INT32) (temp >> 13) ;
+#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER) && defined(_M_IX86)
+ OPJ_INT64 temp = __emul(a, b);
+#else
+ OPJ_INT64 temp = (OPJ_INT64) a * (OPJ_INT64) b ;
+#endif
+ temp += 4096;
+ assert((temp >> 13) <= (OPJ_INT64)0x7FFFFFFF);
+ assert((temp >> 13) >= (-(OPJ_INT64)0x7FFFFFFF - (OPJ_INT64)1));
+ return (OPJ_INT32) (temp >> 13);
+}
+
+static INLINE OPJ_INT32 opj_int_fix_mul_t1(OPJ_INT32 a, OPJ_INT32 b) {
+#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER) && defined(_M_IX86)
+ OPJ_INT64 temp = __emul(a, b);
+#else
+ OPJ_INT64 temp = (OPJ_INT64) a * (OPJ_INT64) b ;
+#endif
+ temp += 4096;
+ assert((temp >> (13 + 11 - T1_NMSEDEC_FRACBITS)) <= (OPJ_INT64)0x7FFFFFFF);
+ assert((temp >> (13 + 11 - T1_NMSEDEC_FRACBITS)) >= (-(OPJ_INT64)0x7FFFFFFF - (OPJ_INT64)1));
+ return (OPJ_INT32) (temp >> (13 + 11 - T1_NMSEDEC_FRACBITS)) ;
}
/* ----------------------------------------------------------------------- */
diff --git a/openjpeg/src/lib/openjp2/opj_malloc.c b/openjpeg/src/lib/openjp2/opj_malloc.c
new file mode 100644
index 000000000..4f8b1d6f7
--- /dev/null
+++ b/openjpeg/src/lib/openjp2/opj_malloc.c
@@ -0,0 +1,239 @@
+/*
+ * The copyright in this software is being made available under the 2-clauses
+ * BSD License, included below. This software may be subject to other third
+ * party and contributor rights, including patent rights, and no such rights
+ * are granted under this license.
+ *
+ * Copyright (c) 2015, Mathieu Malaterre <mathieu.malaterre@gmail.com>
+ * Copyright (c) 2015, Matthieu Darbois
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#define OPJ_SKIP_POISON
+#include "opj_includes.h"
+
+#if defined(OPJ_HAVE_MALLOC_H) && defined(OPJ_HAVE_MEMALIGN)
+# include <malloc.h>
+#endif
+
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+
+static INLINE void *opj_aligned_alloc_n(size_t alignment, size_t size)
+{
+ void* ptr;
+
+ /* alignment shall be power of 2 */
+ assert( (alignment != 0U) && ((alignment & (alignment - 1U)) == 0U));
+ /* alignment shall be at least sizeof(void*) */
+ assert( alignment >= sizeof(void*));
+
+ if (size == 0U) { /* prevent implementation defined behavior of realloc */
+ return NULL;
+ }
+
+#if defined(OPJ_HAVE_POSIX_MEMALIGN)
+ /* aligned_alloc requires c11, restrict to posix_memalign for now. Quote:
+ * This function was introduced in POSIX 1003.1d. Although this function is
+ * superseded by aligned_alloc, it is more portable to older POSIX systems
+ * that do not support ISO C11. */
+ if (posix_memalign (&ptr, alignment, size))
+ {
+ ptr = NULL;
+ }
+ /* older linux */
+#elif defined(OPJ_HAVE_MEMALIGN)
+ ptr = memalign( alignment, size );
+/* _MSC_VER */
+#elif defined(OPJ_HAVE__ALIGNED_MALLOC)
+ ptr = _aligned_malloc(size, alignment);
+#else
+ /*
+ * Generic aligned malloc implementation.
+ * Uses size_t offset for the integer manipulation of the pointer,
+ * as uintptr_t is not available in C89 to do
+ * bitwise operations on the pointer itself.
+ */
+ alignment--;
+ {
+ size_t offset;
+ OPJ_UINT8 *mem;
+
+ /* Room for padding and extra pointer stored in front of allocated area */
+ size_t overhead = alignment + sizeof(void *);
+
+ /* let's be extra careful */
+ assert(alignment <= (SIZE_MAX - sizeof(void *)));
+
+ /* Avoid integer overflow */
+ if (size > (SIZE_MAX - overhead)) {
+ return NULL;
+ }
+
+ mem = (OPJ_UINT8*)malloc(size + overhead);
+ if (mem == NULL) {
+ return mem;
+ }
+ /* offset = ((alignment + 1U) - ((size_t)(mem + sizeof(void*)) & alignment)) & alignment; */
+ /* Use the fact that alignment + 1U is a power of 2 */
+ offset = ((alignment ^ ((size_t)(mem + sizeof(void*)) & alignment)) + 1U) & alignment;
+ ptr = (void *)(mem + sizeof(void*) + offset);
+ ((void**) ptr)[-1] = mem;
+ }
+#endif
+ return ptr;
+}
+static INLINE void *opj_aligned_realloc_n(void *ptr, size_t alignment, size_t new_size)
+{
+ void *r_ptr;
+
+ /* alignment shall be power of 2 */
+ assert( (alignment != 0U) && ((alignment & (alignment - 1U)) == 0U));
+ /* alignment shall be at least sizeof(void*) */
+ assert( alignment >= sizeof(void*));
+
+ if (new_size == 0U) { /* prevent implementation defined behavior of realloc */
+ return NULL;
+ }
+
+/* no portable aligned realloc */
+#if defined(OPJ_HAVE_POSIX_MEMALIGN) || defined(OPJ_HAVE_MEMALIGN)
+ /* glibc doc states one can mix aligned malloc with realloc */
+ r_ptr = realloc( ptr, new_size ); /* fast path */
+ /* we simply use `size_t` to cast, since we are only interest in binary AND
+ * operator */
+ if( ((size_t)r_ptr & (alignment - 1U)) != 0U ) {
+ /* this is non-trivial to implement a portable aligned realloc, so use a
+ * simple approach where we do not need a function that return the size of an
+ * allocated array (eg. _msize on Windows, malloc_size on MacOS,
+ * malloc_usable_size on systems with glibc) */
+ void *a_ptr = opj_aligned_alloc_n(alignment, new_size);
+ if (a_ptr != NULL) {
+ memcpy(a_ptr, r_ptr, new_size);
+ }
+ free( r_ptr );
+ r_ptr = a_ptr;
+ }
+/* _MSC_VER */
+#elif defined(OPJ_HAVE__ALIGNED_MALLOC)
+ r_ptr = _aligned_realloc( ptr, new_size, alignment );
+#else
+ if (ptr == NULL) {
+ return opj_aligned_alloc_n(alignment, new_size);
+ }
+ alignment--;
+ {
+ void *oldmem;
+ OPJ_UINT8 *newmem;
+ size_t overhead = alignment + sizeof(void *);
+
+ /* let's be extra careful */
+ assert(alignment <= (SIZE_MAX - sizeof(void *)));
+
+ /* Avoid integer overflow */
+ if (new_size > SIZE_MAX - overhead) {
+ return NULL;
+ }
+
+ oldmem = ((void**) ptr)[-1];
+ newmem = (OPJ_UINT8*)realloc(oldmem, new_size + overhead);
+ if (newmem == NULL) {
+ return newmem;
+ }
+
+ if (newmem == oldmem) {
+ r_ptr = ptr;
+ }
+ else {
+ size_t old_offset;
+ size_t new_offset;
+
+ /* realloc created a new copy, realign the copied memory block */
+ old_offset = (size_t)((OPJ_UINT8*)ptr - (OPJ_UINT8*)oldmem);
+
+ /* offset = ((alignment + 1U) - ((size_t)(mem + sizeof(void*)) & alignment)) & alignment; */
+ /* Use the fact that alignment + 1U is a power of 2 */
+ new_offset = ((alignment ^ ((size_t)(newmem + sizeof(void*)) & alignment)) + 1U) & alignment;
+ new_offset += sizeof(void*);
+ r_ptr = (void *)(newmem + new_offset);
+
+ if (new_offset != old_offset) {
+ memmove(newmem + new_offset, newmem + old_offset, new_size);
+ }
+ ((void**) r_ptr)[-1] = newmem;
+ }
+ }
+#endif
+ return r_ptr;
+}
+void * opj_malloc(size_t size)
+{
+ if (size == 0U) { /* prevent implementation defined behavior of realloc */
+ return NULL;
+ }
+ return malloc(size);
+}
+void * opj_calloc(size_t num, size_t size)
+{
+ if (num == 0 || size == 0) {
+ /* prevent implementation defined behavior of realloc */
+ return NULL;
+ }
+ return calloc(num, size);
+}
+
+void *opj_aligned_malloc(size_t size)
+{
+ return opj_aligned_alloc_n(16U, size);
+}
+void * opj_aligned_realloc(void *ptr, size_t size)
+{
+ return opj_aligned_realloc_n(ptr, 16U, size);
+}
+
+void opj_aligned_free(void* ptr)
+{
+#if defined(OPJ_HAVE_POSIX_MEMALIGN) || defined(OPJ_HAVE_MEMALIGN)
+ free( ptr );
+#elif defined(OPJ_HAVE__ALIGNED_MALLOC)
+ _aligned_free( ptr );
+#else
+ /* Generic implementation has malloced pointer stored in front of used area */
+ if (ptr != NULL) {
+ free(((void**) ptr)[-1]);
+ }
+#endif
+}
+
+void * opj_realloc(void *ptr, size_t new_size)
+{
+ if (new_size == 0U) { /* prevent implementation defined behavior of realloc */
+ return NULL;
+ }
+ return realloc(ptr, new_size);
+}
+void opj_free(void *ptr)
+{
+ free(ptr);
+}
diff --git a/openjpeg/src/lib/openjp2/opj_malloc.h b/openjpeg/src/lib/openjp2/opj_malloc.h
index 305850238..1b3fced91 100644
--- a/openjpeg/src/lib/openjp2/opj_malloc.h
+++ b/openjpeg/src/lib/openjp2/opj_malloc.h
@@ -31,6 +31,8 @@
*/
#ifndef __OPJ_MALLOC_H
#define __OPJ_MALLOC_H
+
+#include <stddef.h>
/**
@file opj_malloc.h
@brief Internal functions
@@ -50,16 +52,7 @@ Allocate an uninitialized memory block
@param size Bytes to allocate
@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
*/
-#ifdef ALLOC_PERF_OPT
-void * OPJ_CALLCONV opj_malloc(size_t size);
-#else
-/* prevent assertion on overflow for MSVC */
-#ifdef _MSC_VER
-#define opj_malloc(size) ((size_t)(size) >= 0x7ffdefff ? NULL : malloc(size))
-#else
-#define opj_malloc(size) malloc(size)
-#endif
-#endif
+void * opj_malloc(size_t size);
/**
Allocate a memory block with elements initialized to 0
@@ -67,83 +60,16 @@ Allocate a memory block with elements initialized to 0
@param size Bytes per block to allocate
@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
*/
-#ifdef ALLOC_PERF_OPT
-void * OPJ_CALLCONV opj_calloc(size_t _NumOfElements, size_t _SizeOfElements);
-#else
-/* prevent assertion on overflow for MSVC */
-#ifdef _MSC_VER
-#define opj_calloc(num, size) ((size_t)(num) != 0 && (size_t)(num) >= 0x7ffdefff / (size_t)(size) ? NULL : calloc(num, size))
-#else
-#define opj_calloc(num, size) calloc(num, size)
-#endif
-#endif
+void * opj_calloc(size_t numOfElements, size_t sizeOfElements);
/**
-Allocate memory aligned to a 16 byte boundry
+Allocate memory aligned to a 16 byte boundary
@param size Bytes to allocate
@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
*/
-/* FIXME: These should be set with cmake tests, but we're currently not requiring use of cmake */
-#ifdef _WIN32
- /* Someone should tell the mingw people that their malloc.h ought to provide _mm_malloc() */
- #ifdef __GNUC__
- #include <mm_malloc.h>
- #define HAVE_MM_MALLOC
- #else /* MSVC, Intel C++ */
- #include <malloc.h>
- #ifdef _mm_malloc
- #define HAVE_MM_MALLOC
- #endif
- #endif
-#else /* Not _WIN32 */
- #if defined(__sun)
- #define HAVE_MEMALIGN
- #elif defined(__FreeBSD__)
- #define HAVE_POSIX_MEMALIGN
- /* Linux x86_64 and OSX always align allocations to 16 bytes */
- #elif !defined(__amd64__) && !defined(__APPLE__) && !defined(_AIX)
- #define HAVE_MEMALIGN
- #include <malloc.h>
- #endif
-#endif
-
-#define opj_aligned_malloc(size) malloc(size)
-#define opj_aligned_free(m) free(m)
-
-#ifdef HAVE_MM_MALLOC
- #undef opj_aligned_malloc
- #define opj_aligned_malloc(size) _mm_malloc(size, 16)
- #undef opj_aligned_free
- #define opj_aligned_free(m) _mm_free(m)
-#endif
-
-#ifdef HAVE_MEMALIGN
- extern void* memalign(size_t, size_t);
- #undef opj_aligned_malloc
- #define opj_aligned_malloc(size) memalign(16, (size))
- #undef opj_aligned_free
- #define opj_aligned_free(m) free(m)
-#endif
-
-#ifdef HAVE_POSIX_MEMALIGN
- #undef opj_aligned_malloc
- extern int posix_memalign(void**, size_t, size_t);
-
- static INLINE void* __attribute__ ((malloc)) opj_aligned_malloc(size_t size){
- void* mem = NULL;
- posix_memalign(&mem, 16, size);
- return mem;
- }
- #undef opj_aligned_free
- #define opj_aligned_free(m) free(m)
-#endif
-
-#ifdef ALLOC_PERF_OPT
- #undef opj_aligned_malloc
- #define opj_aligned_malloc(size) opj_malloc(size)
- #undef opj_aligned_free
- #define opj_aligned_free(m) opj_free(m)
-#endif
+void * opj_aligned_malloc(size_t size);
+void * opj_aligned_realloc(void *ptr, size_t size);
+void opj_aligned_free(void* ptr);
/**
Reallocate memory blocks.
@@ -151,28 +77,15 @@ Reallocate memory blocks.
@param s New size in bytes
@return Returns a void pointer to the reallocated (and possibly moved) memory block
*/
-#ifdef ALLOC_PERF_OPT
-void * OPJ_CALLCONV opj_realloc(void * m, size_t s);
-#else
-/* prevent assertion on overflow for MSVC */
-#ifdef _MSC_VER
-#define opj_realloc(m, s) ((size_t)(s) >= 0x7ffdefff ? NULL : realloc(m, s))
-#else
-#define opj_realloc(m, s) realloc(m, s)
-#endif
-#endif
+void * opj_realloc(void * m, size_t s);
/**
Deallocates or frees a memory block.
@param m Previously allocated memory block to be freed
*/
-#ifdef ALLOC_PERF_OPT
-void OPJ_CALLCONV opj_free(void * m);
-#else
-#define opj_free(m) free(m)
-#endif
+void opj_free(void * m);
-#ifdef __GNUC__
+#if defined(__GNUC__) && !defined(OPJ_SKIP_POISON)
#pragma GCC poison malloc calloc realloc free
#endif
diff --git a/openjpeg/src/lib/openjp2/phix_manager.c b/openjpeg/src/lib/openjp2/phix_manager.c
index 5a3e88387..45e559d43 100644
--- a/openjpeg/src/lib/openjp2/phix_manager.c
+++ b/openjpeg/src/lib/openjp2/phix_manager.c
@@ -57,7 +57,9 @@ int opj_write_phix( int coff, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused,
OPJ_OFF_T lenp = 0;
box = (opj_jp2_box_t *)opj_calloc( (size_t)cstr_info.numcomps, sizeof(opj_jp2_box_t));
-
+ if(box == NULL){
+ return 0;
+ }
for( i=0;i<2;i++){
if (i)
opj_stream_seek( cio, lenp, p_manager);
diff --git a/openjpeg/src/lib/openjp2/pi.c b/openjpeg/src/lib/openjp2/pi.c
index 1d8db41b0..41a2f046f 100644
--- a/openjpeg/src/lib/openjp2/pi.c
+++ b/openjpeg/src/lib/openjp2/pi.c
@@ -136,10 +136,10 @@ static void opj_pi_update_encode_not_poc ( opj_cp_t *p_cp,
* @param p_tx1 pointer that will hold the X1 parameter for the tile
* @param p_ty0 pointer that will hold the Y0 parameter for the tile
* @param p_ty1 pointer that will hold the Y1 parameter for the tile
- * @param p_max_prec pointer that will hold the the maximum precision for all the bands of the tile
- * @param p_max_res pointer that will hold the the maximum number of resolutions for all the poc inside the tile.
- * @param p_dx_min pointer that will hold the the minimum dx of all the components of all the resolutions for the tile.
- * @param p_dy_min pointer that will hold the the minimum dy of all the components of all the resolutions for the tile.
+ * @param p_max_prec pointer that will hold the maximum precision for all the bands of the tile
+ * @param p_max_res pointer that will hold the maximum number of resolutions for all the poc inside the tile.
+ * @param p_dx_min pointer that will hold the minimum dx of all the components of all the resolutions for the tile.
+ * @param p_dy_min pointer that will hold the minimum dy of all the components of all the resolutions for the tile.
*/
static void opj_get_encoding_parameters(const opj_image_t *p_image,
const opj_cp_t *p_cp,
@@ -167,10 +167,10 @@ static void opj_get_encoding_parameters(const opj_image_t *p_image,
* @param p_tx1 pointer that will hold the X1 parameter for the tile
* @param p_ty0 pointer that will hold the Y0 parameter for the tile
* @param p_ty1 pointer that will hold the Y1 parameter for the tile
- * @param p_max_prec pointer that will hold the the maximum precision for all the bands of the tile
- * @param p_max_res pointer that will hold the the maximum number of resolutions for all the poc inside the tile.
- * @param p_dx_min pointer that will hold the the minimum dx of all the components of all the resolutions for the tile.
- * @param p_dy_min pointer that will hold the the minimum dy of all the components of all the resolutions for the tile.
+ * @param p_max_prec pointer that will hold the maximum precision for all the bands of the tile
+ * @param p_max_res pointer that will hold the maximum number of resolutions for all the poc inside the tile.
+ * @param p_dx_min pointer that will hold the minimum dx of all the components of all the resolutions for the tile.
+ * @param p_dy_min pointer that will hold the minimum dy of all the components of all the resolutions for the tile.
* @param p_resolutions pointer to an area corresponding to the one described above.
*/
static void opj_get_all_encoding_parameters(const opj_image_t *p_image,
@@ -214,7 +214,7 @@ static void opj_pi_update_decode_poc ( opj_pi_iterator_t * p_pi,
/**
* FIXME DOC
*/
-OPJ_BOOL opj_pi_check_next_level( OPJ_INT32 pos,
+static OPJ_BOOL opj_pi_check_next_level( OPJ_INT32 pos,
opj_cp_t *cp,
OPJ_UINT32 tileno,
OPJ_UINT32 pino,
@@ -230,7 +230,7 @@ OPJ_BOOL opj_pi_check_next_level( OPJ_INT32 pos,
==========================================================
*/
-OPJ_BOOL opj_pi_next_lrcp(opj_pi_iterator_t * pi) {
+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;
@@ -270,7 +270,7 @@ LABEL_SKIP:;
return OPJ_FALSE;
}
-OPJ_BOOL opj_pi_next_rlcp(opj_pi_iterator_t * pi) {
+static OPJ_BOOL opj_pi_next_rlcp(opj_pi_iterator_t * pi) {
opj_pi_comp_t *comp = NULL;
opj_pi_resolution_t *res = NULL;
OPJ_UINT32 index = 0;
@@ -309,7 +309,7 @@ LABEL_SKIP:;
return OPJ_FALSE;
}
-OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi) {
+static OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi) {
opj_pi_comp_t *comp = NULL;
opj_pi_resolution_t *res = NULL;
OPJ_UINT32 index = 0;
@@ -392,7 +392,7 @@ LABEL_SKIP:;
return OPJ_FALSE;
}
-OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi) {
+static OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi) {
opj_pi_comp_t *comp = NULL;
opj_pi_resolution_t *res = NULL;
OPJ_UINT32 index = 0;
@@ -473,7 +473,7 @@ LABEL_SKIP:;
return OPJ_FALSE;
}
-OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi) {
+static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi) {
opj_pi_comp_t *comp = NULL;
opj_pi_resolution_t *res = NULL;
OPJ_UINT32 index = 0;
@@ -552,7 +552,7 @@ LABEL_SKIP:;
return OPJ_FALSE;
}
-void opj_get_encoding_parameters( const opj_image_t *p_image,
+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,
@@ -666,7 +666,7 @@ void opj_get_encoding_parameters( const opj_image_t *p_image,
}
-void opj_get_all_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,
@@ -693,6 +693,9 @@ void opj_get_all_encoding_parameters( const opj_image_t *p_image,
/* position in x and y of tile*/
OPJ_UINT32 p, q;
+ /* non-corrected (in regard to image offset) tile offset */
+ OPJ_UINT32 l_tx0, l_ty0;
+
/* preconditions in debug*/
assert(p_cp != 00);
assert(p_image != 00);
@@ -708,10 +711,12 @@ void opj_get_all_encoding_parameters( const opj_image_t *p_image,
q = tileno / p_cp->tw;
/* here calculation of tx0, tx1, ty0, ty1, maxprec, l_dx and l_dy */
- *p_tx0 = opj_int_max((OPJ_INT32)(p_cp->tx0 + p * p_cp->tdx), (OPJ_INT32)p_image->x0);
- *p_tx1 = opj_int_min((OPJ_INT32)(p_cp->tx0 + (p + 1) * p_cp->tdx), (OPJ_INT32)p_image->x1);
- *p_ty0 = opj_int_max((OPJ_INT32)(p_cp->ty0 + q * p_cp->tdy), (OPJ_INT32)p_image->y0);
- *p_ty1 = opj_int_min((OPJ_INT32)(p_cp->ty0 + (q + 1) * p_cp->tdy), (OPJ_INT32)p_image->y1);
+ 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);
+ 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);
/* max precision and resolution is 0 (can only grow)*/
*p_max_prec = 0;
@@ -742,10 +747,12 @@ void opj_get_all_encoding_parameters( const opj_image_t *p_image,
}
/* use custom size for precincts*/
- l_level_no = l_tccp->numresolutions - 1;
+ l_level_no = l_tccp->numresolutions;
for (resno = 0; resno < l_tccp->numresolutions; ++resno) {
OPJ_UINT32 l_dx, l_dy;
+ --l_level_no;
+
/* precinct width and height*/
l_pdx = l_tccp->prcw[resno];
l_pdy = l_tccp->prch[resno];
@@ -777,14 +784,13 @@ void opj_get_all_encoding_parameters( const opj_image_t *p_image,
*p_max_prec = l_product;
}
- --l_level_no;
}
++l_tccp;
++l_img_comp;
}
}
-opj_pi_iterator_t * opj_pi_create( const opj_image_t *image,
+static opj_pi_iterator_t * opj_pi_create( const opj_image_t *image,
const opj_cp_t *cp,
OPJ_UINT32 tileno )
{
@@ -815,7 +821,6 @@ opj_pi_iterator_t * opj_pi_create( const opj_image_t *image,
if (!l_pi) {
return NULL;
}
- memset(l_pi,0,l_poc_bound * sizeof(opj_pi_iterator_t));
l_current_pi = l_pi;
for (pino = 0; pino < l_poc_bound ; ++pino) {
@@ -827,28 +832,26 @@ opj_pi_iterator_t * opj_pi_create( const opj_image_t *image,
}
l_current_pi->numcomps = image->numcomps;
- memset(l_current_pi->comps,0,image->numcomps * sizeof(opj_pi_comp_t));
for (compno = 0; compno < image->numcomps; ++compno) {
opj_pi_comp_t *comp = &l_current_pi->comps[compno];
tccp = &tcp->tccps[compno];
- comp->resolutions = (opj_pi_resolution_t*) opj_malloc(tccp->numresolutions * sizeof(opj_pi_resolution_t));
+ comp->resolutions = (opj_pi_resolution_t*) opj_calloc(tccp->numresolutions, sizeof(opj_pi_resolution_t));
if (!comp->resolutions) {
opj_pi_destroy(l_pi, l_poc_bound);
return 00;
}
comp->numresolutions = tccp->numresolutions;
- memset(comp->resolutions,0,tccp->numresolutions * sizeof(opj_pi_resolution_t));
}
++l_current_pi;
}
return l_pi;
}
-void opj_pi_update_encode_poc_and_final ( opj_cp_t *p_cp,
+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,
@@ -926,7 +929,7 @@ void opj_pi_update_encode_poc_and_final ( opj_cp_t *p_cp,
}
}
-void opj_pi_update_encode_not_poc ( 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,
@@ -981,7 +984,7 @@ void opj_pi_update_encode_not_poc ( opj_cp_t *p_cp,
}
}
-void opj_pi_update_decode_poc (opj_pi_iterator_t * p_pi,
+static void opj_pi_update_decode_poc (opj_pi_iterator_t * p_pi,
opj_tcp_t * p_tcp,
OPJ_UINT32 p_max_precision,
OPJ_UINT32 p_max_res)
@@ -1023,7 +1026,7 @@ void opj_pi_update_decode_poc (opj_pi_iterator_t * p_pi,
}
}
-void opj_pi_update_decode_not_poc (opj_pi_iterator_t * p_pi,
+static void opj_pi_update_decode_not_poc (opj_pi_iterator_t * p_pi,
opj_tcp_t * p_tcp,
OPJ_UINT32 p_max_precision,
OPJ_UINT32 p_max_res)
@@ -1060,7 +1063,7 @@ void opj_pi_update_decode_not_poc (opj_pi_iterator_t * p_pi,
-OPJ_BOOL opj_pi_check_next_level( OPJ_INT32 pos,
+static OPJ_BOOL opj_pi_check_next_level( OPJ_INT32 pos,
opj_cp_t *cp,
OPJ_UINT32 tileno,
OPJ_UINT32 pino,
@@ -1108,7 +1111,8 @@ OPJ_BOOL opj_pi_check_next_level( OPJ_INT32 pos,
break;
case 'P':
switch(tcp->prg){
- case OPJ_LRCP||OPJ_RLCP:
+ case OPJ_LRCP: /* fall through */
+ case OPJ_RLCP:
if(tcp->prc_t == tcp->prcE){
if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){
return OPJ_TRUE;
@@ -1233,16 +1237,21 @@ opj_pi_iterator_t *opj_pi_create_decode(opj_image_t *p_image,
l_current_pi = l_pi;
/* memory allocation for include */
- l_current_pi->include = (OPJ_INT16*) opj_calloc((l_tcp->numlayers +1) * l_step_l, sizeof(OPJ_INT16));
- if
- (!l_current_pi->include)
+ /* prevent an integer overflow issue */
+ /* 0 < l_tcp->numlayers < 65536 c.f. opj_j2k_read_cod in j2k.c */
+ l_current_pi->include = 00;
+ if (l_step_l <= (SIZE_MAX / (l_tcp->numlayers + 1U)))
+ {
+ l_current_pi->include = (OPJ_INT16*) opj_calloc((size_t)(l_tcp->numlayers + 1U) * l_step_l, sizeof(OPJ_INT16));
+ }
+
+ if (!l_current_pi->include)
{
opj_free(l_tmp_data);
opj_free(l_tmp_ptr);
opj_pi_destroy(l_pi, l_bound);
return 00;
}
- memset(l_current_pi->include,0, (l_tcp->numlayers + 1) * l_step_l* sizeof(OPJ_INT16));
/* special treatment for the first packet iterator */
l_current_comp = l_current_pi->comps;
@@ -1428,7 +1437,7 @@ opj_pi_iterator_t *opj_pi_initialise_encode(const opj_image_t *p_image,
l_step_l = l_max_res * l_step_r;
/* set values for first packet iterator*/
- l_pi->tp_on = p_cp->m_specific_param.m_enc.m_tp_on;
+ l_pi->tp_on = (OPJ_BYTE)p_cp->m_specific_param.m_enc.m_tp_on;
l_current_pi = l_pi;
/* memory allocation for include*/
@@ -1439,7 +1448,6 @@ opj_pi_iterator_t *opj_pi_initialise_encode(const opj_image_t *p_image,
opj_pi_destroy(l_pi, l_bound);
return 00;
}
- memset(l_current_pi->include,0,l_tcp->numlayers * l_step_l* sizeof(OPJ_INT16));
/* special treatment for the first packet iterator*/
l_current_comp = l_current_pi->comps;
diff --git a/openjpeg/src/lib/openjp2/pi.h b/openjpeg/src/lib/openjp2/pi.h
index f239679f5..265d5b1e2 100644
--- a/openjpeg/src/lib/openjp2/pi.h
+++ b/openjpeg/src/lib/openjp2/pi.h
@@ -73,7 +73,7 @@ Packet iterator
typedef struct opj_pi_iterator {
/** Enabling Tile part generation*/
OPJ_BYTE tp_on;
- /** precise if the packet has been already used (usefull for progression order change) */
+ /** precise if the packet has been already used (useful for progression order change) */
OPJ_INT16 *include;
/** layer step used to localize the packet in the include vector */
OPJ_UINT32 step_l;
diff --git a/openjpeg/src/lib/openjp2/ppix_manager.c b/openjpeg/src/lib/openjp2/ppix_manager.c
index fce514899..018a88123 100644
--- a/openjpeg/src/lib/openjp2/ppix_manager.c
+++ b/openjpeg/src/lib/openjp2/ppix_manager.c
@@ -61,7 +61,9 @@ int opj_write_ppix( int coff, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused,
lenp = -1;
box = (opj_jp2_box_t *)opj_calloc( (size_t)cstr_info.numcomps, sizeof(opj_jp2_box_t));
-
+ if(box == NULL){
+ return 0;
+ }
for (i=0;i<2;i++){
if (i)
diff --git a/openjpeg/src/lib/openjp2/raw.c b/openjpeg/src/lib/openjp2/raw.c
index 2498761c4..d3581d1a0 100644
--- a/openjpeg/src/lib/openjp2/raw.c
+++ b/openjpeg/src/lib/openjp2/raw.c
@@ -88,7 +88,7 @@ OPJ_UINT32 opj_raw_decode(opj_raw_t *raw) {
}
}
raw->ct--;
- d = (raw->c >> raw->ct) & 0x01;
+ d = ((OPJ_UINT32)raw->c >> raw->ct) & 0x01U;
return d;
}
diff --git a/openjpeg/src/lib/openjp2/t1.c b/openjpeg/src/lib/openjp2/t1.c
index 0d6c2f606..453d29089 100644
--- a/openjpeg/src/lib/openjp2/t1.c
+++ b/openjpeg/src/lib/openjp2/t1.c
@@ -39,26 +39,27 @@
#include "opj_includes.h"
#include "t1_luts.h"
+/* #define CONSISTENCY_CHECK */
+
/** @defgroup T1 T1 - Implementation of the tier-1 coding */
/*@{*/
/** @name Local static functions */
/*@{*/
-static INLINE OPJ_BYTE opj_t1_getctxno_zc(OPJ_UINT32 f, OPJ_UINT32 orient);
+static INLINE OPJ_BYTE opj_t1_getctxno_zc(opj_mqc_t *mqc, OPJ_UINT32 f);
static OPJ_BYTE opj_t1_getctxno_sc(OPJ_UINT32 f);
static INLINE OPJ_UINT32 opj_t1_getctxno_mag(OPJ_UINT32 f);
static OPJ_BYTE opj_t1_getspb(OPJ_UINT32 f);
static OPJ_INT16 opj_t1_getnmsedec_sig(OPJ_UINT32 x, OPJ_UINT32 bitpos);
static OPJ_INT16 opj_t1_getnmsedec_ref(OPJ_UINT32 x, OPJ_UINT32 bitpos);
-static void opj_t1_updateflags(opj_flag_t *flagsp, OPJ_UINT32 s, OPJ_UINT32 stride);
+static INLINE void opj_t1_updateflags(opj_flag_t *flagsp, OPJ_UINT32 s, OPJ_UINT32 stride);
/**
Encode significant pass
*/
static void opj_t1_enc_sigpass_step(opj_t1_t *t1,
opj_flag_t *flagsp,
OPJ_INT32 *datap,
- OPJ_UINT32 orient,
OPJ_INT32 bpno,
OPJ_INT32 one,
OPJ_INT32 *nmsedec,
@@ -81,23 +82,27 @@ static void opj_t1_dec_sigpass_step(opj_t1_t *t1,
static INLINE void opj_t1_dec_sigpass_step_raw(
opj_t1_t *t1,
opj_flag_t *flagsp,
+ opj_colflag_t* colflagsp,
OPJ_INT32 *datap,
- OPJ_INT32 orient,
OPJ_INT32 oneplushalf,
- OPJ_INT32 vsc);
+ OPJ_INT32 vsc,
+ OPJ_UINT32 row);
static INLINE void opj_t1_dec_sigpass_step_mqc(
opj_t1_t *t1,
opj_flag_t *flagsp,
+ opj_colflag_t* colflagsp,
OPJ_INT32 *datap,
- OPJ_INT32 orient,
- OPJ_INT32 oneplushalf);
+ OPJ_INT32 oneplushalf,
+ OPJ_UINT32 row,
+ OPJ_UINT32 flags_stride);
static INLINE void opj_t1_dec_sigpass_step_mqc_vsc(
opj_t1_t *t1,
opj_flag_t *flagsp,
+ opj_colflag_t* colflagsp,
OPJ_INT32 *datap,
- OPJ_INT32 orient,
OPJ_INT32 oneplushalf,
- OPJ_INT32 vsc);
+ OPJ_INT32 vsc,
+ OPJ_UINT32 row);
/**
@@ -105,7 +110,6 @@ Encode significant pass
*/
static void opj_t1_enc_sigpass( opj_t1_t *t1,
OPJ_INT32 bpno,
- OPJ_UINT32 orient,
OPJ_INT32 *nmsedec,
OPJ_BYTE type,
OPJ_UINT32 cblksty);
@@ -116,16 +120,10 @@ Decode significant pass
static void opj_t1_dec_sigpass_raw(
opj_t1_t *t1,
OPJ_INT32 bpno,
- OPJ_INT32 orient,
OPJ_INT32 cblksty);
-static void opj_t1_dec_sigpass_mqc(
- opj_t1_t *t1,
- OPJ_INT32 bpno,
- OPJ_INT32 orient);
static void opj_t1_dec_sigpass_mqc_vsc(
opj_t1_t *t1,
- OPJ_INT32 bpno,
- OPJ_INT32 orient);
+ OPJ_INT32 bpno);
@@ -156,10 +154,6 @@ Decode refinement pass
*/
static void opj_t1_dec_refpass_raw(
opj_t1_t *t1,
- OPJ_INT32 bpno,
- OPJ_INT32 cblksty);
-static void opj_t1_dec_refpass_mqc(
- opj_t1_t *t1,
OPJ_INT32 bpno);
static void opj_t1_dec_refpass_mqc_vsc(
opj_t1_t *t1,
@@ -181,24 +175,28 @@ static void opj_t1_dec_refpass_step(opj_t1_t *t1,
static INLINE void opj_t1_dec_refpass_step_raw(
opj_t1_t *t1,
- opj_flag_t *flagsp,
+ opj_colflag_t *colflagsp,
OPJ_INT32 *datap,
OPJ_INT32 poshalf,
OPJ_INT32 neghalf,
- OPJ_INT32 vsc);
+ OPJ_UINT32 row);
static INLINE void opj_t1_dec_refpass_step_mqc(
opj_t1_t *t1,
opj_flag_t *flagsp,
+ opj_colflag_t *colflagsp,
OPJ_INT32 *datap,
OPJ_INT32 poshalf,
- OPJ_INT32 neghalf);
+ OPJ_INT32 neghalf,
+ OPJ_UINT32 row);
static INLINE void opj_t1_dec_refpass_step_mqc_vsc(
opj_t1_t *t1,
opj_flag_t *flagsp,
+ opj_colflag_t *colflagsp,
OPJ_INT32 *datap,
OPJ_INT32 poshalf,
OPJ_INT32 neghalf,
- OPJ_INT32 vsc);
+ OPJ_INT32 vsc,
+ OPJ_UINT32 row);
@@ -209,7 +207,6 @@ static void opj_t1_enc_clnpass_step(
opj_t1_t *t1,
opj_flag_t *flagsp,
OPJ_INT32 *datap,
- OPJ_UINT32 orient,
OPJ_INT32 bpno,
OPJ_INT32 one,
OPJ_INT32 *nmsedec,
@@ -221,40 +218,34 @@ Decode clean-up pass
static void opj_t1_dec_clnpass_step_partial(
opj_t1_t *t1,
opj_flag_t *flagsp,
+ opj_colflag_t *colflagsp,
OPJ_INT32 *datap,
- OPJ_INT32 orient,
- OPJ_INT32 oneplushalf);
+ OPJ_INT32 oneplushalf,
+ OPJ_UINT32 row);
static void opj_t1_dec_clnpass_step(
opj_t1_t *t1,
opj_flag_t *flagsp,
+ opj_colflag_t *colflagsp,
OPJ_INT32 *datap,
- OPJ_INT32 orient,
- OPJ_INT32 oneplushalf);
+ OPJ_INT32 oneplushalf,
+ OPJ_UINT32 row);
static void opj_t1_dec_clnpass_step_vsc(
opj_t1_t *t1,
opj_flag_t *flagsp,
+ opj_colflag_t *colflagsp,
OPJ_INT32 *datap,
- OPJ_INT32 orient,
OPJ_INT32 oneplushalf,
OPJ_INT32 partial,
- OPJ_INT32 vsc);
+ OPJ_INT32 vsc,
+ OPJ_UINT32 row);
/**
Encode clean-up pass
*/
static void opj_t1_enc_clnpass(
opj_t1_t *t1,
OPJ_INT32 bpno,
- OPJ_UINT32 orient,
OPJ_INT32 *nmsedec,
OPJ_UINT32 cblksty);
-/**
-Decode clean-up pass
-*/
-static void opj_t1_dec_clnpass(
- opj_t1_t *t1,
- OPJ_INT32 bpno,
- OPJ_INT32 orient,
- OPJ_INT32 cblksty);
static OPJ_FLOAT64 opj_t1_getwmsedec(
OPJ_INT32 nmsedec,
@@ -265,7 +256,8 @@ static OPJ_FLOAT64 opj_t1_getwmsedec(
OPJ_UINT32 qmfbid,
OPJ_FLOAT64 stepsize,
OPJ_UINT32 numcomps,
- const OPJ_FLOAT64 * mct_norms);
+ const OPJ_FLOAT64 * mct_norms,
+ OPJ_UINT32 mct_numcomps);
static void opj_t1_encode_cblk( opj_t1_t *t1,
opj_tcd_cblk_enc_t* cblk,
@@ -277,7 +269,8 @@ static void opj_t1_encode_cblk( opj_t1_t *t1,
OPJ_UINT32 cblksty,
OPJ_UINT32 numcomps,
opj_tcd_tile_t * tile,
- const OPJ_FLOAT64 * mct_norms);
+ const OPJ_FLOAT64 * mct_norms,
+ OPJ_UINT32 mct_numcomps);
/**
Decode 1 code-block
@@ -293,7 +286,7 @@ static OPJ_BOOL opj_t1_decode_cblk( opj_t1_t *t1,
OPJ_UINT32 roishift,
OPJ_UINT32 cblksty);
-OPJ_BOOL opj_t1_allocate_buffers( opj_t1_t *t1,
+static OPJ_BOOL opj_t1_allocate_buffers( opj_t1_t *t1,
OPJ_UINT32 w,
OPJ_UINT32 h);
@@ -303,68 +296,107 @@ OPJ_BOOL opj_t1_allocate_buffers( opj_t1_t *t1,
/* ----------------------------------------------------------------------- */
-OPJ_BYTE opj_t1_getctxno_zc(OPJ_UINT32 f, OPJ_UINT32 orient) {
- return lut_ctxno_zc[(orient << 8) | (f & T1_SIG_OTH)];
+static OPJ_BYTE opj_t1_getctxno_zc(opj_mqc_t *mqc, OPJ_UINT32 f) {
+ return mqc->lut_ctxno_zc_orient[(f & T1_SIG_OTH)];
}
-OPJ_BYTE opj_t1_getctxno_sc(OPJ_UINT32 f) {
+static OPJ_BYTE opj_t1_getctxno_sc(OPJ_UINT32 f) {
return lut_ctxno_sc[(f & (T1_SIG_PRIM | T1_SGN)) >> 4];
}
-OPJ_UINT32 opj_t1_getctxno_mag(OPJ_UINT32 f) {
+static OPJ_UINT32 opj_t1_getctxno_mag(OPJ_UINT32 f) {
OPJ_UINT32 tmp1 = (f & T1_SIG_OTH) ? T1_CTXNO_MAG + 1 : T1_CTXNO_MAG;
OPJ_UINT32 tmp2 = (f & T1_REFINE) ? T1_CTXNO_MAG + 2 : tmp1;
return (tmp2);
}
-OPJ_BYTE opj_t1_getspb(OPJ_UINT32 f) {
+static OPJ_BYTE opj_t1_getspb(OPJ_UINT32 f) {
return lut_spb[(f & (T1_SIG_PRIM | T1_SGN)) >> 4];
}
-OPJ_INT16 opj_t1_getnmsedec_sig(OPJ_UINT32 x, OPJ_UINT32 bitpos) {
- if (bitpos > T1_NMSEDEC_FRACBITS) {
- return lut_nmsedec_sig[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)];
+static OPJ_INT16 opj_t1_getnmsedec_sig(OPJ_UINT32 x, OPJ_UINT32 bitpos) {
+ if (bitpos > 0) {
+ return lut_nmsedec_sig[(x >> (bitpos)) & ((1 << T1_NMSEDEC_BITS) - 1)];
}
return lut_nmsedec_sig0[x & ((1 << T1_NMSEDEC_BITS) - 1)];
}
-OPJ_INT16 opj_t1_getnmsedec_ref(OPJ_UINT32 x, OPJ_UINT32 bitpos) {
- if (bitpos > T1_NMSEDEC_FRACBITS) {
- return lut_nmsedec_ref[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)];
+static OPJ_INT16 opj_t1_getnmsedec_ref(OPJ_UINT32 x, OPJ_UINT32 bitpos) {
+ if (bitpos > 0) {
+ return lut_nmsedec_ref[(x >> (bitpos)) & ((1 << T1_NMSEDEC_BITS) - 1)];
}
return lut_nmsedec_ref0[x & ((1 << T1_NMSEDEC_BITS) - 1)];
}
-void opj_t1_updateflags(opj_flag_t *flagsp, OPJ_UINT32 s, OPJ_UINT32 stride) {
+static INLINE void opj_t1_updateflags(opj_flag_t *flagsp, OPJ_UINT32 s, OPJ_UINT32 stride) {
opj_flag_t *np = flagsp - stride;
opj_flag_t *sp = flagsp + stride;
- static const opj_flag_t mod[] = {
- T1_SIG_S, T1_SIG_S|T1_SGN_S,
- T1_SIG_E, T1_SIG_E|T1_SGN_E,
- T1_SIG_W, T1_SIG_W|T1_SGN_W,
- T1_SIG_N, T1_SIG_N|T1_SGN_N
- };
+ /* We strongly rely on (T1_SGN_N == 0x0100) == (T1_SIG_N == 0x0010) << 4 */
+ /* and T1_SIG_E == T1_SIG_N << 1, T1_SIG_W == T1_SIG_N << 2 and T1_SIG_S == T1_SIG_N << 2 */
+ /* and T1_SGN_E == T1_SGN_N << 1, T1_SGN_W == T1_SGN_N << 2 and T1_SGN_S == T1_SGN_N << 2 */
+
+ unsigned int flag_N = T1_SIG_N | ((unsigned int)T1_SIG_N << (4U * s));
np[-1] |= T1_SIG_SE;
- np[0] |= mod[s];
+ np[0] |= (opj_flag_t)(flag_N << 2U);
np[1] |= T1_SIG_SW;
- flagsp[-1] |= mod[s+2];
+ flagsp[-1] |= (opj_flag_t)(flag_N << 1U);
flagsp[0] |= T1_SIG;
- flagsp[1] |= mod[s+4];
+ flagsp[1] |= (opj_flag_t)(flag_N << 3U);
sp[-1] |= T1_SIG_NE;
- sp[0] |= mod[s+6];
+ sp[0] |= (opj_flag_t)flag_N;
sp[1] |= T1_SIG_NW;
}
-void opj_t1_enc_sigpass_step( opj_t1_t *t1,
+static INLINE void opj_t1_updateflagscolflags(opj_flag_t *flagsp, opj_colflag_t *colflagsp, OPJ_UINT32 s, OPJ_UINT32 stride, OPJ_UINT32 row)
+{
+ opj_t1_updateflags(flagsp, s, stride);
+ if( row == 0U )
+ {
+ *colflagsp |= (opj_colflag_t)((T1_COLFLAG_SIG_ROW_0 << (T1_COLFLAG_RBS * row)) |
+ (T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * (row+1U))));
+ *(colflagsp - 1) |= (opj_colflag_t)((T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * row)) |
+ (T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * (row+1U))));
+ *(colflagsp + 1) |= (opj_colflag_t)((T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * row)) |
+ (T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * (row+1U))));
+ *(colflagsp - stride - 1) |= (T1_COLFLAG_SIG_OTHER_ROW_3);
+ *(colflagsp - stride) |= (T1_COLFLAG_SIG_OTHER_ROW_3);
+ *(colflagsp - stride + 1) |= (T1_COLFLAG_SIG_OTHER_ROW_3);
+ }
+ else if( row == 3U )
+ {
+ *colflagsp |= (opj_colflag_t)((T1_COLFLAG_SIG_ROW_0 << (T1_COLFLAG_RBS * row)) |
+ (T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * (row-1U))));
+ *(colflagsp - 1) |= (opj_colflag_t)((T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * row)) |
+ (T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * (row-1U))));
+ *(colflagsp + 1) |= (opj_colflag_t)((T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * row)) |
+ (T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS* (row-1))));
+ *(colflagsp + stride - 1) |= (T1_COLFLAG_SIG_OTHER_ROW_0);
+ *(colflagsp + stride) |= (T1_COLFLAG_SIG_OTHER_ROW_0);
+ *(colflagsp + stride + 1) |= (T1_COLFLAG_SIG_OTHER_ROW_0);
+ }
+ else
+ {
+ *(colflagsp - 1) |= (opj_colflag_t)((T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * row)) |
+ (T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * (row-1U))) |
+ (T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * (row+1U))));
+ *colflagsp |= (opj_colflag_t)((T1_COLFLAG_SIG_ROW_0 << (T1_COLFLAG_RBS * row)) |
+ (T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * (row-1U))) |
+ (T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * (row+1U))));
+ *(colflagsp + 1) |= (opj_colflag_t)((T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * row)) |
+ (T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * (row-1U))) |
+ (T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * (row+1U))));
+ }
+}
+
+static void opj_t1_enc_sigpass_step( opj_t1_t *t1,
opj_flag_t *flagsp,
OPJ_INT32 *datap,
- OPJ_UINT32 orient,
OPJ_INT32 bpno,
OPJ_INT32 one,
OPJ_INT32 *nmsedec,
@@ -379,8 +411,8 @@ void opj_t1_enc_sigpass_step( opj_t1_t *t1,
flag = vsc ? (OPJ_UINT32)((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (OPJ_UINT32)(*flagsp);
if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
- v = opj_int_abs(*datap) & one ? 1 : 0;
- opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(flag, orient)); /* ESSAI */
+ v = (opj_int_abs(*datap) & one) ? 1 : 0;
+ opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(mqc, flag)); /* ESSAI */
if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */
opj_mqc_bypass_enc(mqc, (OPJ_UINT32)v);
} else {
@@ -388,7 +420,7 @@ void opj_t1_enc_sigpass_step( opj_t1_t *t1,
}
if (v) {
v = *datap < 0 ? 1 : 0;
- *nmsedec += opj_t1_getnmsedec_sig((OPJ_UINT32)opj_int_abs(*datap), (OPJ_UINT32)(bpno + T1_NMSEDEC_FRACBITS));
+ *nmsedec += opj_t1_getnmsedec_sig((OPJ_UINT32)opj_int_abs(*datap), (OPJ_UINT32)(bpno));
opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc(flag)); /* ESSAI */
if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */
opj_mqc_bypass_enc(mqc, (OPJ_UINT32)v);
@@ -405,80 +437,96 @@ void opj_t1_enc_sigpass_step( opj_t1_t *t1,
static INLINE void opj_t1_dec_sigpass_step_raw(
opj_t1_t *t1,
opj_flag_t *flagsp,
+ opj_colflag_t* colflagsp,
OPJ_INT32 *datap,
- OPJ_INT32 orient,
OPJ_INT32 oneplushalf,
- OPJ_INT32 vsc)
+ OPJ_INT32 vsc,
+ OPJ_UINT32 row)
{
- OPJ_INT32 v, flag;
+ OPJ_UINT32 v, flag;
opj_raw_t *raw = t1->raw; /* RAW component */
- OPJ_ARG_NOT_USED(orient);
-
+
flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
- if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
+ if ((flag & T1_SIG_OTH) && !(*colflagsp & ((T1_COLFLAG_SIG_ROW_0 | T1_COLFLAG_VISIT_ROW_0) << (T1_COLFLAG_RBS * row)))) {
if (opj_raw_decode(raw)) {
- v = (OPJ_INT32)opj_raw_decode(raw); /* ESSAI */
+ v = opj_raw_decode(raw); /* ESSAI */
*datap = v ? -oneplushalf : oneplushalf;
- opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride);
+ opj_t1_updateflagscolflags(flagsp, colflagsp, v, t1->flags_stride, row);
}
+#ifdef CONSISTENCY_CHECK
*flagsp |= T1_VISIT;
+#endif
+ *colflagsp |= (opj_colflag_t)(T1_COLFLAG_VISIT_ROW_0 << (T1_COLFLAG_RBS * row));
}
}
-INLINE void opj_t1_dec_sigpass_step_mqc(
+static INLINE void opj_t1_dec_sigpass_step_mqc(
opj_t1_t *t1,
opj_flag_t *flagsp,
+ opj_colflag_t* colflagsp,
OPJ_INT32 *datap,
- OPJ_INT32 orient,
- OPJ_INT32 oneplushalf)
+ OPJ_INT32 oneplushalf,
+ OPJ_UINT32 row,
+ OPJ_UINT32 flags_stride)
{
OPJ_INT32 v, flag;
opj_mqc_t *mqc = t1->mqc; /* MQC component */
-
- flag = *flagsp;
- if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
- opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc((OPJ_UINT32)flag, (OPJ_UINT32)orient));
+#ifdef CONSISTENCY_CHECK
+ assert( ((*flagsp & T1_SIG_OTH) && !(*flagsp & (T1_SIG | T1_VISIT))) ==
+ ((*colflagsp & ((T1_COLFLAG_SIG_ROW_0 | T1_COLFLAG_VISIT_ROW_0 | T1_COLFLAG_SIG_OTHER_ROW_0) << (T1_COLFLAG_RBS * row))) ==
+ (T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * row))) );
+#endif
+ if( (*colflagsp & ((T1_COLFLAG_SIG_ROW_0 | T1_COLFLAG_VISIT_ROW_0 | T1_COLFLAG_SIG_OTHER_ROW_0) << (T1_COLFLAG_RBS * row))) ==
+ (T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * row)) ) {
+ flag = *flagsp;
+ opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(mqc, (OPJ_UINT32)flag));
if (opj_mqc_decode(mqc)) {
opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag));
v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag);
*datap = v ? -oneplushalf : oneplushalf;
- opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride);
+ opj_t1_updateflagscolflags(flagsp, colflagsp, (OPJ_UINT32)v, flags_stride, row);
}
+#ifdef CONSISTENCY_CHECK
*flagsp |= T1_VISIT;
+#endif
+ *colflagsp |= (opj_colflag_t)(T1_COLFLAG_VISIT_ROW_0 << (T1_COLFLAG_RBS * row));
}
} /* VSC and BYPASS by Antonin */
-INLINE void opj_t1_dec_sigpass_step_mqc_vsc(
+static INLINE void opj_t1_dec_sigpass_step_mqc_vsc(
opj_t1_t *t1,
opj_flag_t *flagsp,
+ opj_colflag_t* colflagsp,
OPJ_INT32 *datap,
- OPJ_INT32 orient,
OPJ_INT32 oneplushalf,
- OPJ_INT32 vsc)
+ OPJ_INT32 vsc,
+ OPJ_UINT32 row)
{
- OPJ_INT32 v, flag;
+ OPJ_UINT32 v, flag;
opj_mqc_t *mqc = t1->mqc; /* MQC component */
flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
- if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
- opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc((OPJ_UINT32)flag, (OPJ_UINT32)orient));
+ if ((flag & T1_SIG_OTH) && !(*colflagsp & ((T1_COLFLAG_SIG_ROW_0 | T1_COLFLAG_VISIT_ROW_0) << (T1_COLFLAG_RBS * row)))) {
+ opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(mqc, flag));
if (opj_mqc_decode(mqc)) {
- opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag));
- v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag);
+ opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc(flag));
+ v = (OPJ_UINT32)opj_mqc_decode(mqc) ^ opj_t1_getspb(flag);
*datap = v ? -oneplushalf : oneplushalf;
- opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride);
+ opj_t1_updateflagscolflags(flagsp, colflagsp, v, t1->flags_stride, row);
}
+#ifdef CONSISTENCY_CHECK
*flagsp |= T1_VISIT;
+#endif
+ *colflagsp |= (opj_colflag_t)(T1_COLFLAG_VISIT_ROW_0 << (T1_COLFLAG_RBS * row));
}
} /* VSC and BYPASS by Antonin */
-void opj_t1_enc_sigpass(opj_t1_t *t1,
+static void opj_t1_enc_sigpass(opj_t1_t *t1,
OPJ_INT32 bpno,
- OPJ_UINT32 orient,
OPJ_INT32 *nmsedec,
OPJ_BYTE type,
OPJ_UINT32 cblksty
@@ -496,8 +544,7 @@ void opj_t1_enc_sigpass(opj_t1_t *t1,
opj_t1_enc_sigpass_step(
t1,
&t1->flags[((j+1) * t1->flags_stride) + i + 1],
- &t1->data[(j * t1->w) + i],
- orient,
+ &t1->data[(j * t1->data_stride) + i],
bpno,
one,
nmsedec,
@@ -508,105 +555,149 @@ void opj_t1_enc_sigpass(opj_t1_t *t1,
}
}
-void opj_t1_dec_sigpass_raw(
+static void opj_t1_dec_sigpass_raw(
opj_t1_t *t1,
OPJ_INT32 bpno,
- OPJ_INT32 orient,
OPJ_INT32 cblksty)
{
OPJ_INT32 one, half, oneplushalf, vsc;
OPJ_UINT32 i, j, k;
+ opj_colflag_t *colflags1 = &t1->colflags[t1->flags_stride + 1];
one = 1 << bpno;
half = one >> 1;
oneplushalf = one | half;
for (k = 0; k < t1->h; k += 4) {
for (i = 0; i < t1->w; ++i) {
+ opj_colflag_t *colflags2 = colflags1 + i;
for (j = k; j < k + 4 && j < t1->h; ++j) {
vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0;
opj_t1_dec_sigpass_step_raw(
t1,
&t1->flags[((j+1) * t1->flags_stride) + i + 1],
+ colflags2,
&t1->data[(j * t1->w) + i],
- orient,
oneplushalf,
- vsc);
+ vsc,
+ j - k);
}
}
+ colflags1 += t1->flags_stride;
}
} /* VSC and BYPASS by Antonin */
-void opj_t1_dec_sigpass_mqc(
+#define opj_t1_dec_sigpass_mqc_internal(t1, bpno, w, h, flags_stride) \
+{ \
+ OPJ_INT32 one, half, oneplushalf; \
+ OPJ_UINT32 i, j, k; \
+ OPJ_INT32 *data1 = t1->data; \
+ opj_flag_t *flags1 = &t1->flags[1]; \
+ opj_colflag_t *colflags1 = &t1->colflags[flags_stride + 1]; \
+ one = 1 << bpno; \
+ half = one >> 1; \
+ oneplushalf = one | half; \
+ for (k = 0; k < (h & ~3u); k += 4) { \
+ for (i = 0; i < w; ++i) { \
+ OPJ_INT32 *data2 = data1 + i; \
+ opj_flag_t *flags2 = flags1 + i; \
+ opj_colflag_t *colflags2 = colflags1 + i; \
+ if( *colflags2 == 0 ) continue; \
+ flags2 += flags_stride; \
+ opj_t1_dec_sigpass_step_mqc(t1, flags2, colflags2, data2, oneplushalf, 0U, flags_stride); \
+ data2 += w; \
+ flags2 += flags_stride; \
+ opj_t1_dec_sigpass_step_mqc(t1, flags2, colflags2, data2, oneplushalf, 1U, flags_stride); \
+ data2 += w; \
+ flags2 += flags_stride; \
+ opj_t1_dec_sigpass_step_mqc(t1, flags2, colflags2, data2, oneplushalf, 2U, flags_stride); \
+ data2 += w; \
+ flags2 += flags_stride; \
+ opj_t1_dec_sigpass_step_mqc(t1, flags2, colflags2, data2, oneplushalf, 3U, flags_stride); \
+ data2 += w; \
+ } \
+ data1 += w << 2; \
+ flags1 += flags_stride << 2; \
+ colflags1 += flags_stride; \
+ } \
+ for (i = 0; i < w; ++i) { \
+ OPJ_INT32 *data2 = data1 + i; \
+ opj_flag_t *flags2 = flags1 + i; \
+ opj_colflag_t *colflags2 = colflags1 + i; \
+ for (j = k; j < h; ++j) { \
+ flags2 += flags_stride; \
+ opj_t1_dec_sigpass_step_mqc(t1, flags2, colflags2, data2, oneplushalf, j - k, flags_stride); \
+ data2 += w; \
+ } \
+ } \
+}
+
+static void opj_t1_dec_sigpass_mqc_64x64(
opj_t1_t *t1,
- OPJ_INT32 bpno,
- OPJ_INT32 orient)
+ OPJ_INT32 bpno)
+{
+ opj_t1_dec_sigpass_mqc_internal(t1, bpno, 64, 64, 66);
+}
+
+static void opj_t1_dec_sigpass_mqc_generic(
+ opj_t1_t *t1,
+ OPJ_INT32 bpno)
{
- OPJ_INT32 one, half, oneplushalf;
+ opj_t1_dec_sigpass_mqc_internal(t1, bpno, t1->w, t1->h, t1->flags_stride);
+}
+
+/* VSC and BYPASS by Antonin */
+static void opj_t1_dec_sigpass_mqc_vsc(
+ opj_t1_t *t1,
+ OPJ_INT32 bpno)
+{
+ OPJ_INT32 one, half, oneplushalf, vsc;
OPJ_UINT32 i, j, k;
OPJ_INT32 *data1 = t1->data;
opj_flag_t *flags1 = &t1->flags[1];
+ opj_colflag_t *colflags1 = &t1->colflags[t1->flags_stride + 1];
one = 1 << bpno;
half = one >> 1;
oneplushalf = one | half;
- for (k = 0; k < (t1->h & ~3u); k += 4) {
+ for (k = 0; k < (t1->h & ~(OPJ_UINT32)3); k += 4U) {
for (i = 0; i < t1->w; ++i) {
OPJ_INT32 *data2 = data1 + i;
opj_flag_t *flags2 = flags1 + i;
+ opj_colflag_t *colflags2 = colflags1 + i;
flags2 += t1->flags_stride;
- opj_t1_dec_sigpass_step_mqc(t1, flags2, data2, orient, oneplushalf);
+ opj_t1_dec_sigpass_step_mqc_vsc(t1, flags2, colflags2, data2, oneplushalf, 0, 0U);
data2 += t1->w;
flags2 += t1->flags_stride;
- opj_t1_dec_sigpass_step_mqc(t1, flags2, data2, orient, oneplushalf);
+ opj_t1_dec_sigpass_step_mqc_vsc(t1, flags2, colflags2, data2, oneplushalf, 0, 1U);
data2 += t1->w;
flags2 += t1->flags_stride;
- opj_t1_dec_sigpass_step_mqc(t1, flags2, data2, orient, oneplushalf);
+ opj_t1_dec_sigpass_step_mqc_vsc(t1, flags2, colflags2, data2, oneplushalf, 0, 2U);
data2 += t1->w;
flags2 += t1->flags_stride;
- opj_t1_dec_sigpass_step_mqc(t1, flags2, data2, orient, oneplushalf);
+ opj_t1_dec_sigpass_step_mqc_vsc(t1, flags2, colflags2, data2, oneplushalf, 1, 3U);
data2 += t1->w;
}
data1 += t1->w << 2;
flags1 += t1->flags_stride << 2;
+ colflags1 += t1->flags_stride;
}
for (i = 0; i < t1->w; ++i) {
- OPJ_INT32 *data2 = data1 + i;
- opj_flag_t *flags2 = flags1 + i;
+ opj_colflag_t *colflags2 = colflags1 + i;
for (j = k; j < t1->h; ++j) {
- flags2 += t1->flags_stride;
- opj_t1_dec_sigpass_step_mqc(t1, flags2, data2, orient, oneplushalf);
- data2 += t1->w;
- }
- }
-} /* VSC and BYPASS by Antonin */
-
-void opj_t1_dec_sigpass_mqc_vsc(
- opj_t1_t *t1,
- OPJ_INT32 bpno,
- OPJ_INT32 orient)
-{
- OPJ_INT32 one, half, oneplushalf, vsc;
- OPJ_UINT32 i, j, k;
- one = 1 << bpno;
- half = one >> 1;
- oneplushalf = one | half;
- for (k = 0; k < t1->h; k += 4) {
- for (i = 0; i < t1->w; ++i) {
- for (j = k; j < k + 4 && j < t1->h; ++j) {
- vsc = (j == k + 3 || j == t1->h - 1) ? 1 : 0;
- opj_t1_dec_sigpass_step_mqc_vsc(
- t1,
- &t1->flags[((j+1) * t1->flags_stride) + i + 1],
- &t1->data[(j * t1->w) + i],
- orient,
- oneplushalf,
- vsc);
- }
+ vsc = (j == t1->h - 1) ? 1 : 0;
+ opj_t1_dec_sigpass_step_mqc_vsc(
+ t1,
+ &t1->flags[((j+1) * t1->flags_stride) + i + 1],
+ colflags2,
+ &t1->data[(j * t1->w) + i],
+ oneplushalf,
+ vsc,
+ j - k);
}
}
} /* VSC and BYPASS by Antonin */
-void opj_t1_enc_refpass_step( opj_t1_t *t1,
+static void opj_t1_enc_refpass_step( opj_t1_t *t1,
opj_flag_t *flagsp,
OPJ_INT32 *datap,
OPJ_INT32 bpno,
@@ -622,8 +713,8 @@ void opj_t1_enc_refpass_step( opj_t1_t *t1,
flag = vsc ? (OPJ_UINT32)((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (OPJ_UINT32)(*flagsp);
if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) {
- *nmsedec += opj_t1_getnmsedec_ref((OPJ_UINT32)opj_int_abs(*datap), (OPJ_UINT32)(bpno + T1_NMSEDEC_FRACBITS));
- v = opj_int_abs(*datap) & one ? 1 : 0;
+ *nmsedec += opj_t1_getnmsedec_ref((OPJ_UINT32)opj_int_abs(*datap), (OPJ_UINT32)(bpno));
+ v = (opj_int_abs(*datap) & one) ? 1 : 0;
opj_mqc_setcurctx(mqc, opj_t1_getctxno_mag(flag)); /* ESSAI */
if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */
opj_mqc_bypass_enc(mqc, (OPJ_UINT32)v);
@@ -634,72 +725,91 @@ void opj_t1_enc_refpass_step( opj_t1_t *t1,
}
}
-INLINE void opj_t1_dec_refpass_step_raw(
+static INLINE void opj_t1_dec_refpass_step_raw(
opj_t1_t *t1,
- opj_flag_t *flagsp,
+ opj_colflag_t *colflagsp,
OPJ_INT32 *datap,
OPJ_INT32 poshalf,
OPJ_INT32 neghalf,
- OPJ_INT32 vsc)
+ OPJ_UINT32 row)
{
- OPJ_INT32 v, t, flag;
+ OPJ_INT32 v, t;
opj_raw_t *raw = t1->raw; /* RAW component */
- flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
- if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) {
+ if ((*colflagsp & ((T1_COLFLAG_SIG_ROW_0 | T1_COLFLAG_VISIT_ROW_0) << (T1_COLFLAG_RBS * row))) ==
+ ((T1_COLFLAG_SIG_ROW_0) << (T1_COLFLAG_RBS * row))) {
v = (OPJ_INT32)opj_raw_decode(raw);
t = v ? poshalf : neghalf;
*datap += *datap < 0 ? -t : t;
- *flagsp |= T1_REFINE;
+ *colflagsp |= (opj_colflag_t)(T1_COLFLAG_REFINE_ROW_0 << (T1_COLFLAG_RBS * row));
}
} /* VSC and BYPASS by Antonin */
-INLINE void opj_t1_dec_refpass_step_mqc(
+static INLINE void opj_t1_dec_refpass_step_mqc(
opj_t1_t *t1,
+#ifdef CONSISTENCY_CHECK
opj_flag_t *flagsp,
+#else
+ opj_flag_t *flagsp_unused,
+#endif
+ opj_colflag_t *colflagsp,
OPJ_INT32 *datap,
OPJ_INT32 poshalf,
- OPJ_INT32 neghalf)
+ OPJ_INT32 neghalf,
+ OPJ_UINT32 row)
{
- OPJ_INT32 v, t, flag;
+ OPJ_INT32 v, t;
opj_mqc_t *mqc = t1->mqc; /* MQC component */
-
- flag = *flagsp;
- if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) {
- opj_mqc_setcurctx(mqc, opj_t1_getctxno_mag((OPJ_UINT32)flag)); /* ESSAI */
+#ifdef CONSISTENCY_CHECK
+ assert( ((*flagsp & (T1_SIG | T1_VISIT)) == T1_SIG) ==
+ ((*colflagsp & ((T1_COLFLAG_SIG_ROW_0 | T1_COLFLAG_VISIT_ROW_0) << (T1_COLFLAG_RBS * row))) == ((T1_COLFLAG_SIG_ROW_0) << (T1_COLFLAG_RBS * row))) );
+#else
+ (void)flagsp_unused;
+#endif
+ if ((*colflagsp & ((T1_COLFLAG_SIG_ROW_0 | T1_COLFLAG_VISIT_ROW_0) << (T1_COLFLAG_RBS * row))) ==
+ ((T1_COLFLAG_SIG_ROW_0) << (T1_COLFLAG_RBS * row))) {
+ OPJ_UINT32 tmp1 = (*colflagsp & (T1_COLFLAG_SIG_OTHER_ROW_0 << (T1_COLFLAG_RBS * row))) ? T1_CTXNO_MAG + 1 : T1_CTXNO_MAG;
+ OPJ_UINT32 tmp2 = (*colflagsp & (T1_COLFLAG_REFINE_ROW_0 << (T1_COLFLAG_RBS * row))) ? T1_CTXNO_MAG + 2 : tmp1;
+ opj_mqc_setcurctx(mqc, tmp2); /* ESSAI */
v = opj_mqc_decode(mqc);
t = v ? poshalf : neghalf;
*datap += *datap < 0 ? -t : t;
- *flagsp |= T1_REFINE;
+ *colflagsp |= (opj_colflag_t)(T1_COLFLAG_REFINE_ROW_0 << (T1_COLFLAG_RBS * row));
}
} /* VSC and BYPASS by Antonin */
-INLINE void opj_t1_dec_refpass_step_mqc_vsc(
+static INLINE void opj_t1_dec_refpass_step_mqc_vsc(
opj_t1_t *t1,
opj_flag_t *flagsp,
+ opj_colflag_t *colflagsp,
OPJ_INT32 *datap,
OPJ_INT32 poshalf,
OPJ_INT32 neghalf,
- OPJ_INT32 vsc)
+ OPJ_INT32 vsc,
+ OPJ_UINT32 row)
{
- OPJ_INT32 v, t, flag;
-
+ OPJ_UINT32 v;
+ OPJ_INT32 t;
+
opj_mqc_t *mqc = t1->mqc; /* MQC component */
- flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
- if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) {
- opj_mqc_setcurctx(mqc, opj_t1_getctxno_mag((OPJ_UINT32)flag)); /* ESSAI */
- v = opj_mqc_decode(mqc);
+ if ((*colflagsp & ((T1_COLFLAG_SIG_ROW_0 | T1_COLFLAG_VISIT_ROW_0) << (T1_COLFLAG_RBS * row))) ==
+ ((T1_COLFLAG_SIG_ROW_0) << (T1_COLFLAG_RBS * row))) {
+ OPJ_UINT32 flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
+ OPJ_UINT32 tmp1 = (flag & T1_SIG_OTH) ? T1_CTXNO_MAG + 1 : T1_CTXNO_MAG;
+ OPJ_UINT32 tmp2 = (*colflagsp & (T1_COLFLAG_REFINE_ROW_0 << (T1_COLFLAG_RBS * row))) ? T1_CTXNO_MAG + 2U : tmp1;
+ opj_mqc_setcurctx(mqc, tmp2); /* ESSAI */
+ v = (OPJ_UINT32)opj_mqc_decode(mqc);
t = v ? poshalf : neghalf;
*datap += *datap < 0 ? -t : t;
- *flagsp |= T1_REFINE;
+ *colflagsp |= (opj_colflag_t)(T1_COLFLAG_REFINE_ROW_0 << (T1_COLFLAG_RBS * row));
}
} /* VSC and BYPASS by Antonin */
-void opj_t1_enc_refpass(
+static void opj_t1_enc_refpass(
opj_t1_t *t1,
OPJ_INT32 bpno,
OPJ_INT32 *nmsedec,
@@ -718,7 +828,7 @@ void opj_t1_enc_refpass(
opj_t1_enc_refpass_step(
t1,
&t1->flags[((j+1) * t1->flags_stride) + i + 1],
- &t1->data[(j * t1->w) + i],
+ &t1->data[(j * t1->data_stride) + i],
bpno,
one,
nmsedec,
@@ -729,107 +839,148 @@ void opj_t1_enc_refpass(
}
}
-void opj_t1_dec_refpass_raw(
+static void opj_t1_dec_refpass_raw(
opj_t1_t *t1,
- OPJ_INT32 bpno,
- OPJ_INT32 cblksty)
+ OPJ_INT32 bpno)
{
OPJ_INT32 one, poshalf, neghalf;
OPJ_UINT32 i, j, k;
- OPJ_INT32 vsc;
+ opj_colflag_t *colflags1 = &t1->colflags[t1->flags_stride + 1];
one = 1 << bpno;
poshalf = one >> 1;
neghalf = bpno > 0 ? -poshalf : -1;
for (k = 0; k < t1->h; k += 4) {
for (i = 0; i < t1->w; ++i) {
+ opj_colflag_t *colflags2 = colflags1 + i;
for (j = k; j < k + 4 && j < t1->h; ++j) {
- vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0;
opj_t1_dec_refpass_step_raw(
t1,
- &t1->flags[((j+1) * t1->flags_stride) + i + 1],
+ colflags2,
&t1->data[(j * t1->w) + i],
poshalf,
- neghalf,
- vsc);
+ neghalf, j - k);
}
}
+ colflags1 += t1->flags_stride;
}
} /* VSC and BYPASS by Antonin */
-void opj_t1_dec_refpass_mqc(
+#define opj_t1_dec_refpass_mqc_internal(t1, bpno, w, h, flags_stride) \
+{ \
+ OPJ_INT32 one, poshalf, neghalf; \
+ OPJ_UINT32 i, j, k; \
+ OPJ_INT32 *data1 = t1->data; \
+ opj_flag_t *flags1 = &t1->flags[1]; \
+ opj_colflag_t *colflags1 = &t1->colflags[flags_stride + 1]; \
+ one = 1 << bpno; \
+ poshalf = one >> 1; \
+ neghalf = bpno > 0 ? -poshalf : -1; \
+ for (k = 0; k < (h & ~3u); k += 4) { \
+ for (i = 0; i < w; ++i) { \
+ OPJ_INT32 *data2 = data1 + i; \
+ opj_flag_t *flags2 = flags1 + i; \
+ opj_colflag_t *colflags2 = colflags1 + i; \
+ if( *colflags2 == 0 ) continue; \
+ flags2 += flags_stride; \
+ opj_t1_dec_refpass_step_mqc(t1, flags2, colflags2, data2, poshalf, neghalf, 0U); \
+ data2 += w; \
+ flags2 += flags_stride; \
+ opj_t1_dec_refpass_step_mqc(t1, flags2, colflags2, data2, poshalf, neghalf, 1U); \
+ data2 += w; \
+ flags2 += flags_stride; \
+ opj_t1_dec_refpass_step_mqc(t1, flags2, colflags2, data2, poshalf, neghalf, 2U); \
+ data2 += w; \
+ flags2 += flags_stride; \
+ opj_t1_dec_refpass_step_mqc(t1, flags2, colflags2, data2, poshalf, neghalf, 3U); \
+ data2 += w; \
+ } \
+ data1 += w << 2; \
+ flags1 += flags_stride << 2; \
+ colflags1 += flags_stride; \
+ } \
+ for (i = 0; i < w; ++i) { \
+ OPJ_INT32 *data2 = data1 + i; \
+ opj_flag_t *flags2 = flags1 + i; \
+ opj_colflag_t *colflags2 = colflags1 + i; \
+ for (j = k; j < h; ++j) { \
+ flags2 += flags_stride; \
+ opj_t1_dec_refpass_step_mqc(t1, flags2, colflags2, data2, poshalf, neghalf, j - k); \
+ data2 += w; \
+ } \
+ } \
+}
+
+static void opj_t1_dec_refpass_mqc_64x64(
+ opj_t1_t *t1,
+ OPJ_INT32 bpno)
+{
+ opj_t1_dec_refpass_mqc_internal(t1, bpno, 64, 64, 66);
+}
+
+static void opj_t1_dec_refpass_mqc_generic(
+ opj_t1_t *t1,
+ OPJ_INT32 bpno)
+{
+ opj_t1_dec_refpass_mqc_internal(t1, bpno, t1->w, t1->h, t1->flags_stride);
+}
+
+/* VSC and BYPASS by Antonin */
+static void opj_t1_dec_refpass_mqc_vsc(
opj_t1_t *t1,
OPJ_INT32 bpno)
{
OPJ_INT32 one, poshalf, neghalf;
OPJ_UINT32 i, j, k;
+ OPJ_INT32 vsc;
OPJ_INT32 *data1 = t1->data;
opj_flag_t *flags1 = &t1->flags[1];
+ opj_colflag_t *colflags1 = &t1->colflags[t1->flags_stride + 1];
one = 1 << bpno;
poshalf = one >> 1;
neghalf = bpno > 0 ? -poshalf : -1;
- for (k = 0; k < (t1->h & ~3u); k += 4) {
+ for (k = 0; k < (t1->h & ~(OPJ_UINT32)3U); k += 4U) {
for (i = 0; i < t1->w; ++i) {
OPJ_INT32 *data2 = data1 + i;
opj_flag_t *flags2 = flags1 + i;
+ opj_colflag_t *colflags2 = colflags1 + i;
flags2 += t1->flags_stride;
- opj_t1_dec_refpass_step_mqc(t1, flags2, data2, poshalf, neghalf);
+ opj_t1_dec_refpass_step_mqc_vsc(t1, flags2, colflags2, data2, poshalf, neghalf, 0, 0U);
data2 += t1->w;
flags2 += t1->flags_stride;
- opj_t1_dec_refpass_step_mqc(t1, flags2, data2, poshalf, neghalf);
+ opj_t1_dec_refpass_step_mqc_vsc(t1, flags2, colflags2, data2, poshalf, neghalf, 0, 1U);
data2 += t1->w;
flags2 += t1->flags_stride;
- opj_t1_dec_refpass_step_mqc(t1, flags2, data2, poshalf, neghalf);
+ opj_t1_dec_refpass_step_mqc_vsc(t1, flags2, colflags2, data2, poshalf, neghalf, 0, 2U);
data2 += t1->w;
flags2 += t1->flags_stride;
- opj_t1_dec_refpass_step_mqc(t1, flags2, data2, poshalf, neghalf);
+ opj_t1_dec_refpass_step_mqc_vsc(t1, flags2, colflags2, data2, poshalf, neghalf, 1, 3U);
data2 += t1->w;
}
data1 += t1->w << 2;
flags1 += t1->flags_stride << 2;
+ colflags1 += t1->flags_stride;
}
for (i = 0; i < t1->w; ++i) {
- OPJ_INT32 *data2 = data1 + i;
- opj_flag_t *flags2 = flags1 + i;
+ opj_colflag_t *colflags2 = colflags1 + i;
for (j = k; j < t1->h; ++j) {
- flags2 += t1->flags_stride;
- opj_t1_dec_refpass_step_mqc(t1, flags2, data2, poshalf, neghalf);
- data2 += t1->w;
- }
- }
-} /* VSC and BYPASS by Antonin */
-
-void opj_t1_dec_refpass_mqc_vsc(
- opj_t1_t *t1,
- OPJ_INT32 bpno)
-{
- OPJ_INT32 one, poshalf, neghalf;
- OPJ_UINT32 i, j, k;
- OPJ_INT32 vsc;
- one = 1 << bpno;
- poshalf = one >> 1;
- neghalf = bpno > 0 ? -poshalf : -1;
- for (k = 0; k < t1->h; k += 4) {
- for (i = 0; i < t1->w; ++i) {
- for (j = k; j < k + 4 && j < t1->h; ++j) {
- vsc = ((j == k + 3 || j == t1->h - 1)) ? 1 : 0;
- opj_t1_dec_refpass_step_mqc_vsc(
- t1,
- &t1->flags[((j+1) * t1->flags_stride) + i + 1],
- &t1->data[(j * t1->w) + i],
- poshalf,
- neghalf,
- vsc);
- }
+ vsc = (j == t1->h - 1) ? 1 : 0;
+ opj_t1_dec_refpass_step_mqc_vsc(
+ t1,
+ &t1->flags[((j+1) * t1->flags_stride) + i + 1],
+ colflags2,
+ &t1->data[(j * t1->w) + i],
+ poshalf, neghalf,
+ vsc,
+ j - k);
}
}
} /* VSC and BYPASS by Antonin */
-void opj_t1_enc_clnpass_step(
+static void opj_t1_enc_clnpass_step(
opj_t1_t *t1,
opj_flag_t *flagsp,
OPJ_INT32 *datap,
- OPJ_UINT32 orient,
OPJ_INT32 bpno,
OPJ_INT32 one,
OPJ_INT32 *nmsedec,
@@ -846,75 +997,110 @@ void opj_t1_enc_clnpass_step(
goto LABEL_PARTIAL;
}
if (!(*flagsp & (T1_SIG | T1_VISIT))) {
- opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(flag, orient));
- v = opj_int_abs(*datap) & one ? 1 : 0;
+ opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(mqc, flag));
+ v = (opj_int_abs(*datap) & one) ? 1 : 0;
opj_mqc_encode(mqc, (OPJ_UINT32)v);
if (v) {
LABEL_PARTIAL:
- *nmsedec += opj_t1_getnmsedec_sig((OPJ_UINT32)opj_int_abs(*datap), (OPJ_UINT32)(bpno + T1_NMSEDEC_FRACBITS));
+ *nmsedec += opj_t1_getnmsedec_sig((OPJ_UINT32)opj_int_abs(*datap), (OPJ_UINT32)(bpno));
opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc(flag));
v = *datap < 0 ? 1 : 0;
opj_mqc_encode(mqc, (OPJ_UINT32)(v ^ opj_t1_getspb((OPJ_UINT32)flag)));
opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride);
}
}
- *flagsp &= ~T1_VISIT;
+ *flagsp &= (opj_flag_t)~T1_VISIT;
}
static void opj_t1_dec_clnpass_step_partial(
opj_t1_t *t1,
opj_flag_t *flagsp,
+ opj_colflag_t *colflagsp,
OPJ_INT32 *datap,
- OPJ_INT32 orient,
- OPJ_INT32 oneplushalf)
+ OPJ_INT32 oneplushalf,
+ OPJ_UINT32 row)
{
OPJ_INT32 v, flag;
opj_mqc_t *mqc = t1->mqc; /* MQC component */
- OPJ_ARG_NOT_USED(orient);
-
flag = *flagsp;
opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag));
v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag);
*datap = v ? -oneplushalf : oneplushalf;
- opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride);
+ opj_t1_updateflagscolflags(flagsp, colflagsp, (OPJ_UINT32)v, t1->flags_stride, row);
+#ifdef CONSISTENCY_CHECK
*flagsp &= ~T1_VISIT;
+#endif
} /* VSC and BYPASS by Antonin */
static void opj_t1_dec_clnpass_step(
opj_t1_t *t1,
opj_flag_t *flagsp,
+ opj_colflag_t *colflagsp,
OPJ_INT32 *datap,
- OPJ_INT32 orient,
- OPJ_INT32 oneplushalf)
+ OPJ_INT32 oneplushalf,
+ OPJ_UINT32 row)
{
OPJ_INT32 v, flag;
opj_mqc_t *mqc = t1->mqc; /* MQC component */
-
- flag = *flagsp;
- if (!(flag & (T1_SIG | T1_VISIT))) {
- opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc((OPJ_UINT32)flag, (OPJ_UINT32)orient));
+#ifdef CONSISTENCY_CHECK
+ assert( (!(*flagsp & (T1_SIG | T1_VISIT))) == (!(*colflagsp & ((T1_COLFLAG_SIG_ROW_0 | T1_COLFLAG_VISIT_ROW_0) << (4*row)))) );
+#endif
+ if (!(*colflagsp & ((T1_COLFLAG_SIG_ROW_0 | T1_COLFLAG_VISIT_ROW_0) << (4*row)))) {
+ flag = *flagsp;
+ opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(mqc, (OPJ_UINT32)flag));
if (opj_mqc_decode(mqc)) {
opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag));
v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag);
*datap = v ? -oneplushalf : oneplushalf;
- opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride);
+ opj_t1_updateflagscolflags(flagsp, colflagsp, (OPJ_UINT32)v, t1->flags_stride, row);
}
}
+#ifdef CONSISTENCY_CHECK
*flagsp &= ~T1_VISIT;
+#endif
} /* VSC and BYPASS by Antonin */
+static void opj_t1_dec_clnpass_step_only_if_flag_not_sig_visit(
+ opj_t1_t *t1,
+ opj_flag_t *flagsp,
+ opj_colflag_t *colflagsp,
+ OPJ_INT32 *datap,
+ OPJ_INT32 oneplushalf,
+ OPJ_UINT32 row,
+ OPJ_UINT32 flags_stride)
+{
+ OPJ_INT32 v;
+ OPJ_INT32 flag;
+
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */
+
+ flag = *flagsp;
+ /*if (!(flag & (T1_SIG | T1_VISIT)))*/
+ {
+ opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(mqc, (OPJ_UINT32)flag));
+ if (opj_mqc_decode(mqc)) {
+ opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag));
+ v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag);
+ *datap = v ? -oneplushalf : oneplushalf;
+ opj_t1_updateflagscolflags(flagsp, colflagsp, (OPJ_UINT32)v, flags_stride, row);
+ }
+ }
+ /*flagsp &= ~T1_VISIT;*/
+}
+
static void opj_t1_dec_clnpass_step_vsc(
opj_t1_t *t1,
opj_flag_t *flagsp,
+ opj_colflag_t *colflagsp,
OPJ_INT32 *datap,
- OPJ_INT32 orient,
OPJ_INT32 oneplushalf,
OPJ_INT32 partial,
- OPJ_INT32 vsc)
+ OPJ_INT32 vsc,
+ OPJ_UINT32 row)
{
- OPJ_INT32 v, flag;
+ OPJ_UINT32 v, flag;
opj_mqc_t *mqc = t1->mqc; /* MQC component */
@@ -922,23 +1108,24 @@ static void opj_t1_dec_clnpass_step_vsc(
if (partial) {
goto LABEL_PARTIAL;
}
- if (!(flag & (T1_SIG | T1_VISIT))) {
- opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc((OPJ_UINT32)flag, (OPJ_UINT32)orient));
+ if (!(*colflagsp & ((T1_COLFLAG_SIG_ROW_0 | T1_COLFLAG_VISIT_ROW_0) << (T1_COLFLAG_RBS * row)))) {
+ opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(mqc, flag));
if (opj_mqc_decode(mqc)) {
LABEL_PARTIAL:
- opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag));
- v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag);
+ opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc(flag));
+ v = (OPJ_UINT32)opj_mqc_decode(mqc) ^ opj_t1_getspb(flag);
*datap = v ? -oneplushalf : oneplushalf;
- opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride);
+ opj_t1_updateflagscolflags(flagsp, colflagsp, v, t1->flags_stride, row);
}
}
+#ifdef CONSISTENCY_CHECK
*flagsp &= ~T1_VISIT;
+#endif
}
-void opj_t1_enc_clnpass(
+static void opj_t1_enc_clnpass(
opj_t1_t *t1,
OPJ_INT32 bpno,
- OPJ_UINT32 orient,
OPJ_INT32 *nmsedec,
OPJ_UINT32 cblksty)
{
@@ -960,17 +1147,17 @@ void opj_t1_enc_clnpass(
|| (MACRO_t1_flags(1 + k + 3,1 + i)
& (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) & (T1_SIG | T1_VISIT | T1_SIG_OTH));
} else {
- agg = !(MACRO_t1_flags(1 + k,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
- || MACRO_t1_flags(1 + k + 1,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
- || MACRO_t1_flags(1 + k + 2,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
- || MACRO_t1_flags(1 + k + 3,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH));
+ agg = !((MACRO_t1_flags(1 + k,1 + i) |
+ MACRO_t1_flags(1 + k + 1,1 + i) |
+ MACRO_t1_flags(1 + k + 2,1 + i) |
+ MACRO_t1_flags(1 + k + 3,1 + i)) & (T1_SIG | T1_VISIT | T1_SIG_OTH));
}
} else {
agg = 0;
}
if (agg) {
for (runlen = 0; runlen < 4; ++runlen) {
- if (opj_int_abs(t1->data[((k + runlen)*t1->w) + i]) & one)
+ if (opj_int_abs(t1->data[((k + runlen)*t1->data_stride) + i]) & one)
break;
}
opj_mqc_setcurctx(mqc, T1_CTXNO_AGG);
@@ -989,8 +1176,7 @@ void opj_t1_enc_clnpass(
opj_t1_enc_clnpass_step(
t1,
&t1->flags[((j+1) * t1->flags_stride) + i + 1],
- &t1->data[(j * t1->w) + i],
- orient,
+ &t1->data[(j * t1->data_stride) + i],
bpno,
one,
nmsedec,
@@ -1001,130 +1187,186 @@ void opj_t1_enc_clnpass(
}
}
-static void opj_t1_dec_clnpass(
+#define MACRO_t1_flags_internal(x,y,flags_stride) t1->flags[((x)*(flags_stride))+(y)]
+
+#define opj_t1_dec_clnpass_internal(consistency_check, t1, bpno, cblksty, w, h, flags_stride) \
+{ \
+ OPJ_INT32 one, half, oneplushalf, agg, runlen, vsc; \
+ OPJ_UINT32 i, j, k; \
+ OPJ_INT32 segsym = cblksty & J2K_CCP_CBLKSTY_SEGSYM; \
+ \
+ opj_mqc_t *mqc = t1->mqc; /* MQC component */ \
+ \
+ one = 1 << bpno; \
+ half = one >> 1; \
+ oneplushalf = one | half; \
+ if (cblksty & J2K_CCP_CBLKSTY_VSC) { \
+ opj_colflag_t *colflags1 = &t1->colflags[flags_stride + 1]; \
+ for (k = 0; k < h; k += 4) { \
+ for (i = 0; i < w; ++i) { \
+ opj_colflag_t *colflags2 = colflags1 + i; \
+ if (k + 3 < h) { \
+ agg = !((*colflags2 & (T1_COLFLAG_SIG_ROW_0 | T1_COLFLAG_VISIT_ROW_0 | T1_COLFLAG_SIG_OTHER_ROW_0 | \
+ T1_COLFLAG_SIG_ROW_1 | T1_COLFLAG_VISIT_ROW_1 | T1_COLFLAG_SIG_OTHER_ROW_1 | \
+ T1_COLFLAG_SIG_ROW_2 | T1_COLFLAG_VISIT_ROW_2 | T1_COLFLAG_SIG_OTHER_ROW_2 | \
+ T1_COLFLAG_SIG_ROW_3 | T1_COLFLAG_VISIT_ROW_3)) || \
+ ((MACRO_t1_flags_internal(1 + k + 3,1 + i,flags_stride) \
+ & ((~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) & (T1_SIG_OTH)))); \
+ } else { \
+ agg = 0; \
+ } \
+ if (agg) { \
+ opj_mqc_setcurctx(mqc, T1_CTXNO_AGG); \
+ if (!opj_mqc_decode(mqc)) { \
+ continue; \
+ } \
+ opj_mqc_setcurctx(mqc, T1_CTXNO_UNI); \
+ runlen = opj_mqc_decode(mqc); \
+ runlen = (runlen << 1) | opj_mqc_decode(mqc); \
+ } else { \
+ runlen = 0; \
+ } \
+ for (j = k + (OPJ_UINT32)runlen; j < k + 4 && j < h; ++j) { \
+ vsc = (j == k + 3 || j == h - 1) ? 1 : 0; \
+ opj_t1_dec_clnpass_step_vsc( \
+ t1, \
+ &t1->flags[((j+1) * flags_stride) + i + 1], \
+ colflags2, \
+ &t1->data[(j * w) + i], \
+ oneplushalf, \
+ agg && (j == k + (OPJ_UINT32)runlen), \
+ vsc, j - k); \
+ } \
+ *colflags2 &= (opj_colflag_t)~(T1_COLFLAG_VISIT_ROW_0 | T1_COLFLAG_VISIT_ROW_1 | T1_COLFLAG_VISIT_ROW_2 | T1_COLFLAG_VISIT_ROW_3); \
+ } \
+ colflags1 += flags_stride; \
+ } \
+ } else { \
+ OPJ_INT32 *data1 = t1->data; \
+ opj_flag_t *flags1 = &t1->flags[1]; \
+ opj_colflag_t *colflags1 = &t1->colflags[flags_stride + 1]; \
+ for (k = 0; k < (h & ~3u); k += 4) { \
+ for (i = 0; i < w; ++i) { \
+ OPJ_INT32 *data2 = data1 + i; \
+ opj_flag_t *flags2 = flags1 + i; \
+ opj_colflag_t *colflags2 = colflags1 + i; \
+ opj_colflag_t colflags = *colflags2; \
+ agg = !(colflags & (T1_COLFLAG_SIG_ROW_0 | T1_COLFLAG_VISIT_ROW_0 | T1_COLFLAG_SIG_OTHER_ROW_0 | \
+ T1_COLFLAG_SIG_ROW_1 | T1_COLFLAG_VISIT_ROW_1 | T1_COLFLAG_SIG_OTHER_ROW_1 | \
+ T1_COLFLAG_SIG_ROW_2 | T1_COLFLAG_VISIT_ROW_2 | T1_COLFLAG_SIG_OTHER_ROW_2 | \
+ T1_COLFLAG_SIG_ROW_3 | T1_COLFLAG_VISIT_ROW_3 | T1_COLFLAG_SIG_OTHER_ROW_3)); \
+ if( consistency_check ) { \
+ assert( agg == !((MACRO_t1_flags_internal(1 + k, 1 + i,flags_stride) | \
+ MACRO_t1_flags_internal(1 + k + 1, 1 + i,flags_stride) | \
+ MACRO_t1_flags_internal(1 + k + 2, 1 + i,flags_stride) | \
+ MACRO_t1_flags_internal(1 + k + 3, 1 + i,flags_stride)) & (T1_SIG | T1_VISIT | T1_SIG_OTH)) ); \
+ } \
+ if (agg) { \
+ opj_mqc_setcurctx(mqc, T1_CTXNO_AGG); \
+ if (!opj_mqc_decode(mqc)) { \
+ continue; \
+ } \
+ opj_mqc_setcurctx(mqc, T1_CTXNO_UNI); \
+ runlen = opj_mqc_decode(mqc); \
+ runlen = (runlen << 1) | opj_mqc_decode(mqc); \
+ flags2 += (OPJ_UINT32)runlen * flags_stride; \
+ data2 += (OPJ_UINT32)runlen * w; \
+ for (j = (OPJ_UINT32)runlen; j < 4; ++j) { \
+ flags2 += flags_stride; \
+ if (j == (OPJ_UINT32)runlen) { \
+ opj_t1_dec_clnpass_step_partial(t1, flags2, colflags2, data2, oneplushalf, j); \
+ } else { \
+ opj_t1_dec_clnpass_step(t1, flags2, colflags2, data2, oneplushalf, j); \
+ } \
+ data2 += w; \
+ } \
+ } else { \
+ flags2 += flags_stride; \
+ if( consistency_check ) { assert( (!(colflags & (T1_COLFLAG_SIG_ROW_0 | T1_COLFLAG_VISIT_ROW_0))) == (!(*flags2 & (T1_SIG | T1_VISIT))) ); } \
+ if (!(colflags & (T1_COLFLAG_SIG_ROW_0 | T1_COLFLAG_VISIT_ROW_0))) {\
+ opj_t1_dec_clnpass_step_only_if_flag_not_sig_visit(t1, flags2, colflags2, data2, oneplushalf, 0U, flags_stride); \
+ } \
+ if( consistency_check ) *flags2 &= (opj_flag_t)~T1_VISIT; \
+ data2 += w; \
+ flags2 += flags_stride; \
+ if( consistency_check ) { assert( (!(colflags & (T1_COLFLAG_SIG_ROW_1 | T1_COLFLAG_VISIT_ROW_1))) == (!(*flags2 & (T1_SIG | T1_VISIT))) ); } \
+ if (!(colflags & (T1_COLFLAG_SIG_ROW_1 | T1_COLFLAG_VISIT_ROW_1))) {\
+ opj_t1_dec_clnpass_step_only_if_flag_not_sig_visit(t1, flags2, colflags2, data2, oneplushalf, 1U, flags_stride); \
+ } \
+ if( consistency_check ) *flags2 &= (opj_flag_t)~T1_VISIT; \
+ data2 += w; \
+ flags2 += flags_stride; \
+ if( consistency_check ) { assert( (!(colflags & (T1_COLFLAG_SIG_ROW_2 | T1_COLFLAG_VISIT_ROW_2))) == (!(*flags2 & (T1_SIG | T1_VISIT))) ); } \
+ if (!(colflags & (T1_COLFLAG_SIG_ROW_2 | T1_COLFLAG_VISIT_ROW_2))) {\
+ opj_t1_dec_clnpass_step_only_if_flag_not_sig_visit(t1, flags2, colflags2, data2, oneplushalf, 2U, flags_stride); \
+ } \
+ if( consistency_check ) *flags2 &= (opj_flag_t)~T1_VISIT; \
+ data2 += w; \
+ flags2 += flags_stride; \
+ if( consistency_check ) { assert( (!(colflags & (T1_COLFLAG_SIG_ROW_3 | T1_COLFLAG_VISIT_ROW_3))) == (!(*flags2 & (T1_SIG | T1_VISIT))) ); } \
+ if (!(colflags & (T1_COLFLAG_SIG_ROW_3 | T1_COLFLAG_VISIT_ROW_3))) {\
+ opj_t1_dec_clnpass_step_only_if_flag_not_sig_visit(t1, flags2, colflags2, data2, oneplushalf, 3U, flags_stride); \
+ } \
+ if( consistency_check ) *flags2 &= (opj_flag_t)~T1_VISIT; \
+ data2 += w; \
+ } \
+ *colflags2 &= (opj_colflag_t)~(T1_COLFLAG_VISIT_ROW_0 | T1_COLFLAG_VISIT_ROW_1 | T1_COLFLAG_VISIT_ROW_2 | T1_COLFLAG_VISIT_ROW_3); \
+ } \
+ data1 += w << 2; \
+ flags1 += flags_stride << 2; \
+ colflags1 += flags_stride; \
+ } \
+ for (i = 0; i < w; ++i) { \
+ OPJ_INT32 *data2 = data1 + i; \
+ opj_flag_t *flags2 = flags1 + i; \
+ opj_colflag_t *colflags2 = colflags1 + i; \
+ for (j = k; j < h; ++j) { \
+ flags2 += flags_stride; \
+ opj_t1_dec_clnpass_step(t1, flags2, colflags2, data2, oneplushalf, j - k); \
+ data2 += w; \
+ } \
+ *colflags2 &= (opj_colflag_t)~(T1_COLFLAG_VISIT_ROW_0 | T1_COLFLAG_VISIT_ROW_1 | T1_COLFLAG_VISIT_ROW_2 | T1_COLFLAG_VISIT_ROW_3); \
+ } \
+ } \
+ \
+ if (segsym) { \
+ OPJ_INT32 v = 0; \
+ opj_mqc_setcurctx(mqc, T1_CTXNO_UNI); \
+ v = opj_mqc_decode(mqc); \
+ v = (v << 1) | opj_mqc_decode(mqc); \
+ v = (v << 1) | opj_mqc_decode(mqc); \
+ v = (v << 1) | opj_mqc_decode(mqc); \
+ /* \
+ if (v!=0xa) { \
+ opj_event_msg(t1->cinfo, EVT_WARNING, "Bad segmentation symbol %x\n", v); \
+ } \
+ */ \
+ } \
+} /* VSC and BYPASS by Antonin */
+
+static void opj_t1_dec_clnpass_64x64(
opj_t1_t *t1,
OPJ_INT32 bpno,
- OPJ_INT32 orient,
OPJ_INT32 cblksty)
{
- OPJ_INT32 one, half, oneplushalf, agg, runlen, vsc;
- OPJ_UINT32 i, j, k;
- OPJ_INT32 segsym = cblksty & J2K_CCP_CBLKSTY_SEGSYM;
-
- opj_mqc_t *mqc = t1->mqc; /* MQC component */
-
- one = 1 << bpno;
- half = one >> 1;
- oneplushalf = one | half;
- if (cblksty & J2K_CCP_CBLKSTY_VSC) {
- for (k = 0; k < t1->h; k += 4) {
- for (i = 0; i < t1->w; ++i) {
- if (k + 3 < t1->h) {
- agg = !(MACRO_t1_flags(1 + k,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
- || MACRO_t1_flags(1 + k + 1,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
- || MACRO_t1_flags(1 + k + 2,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
- || (MACRO_t1_flags(1 + k + 3,1 + i)
- & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) & (T1_SIG | T1_VISIT | T1_SIG_OTH));
- } else {
- agg = 0;
- }
- if (agg) {
- opj_mqc_setcurctx(mqc, T1_CTXNO_AGG);
- if (!opj_mqc_decode(mqc)) {
- continue;
- }
- opj_mqc_setcurctx(mqc, T1_CTXNO_UNI);
- runlen = opj_mqc_decode(mqc);
- runlen = (runlen << 1) | opj_mqc_decode(mqc);
- } else {
- runlen = 0;
- }
- for (j = k + (OPJ_UINT32)runlen; j < k + 4 && j < t1->h; ++j) {
- vsc = (j == k + 3 || j == t1->h - 1) ? 1 : 0;
- opj_t1_dec_clnpass_step_vsc(
- t1,
- &t1->flags[((j+1) * t1->flags_stride) + i + 1],
- &t1->data[(j * t1->w) + i],
- orient,
- oneplushalf,
- agg && (j == k + (OPJ_UINT32)runlen),
- vsc);
- }
- }
- }
- } else {
- OPJ_INT32 *data1 = t1->data;
- opj_flag_t *flags1 = &t1->flags[1];
- for (k = 0; k < (t1->h & ~3u); k += 4) {
- for (i = 0; i < t1->w; ++i) {
- OPJ_INT32 *data2 = data1 + i;
- opj_flag_t *flags2 = flags1 + i;
- agg = !(MACRO_t1_flags(1 + k,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
- || MACRO_t1_flags(1 + k + 1,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
- || MACRO_t1_flags(1 + k + 2,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)
- || MACRO_t1_flags(1 + k + 3,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH));
- if (agg) {
- opj_mqc_setcurctx(mqc, T1_CTXNO_AGG);
- if (!opj_mqc_decode(mqc)) {
- continue;
- }
- opj_mqc_setcurctx(mqc, T1_CTXNO_UNI);
- runlen = opj_mqc_decode(mqc);
- runlen = (runlen << 1) | opj_mqc_decode(mqc);
- flags2 += (OPJ_UINT32)runlen * t1->flags_stride;
- data2 += (OPJ_UINT32)runlen * t1->w;
- for (j = k + (OPJ_UINT32)runlen; j < k + 4 && j < t1->h; ++j) {
- flags2 += t1->flags_stride;
- if (agg && (j == k + (OPJ_UINT32)runlen)) {
- opj_t1_dec_clnpass_step_partial(t1, flags2, data2, orient, oneplushalf);
- } else {
- opj_t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
- }
- data2 += t1->w;
- }
- } else {
- flags2 += t1->flags_stride;
- opj_t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
- data2 += t1->w;
- flags2 += t1->flags_stride;
- opj_t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
- data2 += t1->w;
- flags2 += t1->flags_stride;
- opj_t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
- data2 += t1->w;
- flags2 += t1->flags_stride;
- opj_t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
- data2 += t1->w;
- }
- }
- data1 += t1->w << 2;
- flags1 += t1->flags_stride << 2;
- }
- for (i = 0; i < t1->w; ++i) {
- OPJ_INT32 *data2 = data1 + i;
- opj_flag_t *flags2 = flags1 + i;
- for (j = k; j < t1->h; ++j) {
- flags2 += t1->flags_stride;
- opj_t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf);
- data2 += t1->w;
- }
- }
- }
+#ifdef CONSISTENCY_CHECK
+ opj_t1_dec_clnpass_internal(OPJ_TRUE, t1, bpno, cblksty, 64, 64, 66);
+#else
+ opj_t1_dec_clnpass_internal(OPJ_FALSE, t1, bpno, cblksty, 64, 64, 66);
+#endif
+}
- if (segsym) {
- OPJ_INT32 v = 0;
- opj_mqc_setcurctx(mqc, T1_CTXNO_UNI);
- v = opj_mqc_decode(mqc);
- v = (v << 1) | opj_mqc_decode(mqc);
- v = (v << 1) | opj_mqc_decode(mqc);
- v = (v << 1) | opj_mqc_decode(mqc);
- /*
- if (v!=0xa) {
- opj_event_msg(t1->cinfo, EVT_WARNING, "Bad segmentation symbol %x\n", v);
- }
- */
- }
-} /* VSC and BYPASS by Antonin */
+static void opj_t1_dec_clnpass_generic(
+ opj_t1_t *t1,
+ OPJ_INT32 bpno,
+ OPJ_INT32 cblksty)
+{
+#ifdef CONSISTENCY_CHECK
+ opj_t1_dec_clnpass_internal(OPJ_TRUE, t1, bpno, cblksty, t1->w, t1->h, t1->flags_stride);
+#else
+ opj_t1_dec_clnpass_internal(OPJ_FALSE, t1, bpno, cblksty, t1->w, t1->h, t1->flags_stride);
+#endif
+}
/** mod fixed_quality */
@@ -1137,12 +1379,13 @@ static OPJ_FLOAT64 opj_t1_getwmsedec(
OPJ_UINT32 qmfbid,
OPJ_FLOAT64 stepsize,
OPJ_UINT32 numcomps,
- const OPJ_FLOAT64 * mct_norms)
+ const OPJ_FLOAT64 * mct_norms,
+ OPJ_UINT32 mct_numcomps)
{
OPJ_FLOAT64 w1 = 1, w2, wmsedec;
- OPJ_ARG_NOT_USED(numcomps);
+ OPJ_ARG_NOT_USED(numcomps);
- if (mct_norms) {
+ if (mct_norms && (compno < mct_numcomps)) {
w1 = mct_norms[compno];
}
@@ -1158,39 +1401,140 @@ static OPJ_FLOAT64 opj_t1_getwmsedec(
return wmsedec;
}
-OPJ_BOOL opj_t1_allocate_buffers(
+static OPJ_BOOL opj_t1_allocate_buffers(
opj_t1_t *t1,
OPJ_UINT32 w,
OPJ_UINT32 h)
{
- OPJ_UINT32 datasize=w * h;
- OPJ_UINT32 flagssize;
+ /* encoder uses tile buffer, so no need to allocate */
+ if (!t1->encoder) {
+ size_t datasize;
+
+#if (SIZE_MAX / 0xFFFFFFFFU) < 0xFFFFFFFFU /* UINT32_MAX */
+ /* Overflow check */
+ if ((w > 0U) && ((size_t)h > (SIZE_MAX / (size_t)w))) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+#endif
+ datasize = (size_t)w * h;
- if(datasize > t1->datasize){
- opj_aligned_free(t1->data);
- t1->data = (OPJ_INT32*) opj_aligned_malloc(datasize * sizeof(OPJ_INT32));
- if(!t1->data){
+ /* Overflow check */
+ if (datasize > (SIZE_MAX / sizeof(OPJ_INT32))) {
+ /* FIXME event manager error callback */
return OPJ_FALSE;
}
- t1->datasize=datasize;
+
+ if(datasize > (size_t)t1->datasize){
+ opj_aligned_free(t1->data);
+ t1->data = (OPJ_INT32*) opj_aligned_malloc(datasize * sizeof(OPJ_INT32));
+ if(!t1->data){
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+#if SIZE_MAX > 0xFFFFFFFFU /* UINT32_MAX */
+ /* TODO remove this if t1->datasize type changes to size_t */
+ /* Overflow check */
+ if (datasize > (size_t)0xFFFFFFFFU /* UINT32_MAX */) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+#endif
+ t1->datasize = (OPJ_UINT32)datasize;
+ }
+ /* memset first arg is declared to never be null by gcc */
+ if (t1->data != NULL) {
+ memset(t1->data, 0, datasize * sizeof(OPJ_INT32));
+ }
}
- memset(t1->data,0,datasize * sizeof(OPJ_INT32));
- t1->flags_stride=w+2;
- flagssize=t1->flags_stride * (h+2);
+ {
+ size_t flagssize;
+
+ /* Overflow check */
+ if (w > (0xFFFFFFFFU /* UINT32_MAX */ - 2U)) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+ t1->flags_stride = w + 2U; /* can't be 0U */
- if(flagssize > t1->flagssize){
- opj_aligned_free(t1->flags);
- t1->flags = (opj_flag_t*) opj_aligned_malloc(flagssize * sizeof(opj_flag_t));
- if(!t1->flags){
+#if (SIZE_MAX - 3U) < 0xFFFFFFFFU /* UINT32_MAX */
+ /* Overflow check */
+ if (h > (0xFFFFFFFFU /* UINT32_MAX */ - 3U)) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+#endif
+ flagssize = (size_t)h + 3U;
+
+ /* Overflow check */
+ if (flagssize > (SIZE_MAX / (size_t)t1->flags_stride)) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+ flagssize *= (size_t)t1->flags_stride;
+
+ if(flagssize > (size_t)t1->flagssize){
+ /* Overflow check */
+ if (flagssize > (SIZE_MAX / sizeof(opj_flag_t))) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+ opj_aligned_free(t1->flags);
+ t1->flags = (opj_flag_t*) opj_aligned_malloc(flagssize * sizeof(opj_flag_t));
+ if(!t1->flags){
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+#if SIZE_MAX > 0xFFFFFFFFU /* UINT32_MAX */
+ /* TODO remove this if t1->flagssize type changes to size_t */
+ /* Overflow check */
+ if (flagssize > (size_t)0xFFFFFFFFU /* UINT32_MAX */) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+#endif
+ t1->flagssize = (OPJ_UINT32)flagssize;
+ }
+ memset(t1->flags, 0, flagssize * sizeof(opj_flag_t));
+ }
+ if (!t1->encoder) {
+ size_t colflags_size = ((((size_t)h + 3U) / 4U) + 2U); /* Can't overflow, h checked against UINT32_MAX - 3U */
+
+ /* Overflow check */
+ if (colflags_size > (SIZE_MAX / (size_t)t1->flags_stride)) {
+ /* FIXME event manager error callback */
return OPJ_FALSE;
}
- t1->flagssize=flagssize;
+ colflags_size *= (size_t)t1->flags_stride;
+
+ if(colflags_size > (size_t)t1->colflags_size){
+ /* Overflow check */
+ if ((size_t)colflags_size > (SIZE_MAX / sizeof(opj_colflag_t))) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+ opj_aligned_free(t1->colflags);
+ t1->colflags = (opj_colflag_t*) opj_aligned_malloc(colflags_size * sizeof(opj_colflag_t));
+ if(!t1->colflags){
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+#if SIZE_MAX > 0xFFFFFFFFU /* UINT32_MAX */
+ /* TODO remove this if t1->colflags_size type changes to size_t */
+ /* Overflow check */
+ if (colflags_size > (size_t)0xFFFFFFFFU /* UINT32_MAX */) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
+#endif
+ t1->colflags_size = (OPJ_UINT32)colflags_size;
+ }
+ memset(t1->colflags, 0, colflags_size * sizeof(opj_colflag_t));
}
- memset(t1->flags,0,flagssize * sizeof(opj_flag_t));
- t1->w=w;
- t1->h=h;
+ t1->w = w;
+ t1->h = h;
return OPJ_TRUE;
}
@@ -1203,15 +1547,14 @@ OPJ_BOOL opj_t1_allocate_buffers(
* and initializes the look-up tables of the Tier-1 coder/decoder
* @return a new T1 handle if successful, returns NULL otherwise
*/
-opj_t1_t* opj_t1_create()
+opj_t1_t* opj_t1_create(OPJ_BOOL isEncoder)
{
opj_t1_t *l_t1 = 00;
- l_t1 = (opj_t1_t*) opj_malloc(sizeof(opj_t1_t));
+ l_t1 = (opj_t1_t*) opj_calloc(1,sizeof(opj_t1_t));
if (!l_t1) {
return 00;
}
- memset(l_t1,0,sizeof(opj_t1_t));
/* create MQC and RAW handles */
l_t1->mqc = opj_mqc_create();
@@ -1225,6 +1568,7 @@ opj_t1_t* opj_t1_create()
opj_t1_destroy(l_t1);
return 00;
}
+ l_t1->encoder = isEncoder;
return l_t1;
}
@@ -1247,7 +1591,8 @@ void opj_t1_destroy(opj_t1_t *p_t1)
opj_raw_destroy(p_t1->raw);
p_t1->raw = 00;
- if (p_t1->data) {
+ /* encoder uses tile buffer, so no need to free */
+ if (!p_t1->encoder && p_t1->data) {
opj_aligned_free(p_t1->data);
p_t1->data = 00;
}
@@ -1257,110 +1602,186 @@ void opj_t1_destroy(opj_t1_t *p_t1)
p_t1->flags = 00;
}
+ if (p_t1->colflags) {
+ opj_aligned_free(p_t1->colflags);
+ p_t1->colflags = 00;
+ }
opj_free(p_t1);
}
-OPJ_BOOL opj_t1_decode_cblks( opj_t1_t* t1,
- opj_tcd_tilecomp_t* tilec,
- opj_tccp_t* tccp
- )
+typedef struct
+{
+ OPJ_UINT32 resno;
+ opj_tcd_cblk_dec_t* cblk;
+ opj_tcd_band_t* band;
+ opj_tcd_tilecomp_t* tilec;
+ opj_tccp_t* tccp;
+ volatile OPJ_BOOL* pret;
+} opj_t1_cblk_decode_processing_job_t;
+
+static void opj_t1_destroy_wrapper(void* t1)
+{
+ opj_t1_destroy( (opj_t1_t*) t1 );
+}
+
+static void opj_t1_clbl_decode_processor(void* user_data, opj_tls_t* tls)
+{
+ opj_tcd_cblk_dec_t* cblk;
+ opj_tcd_band_t* band;
+ opj_tcd_tilecomp_t* tilec;
+ opj_tccp_t* tccp;
+ OPJ_INT32* OPJ_RESTRICT datap;
+ OPJ_UINT32 cblk_w, cblk_h;
+ OPJ_INT32 x, y;
+ OPJ_UINT32 i, j;
+ opj_t1_cblk_decode_processing_job_t* job;
+ opj_t1_t* t1;
+ OPJ_UINT32 resno;
+ OPJ_UINT32 tile_w;
+
+ job = (opj_t1_cblk_decode_processing_job_t*) user_data;
+ resno = job->resno;
+ cblk = job->cblk;
+ band = job->band;
+ tilec = job->tilec;
+ tccp = job->tccp;
+ tile_w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
+
+ if( !*(job->pret) )
+ {
+ opj_free(job);
+ return;
+ }
+
+ t1 = (opj_t1_t*) opj_tls_get(tls, OPJ_TLS_KEY_T1);
+ if( t1 == NULL )
+ {
+ t1 = opj_t1_create( OPJ_FALSE );
+ opj_tls_set( tls, OPJ_TLS_KEY_T1, t1, opj_t1_destroy_wrapper );
+ }
+
+ if (OPJ_FALSE == opj_t1_decode_cblk(
+ t1,
+ cblk,
+ band->bandno,
+ (OPJ_UINT32)tccp->roishift,
+ tccp->cblksty)) {
+ *(job->pret) = OPJ_FALSE;
+ opj_free(job);
+ return;
+ }
+
+ x = cblk->x0 - band->x0;
+ y = cblk->y0 - band->y0;
+ if (band->bandno & 1) {
+ opj_tcd_resolution_t* pres = &tilec->resolutions[resno - 1];
+ x += pres->x1 - pres->x0;
+ }
+ if (band->bandno & 2) {
+ opj_tcd_resolution_t* pres = &tilec->resolutions[resno - 1];
+ y += pres->y1 - pres->y0;
+ }
+
+ datap=t1->data;
+ cblk_w = t1->w;
+ cblk_h = t1->h;
+
+ if (tccp->roishift) {
+ OPJ_INT32 thresh = 1 << tccp->roishift;
+ for (j = 0; j < cblk_h; ++j) {
+ for (i = 0; i < cblk_w; ++i) {
+ OPJ_INT32 val = datap[(j * cblk_w) + i];
+ OPJ_INT32 mag = abs(val);
+ if (mag >= thresh) {
+ mag >>= tccp->roishift;
+ datap[(j * cblk_w) + i] = val < 0 ? -mag : mag;
+ }
+ }
+ }
+ }
+ if (tccp->qmfbid == 1) {
+ OPJ_INT32* OPJ_RESTRICT tiledp = &tilec->data[(OPJ_UINT32)y * tile_w + (OPJ_UINT32)x];
+ for (j = 0; j < cblk_h; ++j) {
+ i = 0;
+ for (; i < (cblk_w & ~(OPJ_UINT32)3U); i += 4U) {
+ OPJ_INT32 tmp0 = datap[(j * cblk_w) + i + 0U];
+ OPJ_INT32 tmp1 = datap[(j * cblk_w) + i + 1U];
+ OPJ_INT32 tmp2 = datap[(j * cblk_w) + i + 2U];
+ OPJ_INT32 tmp3 = datap[(j * cblk_w) + i + 3U];
+ ((OPJ_INT32*)tiledp)[(j * tile_w) + i + 0U] = tmp0 / 2;
+ ((OPJ_INT32*)tiledp)[(j * tile_w) + i + 1U] = tmp1 / 2;
+ ((OPJ_INT32*)tiledp)[(j * tile_w) + i + 2U] = tmp2 / 2;
+ ((OPJ_INT32*)tiledp)[(j * tile_w) + i + 3U] = tmp3 / 2;
+ }
+ for (; i < cblk_w; ++i) {
+ OPJ_INT32 tmp = datap[(j * cblk_w) + i];
+ ((OPJ_INT32*)tiledp)[(j * tile_w) + i] = tmp / 2;
+ }
+ }
+ } else { /* if (tccp->qmfbid == 0) */
+ OPJ_FLOAT32* OPJ_RESTRICT tiledp = (OPJ_FLOAT32*) &tilec->data[(OPJ_UINT32)y * tile_w + (OPJ_UINT32)x];
+ for (j = 0; j < cblk_h; ++j) {
+ OPJ_FLOAT32* OPJ_RESTRICT tiledp2 = tiledp;
+ for (i = 0; i < cblk_w; ++i) {
+ OPJ_FLOAT32 tmp = (OPJ_FLOAT32)*datap * band->stepsize;
+ *tiledp2 = tmp;
+ datap++;
+ tiledp2++;
+ }
+ tiledp += tile_w;
+ }
+ }
+
+ opj_free(job);
+}
+
+
+void opj_t1_decode_cblks( opj_thread_pool_t* tp,
+ volatile OPJ_BOOL* pret,
+ opj_tcd_tilecomp_t* tilec,
+ opj_tccp_t* tccp
+ )
{
OPJ_UINT32 resno, bandno, precno, cblkno;
- OPJ_UINT32 tile_w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
for (resno = 0; resno < tilec->minimum_num_resolutions; ++resno) {
opj_tcd_resolution_t* res = &tilec->resolutions[resno];
for (bandno = 0; bandno < res->numbands; ++bandno) {
- opj_tcd_band_t* restrict band = &res->bands[bandno];
+ opj_tcd_band_t* OPJ_RESTRICT band = &res->bands[bandno];
for (precno = 0; precno < res->pw * res->ph; ++precno) {
opj_tcd_precinct_t* precinct = &band->precincts[precno];
for (cblkno = 0; cblkno < precinct->cw * precinct->ch; ++cblkno) {
opj_tcd_cblk_dec_t* cblk = &precinct->cblks.dec[cblkno];
- OPJ_INT32* restrict datap;
- /*void* restrict tiledp;*/
- OPJ_UINT32 cblk_w, cblk_h;
- OPJ_INT32 x, y;
- OPJ_UINT32 i, j;
-
- if (OPJ_FALSE == opj_t1_decode_cblk(
- t1,
- cblk,
- band->bandno,
- (OPJ_UINT32)tccp->roishift,
- tccp->cblksty)) {
- return OPJ_FALSE;
- }
+ opj_t1_cblk_decode_processing_job_t* job;
- x = cblk->x0 - band->x0;
- y = cblk->y0 - band->y0;
- if (band->bandno & 1) {
- opj_tcd_resolution_t* pres = &tilec->resolutions[resno - 1];
- x += pres->x1 - pres->x0;
- }
- if (band->bandno & 2) {
- opj_tcd_resolution_t* pres = &tilec->resolutions[resno - 1];
- y += pres->y1 - pres->y0;
- }
-
- datap=t1->data;
- cblk_w = t1->w;
- cblk_h = t1->h;
-
- if (tccp->roishift) {
- OPJ_INT32 thresh = 1 << tccp->roishift;
- for (j = 0; j < cblk_h; ++j) {
- for (i = 0; i < cblk_w; ++i) {
- OPJ_INT32 val = datap[(j * cblk_w) + i];
- OPJ_INT32 mag = abs(val);
- if (mag >= thresh) {
- mag >>= tccp->roishift;
- datap[(j * cblk_w) + i] = val < 0 ? -mag : mag;
- }
- }
- }
- }
-
- /*tiledp=(void*)&tilec->data[(y * tile_w) + x];*/
- if (tccp->qmfbid == 1) {
- OPJ_INT32* restrict tiledp = &tilec->data[(OPJ_UINT32)y * tile_w + (OPJ_UINT32)x];
- for (j = 0; j < cblk_h; ++j) {
- for (i = 0; i < cblk_w; ++i) {
- OPJ_INT32 tmp = datap[(j * cblk_w) + i];
- ((OPJ_INT32*)tiledp)[(j * tile_w) + i] = tmp / 2;
- }
- }
- } else { /* if (tccp->qmfbid == 0) */
- OPJ_FLOAT32* restrict tiledp = (OPJ_FLOAT32*) &tilec->data[(OPJ_UINT32)y * tile_w + (OPJ_UINT32)x];
- for (j = 0; j < cblk_h; ++j) {
- OPJ_FLOAT32* restrict tiledp2 = tiledp;
- for (i = 0; i < cblk_w; ++i) {
- OPJ_FLOAT32 tmp = (OPJ_FLOAT32)*datap * band->stepsize;
- *tiledp2 = tmp;
- datap++;
- tiledp2++;
- /*float tmp = datap[(j * cblk_w) + i] * band->stepsize;
- ((float*)tiledp)[(j * tile_w) + i] = tmp;*/
-
- }
- tiledp += tile_w;
- }
- }
- /*opj_free(cblk->data);
- opj_free(cblk->segs);*/
- /*cblk->segs = 00;*/
+ job = (opj_t1_cblk_decode_processing_job_t*) opj_calloc(1, sizeof(opj_t1_cblk_decode_processing_job_t));
+ if( !job )
+ {
+ *pret = OPJ_FALSE;
+ return;
+ }
+ job->resno = resno;
+ job->cblk = cblk;
+ job->band = band;
+ job->tilec = tilec;
+ job->tccp = tccp;
+ job->pret = pret;
+ opj_thread_pool_submit_job( tp, opj_t1_clbl_decode_processor, job );
+ if( !(*pret) )
+ return;
} /* cblkno */
- /*opj_free(precinct->cblks.dec);*/
} /* precno */
} /* bandno */
} /* resno */
- return OPJ_TRUE;
+
+ return;
}
-OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1,
+static OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1,
opj_tcd_cblk_dec_t* cblk,
OPJ_UINT32 orient,
OPJ_UINT32 roishift,
@@ -1368,12 +1789,14 @@ OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1,
{
opj_raw_t *raw = t1->raw; /* RAW component */
opj_mqc_t *mqc = t1->mqc; /* MQC component */
-
- OPJ_INT32 bpno;
+
+ OPJ_INT32 bpno_plus_one;
OPJ_UINT32 passtype;
OPJ_UINT32 segno, passno;
OPJ_BYTE type = T1_TYPE_MQ; /* BYPASS mode */
+ mqc->lut_ctxno_zc_orient = lut_ctxno_zc + orient * 256;
+
if(!opj_t1_allocate_buffers(
t1,
(OPJ_UINT32)(cblk->x1 - cblk->x0),
@@ -1382,7 +1805,7 @@ OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1,
return OPJ_FALSE;
}
- bpno = (OPJ_INT32)(roishift + cblk->numbps - 1);
+ bpno_plus_one = (OPJ_INT32)(roishift + cblk->numbps);
passtype = 2;
opj_mqc_resetstates(mqc);
@@ -1394,7 +1817,7 @@ OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1,
opj_tcd_seg_t *seg = &cblk->segs[segno];
/* BYPASS mode */
- type = ((bpno <= ((OPJ_INT32) (cblk->numbps) - 1) - 4) && (passtype < 2) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
+ type = ((bpno_plus_one <= ((OPJ_INT32) (cblk->numbps)) - 4) && (passtype < 2) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
/* FIXME: slviewer gets here with a null pointer. Why? Partially downloaded and/or corrupt textures? */
if(seg->data == 00){
continue;
@@ -1407,48 +1830,94 @@ OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1,
}
}
- for (passno = 0; passno < seg->real_num_passes; ++passno) {
- switch (passtype) {
- case 0:
- if (type == T1_TYPE_RAW) {
- opj_t1_dec_sigpass_raw(t1, bpno+1, (OPJ_INT32)orient, (OPJ_INT32)cblksty);
- } else {
- if (cblksty & J2K_CCP_CBLKSTY_VSC) {
- opj_t1_dec_sigpass_mqc_vsc(t1, bpno+1, (OPJ_INT32)orient);
- } else {
- opj_t1_dec_sigpass_mqc(t1, bpno+1, (OPJ_INT32)orient);
- }
- }
- break;
- case 1:
- if (type == T1_TYPE_RAW) {
- opj_t1_dec_refpass_raw(t1, bpno+1, (OPJ_INT32)cblksty);
- } else {
- if (cblksty & J2K_CCP_CBLKSTY_VSC) {
- opj_t1_dec_refpass_mqc_vsc(t1, bpno+1);
- } else {
- opj_t1_dec_refpass_mqc(t1, bpno+1);
- }
- }
- break;
- case 2:
- opj_t1_dec_clnpass(t1, bpno+1, (OPJ_INT32)orient, (OPJ_INT32)cblksty);
- break;
- }
-
- if ((cblksty & J2K_CCP_CBLKSTY_RESET) && type == T1_TYPE_MQ) {
- opj_mqc_resetstates(mqc);
- opj_mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
- opj_mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
- opj_mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
- }
- if (++passtype == 3) {
- passtype = 0;
- bpno--;
- }
+ if( t1->w == 64 && t1->h == 64 )
+ {
+ for (passno = 0; (passno < seg->real_num_passes) && (bpno_plus_one >= 1); ++passno) {
+ switch (passtype) {
+ case 0:
+ if (type == T1_TYPE_RAW) {
+ opj_t1_dec_sigpass_raw(t1, bpno_plus_one, (OPJ_INT32)cblksty);
+ } else {
+ if (cblksty & J2K_CCP_CBLKSTY_VSC) {
+ opj_t1_dec_sigpass_mqc_vsc(t1, bpno_plus_one);
+ } else {
+ opj_t1_dec_sigpass_mqc_64x64(t1, bpno_plus_one);
+ }
+ }
+ break;
+ case 1:
+ if (type == T1_TYPE_RAW) {
+ opj_t1_dec_refpass_raw(t1, bpno_plus_one);
+ } else {
+ if (cblksty & J2K_CCP_CBLKSTY_VSC) {
+ opj_t1_dec_refpass_mqc_vsc(t1, bpno_plus_one);
+ } else {
+ opj_t1_dec_refpass_mqc_64x64(t1, bpno_plus_one);
+ }
+ }
+ break;
+ case 2:
+ opj_t1_dec_clnpass_64x64(t1, bpno_plus_one, (OPJ_INT32)cblksty);
+ break;
+ }
+
+ if ((cblksty & J2K_CCP_CBLKSTY_RESET) && type == T1_TYPE_MQ) {
+ opj_mqc_resetstates(mqc);
+ opj_mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
+ opj_mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
+ opj_mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
+ }
+ if (++passtype == 3) {
+ passtype = 0;
+ bpno_plus_one--;
+ }
+ }
+ }
+ else
+ {
+ for (passno = 0; (passno < seg->real_num_passes) && (bpno_plus_one >= 1); ++passno) {
+ switch (passtype) {
+ case 0:
+ if (type == T1_TYPE_RAW) {
+ opj_t1_dec_sigpass_raw(t1, bpno_plus_one, (OPJ_INT32)cblksty);
+ } else {
+ if (cblksty & J2K_CCP_CBLKSTY_VSC) {
+ opj_t1_dec_sigpass_mqc_vsc(t1, bpno_plus_one);
+ } else {
+ opj_t1_dec_sigpass_mqc_generic(t1, bpno_plus_one);
+ }
+ }
+ break;
+ case 1:
+ if (type == T1_TYPE_RAW) {
+ opj_t1_dec_refpass_raw(t1, bpno_plus_one);
+ } else {
+ if (cblksty & J2K_CCP_CBLKSTY_VSC) {
+ opj_t1_dec_refpass_mqc_vsc(t1, bpno_plus_one);
+ } else {
+ opj_t1_dec_refpass_mqc_generic(t1, bpno_plus_one);
+ }
+ }
+ break;
+ case 2:
+ opj_t1_dec_clnpass_generic(t1, bpno_plus_one, (OPJ_INT32)cblksty);
+ break;
+ }
+
+ if ((cblksty & J2K_CCP_CBLKSTY_RESET) && type == T1_TYPE_MQ) {
+ opj_mqc_resetstates(mqc);
+ opj_mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
+ opj_mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
+ opj_mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
+ }
+ if (++passtype == 3) {
+ passtype = 0;
+ bpno_plus_one--;
+ }
+ }
}
}
- return OPJ_TRUE;
+ return OPJ_TRUE;
}
@@ -1457,7 +1926,8 @@ OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1,
OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1,
opj_tcd_tile_t *tile,
opj_tcp_t *tcp,
- const OPJ_FLOAT64 * mct_norms
+ const OPJ_FLOAT64 * mct_norms,
+ OPJ_UINT32 mct_numcomps
)
{
OPJ_UINT32 compno, resno, bandno, precno, cblkno;
@@ -1473,7 +1943,7 @@ OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1,
opj_tcd_resolution_t *res = &tilec->resolutions[resno];
for (bandno = 0; bandno < res->numbands; ++bandno) {
- opj_tcd_band_t* restrict band = &res->bands[bandno];
+ opj_tcd_band_t* OPJ_RESTRICT band = &res->bands[bandno];
OPJ_INT32 bandconst = 8192 * 8192 / ((OPJ_INT32) floor(band->stepsize * 8192));
for (precno = 0; precno < res->pw * res->ph; ++precno) {
@@ -1481,11 +1951,10 @@ OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1,
for (cblkno = 0; cblkno < prc->cw * prc->ch; ++cblkno) {
opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno];
- OPJ_INT32 * restrict datap;
- OPJ_INT32* restrict tiledp;
+ OPJ_INT32* OPJ_RESTRICT tiledp;
OPJ_UINT32 cblk_w;
OPJ_UINT32 cblk_h;
- OPJ_UINT32 i, j;
+ OPJ_UINT32 i, j, tileIndex=0, tileLineAdvance;
OPJ_INT32 x = cblk->x0 - band->x0;
OPJ_INT32 y = cblk->y0 - band->y0;
@@ -1506,27 +1975,32 @@ OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1,
return OPJ_FALSE;
}
- datap=t1->data;
cblk_w = t1->w;
cblk_h = t1->h;
+ tileLineAdvance = tile_w - cblk_w;
tiledp=&tilec->data[(OPJ_UINT32)y * tile_w + (OPJ_UINT32)x];
+ t1->data = tiledp;
+ t1->data_stride = tile_w;
if (tccp->qmfbid == 1) {
for (j = 0; j < cblk_h; ++j) {
for (i = 0; i < cblk_w; ++i) {
- OPJ_INT32 tmp = tiledp[(j * tile_w) + i];
- datap[(j * cblk_w) + i] = tmp << T1_NMSEDEC_FRACBITS;
+ tiledp[tileIndex] *= (1 << T1_NMSEDEC_FRACBITS);
+ tileIndex++;
}
+ tileIndex += tileLineAdvance;
}
} else { /* if (tccp->qmfbid == 0) */
for (j = 0; j < cblk_h; ++j) {
for (i = 0; i < cblk_w; ++i) {
- OPJ_INT32 tmp = tiledp[(j * tile_w) + i];
- datap[(j * cblk_w) + i] =
- opj_int_fix_mul(
+ OPJ_INT32 tmp = tiledp[tileIndex];
+ tiledp[tileIndex] =
+ opj_int_fix_mul_t1(
tmp,
- bandconst) >> (11 - T1_NMSEDEC_FRACBITS);
+ bandconst);
+ tileIndex++;
}
+ tileIndex += tileLineAdvance;
}
}
@@ -1541,7 +2015,8 @@ OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1,
tccp->cblksty,
tile->numcomps,
tile,
- mct_norms);
+ mct_norms,
+ mct_numcomps);
} /* cblkno */
} /* precno */
@@ -1552,7 +2027,7 @@ OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1,
}
/** mod fixed_quality */
-void opj_t1_encode_cblk(opj_t1_t *t1,
+static void opj_t1_encode_cblk(opj_t1_t *t1,
opj_tcd_cblk_enc_t* cblk,
OPJ_UINT32 orient,
OPJ_UINT32 compno,
@@ -1562,7 +2037,8 @@ void opj_t1_encode_cblk(opj_t1_t *t1,
OPJ_UINT32 cblksty,
OPJ_UINT32 numcomps,
opj_tcd_tile_t * tile,
- const OPJ_FLOAT64 * mct_norms)
+ const OPJ_FLOAT64 * mct_norms,
+ OPJ_UINT32 mct_numcomps)
{
OPJ_FLOAT64 cumwmsedec = 0.0;
@@ -1573,14 +2049,18 @@ void opj_t1_encode_cblk(opj_t1_t *t1,
OPJ_UINT32 passtype;
OPJ_INT32 nmsedec = 0;
OPJ_INT32 max;
- OPJ_UINT32 i;
+ OPJ_UINT32 i, j;
OPJ_BYTE type = T1_TYPE_MQ;
OPJ_FLOAT64 tempwmsedec;
+ mqc->lut_ctxno_zc_orient = lut_ctxno_zc + orient * 256;
+
max = 0;
- for (i = 0; i < t1->w * t1->h; ++i) {
- OPJ_INT32 tmp = abs(t1->data[i]);
- max = opj_int_max(max, tmp);
+ for (i = 0; i < t1->w; ++i) {
+ for (j = 0; j < t1->h; ++j) {
+ OPJ_INT32 tmp = abs(t1->data[i + j*t1->data_stride]);
+ max = opj_int_max(max, tmp);
+ }
}
cblk->numbps = max ? (OPJ_UINT32)((opj_int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS) : 0;
@@ -1601,13 +2081,13 @@ void opj_t1_encode_cblk(opj_t1_t *t1,
switch (passtype) {
case 0:
- opj_t1_enc_sigpass(t1, bpno, orient, &nmsedec, type, cblksty);
+ opj_t1_enc_sigpass(t1, bpno, &nmsedec, type, cblksty);
break;
case 1:
opj_t1_enc_refpass(t1, bpno, &nmsedec, type, cblksty);
break;
case 2:
- opj_t1_enc_clnpass(t1, bpno, orient, &nmsedec, cblksty);
+ opj_t1_enc_clnpass(t1, bpno, &nmsedec, cblksty);
/* code switch SEGMARK (i.e. SEGSYM) */
if (cblksty & J2K_CCP_CBLKSTY_SEGSYM)
opj_mqc_segmark_enc(mqc);
@@ -1615,7 +2095,7 @@ void opj_t1_encode_cblk(opj_t1_t *t1,
}
/* fixed_quality */
- tempwmsedec = opj_t1_getwmsedec(nmsedec, compno, level, orient, bpno, qmfbid, stepsize, numcomps,mct_norms) ;
+ tempwmsedec = opj_t1_getwmsedec(nmsedec, compno, level, orient, bpno, qmfbid, stepsize, numcomps,mct_norms, mct_numcomps) ;
cumwmsedec += tempwmsedec;
tile->distotile += tempwmsedec;
@@ -1689,7 +2169,7 @@ void opj_t1_encode_cblk(opj_t1_t *t1,
}
#if 0
-void opj_t1_dec_refpass_step( opj_t1_t *t1,
+static void opj_t1_dec_refpass_step( opj_t1_t *t1,
opj_flag_t *flagsp,
OPJ_INT32 *datap,
OPJ_INT32 poshalf,
@@ -1721,7 +2201,7 @@ void opj_t1_dec_refpass_step( opj_t1_t *t1,
#if 0
-void opj_t1_dec_sigpass_step( opj_t1_t *t1,
+static void opj_t1_dec_sigpass_step( opj_t1_t *t1,
opj_flag_t *flagsp,
OPJ_INT32 *datap,
OPJ_UINT32 orient,
diff --git a/openjpeg/src/lib/openjp2/t1.h b/openjpeg/src/lib/openjp2/t1.h
index e5be70ed5..c3fb7bed0 100644
--- a/openjpeg/src/lib/openjp2/t1.h
+++ b/openjpeg/src/lib/openjp2/t1.h
@@ -50,48 +50,74 @@ in T1.C are used by some function in TCD.C.
/* ----------------------------------------------------------------------- */
#define T1_NMSEDEC_BITS 7
-#define T1_SIG_NE 0x0001 /**< Context orientation : North-East direction */
-#define T1_SIG_SE 0x0002 /**< Context orientation : South-East direction */
-#define T1_SIG_SW 0x0004 /**< Context orientation : South-West direction */
-#define T1_SIG_NW 0x0008 /**< Context orientation : North-West direction */
-#define T1_SIG_N 0x0010 /**< Context orientation : North direction */
-#define T1_SIG_E 0x0020 /**< Context orientation : East direction */
-#define T1_SIG_S 0x0040 /**< Context orientation : South direction */
-#define T1_SIG_W 0x0080 /**< Context orientation : West direction */
+/* CAUTION: the value of those constants must not be changed, otherwise the */
+/* optimization of opj_t1_updateflags() will break! */
+/* BEGINNING of flags that apply to opj_flag_t */
+#define T1_SIG_NE 0x0001U /**< Context orientation : North-East direction */
+#define T1_SIG_SE 0x0002U /**< Context orientation : South-East direction */
+#define T1_SIG_SW 0x0004U /**< Context orientation : South-West direction */
+#define T1_SIG_NW 0x0008U /**< Context orientation : North-West direction */
+#define T1_SIG_N 0x0010U /**< Context orientation : North direction */
+#define T1_SIG_E 0x0020U /**< Context orientation : East direction */
+#define T1_SIG_S 0x0040U /**< Context orientation : South direction */
+#define T1_SIG_W 0x0080U /**< Context orientation : West direction */
#define T1_SIG_OTH (T1_SIG_N|T1_SIG_NE|T1_SIG_E|T1_SIG_SE|T1_SIG_S|T1_SIG_SW|T1_SIG_W|T1_SIG_NW)
#define T1_SIG_PRIM (T1_SIG_N|T1_SIG_E|T1_SIG_S|T1_SIG_W)
-#define T1_SGN_N 0x0100
-#define T1_SGN_E 0x0200
-#define T1_SGN_S 0x0400
-#define T1_SGN_W 0x0800
+#define T1_SGN_N 0x0100U
+#define T1_SGN_E 0x0200U
+#define T1_SGN_S 0x0400U
+#define T1_SGN_W 0x0800U
#define T1_SGN (T1_SGN_N|T1_SGN_E|T1_SGN_S|T1_SGN_W)
-#define T1_SIG 0x1000
-#define T1_REFINE 0x2000
-#define T1_VISIT 0x4000
+#define T1_SIG 0x1000U /**< No longer used by decoder */
+#define T1_REFINE 0x2000U /**< No longer used by decoder */
+#define T1_VISIT 0x4000U /**< No longer used by decoder */
+/* END of flags that apply to opj_flag_t */
-#define T1_NUMCTXS_ZC 9
-#define T1_NUMCTXS_SC 5
+#define T1_NUMCTXS_ZC 9
+#define T1_NUMCTXS_SC 5
#define T1_NUMCTXS_MAG 3
#define T1_NUMCTXS_AGG 1
#define T1_NUMCTXS_UNI 1
-#define T1_CTXNO_ZC 0
-#define T1_CTXNO_SC (T1_CTXNO_ZC+T1_NUMCTXS_ZC)
+#define T1_CTXNO_ZC 0
+#define T1_CTXNO_SC (T1_CTXNO_ZC+T1_NUMCTXS_ZC)
#define T1_CTXNO_MAG (T1_CTXNO_SC+T1_NUMCTXS_SC)
#define T1_CTXNO_AGG (T1_CTXNO_MAG+T1_NUMCTXS_MAG)
#define T1_CTXNO_UNI (T1_CTXNO_AGG+T1_NUMCTXS_AGG)
-#define T1_NUMCTXS (T1_CTXNO_UNI+T1_NUMCTXS_UNI)
+#define T1_NUMCTXS (T1_CTXNO_UNI+T1_NUMCTXS_UNI)
#define T1_NMSEDEC_FRACBITS (T1_NMSEDEC_BITS-1)
#define T1_TYPE_MQ 0 /**< Normal coding using entropy coder */
#define T1_TYPE_RAW 1 /**< No encoding the information is store under raw format in codestream (mode switch RAW)*/
+/* Those flags are used by opj_colflag_t */
+#define T1_COLFLAG_RBS 4U /* RBS = Row Bit Shift */
+#define T1_COLFLAG_SIG_OTHER_ROW_0 (1U << 0U) /**< This sample has at least one significant neighbour */
+#define T1_COLFLAG_SIG_ROW_0 (1U << 1U) /**< This sample is significant */
+#define T1_COLFLAG_VISIT_ROW_0 (1U << 2U) /**< This sample has been visited */
+#define T1_COLFLAG_REFINE_ROW_0 (1U << 3U) /**< This sample has been refined */
+#define T1_COLFLAG_SIG_OTHER_ROW_1 (T1_COLFLAG_SIG_OTHER_ROW_0 << (1U * T1_COLFLAG_RBS))
+#define T1_COLFLAG_SIG_ROW_1 (T1_COLFLAG_SIG_ROW_0 << (1U * T1_COLFLAG_RBS))
+#define T1_COLFLAG_VISIT_ROW_1 (T1_COLFLAG_VISIT_ROW_0 << (1U * T1_COLFLAG_RBS))
+#define T1_COLFLAG_REFINE_ROW_1 (T1_COLFLAG_REFINE_ROW_0 << (1U * T1_COLFLAG_RBS))
+#define T1_COLFLAG_SIG_OTHER_ROW_2 (T1_COLFLAG_SIG_OTHER_ROW_0 << (2U * T1_COLFLAG_RBS))
+#define T1_COLFLAG_SIG_ROW_2 (T1_COLFLAG_SIG_ROW_0 << (2U * T1_COLFLAG_RBS))
+#define T1_COLFLAG_VISIT_ROW_2 (T1_COLFLAG_VISIT_ROW_0 << (2U * T1_COLFLAG_RBS))
+#define T1_COLFLAG_REFINE_ROW_2 (T1_COLFLAG_REFINE_ROW_0 << (2U * T1_COLFLAG_RBS))
+#define T1_COLFLAG_SIG_OTHER_ROW_3 (T1_COLFLAG_SIG_OTHER_ROW_0 << (3U * T1_COLFLAG_RBS))
+#define T1_COLFLAG_SIG_ROW_3 (T1_COLFLAG_SIG_ROW_0 << (3U * T1_COLFLAG_RBS))
+#define T1_COLFLAG_VISIT_ROW_3 (T1_COLFLAG_VISIT_ROW_0 << (3U * T1_COLFLAG_RBS))
+#define T1_COLFLAG_REFINE_ROW_3 (T1_COLFLAG_REFINE_ROW_0 << (3U * T1_COLFLAG_RBS))
+
/* ----------------------------------------------------------------------- */
-typedef OPJ_INT16 opj_flag_t;
+typedef OPJ_UINT16 opj_flag_t;
+
+/** Flags for 4 consecutive rows of a column */
+typedef OPJ_UINT16 opj_colflag_t;
/**
Tier-1 coding (coding of code-block coefficients)
@@ -103,13 +129,21 @@ typedef struct opj_t1 {
/** RAW component */
opj_raw_t *raw;
- OPJ_INT32 *data;
+ OPJ_INT32 *data;
opj_flag_t *flags;
+ /** Addition flag array such that colflags[1+0] is for state of col=0,row=0..3,
+ colflags[1+1] for col=1, row=0..3, colflags[1+flags_stride] for col=0,row=4..7, ...
+ This array avoids too much cache trashing when processing by 4 vertical samples
+ as done in the various decoding steps. */
+ opj_colflag_t* colflags;
OPJ_UINT32 w;
OPJ_UINT32 h;
OPJ_UINT32 datasize;
OPJ_UINT32 flagssize;
OPJ_UINT32 flags_stride;
+ OPJ_UINT32 colflags_size;
+ OPJ_UINT32 data_stride;
+ OPJ_BOOL encoder;
} opj_t1_t;
#define MACRO_t1_flags(x,y) t1->flags[((x)*(t1->flags_stride))+(y)]
@@ -124,11 +158,13 @@ Encode the code-blocks of a tile
@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_tcd_tile_t *tile,
opj_tcp_t *tcp,
- const OPJ_FLOAT64 * mct_norms);
+ const OPJ_FLOAT64 * mct_norms,
+ OPJ_UINT32 mct_numcomps);
/**
Decode the code-blocks of a tile
@@ -136,7 +172,8 @@ Decode the code-blocks of a tile
@param tilec The tile to decode
@param tccp Tile coding parameters
*/
-OPJ_BOOL opj_t1_decode_cblks( opj_t1_t* t1,
+void opj_t1_decode_cblks( opj_thread_pool_t* tp,
+ volatile OPJ_BOOL* pret,
opj_tcd_tilecomp_t* tilec,
opj_tccp_t* tccp);
@@ -147,7 +184,7 @@ OPJ_BOOL opj_t1_decode_cblks( opj_t1_t* t1,
* and initializes the look-up tables of the Tier-1 coder/decoder
* @return a new T1 handle if successful, returns NULL otherwise
*/
-opj_t1_t* opj_t1_create(void);
+opj_t1_t* opj_t1_create(OPJ_BOOL isEncoder);
/**
* Destroys a previously created T1 handle
diff --git a/openjpeg/src/lib/openjp2/t1_generate_luts.c b/openjpeg/src/lib/openjp2/t1_generate_luts.c
index 1997d3997..1a8430898 100644
--- a/openjpeg/src/lib/openjp2/t1_generate_luts.c
+++ b/openjpeg/src/lib/openjp2/t1_generate_luts.c
@@ -38,18 +38,21 @@
#include "opj_includes.h"
-static int t1_init_ctxno_zc(int f, int orient) {
+static int t1_init_ctxno_zc(unsigned int f, unsigned int orient) {
int h, v, d, n, t, hv;
- n = 0;
h = ((f & T1_SIG_W) != 0) + ((f & T1_SIG_E) != 0);
v = ((f & T1_SIG_N) != 0) + ((f & T1_SIG_S) != 0);
d = ((f & T1_SIG_NW) != 0) + ((f & T1_SIG_NE) != 0) + ((f & T1_SIG_SE) != 0) + ((f & T1_SIG_SW) != 0);
+ n = 0;
+ t = 0;
+ hv = 0;
switch (orient) {
case 2:
t = h;
h = v;
v = t;
+ /* fall through */
case 0:
case 1:
if (!h) {
@@ -110,7 +113,7 @@ static int t1_init_ctxno_zc(int f, int orient) {
return (T1_CTXNO_ZC + n);
}
-static int t1_init_ctxno_sc(int f) {
+static int t1_init_ctxno_sc(unsigned int f) {
int hc, vc, n;
n = 0;
@@ -151,7 +154,7 @@ static int t1_init_ctxno_sc(int f) {
return (T1_CTXNO_SC + n);
}
-static int t1_init_spb(int f) {
+static int t1_init_spb(unsigned int f) {
int hc, vc, n;
hc = opj_int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
@@ -189,7 +192,7 @@ static void dump_array16(int array[],int size){
int main(int argc, char **argv)
{
- int i, j;
+ unsigned int i, j;
double u, v, t;
int lut_ctxno_zc[1024];
@@ -202,47 +205,47 @@ int main(int argc, char **argv)
printf("/* This file was automatically generated by t1_generate_luts.c */\n\n");
/* lut_ctxno_zc */
- for (j = 0; j < 4; ++j) {
- for (i = 0; i < 256; ++i) {
- int orient = j;
- if (orient == 2) {
- orient = 1;
- } else if (orient == 1) {
- orient = 2;
+ for (j = 0U; j < 4U; ++j) {
+ for (i = 0U; i < 256U; ++i) {
+ unsigned int orient = j;
+ if (orient == 2U) {
+ orient = 1U;
+ } else if (orient == 1U) {
+ orient = 2U;
}
lut_ctxno_zc[(orient << 8) | i] = t1_init_ctxno_zc(i, j);
}
}
- printf("static OPJ_BYTE lut_ctxno_zc[1024] = {\n ");
- for (i = 0; i < 1023; ++i) {
+ printf("static const OPJ_BYTE lut_ctxno_zc[1024] = {\n ");
+ for (i = 0U; i < 1023U; ++i) {
printf("%i, ", lut_ctxno_zc[i]);
- if(!((i+1)&0x1f))
+ if(!((i+1U)&0x1fU))
printf("\n ");
}
printf("%i\n};\n\n", lut_ctxno_zc[1023]);
/* lut_ctxno_sc */
- printf("static OPJ_BYTE lut_ctxno_sc[256] = {\n ");
- for (i = 0; i < 255; ++i) {
+ printf("static const OPJ_BYTE lut_ctxno_sc[256] = {\n ");
+ for (i = 0U; i < 255U; ++i) {
printf("0x%x, ", t1_init_ctxno_sc(i << 4));
- if(!((i+1)&0xf))
+ if(!((i+1U)&0xfU))
printf("\n ");
}
- printf("0x%x\n};\n\n", t1_init_ctxno_sc(255 << 4));
+ printf("0x%x\n};\n\n", t1_init_ctxno_sc(255U << 4));
/* lut_spb */
- printf("static OPJ_BYTE lut_spb[256] = {\n ");
- for (i = 0; i < 255; ++i) {
+ printf("static const OPJ_BYTE lut_spb[256] = {\n ");
+ for (i = 0U; i < 255U; ++i) {
printf("%i, ", t1_init_spb(i << 4));
- if(!((i+1)&0x1f))
+ if(!((i+1U)&0x1fU))
printf("\n ");
}
- printf("%i\n};\n\n", t1_init_spb(255 << 4));
+ printf("%i\n};\n\n", t1_init_spb(255U << 4));
/* FIXME FIXME FIXME */
/* fprintf(stdout,"nmsedec luts:\n"); */
- for (i = 0; i < (1 << T1_NMSEDEC_BITS); ++i) {
+ for (i = 0U; i < (1U << T1_NMSEDEC_BITS); ++i) {
t = i / pow(2, T1_NMSEDEC_FRACBITS);
u = t;
v = t - 1.5;
@@ -266,17 +269,17 @@ int main(int argc, char **argv)
(int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
}
- printf("static OPJ_INT16 lut_nmsedec_sig[1 << T1_NMSEDEC_BITS] = {\n ");
- dump_array16(lut_nmsedec_sig, 1 << T1_NMSEDEC_BITS);
+ printf("static const OPJ_INT16 lut_nmsedec_sig[1U << T1_NMSEDEC_BITS] = {\n ");
+ dump_array16(lut_nmsedec_sig, 1U << T1_NMSEDEC_BITS);
- printf("static OPJ_INT16 lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS] = {\n ");
- dump_array16(lut_nmsedec_sig0, 1 << T1_NMSEDEC_BITS);
+ printf("static const OPJ_INT16 lut_nmsedec_sig0[1U << T1_NMSEDEC_BITS] = {\n ");
+ dump_array16(lut_nmsedec_sig0, 1U << T1_NMSEDEC_BITS);
- printf("static OPJ_INT16 lut_nmsedec_ref[1 << T1_NMSEDEC_BITS] = {\n ");
- dump_array16(lut_nmsedec_ref, 1 << T1_NMSEDEC_BITS);
+ printf("static const OPJ_INT16 lut_nmsedec_ref[1U << T1_NMSEDEC_BITS] = {\n ");
+ dump_array16(lut_nmsedec_ref, 1U << T1_NMSEDEC_BITS);
- printf("static OPJ_INT16 lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS] = {\n ");
- dump_array16(lut_nmsedec_ref0, 1 << T1_NMSEDEC_BITS);
+ printf("static const OPJ_INT16 lut_nmsedec_ref0[1U << T1_NMSEDEC_BITS] = {\n ");
+ dump_array16(lut_nmsedec_ref0, 1U << T1_NMSEDEC_BITS);
return 0;
}
diff --git a/openjpeg/src/lib/openjp2/t1_luts.h b/openjpeg/src/lib/openjp2/t1_luts.h
index 37776b65a..561133fbd 100644
--- a/openjpeg/src/lib/openjp2/t1_luts.h
+++ b/openjpeg/src/lib/openjp2/t1_luts.h
@@ -1,6 +1,6 @@
/* This file was automatically generated by t1_generate_luts.c */
-static OPJ_BYTE lut_ctxno_zc[1024] = {
+static const OPJ_BYTE lut_ctxno_zc[1024] = {
0, 1, 1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
@@ -35,7 +35,7 @@ static OPJ_BYTE lut_ctxno_zc[1024] = {
2, 5, 5, 7, 5, 7, 7, 8, 5, 7, 7, 8, 7, 8, 8, 8, 2, 5, 5, 7, 5, 7, 7, 8, 5, 7, 7, 8, 7, 8, 8, 8
};
-static OPJ_BYTE lut_ctxno_sc[256] = {
+static const OPJ_BYTE lut_ctxno_sc[256] = {
0x9, 0xa, 0xc, 0xd, 0xa, 0xa, 0xd, 0xd, 0xc, 0xd, 0xc, 0xd, 0xd, 0xd, 0xd, 0xd,
0x9, 0xa, 0xc, 0xb, 0xa, 0x9, 0xd, 0xc, 0xc, 0xb, 0xc, 0xb, 0xd, 0xc, 0xd, 0xc,
0x9, 0xa, 0xc, 0xb, 0xa, 0xa, 0xb, 0xb, 0xc, 0xd, 0x9, 0xa, 0xd, 0xd, 0xa, 0xa,
@@ -54,7 +54,7 @@ static OPJ_BYTE lut_ctxno_sc[256] = {
0x9, 0xa, 0xc, 0xd, 0xa, 0xa, 0xd, 0xd, 0xc, 0xd, 0xc, 0xd, 0xd, 0xd, 0xd, 0xd
};
-static OPJ_BYTE lut_spb[256] = {
+static const OPJ_BYTE lut_spb[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -65,7 +65,7 @@ static OPJ_BYTE lut_spb[256] = {
0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
-static OPJ_INT16 lut_nmsedec_sig[1 << T1_NMSEDEC_BITS] = {
+static const OPJ_INT16 lut_nmsedec_sig[1U << T1_NMSEDEC_BITS] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -84,7 +84,7 @@ static OPJ_INT16 lut_nmsedec_sig[1 << T1_NMSEDEC_BITS] = {
0x6c00, 0x6d80, 0x6f00, 0x7080, 0x7200, 0x7380, 0x7500, 0x7680
};
-static OPJ_INT16 lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS] = {
+static const OPJ_INT16 lut_nmsedec_sig0[1U << T1_NMSEDEC_BITS] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0080, 0x0080,
0x0080, 0x0080, 0x0100, 0x0100, 0x0100, 0x0180, 0x0180, 0x0200,
0x0200, 0x0280, 0x0280, 0x0300, 0x0300, 0x0380, 0x0400, 0x0400,
@@ -103,7 +103,7 @@ static OPJ_INT16 lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS] = {
0x7080, 0x7280, 0x7480, 0x7600, 0x7800, 0x7a00, 0x7c00, 0x7e00
};
-static OPJ_INT16 lut_nmsedec_ref[1 << T1_NMSEDEC_BITS] = {
+static const OPJ_INT16 lut_nmsedec_ref[1U << T1_NMSEDEC_BITS] = {
0x1800, 0x1780, 0x1700, 0x1680, 0x1600, 0x1580, 0x1500, 0x1480,
0x1400, 0x1380, 0x1300, 0x1280, 0x1200, 0x1180, 0x1100, 0x1080,
0x1000, 0x0f80, 0x0f00, 0x0e80, 0x0e00, 0x0d80, 0x0d00, 0x0c80,
@@ -122,7 +122,7 @@ static OPJ_INT16 lut_nmsedec_ref[1 << T1_NMSEDEC_BITS] = {
0x1400, 0x1480, 0x1500, 0x1580, 0x1600, 0x1680, 0x1700, 0x1780
};
-static OPJ_INT16 lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS] = {
+static const OPJ_INT16 lut_nmsedec_ref0[1U << T1_NMSEDEC_BITS] = {
0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x1b00, 0x1a80, 0x1980,
0x1880, 0x1780, 0x1700, 0x1600, 0x1500, 0x1480, 0x1380, 0x1300,
0x1200, 0x1180, 0x1080, 0x1000, 0x0f00, 0x0e80, 0x0e00, 0x0d00,
diff --git a/openjpeg/src/lib/openjp2/t2.c b/openjpeg/src/lib/openjp2/t2.c
index a17ed9b17..16620ecd7 100644
--- a/openjpeg/src/lib/openjp2/t2.c
+++ b/openjpeg/src/lib/openjp2/t2.c
@@ -97,7 +97,8 @@ static OPJ_BOOL opj_t2_decode_packet( opj_t2_t* t2,
OPJ_BYTE *src,
OPJ_UINT32 * data_read,
OPJ_UINT32 max_length,
- opj_packet_info_t *pack_info);
+ opj_packet_info_t *pack_info,
+ opj_event_mgr_t *p_manager);
static OPJ_BOOL opj_t2_skip_packet( opj_t2_t* p_t2,
opj_tcd_tile_t *p_tile,
@@ -106,7 +107,8 @@ static OPJ_BOOL opj_t2_skip_packet( opj_t2_t* p_t2,
OPJ_BYTE *p_src,
OPJ_UINT32 * p_data_read,
OPJ_UINT32 p_max_length,
- opj_packet_info_t *p_pack_info);
+ opj_packet_info_t *p_pack_info,
+ opj_event_mgr_t *p_manager);
static OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2,
opj_tcd_tile_t *p_tile,
@@ -116,7 +118,8 @@ static OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2,
OPJ_BYTE *p_src_data,
OPJ_UINT32 * p_data_read,
OPJ_UINT32 p_max_length,
- opj_packet_info_t *p_pack_info);
+ opj_packet_info_t *p_pack_info,
+ opj_event_mgr_t *p_manager);
static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
opj_tcd_tile_t *p_tile,
@@ -124,14 +127,16 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
OPJ_BYTE *p_src_data,
OPJ_UINT32 * p_data_read,
OPJ_UINT32 p_max_length,
- opj_packet_info_t *pack_info);
+ opj_packet_info_t *pack_info,
+ opj_event_mgr_t *p_manager);
static OPJ_BOOL opj_t2_skip_packet_data(opj_t2_t* p_t2,
opj_tcd_tile_t *p_tile,
opj_pi_iterator_t *p_pi,
OPJ_UINT32 * p_data_read,
OPJ_UINT32 p_max_length,
- opj_packet_info_t *pack_info);
+ opj_packet_info_t *pack_info,
+ opj_event_mgr_t *p_manager);
/**
@param cblk
@@ -158,7 +163,7 @@ static void opj_t2_putcommacode(opj_bio_t *bio, OPJ_INT32 n) {
opj_bio_write(bio, 0, 1);
}
-OPJ_UINT32 opj_t2_getcommacode(opj_bio_t *bio)
+static OPJ_UINT32 opj_t2_getcommacode(opj_bio_t *bio)
{
OPJ_UINT32 n = 0;
while (opj_bio_read(bio, 1)) {
@@ -167,7 +172,7 @@ OPJ_UINT32 opj_t2_getcommacode(opj_bio_t *bio)
return n;
}
-void opj_t2_putnumpasses(opj_bio_t *bio, OPJ_UINT32 n) {
+static void opj_t2_putnumpasses(opj_bio_t *bio, OPJ_UINT32 n) {
if (n == 1) {
opj_bio_write(bio, 0, 1);
} else if (n == 2) {
@@ -181,7 +186,7 @@ void opj_t2_putnumpasses(opj_bio_t *bio, OPJ_UINT32 n) {
}
}
-OPJ_UINT32 opj_t2_getnumpasses(opj_bio_t *bio) {
+static OPJ_UINT32 opj_t2_getnumpasses(opj_bio_t *bio) {
OPJ_UINT32 n;
if (!opj_bio_read(bio, 1))
return 1;
@@ -242,6 +247,11 @@ OPJ_BOOL opj_t2_encode_packets( opj_t2_t* p_t2,
/* TODO MSD : check why this function cannot fail (cf. v1) */
opj_pi_create_encode(l_pi, l_cp,p_tile_no,poc,l_tp_num,p_tp_pos,p_t2_mode);
+ if (l_current_pi->poc.prg == OPJ_PROG_UNKNOWN) {
+ /* TODO ADE : add an error */
+ 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;
@@ -274,7 +284,11 @@ OPJ_BOOL opj_t2_encode_packets( opj_t2_t* p_t2,
opj_pi_create_encode(l_pi, l_cp,p_tile_no,p_pino,p_tp_num,p_tp_pos,p_t2_mode);
l_current_pi = &l_pi[p_pino];
-
+ if (l_current_pi->poc.prg == OPJ_PROG_UNKNOWN) {
+ /* TODO ADE : add an error */
+ 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;
@@ -336,7 +350,8 @@ OPJ_BOOL opj_t2_decode_packets( opj_t2_t *p_t2,
OPJ_BYTE *p_src,
OPJ_UINT32 * p_data_read,
OPJ_UINT32 p_max_len,
- opj_codestream_index_t *p_cstr_index)
+ opj_codestream_index_t *p_cstr_index,
+ opj_event_mgr_t *p_manager)
{
OPJ_BYTE *l_current_data = p_src;
opj_pi_iterator_t *l_pi = 00;
@@ -378,7 +393,15 @@ OPJ_BOOL opj_t2_decode_packets( opj_t2_t *p_t2,
* l_current_pi->resno is always >= p_tile->comps[l_current_pi->compno].minimum_num_resolutions
* and no l_img_comp->resno_decoded are computed
*/
- OPJ_BOOL* first_pass_failed = (OPJ_BOOL*)opj_malloc(l_image->numcomps * sizeof(OPJ_BOOL));
+ OPJ_BOOL* first_pass_failed = NULL;
+
+ if (l_current_pi->poc.prg == OPJ_PROG_UNKNOWN) {
+ /* TODO ADE : add an error */
+ opj_pi_destroy(l_pi, l_nb_pocs);
+ return OPJ_FALSE;
+ }
+
+ first_pass_failed = (OPJ_BOOL*)opj_malloc(l_image->numcomps * sizeof(OPJ_BOOL));
if (!first_pass_failed)
{
opj_pi_destroy(l_pi,l_nb_pocs);
@@ -396,7 +419,7 @@ OPJ_BOOL opj_t2_decode_packets( opj_t2_t *p_t2,
first_pass_failed[l_current_pi->compno] = OPJ_FALSE;
- if (! opj_t2_decode_packet(p_t2,p_tile,l_tcp,l_current_pi,l_current_data,&l_nb_bytes_read,p_max_len,l_pack_info)) {
+ if (! opj_t2_decode_packet(p_t2,p_tile,l_tcp,l_current_pi,l_current_data,&l_nb_bytes_read,p_max_len,l_pack_info, p_manager)) {
opj_pi_destroy(l_pi,l_nb_pocs);
opj_free(first_pass_failed);
return OPJ_FALSE;
@@ -407,7 +430,7 @@ OPJ_BOOL opj_t2_decode_packets( opj_t2_t *p_t2,
}
else {
l_nb_bytes_read = 0;
- if (! opj_t2_skip_packet(p_t2,p_tile,l_tcp,l_current_pi,l_current_data,&l_nb_bytes_read,p_max_len,l_pack_info)) {
+ if (! opj_t2_skip_packet(p_t2,p_tile,l_tcp,l_current_pi,l_current_data,&l_nb_bytes_read,p_max_len,l_pack_info, p_manager)) {
opj_pi_destroy(l_pi,l_nb_pocs);
opj_free(first_pass_failed);
return OPJ_FALSE;
@@ -477,11 +500,10 @@ OPJ_BOOL opj_t2_decode_packets( opj_t2_t *p_t2,
opj_t2_t* opj_t2_create(opj_image_t *p_image, opj_cp_t *p_cp)
{
/* create the t2 structure */
- opj_t2_t *l_t2 = (opj_t2_t*)opj_malloc(sizeof(opj_t2_t));
+ opj_t2_t *l_t2 = (opj_t2_t*)opj_calloc(1,sizeof(opj_t2_t));
if (!l_t2) {
return NULL;
}
- memset(l_t2,0,sizeof(opj_t2_t));
l_t2->image = p_image;
l_t2->cp = p_cp;
@@ -495,14 +517,15 @@ void opj_t2_destroy(opj_t2_t *t2) {
}
}
-OPJ_BOOL opj_t2_decode_packet( opj_t2_t* p_t2,
+static OPJ_BOOL opj_t2_decode_packet( opj_t2_t* p_t2,
opj_tcd_tile_t *p_tile,
opj_tcp_t *p_tcp,
opj_pi_iterator_t *p_pi,
OPJ_BYTE *p_src,
OPJ_UINT32 * p_data_read,
OPJ_UINT32 p_max_length,
- opj_packet_info_t *p_pack_info)
+ opj_packet_info_t *p_pack_info,
+ opj_event_mgr_t *p_manager)
{
OPJ_BOOL l_read_data;
OPJ_UINT32 l_nb_bytes_read = 0;
@@ -510,7 +533,7 @@ OPJ_BOOL opj_t2_decode_packet( opj_t2_t* p_t2,
*p_data_read = 0;
- if (! opj_t2_read_packet_header(p_t2,p_tile,p_tcp,p_pi,&l_read_data,p_src,&l_nb_bytes_read,p_max_length,p_pack_info)) {
+ if (! opj_t2_read_packet_header(p_t2,p_tile,p_tcp,p_pi,&l_read_data,p_src,&l_nb_bytes_read,p_max_length,p_pack_info, p_manager)) {
return OPJ_FALSE;
}
@@ -522,7 +545,7 @@ OPJ_BOOL opj_t2_decode_packet( opj_t2_t* p_t2,
if (l_read_data) {
l_nb_bytes_read = 0;
- if (! opj_t2_read_packet_data(p_t2,p_tile,p_pi,p_src,&l_nb_bytes_read,p_max_length,p_pack_info)) {
+ if (! opj_t2_read_packet_data(p_t2,p_tile,p_pi,p_src,&l_nb_bytes_read,p_max_length,p_pack_info, p_manager)) {
return OPJ_FALSE;
}
@@ -534,7 +557,7 @@ OPJ_BOOL opj_t2_decode_packet( opj_t2_t* p_t2,
return OPJ_TRUE;
}
-OPJ_BOOL opj_t2_encode_packet( OPJ_UINT32 tileno,
+static OPJ_BOOL opj_t2_encode_packet( OPJ_UINT32 tileno,
opj_tcd_tile_t * tile,
opj_tcp_t * tcp,
opj_pi_iterator_t *pi,
@@ -599,6 +622,10 @@ OPJ_BOOL opj_t2_encode_packet( OPJ_UINT32 tileno,
}
bio = opj_bio_create();
+ if (!bio) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
opj_bio_init_enc(bio, c, length);
opj_bio_write(bio, 1, 1); /* Empty header bit */
@@ -773,7 +800,8 @@ static OPJ_BOOL opj_t2_skip_packet( opj_t2_t* p_t2,
OPJ_BYTE *p_src,
OPJ_UINT32 * p_data_read,
OPJ_UINT32 p_max_length,
- opj_packet_info_t *p_pack_info)
+ opj_packet_info_t *p_pack_info,
+ opj_event_mgr_t *p_manager)
{
OPJ_BOOL l_read_data;
OPJ_UINT32 l_nb_bytes_read = 0;
@@ -781,7 +809,7 @@ static OPJ_BOOL opj_t2_skip_packet( opj_t2_t* p_t2,
*p_data_read = 0;
- if (! opj_t2_read_packet_header(p_t2,p_tile,p_tcp,p_pi,&l_read_data,p_src,&l_nb_bytes_read,p_max_length,p_pack_info)) {
+ if (! opj_t2_read_packet_header(p_t2,p_tile,p_tcp,p_pi,&l_read_data,p_src,&l_nb_bytes_read,p_max_length,p_pack_info, p_manager)) {
return OPJ_FALSE;
}
@@ -793,7 +821,7 @@ static OPJ_BOOL opj_t2_skip_packet( opj_t2_t* p_t2,
if (l_read_data) {
l_nb_bytes_read = 0;
- if (! opj_t2_skip_packet_data(p_t2,p_tile,p_pi,&l_nb_bytes_read,p_max_length,p_pack_info)) {
+ if (! opj_t2_skip_packet_data(p_t2,p_tile,p_pi,&l_nb_bytes_read,p_max_length,p_pack_info, p_manager)) {
return OPJ_FALSE;
}
@@ -805,7 +833,7 @@ static OPJ_BOOL opj_t2_skip_packet( opj_t2_t* p_t2,
}
-OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2,
+static OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2,
opj_tcd_tile_t *p_tile,
opj_tcp_t *p_tcp,
opj_pi_iterator_t *p_pi,
@@ -813,7 +841,8 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2,
OPJ_BYTE *p_src_data,
OPJ_UINT32 * p_data_read,
OPJ_UINT32 p_max_length,
- opj_packet_info_t *p_pack_info)
+ opj_packet_info_t *p_pack_info,
+ opj_event_mgr_t *p_manager)
{
/* loop */
@@ -839,9 +868,14 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2,
/* reset tagtrees */
for (bandno = 0; bandno < l_res->numbands; ++bandno) {
- opj_tcd_precinct_t *l_prc = &l_band->precincts[p_pi->precno];
-
if ( ! ((l_band->x1-l_band->x0 == 0)||(l_band->y1-l_band->y0 == 0)) ) {
+ opj_tcd_precinct_t *l_prc = &l_band->precincts[p_pi->precno];
+ if (!(p_pi->precno < (l_band->precincts_data_size / sizeof(opj_tcd_precinct_t)))) {
+ opj_event_msg(p_manager, EVT_ERROR, "Invalid precinct\n");
+ return OPJ_FALSE;
+ }
+
+
opj_tgt_reset(l_prc->incltree);
opj_tgt_reset(l_prc->imsbtree);
l_cblk = l_prc->cblks.dec;
@@ -862,11 +896,9 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2,
if (p_tcp->csty & J2K_CP_CSTY_SOP) {
if (p_max_length < 6) {
- /* TODO opj_event_msg(p_t2->cinfo->event_mgr, EVT_WARNING, "Not enough space for expected SOP marker\n"); */
- fprintf(stderr, "Not enough space for expected SOP marker\n");
+ opj_event_msg(p_manager, EVT_WARNING, "Not enough space for expected SOP marker\n");
} else if ((*l_current_data) != 0xff || (*(l_current_data + 1) != 0x91)) {
- /* TODO opj_event_msg(p_t2->cinfo->event_mgr, EVT_WARNING, "Expected SOP marker\n"); */
- fprintf(stderr, "Error : expected SOP marker\n");
+ opj_event_msg(p_manager, EVT_WARNING, "Expected SOP marker\n");
} else {
l_current_data += 6;
}
@@ -916,10 +948,10 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2,
/* EPH markers */
if (p_tcp->csty & J2K_CP_CSTY_EPH) {
- if (p_max_length < 2) {
- fprintf(stderr, "Not enough space for expected EPH marker\n");
+ if ((*l_modified_length_ptr - (OPJ_UINT32)(l_header_data - *l_header_data_start)) < 2U) {
+ opj_event_msg(p_manager, EVT_WARNING, "Not enough space for expected EPH marker\n");
} else if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) {
- fprintf(stderr, "Error : expected EPH marker\n");
+ opj_event_msg(p_manager, EVT_WARNING, "Expected EPH marker\n");
} else {
l_header_data += 2;
}
@@ -970,7 +1002,7 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2,
if (!l_included) {
l_cblk->numnewpasses = 0;
++l_cblk;
- JAS_FPRINTF(stderr, "included=%d \n", l_included);
+ JAS_FPRINTF(stderr, "included=%d \n", l_included);
continue;
}
@@ -1050,11 +1082,10 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2,
/* EPH markers */
if (p_tcp->csty & J2K_CP_CSTY_EPH) {
- if (p_max_length < 2) {
- fprintf(stderr, "Not enough space for expected EPH marker\n");
+ if ((*l_modified_length_ptr - (OPJ_UINT32)(l_header_data - *l_header_data_start)) < 2U) {
+ opj_event_msg(p_manager, EVT_WARNING, "Not enough space for expected EPH marker\n");
} else if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) {
- /* TODO opj_event_msg(t2->cinfo->event_mgr, EVT_ERROR, "Expected EPH marker\n"); */
- fprintf(stderr, "Error : expected EPH marker\n");
+ opj_event_msg(p_manager, EVT_WARNING, "Expected EPH marker\n");
} else {
l_header_data += 2;
}
@@ -1080,13 +1111,14 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2,
return OPJ_TRUE;
}
-OPJ_BOOL opj_t2_read_packet_data( opj_t2_t* p_t2,
+static OPJ_BOOL opj_t2_read_packet_data( opj_t2_t* p_t2,
opj_tcd_tile_t *p_tile,
opj_pi_iterator_t *p_pi,
OPJ_BYTE *p_src_data,
OPJ_UINT32 * p_data_read,
OPJ_UINT32 p_max_length,
- opj_packet_info_t *pack_info)
+ opj_packet_info_t *pack_info,
+ opj_event_mgr_t* p_manager)
{
OPJ_UINT32 bandno, cblkno;
OPJ_UINT32 l_nb_code_blocks;
@@ -1134,9 +1166,10 @@ OPJ_BOOL opj_t2_read_packet_data( opj_t2_t* p_t2,
}
do {
- if (l_current_data + l_seg->newlen > p_src_data + p_max_length) {
- fprintf(stderr, "read: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
- l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
+ /* Check possible overflow (on l_current_data only, assumes input args already checked) then size */
+ if ((((OPJ_SIZE_T)l_current_data + (OPJ_SIZE_T)l_seg->newlen) < (OPJ_SIZE_T)l_current_data) || (l_current_data + l_seg->newlen > p_src_data + p_max_length)) {
+ opj_event_msg(p_manager, EVT_ERROR, "read: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
+ l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
return OPJ_FALSE;
}
@@ -1146,19 +1179,25 @@ OPJ_BOOL opj_t2_read_packet_data( opj_t2_t* p_t2,
/* let's check that we are not exceeding */
if ((l_cblk->len + l_seg->newlen) > 8192) {
- opj_event_msg(p_t2->cinfo, EVT_WARNING,
+ opj_event_msg(p_manager, EVT_WARNING,
"JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
l_seg->newlen, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
if (!JPWL_ASSUME) {
- opj_event_msg(p_t2->cinfo, EVT_ERROR, "JPWL: giving up\n");
+ opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
return OPJ_FALSE;
}
l_seg->newlen = 8192 - l_cblk->len;
- opj_event_msg(p_t2->cinfo, EVT_WARNING, " - truncating segment to %d\n", l_seg->newlen);
+ opj_event_msg(p_manager, EVT_WARNING, " - truncating segment to %d\n", l_seg->newlen);
break;
};
#endif /* USE_JPWL */
+ /* Check possible overflow on size */
+ if ((l_cblk->data_current_size + l_seg->newlen) < l_cblk->data_current_size) {
+ opj_event_msg(p_manager, EVT_ERROR, "read: segment too long (%d) with current size (%d > %d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
+ l_seg->newlen, l_cblk->data_current_size, 0xFFFFFFFF - l_seg->newlen, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
+ return OPJ_FALSE;
+ }
/* Check if the cblk->data have allocated enough memory */
if ((l_cblk->data_current_size + l_seg->newlen) > l_cblk->data_max_size) {
OPJ_BYTE* new_cblk_data = (OPJ_BYTE*) opj_realloc(l_cblk->data, l_cblk->data_current_size + l_seg->newlen);
@@ -1203,15 +1242,17 @@ OPJ_BOOL opj_t2_read_packet_data( opj_t2_t* p_t2,
*(p_data_read) = (OPJ_UINT32)(l_current_data - p_src_data);
+
return OPJ_TRUE;
}
-OPJ_BOOL opj_t2_skip_packet_data( opj_t2_t* p_t2,
+static OPJ_BOOL opj_t2_skip_packet_data( opj_t2_t* p_t2,
opj_tcd_tile_t *p_tile,
opj_pi_iterator_t *p_pi,
OPJ_UINT32 * p_data_read,
OPJ_UINT32 p_max_length,
- opj_packet_info_t *pack_info)
+ opj_packet_info_t *pack_info,
+ opj_event_mgr_t *p_manager)
{
OPJ_UINT32 bandno, cblkno;
OPJ_UINT32 l_nb_code_blocks;
@@ -1260,8 +1301,9 @@ OPJ_BOOL opj_t2_skip_packet_data( opj_t2_t* p_t2,
}
do {
- if (* p_data_read + l_seg->newlen > p_max_length) {
- fprintf(stderr, "skip: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
+ /* Check possible overflow then size */
+ if (((*p_data_read + l_seg->newlen) < (*p_data_read)) || ((*p_data_read + l_seg->newlen) > p_max_length)) {
+ opj_event_msg(p_manager, EVT_ERROR, "skip: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
return OPJ_FALSE;
}
@@ -1272,15 +1314,15 @@ OPJ_BOOL opj_t2_skip_packet_data( opj_t2_t* p_t2,
/* let's check that we are not exceeding */
if ((l_cblk->len + l_seg->newlen) > 8192) {
- opj_event_msg(p_t2->cinfo, EVT_WARNING,
+ opj_event_msg(p_manager, EVT_WARNING,
"JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
l_seg->newlen, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
if (!JPWL_ASSUME) {
- opj_event_msg(p_t2->cinfo, EVT_ERROR, "JPWL: giving up\n");
+ opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
return -999;
}
l_seg->newlen = 8192 - l_cblk->len;
- opj_event_msg(p_t2->cinfo, EVT_WARNING, " - truncating segment to %d\n", l_seg->newlen);
+ opj_event_msg(p_manager, EVT_WARNING, " - truncating segment to %d\n", l_seg->newlen);
break;
};
@@ -1307,7 +1349,7 @@ OPJ_BOOL opj_t2_skip_packet_data( opj_t2_t* p_t2,
}
-OPJ_BOOL opj_t2_init_seg( opj_tcd_cblk_dec_t* cblk,
+static OPJ_BOOL opj_t2_init_seg( opj_tcd_cblk_dec_t* cblk,
OPJ_UINT32 index,
OPJ_UINT32 cblksty,
OPJ_UINT32 first)
diff --git a/openjpeg/src/lib/openjp2/t2.h b/openjpeg/src/lib/openjp2/t2.h
index 931141e05..3b652eeab 100644
--- a/openjpeg/src/lib/openjp2/t2.h
+++ b/openjpeg/src/lib/openjp2/t2.h
@@ -108,7 +108,8 @@ OPJ_BOOL opj_t2_decode_packets( opj_t2_t *t2,
OPJ_BYTE *src,
OPJ_UINT32 * p_data_read,
OPJ_UINT32 len,
- opj_codestream_index_t *cstr_info);
+ opj_codestream_index_t *cstr_info,
+ opj_event_mgr_t *p_manager);
/**
* Creates a Tier 2 handle
diff --git a/openjpeg/src/lib/openjp2/tcd.c b/openjpeg/src/lib/openjp2/tcd.c
index 79262fcd3..36f408435 100644
--- a/openjpeg/src/lib/openjp2/tcd.c
+++ b/openjpeg/src/lib/openjp2/tcd.c
@@ -103,6 +103,12 @@ void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) {
fprintf(fd, "}\n");
}
#endif
+
+/**
+ * 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_event_mgr_t* manager);
+
/**
* Allocates memory for a decoding code block.
*/
@@ -114,11 +120,16 @@ static OPJ_BOOL opj_tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_blo
static void opj_tcd_code_block_dec_deallocate (opj_tcd_precinct_t * p_precinct);
/**
- * Allocates memory for an encoding code block.
+ * Allocates memory for an encoding code block (but not data).
*/
static OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_block);
/**
+ * Allocates data for an encoding code block
+ */
+static OPJ_BOOL opj_tcd_code_block_enc_allocate_data (opj_tcd_cblk_enc_t * p_code_block);
+
+/**
* Deallocates the encoding data of the given precinct.
*/
static void opj_tcd_code_block_enc_deallocate (opj_tcd_precinct_t * p_precinct);
@@ -135,13 +146,14 @@ static OPJ_BOOL opj_tcd_t2_decode ( opj_tcd_t *p_tcd,
OPJ_BYTE * p_src_data,
OPJ_UINT32 * p_data_read,
OPJ_UINT32 p_max_src_size,
- opj_codestream_index_t *p_cstr_index );
+ opj_codestream_index_t *p_cstr_index,
+ opj_event_mgr_t *p_manager);
static OPJ_BOOL opj_tcd_t1_decode (opj_tcd_t *p_tcd);
static OPJ_BOOL opj_tcd_dwt_decode (opj_tcd_t *p_tcd);
-static OPJ_BOOL opj_tcd_mct_decode (opj_tcd_t *p_tcd);
+static OPJ_BOOL opj_tcd_mct_decode (opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager);
static OPJ_BOOL opj_tcd_dc_level_shift_decode (opj_tcd_t *p_tcd);
@@ -175,20 +187,18 @@ opj_tcd_t* opj_tcd_create(OPJ_BOOL p_is_decoder)
opj_tcd_t *l_tcd = 00;
/* create the tcd structure */
- l_tcd = (opj_tcd_t*) opj_malloc(sizeof(opj_tcd_t));
+ l_tcd = (opj_tcd_t*) opj_calloc(1,sizeof(opj_tcd_t));
if (!l_tcd) {
return 00;
}
- memset(l_tcd,0,sizeof(opj_tcd_t));
l_tcd->m_is_decoder = p_is_decoder ? 1 : 0;
- l_tcd->tcd_image = (opj_tcd_image_t*)opj_malloc(sizeof(opj_tcd_image_t));
+ l_tcd->tcd_image = (opj_tcd_image_t*)opj_calloc(1,sizeof(opj_tcd_image_t));
if (!l_tcd->tcd_image) {
opj_free(l_tcd);
return 00;
}
- memset(l_tcd->tcd_image,0,sizeof(opj_tcd_image_t));
return l_tcd;
}
@@ -258,7 +268,7 @@ void opj_tcd_makelayer( opj_tcd_t *tcd,
n = passno + 1;
continue;
}
- if (dd / dr >= thresh)
+ if (thresh - (dd / dr) < DBL_EPSILON) /* do not rely on float equality, check with DBL_EPSILON margin */
n = passno + 1;
}
@@ -467,13 +477,16 @@ OPJ_BOOL opj_tcd_rateallocate( opj_tcd_t *tcd,
tile_info->numpix = tcd_tile->numpix;
tile_info->distotile = tcd_tile->distotile;
tile_info->thresh = (OPJ_FLOAT64 *) opj_malloc(tcd_tcp->numlayers * sizeof(OPJ_FLOAT64));
+ if (!tile_info->thresh) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
}
for (layno = 0; layno < tcd_tcp->numlayers; layno++) {
OPJ_FLOAT64 lo = min;
OPJ_FLOAT64 hi = max;
- OPJ_BOOL success = OPJ_FALSE;
- OPJ_UINT32 maxlen = tcd_tcp->rates[layno] ? opj_uint_min(((OPJ_UINT32) ceil(tcd_tcp->rates[layno])), len) : len;
+ OPJ_UINT32 maxlen = tcd_tcp->rates[layno] > 0.0f ? opj_uint_min(((OPJ_UINT32) ceil(tcd_tcp->rates[layno])), len) : len;
OPJ_FLOAT64 goodthresh = 0;
OPJ_FLOAT64 stable_thresh = 0;
OPJ_UINT32 i;
@@ -486,7 +499,7 @@ OPJ_BOOL opj_tcd_rateallocate( opj_tcd_t *tcd,
-r xx,yy,zz,0 (disto_alloc == 1 and rates == 0)
-q xx,yy,zz,0 (fixed_quality == 1 and distoratio == 0)
==> possible to have some lossy layers and the last layer for sure lossless */
- if ( ((cp->m_specific_param.m_enc.m_disto_alloc==1) && (tcd_tcp->rates[layno]>0)) || ((cp->m_specific_param.m_enc.m_fixed_quality==1) && (tcd_tcp->distoratio[layno]>0))) {
+ if ( ((cp->m_specific_param.m_enc.m_disto_alloc==1) && (tcd_tcp->rates[layno]>0.0f)) || ((cp->m_specific_param.m_enc.m_fixed_quality==1) && (tcd_tcp->distoratio[layno]>0.0))) {
opj_t2_t*t2 = opj_t2_create(tcd->image, cp);
OPJ_FLOAT64 thresh = 0;
@@ -545,19 +558,13 @@ OPJ_BOOL opj_tcd_rateallocate( opj_tcd_t *tcd,
}
}
- success = OPJ_TRUE;
goodthresh = stable_thresh == 0? thresh : stable_thresh;
opj_t2_destroy(t2);
} else {
- success = OPJ_TRUE;
goodthresh = min;
}
- if (!success) {
- return OPJ_FALSE;
- }
-
if(cstr_info) { /* Threshold for Marcela Index */
cstr_info->tile[tcd->tcd_tileno].thresh[layno] = goodthresh;
}
@@ -573,28 +580,25 @@ OPJ_BOOL opj_tcd_rateallocate( opj_tcd_t *tcd,
OPJ_BOOL opj_tcd_init( opj_tcd_t *p_tcd,
opj_image_t * p_image,
- opj_cp_t * p_cp )
+ opj_cp_t * p_cp,
+ opj_thread_pool_t* p_tp )
{
- OPJ_UINT32 l_tile_comp_size;
-
p_tcd->image = p_image;
p_tcd->cp = p_cp;
- p_tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_malloc(sizeof(opj_tcd_tile_t));
+ p_tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_calloc(1,sizeof(opj_tcd_tile_t));
if (! p_tcd->tcd_image->tiles) {
return OPJ_FALSE;
}
- memset(p_tcd->tcd_image->tiles,0, sizeof(opj_tcd_tile_t));
- l_tile_comp_size = p_image->numcomps * (OPJ_UINT32)sizeof(opj_tcd_tilecomp_t);
- p_tcd->tcd_image->tiles->comps = (opj_tcd_tilecomp_t *) opj_malloc(l_tile_comp_size);
+ p_tcd->tcd_image->tiles->comps = (opj_tcd_tilecomp_t *) opj_calloc(p_image->numcomps,sizeof(opj_tcd_tilecomp_t));
if (! p_tcd->tcd_image->tiles->comps ) {
return OPJ_FALSE;
}
- memset( p_tcd->tcd_image->tiles->comps , 0 , l_tile_comp_size);
p_tcd->tcd_image->tiles->numcomps = p_image->numcomps;
p_tcd->tp_pos = p_cp->m_specific_param.m_enc.m_tp_pos;
+ p_tcd->thread_pool = p_tp;
return OPJ_TRUE;
}
@@ -614,437 +618,502 @@ void opj_tcd_destroy(opj_tcd_t *tcd) {
}
}
-/* ----------------------------------------------------------------------- */
-#define OPJ_MACRO_TCD_ALLOCATE(FUNCTION,TYPE,FRACTION,ELEMENT,FUNCTION_ELEMENT) \
-OPJ_BOOL FUNCTION ( opj_tcd_t *p_tcd, \
- OPJ_UINT32 p_tile_no \
- ) \
-{ \
- 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; \
- opj_tcd_tile_t * l_tile = 00; \
- opj_tccp_t *l_tccp = 00; \
- opj_tcd_tilecomp_t *l_tilec = 00; \
- opj_image_comp_t * l_image_comp = 00; \
- opj_tcd_resolution_t *l_res = 00; \
- opj_tcd_band_t *l_band = 00; \
- opj_stepsize_t * l_step_size = 00; \
- opj_tcd_precinct_t *l_current_precinct = 00; \
- TYPE* l_code_block = 00; \
- opj_image_t *l_image = 00; \
- 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; \
- /* extent of precincts , top left, bottom right**/ \
- OPJ_INT32 l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end, l_br_prc_y_end; \
- /* number of precinct for a resolution */ \
- OPJ_UINT32 l_nb_precincts; \
- /* room needed to store l_nb_precinct precinct for a resolution */ \
- OPJ_UINT32 l_nb_precinct_size; \
- /* number of code blocks for a precinct*/ \
- OPJ_UINT32 l_nb_code_blocks; \
- /* room needed to store l_nb_code_blocks code blocks for a precinct*/ \
- OPJ_UINT32 l_nb_code_blocks_size; \
- /* size of data for a tile */ \
- OPJ_UINT32 l_data_size; \
- \
- l_cp = p_tcd->cp; \
- l_tcp = &(l_cp->tcps[p_tile_no]); \
- l_tile = p_tcd->tcd_image->tiles; \
- l_tccp = l_tcp->tccps; \
- l_tilec = l_tile->comps; \
- l_image = p_tcd->image; \
- l_image_comp = p_tcd->image->comps; \
- \
- p = p_tile_no % l_cp->tw; /* tile coordinates */ \
- q = p_tile_no / l_cp->tw; \
- /*fprintf(stderr, "Tile coordinate = %d,%d\n", p, q);*/ \
- \
- /* 4 borders of the tile rescale on the image if necessary */ \
- l_tile->x0 = opj_int_max((OPJ_INT32)(l_cp->tx0 + p * l_cp->tdx), (OPJ_INT32)l_image->x0); \
- l_tile->y0 = opj_int_max((OPJ_INT32)(l_cp->ty0 + q * l_cp->tdy), (OPJ_INT32)l_image->y0); \
- l_tile->x1 = opj_int_min((OPJ_INT32)(l_cp->tx0 + (p + 1) * l_cp->tdx), (OPJ_INT32)l_image->x1); \
- l_tile->y1 = opj_int_min((OPJ_INT32)(l_cp->ty0 + (q + 1) * l_cp->tdy), (OPJ_INT32)l_image->y1); \
- /* testcase 1888.pdf.asan.35.988 */ \
- if (l_tccp->numresolutions == 0) { \
- fprintf(stderr, "tiles require at least one resolution\n"); \
- return OPJ_FALSE; \
- } \
- /*fprintf(stderr, "Tile border = %d,%d,%d,%d\n", l_tile->x0, l_tile->y0,l_tile->x1,l_tile->y1);*/ \
- \
- /*tile->numcomps = image->numcomps; */ \
- for(compno = 0; compno < l_tile->numcomps; ++compno) { \
- /*fprintf(stderr, "compno = %d/%d\n", compno, l_tile->numcomps);*/ \
- \
- /* border of each l_tile component (global) */ \
- l_tilec->x0 = opj_int_ceildiv(l_tile->x0, (OPJ_INT32)l_image_comp->dx); \
- l_tilec->y0 = opj_int_ceildiv(l_tile->y0, (OPJ_INT32)l_image_comp->dy); \
- l_tilec->x1 = opj_int_ceildiv(l_tile->x1, (OPJ_INT32)l_image_comp->dx); \
- l_tilec->y1 = opj_int_ceildiv(l_tile->y1, (OPJ_INT32)l_image_comp->dy); \
- /*fprintf(stderr, "\tTile compo border = %d,%d,%d,%d\n", l_tilec->x0, l_tilec->y0,l_tilec->x1,l_tilec->y1);*/ \
- \
- l_data_size = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0) \
- * (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0) * (OPJ_UINT32)sizeof(OPJ_UINT32 );\
- l_tilec->numresolutions = l_tccp->numresolutions; \
- if (l_tccp->numresolutions < l_cp->m_specific_param.m_dec.m_reduce) { \
- l_tilec->minimum_num_resolutions = 1; \
- } \
- else { \
- l_tilec->minimum_num_resolutions = l_tccp->numresolutions \
- - l_cp->m_specific_param.m_dec.m_reduce; \
- } \
- \
- if (l_tilec->data == 00) { \
- l_tilec->data = (OPJ_INT32 *) opj_malloc(l_data_size); \
- if (! l_tilec->data ) { \
- return OPJ_FALSE; \
- } \
- /*fprintf(stderr, "\tAllocate data of tilec (int): %d x OPJ_UINT32\n",l_data_size);*/ \
- \
- l_tilec->data_size = l_data_size; \
- } \
- else if (l_data_size > l_tilec->data_size) { \
- OPJ_INT32 * new_data = (OPJ_INT32 *) opj_realloc(l_tilec->data, l_data_size); \
- /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle tile data\n"); */ \
- fprintf(stderr, "Not enough memory to handle tile data\n"); \
- if (! new_data) { \
- opj_free(l_tilec->data); \
- l_tilec->data = NULL; \
- l_tilec->data_size = 0; \
- return OPJ_FALSE; \
- } \
- l_tilec->data = new_data; \
- /*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %d x OPJ_UINT32\n", l_tilec->data_size, l_data_size);*/ \
- l_tilec->data_size = l_data_size; \
- } \
- \
- l_data_size = l_tilec->numresolutions * (OPJ_UINT32)sizeof(opj_tcd_resolution_t); \
- \
- if (l_tilec->resolutions == 00) { \
- l_tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(l_data_size); \
- if (! l_tilec->resolutions ) { \
- return OPJ_FALSE; \
- } \
- /*fprintf(stderr, "\tAllocate resolutions of tilec (opj_tcd_resolution_t): %d\n",l_data_size);*/ \
- l_tilec->resolutions_size = l_data_size; \
- memset(l_tilec->resolutions,0,l_data_size); \
- } \
- else if (l_data_size > l_tilec->resolutions_size) { \
- opj_tcd_resolution_t* new_resolutions = (opj_tcd_resolution_t *) opj_realloc(l_tilec->resolutions, l_data_size); \
- if (! new_resolutions) { \
- /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to tile resolutions\n"); */ \
- fprintf(stderr, "Not enough memory to tile resolutions\n"); \
- opj_free(l_tilec->resolutions); \
- l_tilec->resolutions = NULL; \
- l_tilec->resolutions_size = 0; \
- return OPJ_FALSE; \
- } \
- l_tilec->resolutions = new_resolutions; \
- /*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %d x OPJ_UINT32\n", l_tilec->resolutions_size, l_data_size);*/ \
- memset(((OPJ_BYTE*) l_tilec->resolutions)+l_tilec->resolutions_size,0,l_data_size - l_tilec->resolutions_size); \
- l_tilec->resolutions_size = l_data_size; \
- } \
- \
- l_level_no = l_tilec->numresolutions - 1; \
- 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) { \
- /*fprintf(stderr, "\t\tresno = %d/%d\n", resno, l_tilec->numresolutions);*/ \
- OPJ_INT32 tlcbgxstart, tlcbgystart /*, brcbgxend, brcbgyend*/; \
- OPJ_UINT32 cbgwidthexpn, cbgheightexpn; \
- OPJ_UINT32 cblkwidthexpn, cblkheightexpn; \
- \
- /* border for each resolution level (global) */ \
- l_res->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no); \
- l_res->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no); \
- l_res->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no); \
- l_res->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no); \
- /*fprintf(stderr, "\t\t\tres_x0= %d, res_y0 =%d, res_x1=%d, res_y1=%d\n", l_res->x0, l_res->y0, l_res->x1, l_res->y1);*/ \
- /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */ \
- l_pdx = l_tccp->prcw[resno]; \
- l_pdy = l_tccp->prch[resno]; \
- /*fprintf(stderr, "\t\t\tpdx=%d, pdy=%d\n", l_pdx, l_pdy);*/ \
- /* 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; \
- /*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) ? 0 : (OPJ_UINT32)((l_br_prc_x_end - l_tl_prc_x_start) >> l_pdx); \
- l_res->ph = (l_res->y0 == l_res->y1) ? 0 : (OPJ_UINT32)((l_br_prc_y_end - l_tl_prc_y_start) >> l_pdy); \
- /*fprintf(stderr, "\t\t\tres_pw=%d, res_ph=%d\n", l_res->pw, l_res->ph );*/ \
- \
- l_nb_precincts = l_res->pw * l_res->ph; \
- l_nb_precinct_size = l_nb_precincts * (OPJ_UINT32)sizeof(opj_tcd_precinct_t); \
- if (resno == 0) { \
- tlcbgxstart = l_tl_prc_x_start; \
- tlcbgystart = l_tl_prc_y_start; \
- /*brcbgxend = l_br_prc_x_end;*/ \
- /* brcbgyend = l_br_prc_y_end;*/ \
- cbgwidthexpn = l_pdx; \
- cbgheightexpn = l_pdy; \
- l_res->numbands = 1; \
- } \
- else { \
- tlcbgxstart = opj_int_ceildivpow2(l_tl_prc_x_start, 1); \
- tlcbgystart = opj_int_ceildivpow2(l_tl_prc_y_start, 1); \
- /*brcbgxend = opj_int_ceildivpow2(l_br_prc_x_end, 1);*/ \
- /*brcbgyend = opj_int_ceildivpow2(l_br_prc_y_end, 1);*/ \
- cbgwidthexpn = l_pdx - 1; \
- cbgheightexpn = l_pdy - 1; \
- l_res->numbands = 3; \
- } \
- \
- cblkwidthexpn = opj_uint_min(l_tccp->cblkw, cbgwidthexpn); \
- cblkheightexpn = opj_uint_min(l_tccp->cblkh, cbgheightexpn); \
- l_band = l_res->bands; \
- \
- for (bandno = 0; bandno < l_res->numbands; ++bandno) { \
- OPJ_INT32 numbps; \
- /*fprintf(stderr, "\t\t\tband_no=%d/%d\n", bandno, l_res->numbands );*/ \
- \
- if (resno == 0) { \
- l_band->bandno = 0 ; \
- l_band->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no); \
- l_band->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no); \
- l_band->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no); \
- l_band->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no); \
- } \
- else { \
- l_band->bandno = bandno + 1; \
- /* x0b = 1 if bandno = 1 or 3 */ \
- l_x0b = l_band->bandno&1; \
- /* y0b = 1 if bandno = 2 or 3 */ \
- l_y0b = (OPJ_INT32)((l_band->bandno)>>1); \
- /* l_band border (global) */ \
- l_band->x0 = opj_int_ceildivpow2(l_tilec->x0 - (1 << l_level_no) * l_x0b, (OPJ_INT32)(l_level_no + 1)); \
- l_band->y0 = opj_int_ceildivpow2(l_tilec->y0 - (1 << l_level_no) * l_y0b, (OPJ_INT32)(l_level_no + 1)); \
- l_band->x1 = opj_int_ceildivpow2(l_tilec->x1 - (1 << l_level_no) * l_x0b, (OPJ_INT32)(l_level_no + 1)); \
- l_band->y1 = opj_int_ceildivpow2(l_tilec->y1 - (1 << l_level_no) * l_y0b, (OPJ_INT32)(l_level_no + 1)); \
- } \
- \
- /** 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; \
- l_band->numbps = l_step_size->expn + (OPJ_INT32)l_tccp->numgbits - 1; /* WHY -1 ? */ \
- \
- if (! l_band->precincts) { \
- l_band->precincts = (opj_tcd_precinct_t *) opj_malloc( /*3 * */ l_nb_precinct_size); \
- if (! l_band->precincts) { \
- return OPJ_FALSE; \
- } \
- /*fprintf(stderr, "\t\t\t\tAllocate precincts of a band (opj_tcd_precinct_t): %d\n",l_nb_precinct_size); */ \
- memset(l_band->precincts,0,l_nb_precinct_size); \
- l_band->precincts_data_size = l_nb_precinct_size; \
- } \
- else if (l_band->precincts_data_size < l_nb_precinct_size) { \
- \
- opj_tcd_precinct_t * new_precincts = (opj_tcd_precinct_t *) opj_realloc(l_band->precincts,/*3 * */ l_nb_precinct_size); \
- if (! new_precincts) { \
- /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle band precints\n"); */ \
- fprintf(stderr, "Not enough memory to handle band precints\n"); \
- opj_free(l_band->precincts); \
- l_band->precincts = NULL; \
- l_band->precincts_data_size = 0; \
- return OPJ_FALSE; \
- } \
- l_band->precincts = new_precincts; \
- /*fprintf(stderr, "\t\t\t\tReallocate precincts of a band (opj_tcd_precinct_t): from %d to %d\n",l_band->precincts_data_size, l_nb_precinct_size);*/ \
- memset(((OPJ_BYTE *) l_band->precincts) + l_band->precincts_data_size,0,l_nb_precinct_size - l_band->precincts_data_size); \
- l_band->precincts_data_size = l_nb_precinct_size; \
- } \
- \
- l_current_precinct = l_band->precincts; \
- for (precno = 0; precno < l_nb_precincts; ++precno) { \
- OPJ_INT32 tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend; \
- OPJ_INT32 cbgxstart = tlcbgxstart + (OPJ_INT32)(precno % l_res->pw) * (1 << cbgwidthexpn); \
- OPJ_INT32 cbgystart = tlcbgystart + (OPJ_INT32)(precno / l_res->pw) * (1 << cbgheightexpn); \
- OPJ_INT32 cbgxend = cbgxstart + (1 << cbgwidthexpn); \
- OPJ_INT32 cbgyend = cbgystart + (1 << cbgheightexpn); \
- /*fprintf(stderr, "\t precno=%d; bandno=%d, resno=%d; compno=%d\n", precno, bandno , resno, compno);*/ \
- /*fprintf(stderr, "\t tlcbgxstart(=%d) + (precno(=%d) percent res->pw(=%d)) * (1 << cbgwidthexpn(=%d)) \n",tlcbgxstart,precno,l_res->pw,cbgwidthexpn);*/ \
- \
- /* precinct size (global) */ \
- /*fprintf(stderr, "\t cbgxstart=%d, l_band->x0 = %d \n",cbgxstart, l_band->x0);*/ \
- \
- l_current_precinct->x0 = opj_int_max(cbgxstart, l_band->x0); \
- l_current_precinct->y0 = opj_int_max(cbgystart, l_band->y0); \
- l_current_precinct->x1 = opj_int_min(cbgxend, l_band->x1); \
- l_current_precinct->y1 = opj_int_min(cbgyend, l_band->y1); \
- /*fprintf(stderr, "\t prc_x0=%d; prc_y0=%d, prc_x1=%d; prc_y1=%d\n",l_current_precinct->x0, l_current_precinct->y0 ,l_current_precinct->x1, l_current_precinct->y1);*/ \
- \
- tlcblkxstart = opj_int_floordivpow2(l_current_precinct->x0, (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn; \
- /*fprintf(stderr, "\t tlcblkxstart =%d\n",tlcblkxstart );*/ \
- tlcblkystart = opj_int_floordivpow2(l_current_precinct->y0, (OPJ_INT32)cblkheightexpn) << cblkheightexpn; \
- /*fprintf(stderr, "\t tlcblkystart =%d\n",tlcblkystart );*/ \
- brcblkxend = opj_int_ceildivpow2(l_current_precinct->x1, (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn; \
- /*fprintf(stderr, "\t brcblkxend =%d\n",brcblkxend );*/ \
- brcblkyend = opj_int_ceildivpow2(l_current_precinct->y1, (OPJ_INT32)cblkheightexpn) << cblkheightexpn; \
- /*fprintf(stderr, "\t brcblkyend =%d\n",brcblkyend );*/ \
- l_current_precinct->cw = (OPJ_UINT32)((brcblkxend - tlcblkxstart) >> cblkwidthexpn); \
- l_current_precinct->ch = (OPJ_UINT32)((brcblkyend - tlcblkystart) >> cblkheightexpn); \
- \
- l_nb_code_blocks = l_current_precinct->cw * l_current_precinct->ch; \
- /*fprintf(stderr, "\t\t\t\t precinct_cw = %d x recinct_ch = %d\n",l_current_precinct->cw, l_current_precinct->ch); */ \
- l_nb_code_blocks_size = l_nb_code_blocks * (OPJ_UINT32)sizeof(TYPE); \
- \
- if (! l_current_precinct->cblks.ELEMENT) { \
- l_current_precinct->cblks.ELEMENT = (TYPE*) opj_malloc(l_nb_code_blocks_size); \
- if (! l_current_precinct->cblks.ELEMENT ) { \
- return OPJ_FALSE; \
- } \
- /*fprintf(stderr, "\t\t\t\tAllocate cblks of a precinct (opj_tcd_cblk_dec_t): %d\n",l_nb_code_blocks_size);*/ \
- \
- memset(l_current_precinct->cblks.ELEMENT,0,l_nb_code_blocks_size); \
- \
- l_current_precinct->block_size = l_nb_code_blocks_size; \
- } \
- else if (l_nb_code_blocks_size > l_current_precinct->block_size) { \
- TYPE *new_ELEMENT = (TYPE*) opj_realloc(l_current_precinct->cblks.ELEMENT, l_nb_code_blocks_size); \
- if (! new_ELEMENT) { \
- opj_free(l_current_precinct->cblks.ELEMENT); \
- l_current_precinct->cblks.ELEMENT = NULL; \
- l_current_precinct->block_size = 0; \
- /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory for current precinct codeblock element\n"); */ \
- fprintf(stderr, "Not enough memory for current precinct codeblock element\n"); \
- return OPJ_FALSE; \
- } \
- l_current_precinct->cblks.ELEMENT = new_ELEMENT; \
- /*fprintf(stderr, "\t\t\t\tReallocate cblks of a precinct (opj_tcd_cblk_dec_t): from %d to %d\n",l_current_precinct->block_size, l_nb_code_blocks_size); */\
- \
- memset(((OPJ_BYTE *) l_current_precinct->cblks.ELEMENT) + l_current_precinct->block_size \
- ,0 \
- ,l_nb_code_blocks_size - l_current_precinct->block_size); \
- \
- l_current_precinct->block_size = l_nb_code_blocks_size; \
- } \
- \
- if (! l_current_precinct->incltree) { \
- l_current_precinct->incltree = opj_tgt_create(l_current_precinct->cw, \
- l_current_precinct->ch); \
- } \
- else{ \
- l_current_precinct->incltree = opj_tgt_init(l_current_precinct->incltree, \
- l_current_precinct->cw, \
- l_current_precinct->ch); \
- } \
- \
- if (! l_current_precinct->incltree) { \
- fprintf(stderr, "WARNING: No incltree created.\n"); \
- /*return OPJ_FALSE;*/ \
- } \
- \
- if (! l_current_precinct->imsbtree) { \
- l_current_precinct->imsbtree = opj_tgt_create( \
- l_current_precinct->cw, \
- l_current_precinct->ch); \
- } \
- else { \
- l_current_precinct->imsbtree = opj_tgt_init( \
- l_current_precinct->imsbtree, \
- l_current_precinct->cw, \
- l_current_precinct->ch); \
- } \
- \
- if (! l_current_precinct->imsbtree) { \
- fprintf(stderr, "WARNING: No imsbtree created.\n"); \
- /*return OPJ_FALSE;*/ \
- } \
- \
- l_code_block = l_current_precinct->cblks.ELEMENT; \
- \
- for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) { \
- OPJ_INT32 cblkxstart = tlcblkxstart + (OPJ_INT32)(cblkno % l_current_precinct->cw) * (1 << cblkwidthexpn); \
- OPJ_INT32 cblkystart = tlcblkystart + (OPJ_INT32)(cblkno / l_current_precinct->cw) * (1 << cblkheightexpn); \
- OPJ_INT32 cblkxend = cblkxstart + (1 << cblkwidthexpn); \
- OPJ_INT32 cblkyend = cblkystart + (1 << cblkheightexpn); \
- \
- /* code-block size (global) */ \
- l_code_block->x0 = opj_int_max(cblkxstart, l_current_precinct->x0); \
- l_code_block->y0 = opj_int_max(cblkystart, l_current_precinct->y0); \
- l_code_block->x1 = opj_int_min(cblkxend, l_current_precinct->x1); \
- l_code_block->y1 = opj_int_min(cblkyend, l_current_precinct->y1); \
- \
- if (! FUNCTION_ELEMENT(l_code_block)) { \
- return OPJ_FALSE; \
- } \
- ++l_code_block; \
- } \
- ++l_current_precinct; \
- } /* precno */ \
- ++l_band; \
- ++l_step_size; \
- } /* bandno */ \
- ++l_res; \
- --l_level_no; \
- } /* resno */ \
- ++l_tccp; \
- ++l_tilec; \
- ++l_image_comp; \
- } /* compno */ \
- return OPJ_TRUE; \
-} \
-
-
-OPJ_MACRO_TCD_ALLOCATE(opj_tcd_init_encode_tile, opj_tcd_cblk_enc_t, 1.f, enc, opj_tcd_code_block_enc_allocate)
-OPJ_MACRO_TCD_ALLOCATE(opj_tcd_init_decode_tile, opj_tcd_cblk_dec_t, 0.5f, dec, opj_tcd_code_block_dec_allocate)
-
-#undef OPJ_MACRO_TCD_ALLOCATE
-
-/**
- * Allocates memory for an encoding code block.
- */
-OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_block)
+OPJ_BOOL opj_alloc_tile_component_data(opj_tcd_tilecomp_t *l_tilec)
{
- if (! p_code_block->data) {
+ if ((l_tilec->data == 00) || ((l_tilec->data_size_needed > l_tilec->data_size) && (l_tilec->ownsData == OPJ_FALSE))) {
+ l_tilec->data = (OPJ_INT32 *) opj_aligned_malloc(l_tilec->data_size_needed);
+ if (! l_tilec->data ) {
+ return OPJ_FALSE;
+ }
+ /*fprintf(stderr, "tAllocate data of tilec (int): %d x OPJ_UINT32n",l_data_size);*/
+ l_tilec->data_size = l_tilec->data_size_needed;
+ l_tilec->ownsData = OPJ_TRUE;
+ }
+ else if (l_tilec->data_size_needed > l_tilec->data_size) {
+ /* We don't need to keep old data */
+ opj_aligned_free(l_tilec->data);
+ l_tilec->data = (OPJ_INT32 *) opj_aligned_malloc(l_tilec->data_size_needed);
+ if (! l_tilec->data ) {
+ l_tilec->data_size = 0;
+ l_tilec->data_size_needed = 0;
+ l_tilec->ownsData = OPJ_FALSE;
+ return OPJ_FALSE;
+ }
+ /*fprintf(stderr, "tReallocate data of tilec (int): from %d to %d x OPJ_UINT32n", l_tilec->data_size, l_data_size);*/
+ l_tilec->data_size = l_tilec->data_size_needed;
+ l_tilec->ownsData = OPJ_TRUE;
+ }
+ return OPJ_TRUE;
+}
- p_code_block->data = (OPJ_BYTE*) opj_malloc(OPJ_J2K_DEFAULT_CBLK_DATA_SIZE*2); /*why +1 ?*/
- if(! p_code_block->data) {
- return OPJ_FALSE;
- }
+/* ----------------------------------------------------------------------- */
- p_code_block->data[0] = 0;
- p_code_block->data+=1;
+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_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;
+ opj_tcd_tile_t * l_tile = 00;
+ opj_tccp_t *l_tccp = 00;
+ opj_tcd_tilecomp_t *l_tilec = 00;
+ opj_image_comp_t * l_image_comp = 00;
+ opj_tcd_resolution_t *l_res = 00;
+ opj_tcd_band_t *l_band = 00;
+ opj_stepsize_t * l_step_size = 00;
+ opj_tcd_precinct_t *l_current_precinct = 00;
+ opj_image_t *l_image = 00;
+ 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**/
+ OPJ_INT32 l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end, l_br_prc_y_end;
+ /* number of precinct for a resolution */
+ OPJ_UINT32 l_nb_precincts;
+ /* room needed to store l_nb_precinct precinct for a resolution */
+ OPJ_UINT32 l_nb_precinct_size;
+ /* number of code blocks for a precinct*/
+ OPJ_UINT32 l_nb_code_blocks;
+ /* room needed to store l_nb_code_blocks code blocks for a precinct*/
+ OPJ_UINT32 l_nb_code_blocks_size;
+ /* size of data for a tile */
+ OPJ_UINT32 l_data_size;
+
+ l_cp = p_tcd->cp;
+ l_tcp = &(l_cp->tcps[p_tile_no]);
+ l_tile = p_tcd->tcd_image->tiles;
+ l_tccp = l_tcp->tccps;
+ l_tilec = l_tile->comps;
+ l_image = p_tcd->image;
+ l_image_comp = p_tcd->image->comps;
+
+ p = p_tile_no % l_cp->tw; /* tile coordinates */
+ q = p_tile_no / l_cp->tw;
+ /*fprintf(stderr, "Tile coordinate = %d,%d\n", p, q);*/
+
+ /* 4 borders of the tile rescale on the image if necessary */
+ l_tx0 = l_cp->tx0 + p * l_cp->tdx; /* can't be greater than l_image->x1 so won't overflow */
+ l_tile->x0 = (OPJ_INT32)opj_uint_max(l_tx0, l_image->x0);
+ l_tile->x1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_tx0, l_cp->tdx), l_image->x1);
+ /* all those OPJ_UINT32 are casted to OPJ_INT32, let's do some sanity check */
+ if ((l_tile->x0 < 0) || (l_tile->x1 <= l_tile->x0)) {
+ opj_event_msg(manager, EVT_ERROR, "Tile X coordinates are not supported\n");
+ return OPJ_FALSE;
+ }
+ l_ty0 = l_cp->ty0 + q * l_cp->tdy; /* can't be greater than l_image->y1 so won't overflow */
+ l_tile->y0 = (OPJ_INT32)opj_uint_max(l_ty0, l_image->y0);
+ l_tile->y1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_ty0, l_cp->tdy), l_image->y1);
+ /* all those OPJ_UINT32 are casted to OPJ_INT32, let's do some sanity check */
+ if ((l_tile->y0 < 0) || (l_tile->y1 <= l_tile->y0)) {
+ opj_event_msg(manager, EVT_ERROR, "Tile Y coordinates are not supported\n");
+ return OPJ_FALSE;
+ }
+
+
+ /* testcase 1888.pdf.asan.35.988 */
+ if (l_tccp->numresolutions == 0) {
+ opj_event_msg(manager, EVT_ERROR, "tiles require at least one resolution\n");
+ return OPJ_FALSE;
+ }
+ /*fprintf(stderr, "Tile border = %d,%d,%d,%d\n", l_tile->x0, l_tile->y0,l_tile->x1,l_tile->y1);*/
+
+ /*tile->numcomps = image->numcomps; */
+ for (compno = 0; compno < l_tile->numcomps; ++compno) {
+ /*fprintf(stderr, "compno = %d/%d\n", compno, l_tile->numcomps);*/
+ l_image_comp->resno_decoded = 0;
+ /* border of each l_tile component (global) */
+ l_tilec->x0 = opj_int_ceildiv(l_tile->x0, (OPJ_INT32)l_image_comp->dx);
+ l_tilec->y0 = opj_int_ceildiv(l_tile->y0, (OPJ_INT32)l_image_comp->dy);
+ l_tilec->x1 = opj_int_ceildiv(l_tile->x1, (OPJ_INT32)l_image_comp->dx);
+ l_tilec->y1 = opj_int_ceildiv(l_tile->y1, (OPJ_INT32)l_image_comp->dy);
+ /*fprintf(stderr, "\tTile compo border = %d,%d,%d,%d\n", l_tilec->x0, l_tilec->y0,l_tilec->x1,l_tilec->y1);*/
+
+ /* compute l_data_size with overflow check */
+ l_data_size = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0);
+ /* issue 733, l_data_size == 0U, probably something wrong should be checked before getting here */
+ if ((l_data_size > 0U) && ((((OPJ_UINT32)-1) / l_data_size) < (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0))) {
+ opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n");
+ return OPJ_FALSE;
+ }
+ l_data_size = l_data_size * (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0);
+
+ if ((((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(OPJ_UINT32)) < l_data_size) {
+ opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n");
+ return OPJ_FALSE;
+ }
+ l_data_size = l_data_size * (OPJ_UINT32)sizeof(OPJ_UINT32);
+ l_tilec->numresolutions = l_tccp->numresolutions;
+ if (l_tccp->numresolutions < l_cp->m_specific_param.m_dec.m_reduce) {
+ l_tilec->minimum_num_resolutions = 1;
+ }
+ else {
+ l_tilec->minimum_num_resolutions = l_tccp->numresolutions - l_cp->m_specific_param.m_dec.m_reduce;
+ }
+
+ l_tilec->data_size_needed = l_data_size;
+ if (p_tcd->m_is_decoder && !opj_alloc_tile_component_data(l_tilec)) {
+ opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n");
+ return OPJ_FALSE;
+ }
+
+ l_data_size = l_tilec->numresolutions * (OPJ_UINT32)sizeof(opj_tcd_resolution_t);
+
+ if (l_tilec->resolutions == 00) {
+ l_tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(l_data_size);
+ if (! l_tilec->resolutions ) {
+ return OPJ_FALSE;
+ }
+ /*fprintf(stderr, "\tAllocate resolutions of tilec (opj_tcd_resolution_t): %d\n",l_data_size);*/
+ l_tilec->resolutions_size = l_data_size;
+ memset(l_tilec->resolutions,0,l_data_size);
+ }
+ else if (l_data_size > l_tilec->resolutions_size) {
+ opj_tcd_resolution_t* new_resolutions = (opj_tcd_resolution_t *) opj_realloc(l_tilec->resolutions, l_data_size);
+ if (! new_resolutions) {
+ opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile resolutions\n");
+ opj_free(l_tilec->resolutions);
+ l_tilec->resolutions = NULL;
+ l_tilec->resolutions_size = 0;
+ return OPJ_FALSE;
+ }
+ l_tilec->resolutions = new_resolutions;
+ /*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %d x OPJ_UINT32\n", l_tilec->resolutions_size, l_data_size);*/
+ memset(((OPJ_BYTE*) l_tilec->resolutions)+l_tilec->resolutions_size,0,l_data_size - l_tilec->resolutions_size);
+ l_tilec->resolutions_size = l_data_size;
+ }
+
+ 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) {
+ /*fprintf(stderr, "\t\tresno = %d/%d\n", resno, l_tilec->numresolutions);*/
+ OPJ_INT32 tlcbgxstart, tlcbgystart /*, brcbgxend, brcbgyend*/;
+ OPJ_UINT32 cbgwidthexpn, cbgheightexpn;
+ OPJ_UINT32 cblkwidthexpn, cblkheightexpn;
+
+ --l_level_no;
+
+ /* border for each resolution level (global) */
+ l_res->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no);
+ l_res->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no);
+ l_res->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no);
+ l_res->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no);
+ /*fprintf(stderr, "\t\t\tres_x0= %d, res_y0 =%d, res_x1=%d, res_y1=%d\n", l_res->x0, l_res->y0, l_res->x1, l_res->y1);*/
+ /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */
+ l_pdx = l_tccp->prcw[resno];
+ l_pdy = l_tccp->prch[resno];
+ /*fprintf(stderr, "\t\t\tpdx=%d, pdy=%d\n", l_pdx, l_pdy);*/
+ /* 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;
+ /*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)((l_br_prc_x_end - l_tl_prc_x_start) >> l_pdx);
+ l_res->ph = (l_res->y0 == l_res->y1) ? 0U : (OPJ_UINT32)((l_br_prc_y_end - l_tl_prc_y_start) >> l_pdy);
+ /*fprintf(stderr, "\t\t\tres_pw=%d, res_ph=%d\n", l_res->pw, l_res->ph );*/
+
+ if ((l_res->pw != 0U) && ((((OPJ_UINT32)-1) / l_res->pw) < l_res->ph)) {
+ opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n");
+ return OPJ_FALSE;
+ }
+ l_nb_precincts = l_res->pw * l_res->ph;
+
+ if ((((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(opj_tcd_precinct_t)) < l_nb_precincts) {
+ opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n");
+ return OPJ_FALSE;
+ }
+ l_nb_precinct_size = l_nb_precincts * (OPJ_UINT32)sizeof(opj_tcd_precinct_t);
+
+ if (resno == 0) {
+ tlcbgxstart = l_tl_prc_x_start;
+ tlcbgystart = l_tl_prc_y_start;
+ /*brcbgxend = l_br_prc_x_end;*/
+ /* brcbgyend = l_br_prc_y_end;*/
+ cbgwidthexpn = l_pdx;
+ cbgheightexpn = l_pdy;
+ l_res->numbands = 1;
+ }
+ else {
+ tlcbgxstart = opj_int_ceildivpow2(l_tl_prc_x_start, 1);
+ tlcbgystart = opj_int_ceildivpow2(l_tl_prc_y_start, 1);
+ /*brcbgxend = opj_int_ceildivpow2(l_br_prc_x_end, 1);*/
+ /*brcbgyend = opj_int_ceildivpow2(l_br_prc_y_end, 1);*/
+ cbgwidthexpn = l_pdx - 1;
+ cbgheightexpn = l_pdy - 1;
+ l_res->numbands = 3;
+ }
+
+ cblkwidthexpn = opj_uint_min(l_tccp->cblkw, cbgwidthexpn);
+ cblkheightexpn = opj_uint_min(l_tccp->cblkh, cbgheightexpn);
+ l_band = l_res->bands;
+
+ for (bandno = 0; bandno < l_res->numbands; ++bandno) {
+ OPJ_INT32 numbps;
+ /*fprintf(stderr, "\t\t\tband_no=%d/%d\n", bandno, l_res->numbands );*/
+
+ if (resno == 0) {
+ l_band->bandno = 0 ;
+ l_band->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no);
+ l_band->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no);
+ l_band->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no);
+ l_band->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no);
+ }
+ else {
+ l_band->bandno = bandno + 1;
+ /* x0b = 1 if bandno = 1 or 3 */
+ l_x0b = l_band->bandno&1;
+ /* y0b = 1 if bandno = 2 or 3 */
+ l_y0b = (OPJ_INT32)((l_band->bandno)>>1);
+ /* l_band border (global) */
+ l_band->x0 = opj_int64_ceildivpow2(l_tilec->x0 - ((OPJ_INT64)l_x0b << l_level_no), (OPJ_INT32)(l_level_no + 1));
+ l_band->y0 = opj_int64_ceildivpow2(l_tilec->y0 - ((OPJ_INT64)l_y0b << l_level_no), (OPJ_INT32)(l_level_no + 1));
+ l_band->x1 = opj_int64_ceildivpow2(l_tilec->x1 - ((OPJ_INT64)l_x0b << l_level_no), (OPJ_INT32)(l_level_no + 1));
+ l_band->y1 = opj_int64_ceildivpow2(l_tilec->y1 - ((OPJ_INT64)l_y0b << l_level_no), (OPJ_INT32)(l_level_no + 1));
+ }
+
+ /** 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;
+ l_band->numbps = l_step_size->expn + (OPJ_INT32)l_tccp->numgbits - 1; /* WHY -1 ? */
+
+ if (!l_band->precincts && (l_nb_precincts > 0U)) {
+ l_band->precincts = (opj_tcd_precinct_t *) opj_malloc( /*3 * */ l_nb_precinct_size);
+ if (! l_band->precincts) {
+ opj_event_msg(manager, EVT_ERROR, "Not enough memory to handle band precints\n");
+ return OPJ_FALSE;
+ }
+ /*fprintf(stderr, "\t\t\t\tAllocate precincts of a band (opj_tcd_precinct_t): %d\n",l_nb_precinct_size); */
+ memset(l_band->precincts,0,l_nb_precinct_size);
+ l_band->precincts_data_size = l_nb_precinct_size;
+ }
+ else if (l_band->precincts_data_size < l_nb_precinct_size) {
+
+ opj_tcd_precinct_t * new_precincts = (opj_tcd_precinct_t *) opj_realloc(l_band->precincts,/*3 * */ l_nb_precinct_size);
+ if (! new_precincts) {
+ opj_event_msg(manager, EVT_ERROR, "Not enough memory to handle band precints\n");
+ opj_free(l_band->precincts);
+ l_band->precincts = NULL;
+ l_band->precincts_data_size = 0;
+ return OPJ_FALSE;
+ }
+ l_band->precincts = new_precincts;
+ /*fprintf(stderr, "\t\t\t\tReallocate precincts of a band (opj_tcd_precinct_t): from %d to %d\n",l_band->precincts_data_size, l_nb_precinct_size);*/
+ memset(((OPJ_BYTE *) l_band->precincts) + l_band->precincts_data_size,0,l_nb_precinct_size - l_band->precincts_data_size);
+ l_band->precincts_data_size = l_nb_precinct_size;
+ }
+
+ l_current_precinct = l_band->precincts;
+ for (precno = 0; precno < l_nb_precincts; ++precno) {
+ OPJ_INT32 tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend;
+ OPJ_INT32 cbgxstart = tlcbgxstart + (OPJ_INT32)(precno % l_res->pw) * (1 << cbgwidthexpn);
+ OPJ_INT32 cbgystart = tlcbgystart + (OPJ_INT32)(precno / l_res->pw) * (1 << cbgheightexpn);
+ OPJ_INT32 cbgxend = cbgxstart + (1 << cbgwidthexpn);
+ OPJ_INT32 cbgyend = cbgystart + (1 << cbgheightexpn);
+ /*fprintf(stderr, "\t precno=%d; bandno=%d, resno=%d; compno=%d\n", precno, bandno , resno, compno);*/
+ /*fprintf(stderr, "\t tlcbgxstart(=%d) + (precno(=%d) percent res->pw(=%d)) * (1 << cbgwidthexpn(=%d)) \n",tlcbgxstart,precno,l_res->pw,cbgwidthexpn);*/
+
+ /* precinct size (global) */
+ /*fprintf(stderr, "\t cbgxstart=%d, l_band->x0 = %d \n",cbgxstart, l_band->x0);*/
+
+ l_current_precinct->x0 = opj_int_max(cbgxstart, l_band->x0);
+ l_current_precinct->y0 = opj_int_max(cbgystart, l_band->y0);
+ l_current_precinct->x1 = opj_int_min(cbgxend, l_band->x1);
+ l_current_precinct->y1 = opj_int_min(cbgyend, l_band->y1);
+ /*fprintf(stderr, "\t prc_x0=%d; prc_y0=%d, prc_x1=%d; prc_y1=%d\n",l_current_precinct->x0, l_current_precinct->y0 ,l_current_precinct->x1, l_current_precinct->y1);*/
+
+ tlcblkxstart = opj_int_floordivpow2(l_current_precinct->x0, (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn;
+ /*fprintf(stderr, "\t tlcblkxstart =%d\n",tlcblkxstart );*/
+ tlcblkystart = opj_int_floordivpow2(l_current_precinct->y0, (OPJ_INT32)cblkheightexpn) << cblkheightexpn;
+ /*fprintf(stderr, "\t tlcblkystart =%d\n",tlcblkystart );*/
+ brcblkxend = opj_int_ceildivpow2(l_current_precinct->x1, (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn;
+ /*fprintf(stderr, "\t brcblkxend =%d\n",brcblkxend );*/
+ brcblkyend = opj_int_ceildivpow2(l_current_precinct->y1, (OPJ_INT32)cblkheightexpn) << cblkheightexpn;
+ /*fprintf(stderr, "\t brcblkyend =%d\n",brcblkyend );*/
+ l_current_precinct->cw = (OPJ_UINT32)((brcblkxend - tlcblkxstart) >> cblkwidthexpn);
+ l_current_precinct->ch = (OPJ_UINT32)((brcblkyend - tlcblkystart) >> cblkheightexpn);
+
+ l_nb_code_blocks = l_current_precinct->cw * l_current_precinct->ch;
+ /*fprintf(stderr, "\t\t\t\t precinct_cw = %d x recinct_ch = %d\n",l_current_precinct->cw, l_current_precinct->ch); */
+ l_nb_code_blocks_size = l_nb_code_blocks * (OPJ_UINT32)sizeof_block;
+
+ if (!l_current_precinct->cblks.blocks && (l_nb_code_blocks > 0U)) {
+ l_current_precinct->cblks.blocks = opj_malloc(l_nb_code_blocks_size);
+ if (! l_current_precinct->cblks.blocks ) {
+ return OPJ_FALSE;
+ }
+ /*fprintf(stderr, "\t\t\t\tAllocate cblks of a precinct (opj_tcd_cblk_dec_t): %d\n",l_nb_code_blocks_size);*/
+
+ memset(l_current_precinct->cblks.blocks,0,l_nb_code_blocks_size);
+
+ l_current_precinct->block_size = l_nb_code_blocks_size;
+ }
+ else if (l_nb_code_blocks_size > l_current_precinct->block_size) {
+ void *new_blocks = opj_realloc(l_current_precinct->cblks.blocks, l_nb_code_blocks_size);
+ if (! new_blocks) {
+ opj_free(l_current_precinct->cblks.blocks);
+ l_current_precinct->cblks.blocks = NULL;
+ l_current_precinct->block_size = 0;
+ opj_event_msg(manager, EVT_ERROR, "Not enough memory for current precinct codeblock element\n");
+ return OPJ_FALSE;
+ }
+ l_current_precinct->cblks.blocks = new_blocks;
+ /*fprintf(stderr, "\t\t\t\tReallocate cblks of a precinct (opj_tcd_cblk_dec_t): from %d to %d\n",l_current_precinct->block_size, l_nb_code_blocks_size); */
+
+ memset(((OPJ_BYTE *) l_current_precinct->cblks.blocks) + l_current_precinct->block_size
+ ,0
+ ,l_nb_code_blocks_size - l_current_precinct->block_size);
+
+ l_current_precinct->block_size = l_nb_code_blocks_size;
+ }
+
+ if (! l_current_precinct->incltree) {
+ l_current_precinct->incltree = opj_tgt_create(l_current_precinct->cw, l_current_precinct->ch, manager);
+ }
+ else{
+ l_current_precinct->incltree = opj_tgt_init(l_current_precinct->incltree, l_current_precinct->cw, l_current_precinct->ch, manager);
+ }
+
+ if (! l_current_precinct->incltree) {
+ opj_event_msg(manager, EVT_WARNING, "No incltree created.\n");
+ /*return OPJ_FALSE;*/
+ }
+
+ if (! l_current_precinct->imsbtree) {
+ l_current_precinct->imsbtree = opj_tgt_create(l_current_precinct->cw, l_current_precinct->ch, manager);
+ }
+ else {
+ l_current_precinct->imsbtree = opj_tgt_init(l_current_precinct->imsbtree, l_current_precinct->cw, l_current_precinct->ch, manager);
+ }
+
+ if (! l_current_precinct->imsbtree) {
+ opj_event_msg(manager, EVT_WARNING, "No imsbtree created.\n");
+ /*return OPJ_FALSE;*/
+ }
+
+ for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
+ OPJ_INT32 cblkxstart = tlcblkxstart + (OPJ_INT32)(cblkno % l_current_precinct->cw) * (1 << cblkwidthexpn);
+ OPJ_INT32 cblkystart = tlcblkystart + (OPJ_INT32)(cblkno / l_current_precinct->cw) * (1 << cblkheightexpn);
+ OPJ_INT32 cblkxend = cblkxstart + (1 << cblkwidthexpn);
+ OPJ_INT32 cblkyend = cblkystart + (1 << cblkheightexpn);
+
+ if (isEncoder) {
+ opj_tcd_cblk_enc_t* l_code_block = l_current_precinct->cblks.enc + cblkno;
+
+ if (! opj_tcd_code_block_enc_allocate(l_code_block)) {
+ return OPJ_FALSE;
+ }
+ /* code-block size (global) */
+ l_code_block->x0 = opj_int_max(cblkxstart, l_current_precinct->x0);
+ l_code_block->y0 = opj_int_max(cblkystart, l_current_precinct->y0);
+ l_code_block->x1 = opj_int_min(cblkxend, l_current_precinct->x1);
+ l_code_block->y1 = opj_int_min(cblkyend, l_current_precinct->y1);
+
+ if (! opj_tcd_code_block_enc_allocate_data(l_code_block)) {
+ return OPJ_FALSE;
+ }
+ } else {
+ opj_tcd_cblk_dec_t* l_code_block = l_current_precinct->cblks.dec + cblkno;
+
+ if (! opj_tcd_code_block_dec_allocate(l_code_block)) {
+ return OPJ_FALSE;
+ }
+ /* code-block size (global) */
+ l_code_block->x0 = opj_int_max(cblkxstart, l_current_precinct->x0);
+ l_code_block->y0 = opj_int_max(cblkystart, l_current_precinct->y0);
+ l_code_block->x1 = opj_int_min(cblkxend, l_current_precinct->x1);
+ l_code_block->y1 = opj_int_min(cblkyend, l_current_precinct->y1);
+ }
+ }
+ ++l_current_precinct;
+ } /* precno */
+ ++l_band;
+ ++l_step_size;
+ } /* bandno */
+ ++l_res;
+ } /* resno */
+ ++l_tccp;
+ ++l_tilec;
+ ++l_image_comp;
+ } /* compno */
+ return OPJ_TRUE;
+}
- /* no memset since data */
- p_code_block->layers = (opj_tcd_layer_t*) opj_malloc(100 * sizeof(opj_tcd_layer_t));
- if (! p_code_block->layers) {
- return OPJ_FALSE;
- }
+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, sizeof(opj_tcd_cblk_enc_t), p_manager);
+}
- p_code_block->passes = (opj_tcd_pass_t*) opj_malloc(100 * sizeof(opj_tcd_pass_t));
- if (! p_code_block->passes) {
- return OPJ_FALSE;
- }
- }
+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, sizeof(opj_tcd_cblk_dec_t), p_manager);
+}
- memset(p_code_block->layers,0,100 * sizeof(opj_tcd_layer_t));
- memset(p_code_block->passes,0,100 * sizeof(opj_tcd_pass_t));
+/**
+ * Allocates memory for an encoding code block (but not data memory).
+ */
+static OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_block)
+{
+ if (! p_code_block->layers) {
+ /* no memset since data */
+ p_code_block->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t));
+ if (! p_code_block->layers) {
+ return OPJ_FALSE;
+ }
+ }
+ if (! p_code_block->passes) {
+ p_code_block->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t));
+ if (! p_code_block->passes) {
+ return OPJ_FALSE;
+ }
+ }
+ return OPJ_TRUE;
+}
- return OPJ_TRUE;
+/**
+ * Allocates data memory for an encoding code block.
+ */
+static OPJ_BOOL opj_tcd_code_block_enc_allocate_data (opj_tcd_cblk_enc_t * p_code_block)
+{
+ OPJ_UINT32 l_data_size;
+
+ l_data_size = (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) {
+ opj_free(p_code_block->data - 1); /* again, why -1 */
+ }
+ p_code_block->data = (OPJ_BYTE*) opj_malloc(l_data_size+1);
+ if(! p_code_block->data) {
+ p_code_block->data_size = 0U;
+ return OPJ_FALSE;
+ }
+ p_code_block->data_size = l_data_size;
+
+ p_code_block->data[0] = 0;
+ p_code_block->data+=1; /*why +1 ?*/
+ }
+ return OPJ_TRUE;
}
/**
* Allocates memory for a decoding code block.
*/
-OPJ_BOOL opj_tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_block)
+static OPJ_BOOL opj_tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_block)
{
- OPJ_UINT32 l_seg_size;
-
if (! p_code_block->data) {
p_code_block->data = (OPJ_BYTE*) opj_malloc(OPJ_J2K_DEFAULT_CBLK_DATA_SIZE);
@@ -1054,19 +1123,27 @@ OPJ_BOOL opj_tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_block)
p_code_block->data_max_size = OPJ_J2K_DEFAULT_CBLK_DATA_SIZE;
/*fprintf(stderr, "Allocate 8192 elements of code_block->data\n");*/
- l_seg_size = OPJ_J2K_DEFAULT_NB_SEGS * sizeof(opj_tcd_seg_t);
- p_code_block->segs = (opj_tcd_seg_t *) opj_malloc(l_seg_size);
+ p_code_block->segs = (opj_tcd_seg_t *) opj_calloc(OPJ_J2K_DEFAULT_NB_SEGS,sizeof(opj_tcd_seg_t));
if (! p_code_block->segs) {
return OPJ_FALSE;
}
- memset(p_code_block->segs,0,l_seg_size);
/*fprintf(stderr, "Allocate %d elements of code_block->data\n", OPJ_J2K_DEFAULT_NB_SEGS * sizeof(opj_tcd_seg_t));*/
p_code_block->m_current_max_segs = OPJ_J2K_DEFAULT_NB_SEGS;
/*fprintf(stderr, "m_current_max_segs of code_block->data = %d\n", p_code_block->m_current_max_segs);*/
- }
- /* TODO */
- /*p_code_block->numsegs = 0; */
+ } else {
+ /* sanitize */
+ OPJ_BYTE* l_data = p_code_block->data;
+ OPJ_UINT32 l_data_max_size = p_code_block->data_max_size;
+ opj_tcd_seg_t * l_segs = p_code_block->segs;
+ OPJ_UINT32 l_current_max_segs = p_code_block->m_current_max_segs;
+
+ memset(p_code_block, 0, sizeof(opj_tcd_cblk_dec_t));
+ p_code_block->data = l_data;
+ p_code_block->data_max_size = l_data_max_size;
+ p_code_block->segs = l_segs;
+ p_code_block->m_current_max_segs = l_current_max_segs;
+ }
return OPJ_TRUE;
}
@@ -1135,6 +1212,10 @@ OPJ_BOOL opj_tcd_encode_tile( opj_tcd_t *p_tcd,
p_cstr_info->tile[p_tile_no].pdy[i] = (int)l_tccp->prch[i];
}
p_cstr_info->tile[p_tile_no].packet = (opj_packet_info_t*) opj_calloc((size_t)p_cstr_info->numcomps * (size_t)p_cstr_info->numlayers * l_num_packs, sizeof(opj_packet_info_t));
+ if (!p_cstr_info->tile[p_tile_no].packet) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+ }
}
/* << INDEX */
@@ -1192,7 +1273,8 @@ OPJ_BOOL opj_tcd_decode_tile( opj_tcd_t *p_tcd,
OPJ_BYTE *p_src,
OPJ_UINT32 p_max_length,
OPJ_UINT32 p_tile_no,
- opj_codestream_index_t *p_cstr_index
+ opj_codestream_index_t *p_cstr_index,
+ opj_event_mgr_t *p_manager
)
{
OPJ_UINT32 l_data_read;
@@ -1225,7 +1307,7 @@ OPJ_BOOL opj_tcd_decode_tile( opj_tcd_t *p_tcd,
/*--------------TIER2------------------*/
/* FIXME _ProfStart(PGROUP_T2); */
l_data_read = 0;
- if (! opj_tcd_t2_decode(p_tcd, p_src, &l_data_read, p_max_length, p_cstr_index))
+ if (! opj_tcd_t2_decode(p_tcd, p_src, &l_data_read, p_max_length, p_cstr_index, p_manager))
{
return OPJ_FALSE;
}
@@ -1254,7 +1336,7 @@ OPJ_BOOL opj_tcd_decode_tile( opj_tcd_t *p_tcd,
/*----------------MCT-------------------*/
/* FIXME _ProfStart(PGROUP_MCT); */
if
- (! opj_tcd_mct_decode(p_tcd))
+ (! opj_tcd_mct_decode(p_tcd, p_manager))
{
return OPJ_FALSE;
}
@@ -1388,7 +1470,7 @@ OPJ_BOOL opj_tcd_update_tile_data ( opj_tcd_t *p_tcd,
-void opj_tcd_free_tile(opj_tcd_t *p_tcd)
+static void opj_tcd_free_tile(opj_tcd_t *p_tcd)
{
OPJ_UINT32 compno, resno, bandno, precno;
opj_tcd_tile_t *l_tile = 00;
@@ -1454,9 +1536,12 @@ void opj_tcd_free_tile(opj_tcd_t *p_tcd)
l_tile_comp->resolutions = 00;
}
- if (l_tile_comp->data) {
- opj_free(l_tile_comp->data);
+ if (l_tile_comp->ownsData && l_tile_comp->data) {
+ opj_aligned_free(l_tile_comp->data);
l_tile_comp->data = 00;
+ l_tile_comp->ownsData = 0;
+ l_tile_comp->data_size = 0;
+ l_tile_comp->data_size_needed = 0;
}
++l_tile_comp;
}
@@ -1468,11 +1553,12 @@ void opj_tcd_free_tile(opj_tcd_t *p_tcd)
}
-OPJ_BOOL opj_tcd_t2_decode (opj_tcd_t *p_tcd,
+static OPJ_BOOL opj_tcd_t2_decode (opj_tcd_t *p_tcd,
OPJ_BYTE * p_src_data,
OPJ_UINT32 * p_data_read,
OPJ_UINT32 p_max_src_size,
- opj_codestream_index_t *p_cstr_index
+ opj_codestream_index_t *p_cstr_index,
+ opj_event_mgr_t *p_manager
)
{
opj_t2_t * l_t2;
@@ -1489,7 +1575,8 @@ OPJ_BOOL opj_tcd_t2_decode (opj_tcd_t *p_tcd,
p_src_data,
p_data_read,
p_max_src_size,
- p_cstr_index)) {
+ p_cstr_index,
+ p_manager)) {
opj_t2_destroy(l_t2);
return OPJ_FALSE;
}
@@ -1500,37 +1587,29 @@ OPJ_BOOL opj_tcd_t2_decode (opj_tcd_t *p_tcd,
return OPJ_TRUE;
}
-OPJ_BOOL opj_tcd_t1_decode ( opj_tcd_t *p_tcd )
+static OPJ_BOOL opj_tcd_t1_decode ( opj_tcd_t *p_tcd )
{
OPJ_UINT32 compno;
- opj_t1_t * l_t1;
opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
opj_tcd_tilecomp_t* l_tile_comp = l_tile->comps;
opj_tccp_t * l_tccp = p_tcd->tcp->tccps;
-
-
- l_t1 = opj_t1_create();
- if (l_t1 == 00) {
- return OPJ_FALSE;
- }
+ volatile OPJ_BOOL ret = OPJ_TRUE;
for (compno = 0; compno < l_tile->numcomps; ++compno) {
- /* The +3 is headroom required by the vectorized DWT */
- if (OPJ_FALSE == opj_t1_decode_cblks(l_t1, l_tile_comp, l_tccp)) {
- opj_t1_destroy(l_t1);
- return OPJ_FALSE;
- }
+ opj_t1_decode_cblks(p_tcd->thread_pool, &ret, l_tile_comp, l_tccp);
+ if( !ret )
+ break;
++l_tile_comp;
++l_tccp;
}
- opj_t1_destroy(l_t1);
+ opj_thread_pool_wait_completion(p_tcd->thread_pool, 0);
- return OPJ_TRUE;
+ return ret;
}
-OPJ_BOOL opj_tcd_dwt_decode ( opj_tcd_t *p_tcd )
+static OPJ_BOOL opj_tcd_dwt_decode ( opj_tcd_t *p_tcd )
{
OPJ_UINT32 compno;
opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
@@ -1553,7 +1632,7 @@ OPJ_BOOL opj_tcd_dwt_decode ( opj_tcd_t *p_tcd )
*/
if (l_tccp->qmfbid == 1) {
- if (! opj_dwt_decode(l_tile_comp, l_img_comp->resno_decoded+1)) {
+ if (! opj_dwt_decode(p_tcd->thread_pool, l_tile_comp, l_img_comp->resno_decoded+1)) {
return OPJ_FALSE;
}
}
@@ -1570,7 +1649,7 @@ OPJ_BOOL opj_tcd_dwt_decode ( opj_tcd_t *p_tcd )
return OPJ_TRUE;
}
-OPJ_BOOL opj_tcd_mct_decode ( opj_tcd_t *p_tcd )
+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;
@@ -1588,7 +1667,7 @@ OPJ_BOOL opj_tcd_mct_decode ( opj_tcd_t *p_tcd )
if ((l_tile->comps[0].x1 - l_tile->comps[0].x0) * (l_tile->comps[0].y1 - l_tile->comps[0].y0) < (OPJ_INT32)l_samples ||
(l_tile->comps[1].x1 - l_tile->comps[1].x0) * (l_tile->comps[1].y1 - l_tile->comps[1].y0) < (OPJ_INT32)l_samples ||
(l_tile->comps[2].x1 - l_tile->comps[2].x0) * (l_tile->comps[2].y1 - l_tile->comps[2].y0) < (OPJ_INT32)l_samples) {
- fprintf(stderr, "Tiles don't all have the same dimension. Skip the MCT step.\n");
+ opj_event_msg(p_manager, EVT_ERROR, "Tiles don't all have the same dimension. Skip the MCT step.\n");
return OPJ_FALSE;
}
else if (l_tcp->mct == 2) {
@@ -1640,15 +1719,14 @@ OPJ_BOOL opj_tcd_mct_decode ( opj_tcd_t *p_tcd )
}
}
else {
- /* FIXME need to use opj_event_msg function */
- fprintf(stderr,"Number of components (%d) is inconsistent with a MCT. Skip the MCT step.\n",l_tile->numcomps);
+ opj_event_msg(p_manager, EVT_ERROR, "Number of components (%d) is inconsistent with a MCT. Skip the MCT step.\n",l_tile->numcomps);
}
return OPJ_TRUE;
}
-OPJ_BOOL opj_tcd_dc_level_shift_decode ( opj_tcd_t *p_tcd )
+static OPJ_BOOL opj_tcd_dc_level_shift_decode ( opj_tcd_t *p_tcd )
{
OPJ_UINT32 compno;
opj_tcd_tilecomp_t * l_tile_comp = 00;
@@ -1698,7 +1776,7 @@ OPJ_BOOL opj_tcd_dc_level_shift_decode ( opj_tcd_t *p_tcd )
for (j=0;j<l_height;++j) {
for (i = 0; i < l_width; ++i) {
OPJ_FLOAT32 l_value = *((OPJ_FLOAT32 *) l_current_ptr);
- *l_current_ptr = opj_int_clamp((OPJ_INT32)lrintf(l_value) + l_tccp->m_dc_level_shift, l_min, l_max); ;
+ *l_current_ptr = opj_int_clamp((OPJ_INT32)opj_lrintf(l_value) + l_tccp->m_dc_level_shift, l_min, l_max); ;
++l_current_ptr;
}
l_current_ptr += l_stride;
@@ -1718,7 +1796,7 @@ OPJ_BOOL opj_tcd_dc_level_shift_decode ( opj_tcd_t *p_tcd )
/**
* Deallocates the encoding data of the given precinct.
*/
-void opj_tcd_code_block_dec_deallocate (opj_tcd_precinct_t * p_precinct)
+static void opj_tcd_code_block_dec_deallocate (opj_tcd_precinct_t * p_precinct)
{
OPJ_UINT32 cblkno , l_nb_code_blocks;
@@ -1756,7 +1834,7 @@ void opj_tcd_code_block_dec_deallocate (opj_tcd_precinct_t * p_precinct)
/**
* Deallocates the encoding data of the given precinct.
*/
-void opj_tcd_code_block_enc_deallocate (opj_tcd_precinct_t * p_precinct)
+static void opj_tcd_code_block_enc_deallocate (opj_tcd_precinct_t * p_precinct)
{
OPJ_UINT32 cblkno , l_nb_code_blocks;
@@ -1817,7 +1895,7 @@ OPJ_UINT32 opj_tcd_get_encoded_tile_size ( opj_tcd_t *p_tcd )
return l_data_size;
}
-OPJ_BOOL opj_tcd_dc_level_shift_encode ( opj_tcd_t *p_tcd )
+static OPJ_BOOL opj_tcd_dc_level_shift_encode ( opj_tcd_t *p_tcd )
{
OPJ_UINT32 compno;
opj_tcd_tilecomp_t * l_tile_comp = 00;
@@ -1844,7 +1922,7 @@ 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) << 11 ;
+ *l_current_ptr = (*l_current_ptr - l_tccp->m_dc_level_shift) * (1 << 11);
++l_current_ptr;
}
}
@@ -1857,7 +1935,7 @@ OPJ_BOOL opj_tcd_dc_level_shift_encode ( opj_tcd_t *p_tcd )
return OPJ_TRUE;
}
-OPJ_BOOL opj_tcd_mct_encode ( opj_tcd_t *p_tcd )
+static OPJ_BOOL opj_tcd_mct_encode ( opj_tcd_t *p_tcd )
{
opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
opj_tcd_tilecomp_t * l_tile_comp = p_tcd->tcd_image->tiles->comps;
@@ -1912,7 +1990,7 @@ OPJ_BOOL opj_tcd_mct_encode ( opj_tcd_t *p_tcd )
return OPJ_TRUE;
}
-OPJ_BOOL opj_tcd_dwt_encode ( opj_tcd_t *p_tcd )
+static OPJ_BOOL opj_tcd_dwt_encode ( opj_tcd_t *p_tcd )
{
opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
opj_tcd_tilecomp_t * l_tile_comp = p_tcd->tcd_image->tiles->comps;
@@ -1938,18 +2016,20 @@ OPJ_BOOL opj_tcd_dwt_encode ( opj_tcd_t *p_tcd )
return OPJ_TRUE;
}
-OPJ_BOOL opj_tcd_t1_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();
+ 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 */
if (l_tcp->tccps->qmfbid == 0) {
l_mct_norms = opj_mct_get_mct_norms_real();
@@ -1959,10 +2039,11 @@ OPJ_BOOL opj_tcd_t1_encode ( opj_tcd_t *p_tcd )
}
}
else {
+ l_mct_numcomps = p_tcd->image->numcomps;
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)) {
+ 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;
}
@@ -1972,7 +2053,7 @@ OPJ_BOOL opj_tcd_t1_encode ( opj_tcd_t *p_tcd )
return OPJ_TRUE;
}
-OPJ_BOOL opj_tcd_t2_encode (opj_tcd_t *p_tcd,
+static OPJ_BOOL opj_tcd_t2_encode (opj_tcd_t *p_tcd,
OPJ_BYTE * p_dest_data,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 p_max_dest_size,
@@ -2010,7 +2091,7 @@ OPJ_BOOL opj_tcd_t2_encode (opj_tcd_t *p_tcd,
}
-OPJ_BOOL opj_tcd_rate_allocate_encode( opj_tcd_t *p_tcd,
+static OPJ_BOOL opj_tcd_rate_allocate_encode( opj_tcd_t *p_tcd,
OPJ_BYTE * p_dest_data,
OPJ_UINT32 p_max_dest_size,
opj_codestream_info_t *p_cstr_info )
diff --git a/openjpeg/src/lib/openjp2/tcd.h b/openjpeg/src/lib/openjp2/tcd.h
index 360923b15..76eff0057 100644
--- a/openjpeg/src/lib/openjp2/tcd.h
+++ b/openjpeg/src/lib/openjp2/tcd.h
@@ -70,7 +70,7 @@ typedef struct opj_tcd_pass {
OPJ_UINT32 rate;
OPJ_FLOAT64 distortiondec;
OPJ_UINT32 len;
- OPJ_UINT32 term : 1;
+ OPJ_BITFIELD term : 1;
} opj_tcd_pass_t;
/**
@@ -87,15 +87,16 @@ typedef struct opj_tcd_layer {
FIXME DOC
*/
typedef struct opj_tcd_cblk_enc {
- OPJ_BYTE* data; /* Data */
- opj_tcd_layer_t* layers; /* layer information */
- opj_tcd_pass_t* passes; /* information about the passes */
- OPJ_INT32 x0, y0, x1, y1; /* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
+ OPJ_BYTE* data; /* Data */
+ opj_tcd_layer_t* layers; /* layer information */
+ opj_tcd_pass_t* passes; /* information about the passes */
+ OPJ_INT32 x0, y0, x1, y1; /* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
OPJ_UINT32 numbps;
OPJ_UINT32 numlenbits;
- OPJ_UINT32 numpasses; /* number of pass already done for the code-blocks */
- OPJ_UINT32 numpassesinlayers; /* number of passes in the layer */
- OPJ_UINT32 totalpasses; /* total number of passes */
+ OPJ_UINT32 data_size; /* Size of allocated data buffer */
+ OPJ_UINT32 numpasses; /* number of pass already done for the code-blocks */
+ OPJ_UINT32 numpassesinlayers; /* number of passes in the layer */
+ OPJ_UINT32 totalpasses; /* total number of passes */
} opj_tcd_cblk_enc_t;
@@ -105,7 +106,7 @@ typedef struct opj_tcd_cblk_dec {
OPJ_INT32 x0, y0, x1, y1; /* position of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
OPJ_UINT32 numbps;
OPJ_UINT32 numlenbits;
- OPJ_UINT32 data_max_size; /* Size of allocated data buffer */
+ OPJ_UINT32 data_max_size; /* Size of allocated data buffer */
OPJ_UINT32 data_current_size; /* Size of used data buffer */
OPJ_UINT32 numnewpasses; /* number of pass added to the code-blocks */
OPJ_UINT32 numsegs; /* number of segments */
@@ -122,6 +123,7 @@ typedef struct opj_tcd_precinct {
union{ /* code-blocks information */
opj_tcd_cblk_enc_t* enc;
opj_tcd_cblk_dec_t* dec;
+ void* blocks;
} cblks;
OPJ_UINT32 block_size; /* size taken by cblks (in bytes) */
opj_tgt_tree_t *incltree; /* inclusion tree */
@@ -155,14 +157,16 @@ FIXME DOC
*/
typedef struct opj_tcd_tilecomp
{
- OPJ_INT32 x0, y0, x1, y1; /* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */
- OPJ_UINT32 numresolutions; /* number of resolutions level */
- OPJ_UINT32 minimum_num_resolutions; /* number of resolutions level to decode (at max)*/
- opj_tcd_resolution_t *resolutions; /* resolutions information */
- OPJ_UINT32 resolutions_size; /* size of data for resolutions (in bytes) */
- OPJ_INT32 *data; /* data of the component */
- OPJ_UINT32 data_size; /* size of the data of the component */
- OPJ_INT32 numpix; /* add fixed_quality */
+ OPJ_INT32 x0, y0, x1, y1; /* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */
+ OPJ_UINT32 numresolutions; /* number of resolutions level */
+ OPJ_UINT32 minimum_num_resolutions; /* number of resolutions level to decode (at max)*/
+ opj_tcd_resolution_t *resolutions; /* resolutions information */
+ OPJ_UINT32 resolutions_size; /* size of data for resolutions (in bytes) */
+ OPJ_INT32 *data; /* data of the component */
+ OPJ_BOOL ownsData; /* if true, then need to free after usage, otherwise do not free */
+ OPJ_UINT32 data_size_needed; /* we may either need to allocate this amount of data, or re-use image data and ignore this value */
+ OPJ_UINT32 data_size; /* size of the data of the component */
+ OPJ_INT32 numpix; /* add fixed_quality */
} opj_tcd_tilecomp_t;
@@ -215,7 +219,9 @@ typedef struct opj_tcd
/** current encoded/decoded tile */
OPJ_UINT32 tcd_tileno;
/** tell if the tcd is a decoder. */
- OPJ_UINT32 m_is_decoder : 1;
+ OPJ_BITFIELD m_is_decoder : 1;
+ /** Thread pool */
+ opj_thread_pool_t* thread_pool;
} opj_tcd_t;
/** @name Exported functions */
@@ -245,12 +251,14 @@ void opj_tcd_destroy(opj_tcd_t *tcd);
* @param p_tcd TCD handle.
* @param p_image raw image.
* @param p_cp coding parameters.
+ * @param p_tp thread pool
*
* @return true if the encoding values could be set (false otherwise).
*/
OPJ_BOOL opj_tcd_init( opj_tcd_t *p_tcd,
opj_image_t * p_image,
- opj_cp_t * p_cp );
+ opj_cp_t * p_cp,
+ opj_thread_pool_t* p_tp);
/**
* Allocates memory for decoding a specific tile.
@@ -258,10 +266,11 @@ OPJ_BOOL opj_tcd_init( opj_tcd_t *p_tcd,
* @param p_tcd the tile decoder.
* @param p_tile_no the index of the tile received in sequence. This not necessarily lead to the
* tile at index p_tile_no.
+ * @param p_manager the event manager.
*
* @return true if the remaining data is sufficient.
*/
-OPJ_BOOL opj_tcd_init_decode_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no);
+OPJ_BOOL opj_tcd_init_decode_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, opj_event_mgr_t* p_manager);
void opj_tcd_makelayer_fixed(opj_tcd_t *tcd, OPJ_UINT32 layno, OPJ_UINT32 final);
@@ -291,7 +300,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
- * @return true if the coding is successfull.
+ * @return true if the coding is successful.
*/
OPJ_BOOL opj_tcd_encode_tile( opj_tcd_t *p_tcd,
OPJ_UINT32 p_tile_no,
@@ -308,12 +317,14 @@ Decode a tile from a buffer into a raw image
@param len Length of source buffer
@param tileno Number that identifies one of the tiles to be decoded
@param cstr_info FIXME DOC
+@param manager the event manager.
*/
OPJ_BOOL opj_tcd_decode_tile( opj_tcd_t *tcd,
OPJ_BYTE *src,
OPJ_UINT32 len,
OPJ_UINT32 tileno,
- opj_codestream_index_t *cstr_info);
+ opj_codestream_index_t *cstr_info,
+ opj_event_mgr_t *manager);
/**
@@ -333,11 +344,12 @@ OPJ_UINT32 opj_tcd_get_encoded_tile_size ( opj_tcd_t *p_tcd );
*
* @param p_tcd TCD handle.
* @param p_tile_no current tile index to encode.
+ * @param p_manager the event manager.
*
* @return true if the encoding values could be set (false otherwise).
*/
OPJ_BOOL opj_tcd_init_encode_tile ( opj_tcd_t *p_tcd,
- OPJ_UINT32 p_tile_no );
+ OPJ_UINT32 p_tile_no, opj_event_mgr_t* p_manager );
/**
* Copies tile data from the given memory block onto the system.
@@ -346,6 +358,13 @@ OPJ_BOOL opj_tcd_copy_tile_data (opj_tcd_t *p_tcd,
OPJ_BYTE * p_src,
OPJ_UINT32 p_src_length );
+/**
+ * Allocates tile component data
+ *
+ *
+ */
+OPJ_BOOL opj_alloc_tile_component_data(opj_tcd_tilecomp_t *l_tilec);
+
/* ----------------------------------------------------------------------- */
/*@}*/
diff --git a/openjpeg/src/lib/openjp2/tgt.c b/openjpeg/src/lib/openjp2/tgt.c
index e77adb3bb..5e34aa912 100644
--- a/openjpeg/src/lib/openjp2/tgt.c
+++ b/openjpeg/src/lib/openjp2/tgt.c
@@ -45,7 +45,7 @@
==========================================================
*/
-opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv) {
+opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv, opj_event_mgr_t *manager) {
OPJ_INT32 nplh[32];
OPJ_INT32 nplv[32];
opj_tgt_node_t *node = 00;
@@ -57,12 +57,11 @@ opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv) {
OPJ_UINT32 numlvls;
OPJ_UINT32 n;
- tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t));
+ tree = (opj_tgt_tree_t *) opj_calloc(1,sizeof(opj_tgt_tree_t));
if(!tree) {
- fprintf(stderr, "ERROR in tgt_create while allocating tree\n");
+ opj_event_msg(manager, EVT_ERROR, "Not enough memory to create Tag-tree\n");
return 00;
}
- memset(tree,0,sizeof(opj_tgt_tree_t));
tree->numleafsh = numleafsh;
tree->numleafsv = numleafsv;
@@ -82,17 +81,16 @@ opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv) {
/* ADD */
if (tree->numnodes == 0) {
opj_free(tree);
- fprintf(stderr, "WARNING in tgt_create tree->numnodes == 0, no tree created.\n");
+ opj_event_msg(manager, EVT_WARNING, "tgt_create tree->numnodes == 0, no tree created.\n");
return 00;
}
tree->nodes = (opj_tgt_node_t*) opj_calloc(tree->numnodes, sizeof(opj_tgt_node_t));
if(!tree->nodes) {
- fprintf(stderr, "ERROR in tgt_create while allocating node of the tree\n");
+ opj_event_msg(manager, EVT_ERROR, "Not enough memory to create Tag-tree nodes\n");
opj_free(tree);
return 00;
}
- memset(tree->nodes,0,tree->numnodes * sizeof(opj_tgt_node_t));
tree->nodes_size = tree->numnodes * (OPJ_UINT32)sizeof(opj_tgt_node_t);
node = tree->nodes;
@@ -132,7 +130,7 @@ opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv) {
* @param p_num_leafs_v the height of the array of leafs of the tree
* @return a new tag-tree if successful, NULL otherwise
*/
-opj_tgt_tree_t *opj_tgt_init(opj_tgt_tree_t * p_tree,OPJ_UINT32 p_num_leafs_h, OPJ_UINT32 p_num_leafs_v)
+opj_tgt_tree_t *opj_tgt_init(opj_tgt_tree_t * p_tree,OPJ_UINT32 p_num_leafs_h, OPJ_UINT32 p_num_leafs_v, opj_event_mgr_t *p_manager)
{
OPJ_INT32 l_nplh[32];
OPJ_INT32 l_nplv[32];
@@ -177,7 +175,7 @@ opj_tgt_tree_t *opj_tgt_init(opj_tgt_tree_t * p_tree,OPJ_UINT32 p_num_leafs_h, O
if (l_node_size > p_tree->nodes_size) {
opj_tgt_node_t* new_nodes = (opj_tgt_node_t*) opj_realloc(p_tree->nodes, l_node_size);
if (! new_nodes) {
- fprintf(stderr, "ERROR Not enough memory to reinitialize the tag tree\n");
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to reinitialize the tag tree\n");
opj_tgt_destroy(p_tree);
return 00;
}
diff --git a/openjpeg/src/lib/openjp2/tgt.h b/openjpeg/src/lib/openjp2/tgt.h
index 3d152f8a9..102238052 100644
--- a/openjpeg/src/lib/openjp2/tgt.h
+++ b/openjpeg/src/lib/openjp2/tgt.h
@@ -83,7 +83,7 @@ Create a tag-tree
@param numleafsv Height of the array of leafs of the tree
@return Returns a new tag-tree if successful, returns NULL otherwise
*/
-opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv);
+opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv, opj_event_mgr_t *manager);
/**
* Reinitialises a tag-tree from an exixting one.
@@ -91,11 +91,12 @@ opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv);
* @param p_tree the tree to reinitialize.
* @param p_num_leafs_h the width of the array of leafs of the tree
* @param p_num_leafs_v the height of the array of leafs of the tree
+ * @param p_manager the event manager
* @return a new tag-tree if successful, NULL otherwise
*/
opj_tgt_tree_t *opj_tgt_init(opj_tgt_tree_t * p_tree,
OPJ_UINT32 p_num_leafs_h,
- OPJ_UINT32 p_num_leafs_v);
+ OPJ_UINT32 p_num_leafs_v, opj_event_mgr_t *p_manager);
/**
Destroy a tag-tree, liberating memory
@param tree Tag-tree to destroy
diff --git a/openjpeg/src/lib/openjp2/thix_manager.c b/openjpeg/src/lib/openjp2/thix_manager.c
index 0967b1e9a..0bd798979 100644
--- a/openjpeg/src/lib/openjp2/thix_manager.c
+++ b/openjpeg/src/lib/openjp2/thix_manager.c
@@ -49,7 +49,9 @@ int opj_write_thix( int coff, opj_codestream_info_t cstr_info, opj_stream_privat
lenp = 0;
box = (opj_jp2_box_t *)opj_calloc( (size_t)(cstr_info.tw*cstr_info.th), sizeof(opj_jp2_box_t));
-
+ if(box == NULL){
+ return 0;
+ }
for ( i = 0; i < 2 ; i++ ){
if (i)
opj_stream_seek( cio, lenp, p_manager);
diff --git a/openjpeg/src/lib/openjp2/thread.c b/openjpeg/src/lib/openjp2/thread.c
new file mode 100644
index 000000000..79a9d5fb4
--- /dev/null
+++ b/openjpeg/src/lib/openjp2/thread.c
@@ -0,0 +1,968 @@
+/*
+ * The copyright in this software is being made available under the 2-clauses
+ * BSD License, included below. This software may be subject to other third
+ * party and contributor rights, including patent rights, and no such rights
+ * are granted under this license.
+ *
+ * Copyright (c) 2016, Even Rouault
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+#include "thread.h"
+#include <assert.h>
+
+#ifdef MUTEX_win32
+
+/* Some versions of x86_64-w64-mingw32-gc -m32 resolve InterlockedCompareExchange() */
+/* as __sync_val_compare_and_swap_4 but fails to link it. As this protects against */
+/* a rather unlikely race, skip it */
+#if !(defined(__MINGW32__) && defined(__i386__))
+#define HAVE_INTERLOCKED_COMPARE_EXCHANGE 1
+#endif
+
+#include <windows.h>
+#include <process.h>
+
+OPJ_BOOL OPJ_CALLCONV opj_has_thread_support(void)
+{
+ return OPJ_TRUE;
+}
+
+int OPJ_CALLCONV opj_get_num_cpus(void)
+{
+ SYSTEM_INFO info;
+ DWORD dwNum;
+ GetSystemInfo(&info);
+ dwNum = info.dwNumberOfProcessors;
+ if( dwNum < 1 )
+ return 1;
+ return (int)dwNum;
+}
+
+struct opj_mutex_t
+{
+ CRITICAL_SECTION cs;
+};
+
+opj_mutex_t* opj_mutex_create(void)
+{
+ opj_mutex_t* mutex = (opj_mutex_t*) opj_malloc(sizeof(opj_mutex_t));
+ if( !mutex )
+ return NULL;
+ InitializeCriticalSectionAndSpinCount(&(mutex->cs), 4000);
+ return mutex;
+}
+
+void opj_mutex_lock(opj_mutex_t* mutex)
+{
+ EnterCriticalSection( &(mutex->cs) );
+}
+
+void opj_mutex_unlock(opj_mutex_t* mutex)
+{
+ LeaveCriticalSection( &(mutex->cs) );
+}
+
+void opj_mutex_destroy(opj_mutex_t* mutex)
+{
+ if( !mutex ) return;
+ DeleteCriticalSection( &(mutex->cs) );
+ opj_free( mutex );
+}
+
+struct opj_cond_waiter_list_t
+{
+ HANDLE hEvent;
+ struct opj_cond_waiter_list_t* next;
+};
+typedef struct opj_cond_waiter_list_t opj_cond_waiter_list_t;
+
+struct opj_cond_t
+{
+ opj_mutex_t *internal_mutex;
+ opj_cond_waiter_list_t *waiter_list;
+};
+
+static DWORD TLSKey = 0;
+static volatile LONG inTLSLockedSection = 0;
+static volatile int TLSKeyInit = OPJ_FALSE;
+
+opj_cond_t* opj_cond_create(void)
+{
+ opj_cond_t* cond = (opj_cond_t*) opj_malloc(sizeof(opj_cond_t));
+ if( !cond )
+ return NULL;
+
+ /* Make sure that the TLS key is allocated in a thread-safe way */
+ /* We cannot use a global mutex/critical section since its creation itself would not be */
+ /* thread-safe, so use InterlockedCompareExchange trick */
+ while( OPJ_TRUE )
+ {
+
+#if HAVE_INTERLOCKED_COMPARE_EXCHANGE
+ if( InterlockedCompareExchange(&inTLSLockedSection, 1, 0) == 0 )
+#endif
+ {
+ if( !TLSKeyInit )
+ {
+ TLSKey = TlsAlloc();
+ TLSKeyInit = OPJ_TRUE;
+ }
+#if HAVE_INTERLOCKED_COMPARE_EXCHANGE
+ InterlockedCompareExchange(&inTLSLockedSection, 0, 1);
+#endif
+ break;
+ }
+ }
+
+ if( TLSKey == TLS_OUT_OF_INDEXES )
+ {
+ opj_free(cond);
+ return NULL;
+ }
+ cond->internal_mutex = opj_mutex_create();
+ if (cond->internal_mutex == NULL)
+ {
+ opj_free(cond);
+ return NULL;
+ }
+ cond->waiter_list = NULL;
+ return cond;
+}
+
+void opj_cond_wait(opj_cond_t* cond, opj_mutex_t* mutex)
+{
+ opj_cond_waiter_list_t* item;
+ HANDLE hEvent = (HANDLE) TlsGetValue( TLSKey );
+ if (hEvent == NULL)
+ {
+ hEvent = CreateEvent(NULL, /* security attributes */
+ 0, /* manual reset = no */
+ 0, /* initial state = unsignaled */
+ NULL /* no name */);
+ assert(hEvent);
+
+ TlsSetValue( TLSKey, hEvent );
+ }
+
+ /* Insert the waiter into the waiter list of the condition */
+ opj_mutex_lock(cond->internal_mutex);
+
+ item = (opj_cond_waiter_list_t*)opj_malloc(sizeof(opj_cond_waiter_list_t));
+ assert(item != NULL);
+
+ item->hEvent = hEvent;
+ item->next = cond->waiter_list;
+
+ cond->waiter_list = item;
+
+ opj_mutex_unlock(cond->internal_mutex);
+
+ /* Release the client mutex before waiting for the event being signaled */
+ opj_mutex_unlock(mutex);
+
+ /* Ideally we would check that we do not get WAIT_FAILED but it is hard */
+ /* to report a failure. */
+ WaitForSingleObject(hEvent, INFINITE);
+
+ /* Reacquire the client mutex */
+ opj_mutex_lock(mutex);
+}
+
+void opj_cond_signal(opj_cond_t* cond)
+{
+ opj_cond_waiter_list_t* psIter;
+
+ /* Signal the first registered event, and remove it from the list */
+ opj_mutex_lock(cond->internal_mutex);
+
+ psIter = cond->waiter_list;
+ if (psIter != NULL)
+ {
+ SetEvent(psIter->hEvent);
+ cond->waiter_list = psIter->next;
+ opj_free(psIter);
+ }
+
+ opj_mutex_unlock(cond->internal_mutex);
+}
+
+void opj_cond_destroy(opj_cond_t* cond)
+{
+ if( !cond ) return;
+ opj_mutex_destroy(cond->internal_mutex);
+ assert(cond->waiter_list == NULL);
+ opj_free(cond);
+}
+
+struct opj_thread_t
+{
+ opj_thread_fn thread_fn;
+ void* user_data;
+ HANDLE hThread;
+};
+
+unsigned int __stdcall opj_thread_callback_adapter( void *info )
+{
+ opj_thread_t* thread = (opj_thread_t*) info;
+ HANDLE hEvent = NULL;
+
+ thread->thread_fn( thread->user_data );
+
+ /* Free the handle possible allocated by a cond */
+ while( OPJ_TRUE )
+ {
+ /* Make sure TLSKey is not being created just at that moment... */
+#if HAVE_INTERLOCKED_COMPARE_EXCHANGE
+ if( InterlockedCompareExchange(&inTLSLockedSection, 1, 0) == 0 )
+#endif
+ {
+ if( TLSKeyInit )
+ {
+ hEvent = (HANDLE) TlsGetValue( TLSKey );
+ }
+#if HAVE_INTERLOCKED_COMPARE_EXCHANGE
+ InterlockedCompareExchange(&inTLSLockedSection, 0, 1);
+#endif
+ break;
+ }
+ }
+ if( hEvent )
+ CloseHandle(hEvent);
+
+ return 0;
+}
+
+opj_thread_t* opj_thread_create( opj_thread_fn thread_fn, void* user_data )
+{
+ opj_thread_t* thread;
+
+ assert( thread_fn );
+
+ thread = (opj_thread_t*) opj_malloc( sizeof(opj_thread_t) );
+ if( !thread )
+ return NULL;
+ thread->thread_fn = thread_fn;
+ thread->user_data = user_data;
+
+ thread->hThread = (HANDLE)_beginthreadex(NULL, 0,
+ opj_thread_callback_adapter, thread, 0, NULL);
+
+ if( thread->hThread == NULL )
+ {
+ opj_free( thread );
+ return NULL;
+ }
+ return thread;
+}
+
+void opj_thread_join( opj_thread_t* thread )
+{
+ WaitForSingleObject(thread->hThread, INFINITE);
+ CloseHandle( thread->hThread );
+
+ opj_free(thread);
+}
+
+#elif MUTEX_pthread
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+OPJ_BOOL OPJ_CALLCONV opj_has_thread_support(void)
+{
+ return OPJ_TRUE;
+}
+
+int OPJ_CALLCONV opj_get_num_cpus(void)
+{
+#ifdef _SC_NPROCESSORS_ONLN
+ return (int)sysconf(_SC_NPROCESSORS_ONLN);
+#else
+ return 1;
+#endif
+}
+
+struct opj_mutex_t
+{
+ pthread_mutex_t mutex;
+};
+
+opj_mutex_t* opj_mutex_create(void)
+{
+ opj_mutex_t* mutex = (opj_mutex_t*) opj_calloc(1U, sizeof(opj_mutex_t));
+ if( mutex != NULL ) {
+ if ( pthread_mutex_init(&mutex->mutex, NULL) != 0) {
+ opj_free(mutex);
+ mutex = NULL;
+ }
+ }
+ return mutex;
+}
+
+void opj_mutex_lock(opj_mutex_t* mutex)
+{
+ pthread_mutex_lock(&(mutex->mutex));
+}
+
+void opj_mutex_unlock(opj_mutex_t* mutex)
+{
+ pthread_mutex_unlock(&(mutex->mutex));
+}
+
+void opj_mutex_destroy(opj_mutex_t* mutex)
+{
+ if( !mutex ) return;
+ pthread_mutex_destroy(&(mutex->mutex));
+ opj_free(mutex);
+}
+
+struct opj_cond_t
+{
+ pthread_cond_t cond;
+};
+
+opj_cond_t* opj_cond_create(void)
+{
+ opj_cond_t* cond = (opj_cond_t*) opj_malloc(sizeof(opj_cond_t));
+ if( !cond )
+ return NULL;
+ if( pthread_cond_init(&(cond->cond), NULL) != 0 )
+ {
+ opj_free(cond);
+ return NULL;
+ }
+ return cond;
+}
+
+void opj_cond_wait(opj_cond_t* cond, opj_mutex_t* mutex)
+{
+ pthread_cond_wait(&(cond->cond), &(mutex->mutex));
+}
+
+void opj_cond_signal(opj_cond_t* cond)
+{
+ int ret = pthread_cond_signal(&(cond->cond));
+ (void)ret;
+ assert(ret == 0);
+}
+
+void opj_cond_destroy(opj_cond_t* cond)
+{
+ if( !cond ) return;
+ pthread_cond_destroy(&(cond->cond));
+ opj_free(cond);
+}
+
+
+struct opj_thread_t
+{
+ opj_thread_fn thread_fn;
+ void* user_data;
+ pthread_t thread;
+};
+
+static void* opj_thread_callback_adapter( void* info )
+{
+ opj_thread_t* thread = (opj_thread_t*) info;
+ thread->thread_fn( thread->user_data );
+ return NULL;
+}
+
+opj_thread_t* opj_thread_create( opj_thread_fn thread_fn, void* user_data )
+{
+ pthread_attr_t attr;
+ opj_thread_t* thread;
+
+ assert( thread_fn );
+
+ thread = (opj_thread_t*) opj_malloc( sizeof(opj_thread_t) );
+ if( !thread )
+ return NULL;
+ thread->thread_fn = thread_fn;
+ thread->user_data = user_data;
+
+ pthread_attr_init( &attr );
+ pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE );
+ if( pthread_create( &(thread->thread), &attr,
+ opj_thread_callback_adapter, (void *) thread ) != 0 )
+ {
+ opj_free( thread );
+ return NULL;
+ }
+ return thread;
+}
+
+void opj_thread_join( opj_thread_t* thread )
+{
+ void* status;
+ pthread_join( thread->thread, &status);
+
+ opj_free(thread);
+}
+
+#else
+/* Stub implementation */
+
+OPJ_BOOL OPJ_CALLCONV opj_has_thread_support(void)
+{
+ return OPJ_FALSE;
+}
+
+int OPJ_CALLCONV opj_get_num_cpus(void)
+{
+ return 1;
+}
+
+opj_mutex_t* opj_mutex_create(void)
+{
+ return NULL;
+}
+
+void opj_mutex_lock(opj_mutex_t* mutex)
+{
+ (void) mutex;
+}
+
+void opj_mutex_unlock(opj_mutex_t* mutex)
+{
+ (void) mutex;
+}
+
+void opj_mutex_destroy(opj_mutex_t* mutex)
+{
+ (void) mutex;
+}
+
+opj_cond_t* opj_cond_create(void)
+{
+ return NULL;
+}
+
+void opj_cond_wait(opj_cond_t* cond, opj_mutex_t* mutex)
+{
+ (void) cond;
+ (void) mutex;
+}
+
+void opj_cond_signal(opj_cond_t* cond)
+{
+ (void) cond;
+}
+
+void opj_cond_destroy(opj_cond_t* cond)
+{
+ (void) cond;
+}
+
+opj_thread_t* opj_thread_create( opj_thread_fn thread_fn, void* user_data )
+{
+ (void) thread_fn;
+ (void) user_data;
+ return NULL;
+}
+
+void opj_thread_join( opj_thread_t* thread )
+{
+ (void) thread;
+}
+
+#endif
+
+typedef struct
+{
+ int key;
+ void* value;
+ opj_tls_free_func opj_free_func;
+} opj_tls_key_val_t;
+
+struct opj_tls_t
+{
+ opj_tls_key_val_t* key_val;
+ int key_val_count;
+};
+
+static opj_tls_t* opj_tls_new(void)
+{
+ return (opj_tls_t*) opj_calloc(1, sizeof(opj_tls_t));
+}
+
+static void opj_tls_destroy(opj_tls_t* tls)
+{
+ int i;
+ if( !tls ) return;
+ for(i=0;i<tls->key_val_count;i++)
+ {
+ if( tls->key_val[i].opj_free_func )
+ tls->key_val[i].opj_free_func(tls->key_val[i].value);
+ }
+ opj_free(tls->key_val);
+ opj_free(tls);
+}
+
+void* opj_tls_get(opj_tls_t* tls, int key)
+{
+ int i;
+ for(i=0;i<tls->key_val_count;i++)
+ {
+ if( tls->key_val[i].key == key )
+ return tls->key_val[i].value;
+ }
+ return NULL;
+}
+
+OPJ_BOOL opj_tls_set(opj_tls_t* tls, int key, void* value, opj_tls_free_func opj_free_func)
+{
+ opj_tls_key_val_t* new_key_val;
+ int i;
+
+ if (tls->key_val_count == INT_MAX) {
+ return OPJ_FALSE;
+ }
+ for(i=0;i<tls->key_val_count;i++)
+ {
+ if( tls->key_val[i].key == key )
+ {
+ if( tls->key_val[i].opj_free_func ) {
+ tls->key_val[i].opj_free_func(tls->key_val[i].value);
+ }
+ tls->key_val[i].value = value;
+ tls->key_val[i].opj_free_func = opj_free_func;
+ return OPJ_TRUE;
+ }
+ }
+ new_key_val = (opj_tls_key_val_t*) opj_realloc( tls->key_val,
+ ((size_t)tls->key_val_count + 1U) * sizeof(opj_tls_key_val_t) );
+ if( !new_key_val )
+ return OPJ_FALSE;
+ tls->key_val = new_key_val;
+ new_key_val[tls->key_val_count].key = key;
+ new_key_val[tls->key_val_count].value = value;
+ new_key_val[tls->key_val_count].opj_free_func = opj_free_func;
+ tls->key_val_count ++;
+ return OPJ_TRUE;
+}
+
+
+typedef struct
+{
+ opj_job_fn job_fn;
+ void *user_data;
+} opj_worker_thread_job_t;
+
+typedef struct
+{
+ opj_thread_pool_t *tp;
+ opj_thread_t *thread;
+ int marked_as_waiting;
+
+ opj_mutex_t *mutex;
+ opj_cond_t *cond;
+} opj_worker_thread_t;
+
+typedef enum
+{
+ OPJWTS_OK,
+ OPJWTS_STOP,
+ OPJWTS_ERROR
+} opj_worker_thread_state;
+
+struct opj_job_list_t
+{
+ opj_worker_thread_job_t* job;
+ struct opj_job_list_t* next;
+};
+typedef struct opj_job_list_t opj_job_list_t;
+
+struct opj_worker_thread_list_t
+{
+ opj_worker_thread_t* worker_thread;
+ struct opj_worker_thread_list_t* next;
+};
+typedef struct opj_worker_thread_list_t opj_worker_thread_list_t;
+
+struct opj_thread_pool_t
+{
+ opj_worker_thread_t* worker_threads;
+ int worker_threads_count;
+ opj_cond_t* cond;
+ opj_mutex_t* mutex;
+ volatile opj_worker_thread_state state;
+ opj_job_list_t* job_queue;
+ volatile int pending_jobs_count;
+ opj_worker_thread_list_t* waiting_worker_thread_list;
+ int waiting_worker_thread_count;
+ opj_tls_t* tls;
+ int signaling_threshold;
+};
+
+static OPJ_BOOL opj_thread_pool_setup(opj_thread_pool_t* tp, int num_threads);
+static opj_worker_thread_job_t* opj_thread_pool_get_next_job(opj_thread_pool_t* tp,
+ opj_worker_thread_t* worker_thread,
+ OPJ_BOOL signal_job_finished);
+
+opj_thread_pool_t* opj_thread_pool_create(int num_threads)
+{
+ opj_thread_pool_t* tp;
+
+ tp = (opj_thread_pool_t*) opj_calloc(1, sizeof(opj_thread_pool_t));
+ if( !tp )
+ return NULL;
+ tp->state = OPJWTS_OK;
+
+ if( num_threads <= 0 )
+ {
+ tp->tls = opj_tls_new();
+ if( !tp->tls )
+ {
+ opj_free(tp);
+ tp = NULL;
+ }
+ return tp;
+ }
+
+ tp->mutex = opj_mutex_create();
+ if( !tp->mutex )
+ {
+ opj_free(tp);
+ return NULL;
+ }
+ if( !opj_thread_pool_setup(tp, num_threads) )
+ {
+ opj_thread_pool_destroy(tp);
+ return NULL;
+ }
+ return tp;
+}
+
+static void opj_worker_thread_function(void* user_data)
+{
+ opj_worker_thread_t* worker_thread;
+ opj_thread_pool_t* tp;
+ opj_tls_t* tls;
+ OPJ_BOOL job_finished = OPJ_FALSE;
+
+ worker_thread = (opj_worker_thread_t* ) user_data;
+ tp = worker_thread->tp;
+ tls = opj_tls_new();
+
+ while( OPJ_TRUE )
+ {
+ opj_worker_thread_job_t* job = opj_thread_pool_get_next_job(tp, worker_thread, job_finished);
+ if( job == NULL )
+ break;
+
+ if( job->job_fn )
+ {
+ job->job_fn(job->user_data, tls);
+ }
+ opj_free(job);
+ job_finished = OPJ_TRUE;
+ }
+
+ opj_tls_destroy(tls);
+}
+
+static OPJ_BOOL opj_thread_pool_setup(opj_thread_pool_t* tp, int num_threads)
+{
+ int i;
+ OPJ_BOOL bRet = OPJ_TRUE;
+
+ assert( num_threads > 0 );
+
+ tp->cond = opj_cond_create();
+ if( tp->cond == NULL )
+ return OPJ_FALSE;
+
+ tp->worker_threads = (opj_worker_thread_t*) opj_calloc( (size_t)num_threads,
+ sizeof(opj_worker_thread_t) );
+ if( tp->worker_threads == NULL )
+ return OPJ_FALSE;
+ tp->worker_threads_count = num_threads;
+
+ for(i=0;i<num_threads;i++)
+ {
+ tp->worker_threads[i].tp = tp;
+
+ tp->worker_threads[i].mutex = opj_mutex_create();
+ if( tp->worker_threads[i].mutex == NULL )
+ {
+ tp->worker_threads_count = i;
+ bRet = OPJ_FALSE;
+ break;
+ }
+
+ tp->worker_threads[i].cond = opj_cond_create();
+ if( tp->worker_threads[i].cond == NULL )
+ {
+ opj_mutex_destroy(tp->worker_threads[i].mutex);
+ tp->worker_threads_count = i;
+ bRet = OPJ_FALSE;
+ break;
+ }
+
+ tp->worker_threads[i].marked_as_waiting = OPJ_FALSE;
+
+ tp->worker_threads[i].thread = opj_thread_create(opj_worker_thread_function,
+ &(tp->worker_threads[i]));
+ if( tp->worker_threads[i].thread == NULL )
+ {
+ tp->worker_threads_count = i;
+ bRet = OPJ_FALSE;
+ break;
+ }
+ }
+
+ /* Wait all threads to be started */
+ /* printf("waiting for all threads to be started\n"); */
+ opj_mutex_lock(tp->mutex);
+ while( tp->waiting_worker_thread_count < num_threads )
+ {
+ opj_cond_wait(tp->cond, tp->mutex);
+ }
+ opj_mutex_unlock(tp->mutex);
+ /* printf("all threads started\n"); */
+
+ if( tp->state == OPJWTS_ERROR )
+ bRet = OPJ_FALSE;
+
+ return bRet;
+}
+
+/*
+void opj_waiting()
+{
+ printf("waiting!\n");
+}
+*/
+
+static opj_worker_thread_job_t* opj_thread_pool_get_next_job(opj_thread_pool_t* tp,
+ opj_worker_thread_t* worker_thread,
+ OPJ_BOOL signal_job_finished)
+{
+ while( OPJ_TRUE )
+ {
+ opj_job_list_t* top_job_iter;
+
+ opj_mutex_lock(tp->mutex);
+
+ if( signal_job_finished )
+ {
+ signal_job_finished = OPJ_FALSE;
+ tp->pending_jobs_count --;
+ /*printf("tp=%p, remaining jobs: %d\n", tp, tp->pending_jobs_count);*/
+ if( tp->pending_jobs_count <= tp->signaling_threshold )
+ opj_cond_signal(tp->cond);
+ }
+
+ if( tp->state == OPJWTS_STOP )
+ {
+ opj_mutex_unlock(tp->mutex);
+ return NULL;
+ }
+ top_job_iter = tp->job_queue;
+ if( top_job_iter )
+ {
+ opj_worker_thread_job_t* job;
+ tp->job_queue = top_job_iter->next;
+
+ job = top_job_iter->job;
+ opj_mutex_unlock(tp->mutex);
+ opj_free(top_job_iter);
+ return job;
+ }
+
+ /* opj_waiting(); */
+ if( !worker_thread->marked_as_waiting )
+ {
+ opj_worker_thread_list_t* item;
+
+ worker_thread->marked_as_waiting = OPJ_TRUE;
+ tp->waiting_worker_thread_count ++;
+ assert(tp->waiting_worker_thread_count <= tp->worker_threads_count);
+
+ item= (opj_worker_thread_list_t*) opj_malloc(sizeof(opj_worker_thread_list_t));
+ if( item == NULL )
+ {
+ tp->state = OPJWTS_ERROR;
+ opj_cond_signal(tp->cond);
+
+ opj_mutex_unlock(tp->mutex);
+ return NULL;
+ }
+
+ item->worker_thread = worker_thread;
+ item->next = tp->waiting_worker_thread_list;
+ tp->waiting_worker_thread_list = item;
+ }
+
+ /* printf("signaling that worker thread is ready\n"); */
+ opj_cond_signal(tp->cond);
+
+ opj_mutex_lock(worker_thread->mutex);
+ opj_mutex_unlock(tp->mutex);
+
+ /* printf("waiting for job\n"); */
+ opj_cond_wait( worker_thread->cond, worker_thread->mutex );
+
+ opj_mutex_unlock(worker_thread->mutex);
+ /* printf("got job\n"); */
+ }
+}
+
+OPJ_BOOL opj_thread_pool_submit_job(opj_thread_pool_t* tp,
+ opj_job_fn job_fn,
+ void* user_data)
+{
+ opj_worker_thread_job_t* job;
+ opj_job_list_t* item;
+
+ if( tp->mutex == NULL )
+ {
+ job_fn( user_data, tp->tls );
+ return OPJ_TRUE;
+ }
+
+ job = (opj_worker_thread_job_t*)opj_malloc(sizeof(opj_worker_thread_job_t));
+ if( job == NULL )
+ return OPJ_FALSE;
+ job->job_fn = job_fn;
+ job->user_data = user_data;
+
+ item = (opj_job_list_t*) opj_malloc(sizeof(opj_job_list_t));
+ if( item == NULL )
+ {
+ opj_free(job);
+ return OPJ_FALSE;
+ }
+ item->job = job;
+
+ opj_mutex_lock(tp->mutex);
+
+ tp->signaling_threshold = 100 * tp->worker_threads_count;
+ while( tp->pending_jobs_count > tp->signaling_threshold )
+ {
+ /* printf("%d jobs enqueued. Waiting\n", tp->pending_jobs_count); */
+ opj_cond_wait(tp->cond, tp->mutex);
+ /* printf("...%d jobs enqueued.\n", tp->pending_jobs_count); */
+ }
+
+ item->next = tp->job_queue;
+ tp->job_queue = item;
+ tp->pending_jobs_count ++;
+
+ if( tp->waiting_worker_thread_list )
+ {
+ opj_worker_thread_t* worker_thread;
+ opj_worker_thread_list_t* next;
+ opj_worker_thread_list_t* to_opj_free;
+
+ worker_thread = tp->waiting_worker_thread_list->worker_thread;
+
+ assert( worker_thread->marked_as_waiting );
+ worker_thread->marked_as_waiting = OPJ_FALSE;
+
+ next = tp->waiting_worker_thread_list->next;
+ to_opj_free = tp->waiting_worker_thread_list;
+ tp->waiting_worker_thread_list = next;
+ tp->waiting_worker_thread_count --;
+
+ opj_mutex_lock(worker_thread->mutex);
+ opj_mutex_unlock(tp->mutex);
+ opj_cond_signal(worker_thread->cond);
+ opj_mutex_unlock(worker_thread->mutex);
+
+ opj_free(to_opj_free);
+ }
+ else
+ opj_mutex_unlock(tp->mutex);
+
+ return OPJ_TRUE;
+}
+
+void opj_thread_pool_wait_completion(opj_thread_pool_t* tp, int max_remaining_jobs)
+{
+ if( tp->mutex == NULL )
+ {
+ return;
+ }
+
+ if( max_remaining_jobs < 0 )
+ max_remaining_jobs = 0;
+ opj_mutex_lock(tp->mutex);
+ tp->signaling_threshold = max_remaining_jobs;
+ while( tp->pending_jobs_count > max_remaining_jobs )
+ {
+ /*printf("tp=%p, jobs before wait = %d, max_remaining_jobs = %d\n", tp, tp->pending_jobs_count, max_remaining_jobs);*/
+ opj_cond_wait(tp->cond, tp->mutex);
+ /*printf("tp=%p, jobs after wait = %d\n", tp, tp->pending_jobs_count);*/
+ }
+ opj_mutex_unlock(tp->mutex);
+}
+
+int opj_thread_pool_get_thread_count(opj_thread_pool_t* tp)
+{
+ return tp->worker_threads_count;
+}
+
+void opj_thread_pool_destroy(opj_thread_pool_t* tp)
+{
+ if( !tp ) return;
+ if( tp->cond )
+ {
+ int i;
+ opj_thread_pool_wait_completion(tp, 0);
+
+ opj_mutex_lock(tp->mutex);
+ tp->state = OPJWTS_STOP;
+ opj_mutex_unlock(tp->mutex);
+
+ for(i=0;i<tp->worker_threads_count;i++)
+ {
+ opj_mutex_lock(tp->worker_threads[i].mutex);
+ opj_cond_signal(tp->worker_threads[i].cond);
+ opj_mutex_unlock(tp->worker_threads[i].mutex);
+ opj_thread_join(tp->worker_threads[i].thread);
+ opj_cond_destroy(tp->worker_threads[i].cond);
+ opj_mutex_destroy(tp->worker_threads[i].mutex);
+ }
+
+ opj_free(tp->worker_threads);
+
+ while( tp->waiting_worker_thread_list != NULL )
+ {
+ opj_worker_thread_list_t* next = tp->waiting_worker_thread_list->next;
+ opj_free( tp->waiting_worker_thread_list );
+ tp->waiting_worker_thread_list = next;
+ }
+
+ opj_cond_destroy(tp->cond);
+ }
+ opj_mutex_destroy(tp->mutex);
+ opj_tls_destroy(tp->tls);
+ opj_free(tp);
+}
diff --git a/openjpeg/src/lib/openjp2/thread.h b/openjpeg/src/lib/openjp2/thread.h
new file mode 100644
index 000000000..241e6d880
--- /dev/null
+++ b/openjpeg/src/lib/openjp2/thread.h
@@ -0,0 +1,253 @@
+/*
+ * The copyright in this software is being made available under the 2-clauses
+ * BSD License, included below. This software may be subject to other third
+ * party and contributor rights, including patent rights, and no such rights
+ * are granted under this license.
+ *
+ * Copyright (c) 2016, Even Rouault
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef THREAD_H
+#define THREAD_H
+
+#include "openjpeg.h"
+
+/**
+@file thread.h
+@brief Thread API
+
+The functions in thread.c have for goal to manage mutex, conditions, thread
+creation and thread pools that accept jobs.
+*/
+
+/** @defgroup THREAD THREAD - Mutex, conditions, threads and thread pools */
+/*@{*/
+
+/** @name Mutex */
+/*@{*/
+
+/** Opaque type for a mutex */
+typedef struct opj_mutex_t opj_mutex_t;
+
+/** Creates a mutex.
+ * @return the mutex or NULL in case of error (can for example happen if the library
+ * is built without thread support)
+ */
+opj_mutex_t* opj_mutex_create(void);
+
+/** Lock/acquire the mutex.
+ * @param mutex the mutex to acquire.
+ */
+void opj_mutex_lock(opj_mutex_t* mutex);
+
+/** Unlock/release the mutex.
+ * @param mutex the mutex to release.
+ */
+void opj_mutex_unlock(opj_mutex_t* mutex);
+
+/** Destroy a mutex
+ * @param mutex the mutex to destroy.
+ */
+void opj_mutex_destroy(opj_mutex_t* mutex);
+
+/*@}*/
+
+/** @name Condition */
+/*@{*/
+
+/** Opaque type for a condition */
+typedef struct opj_cond_t opj_cond_t;
+
+/** Creates a condition.
+ * @return the condition or NULL in case of error (can for example happen if the library
+ * is built without thread support)
+ */
+opj_cond_t* opj_cond_create(void);
+
+/** Wait for the condition to be signaled.
+ * The semantics is the same as the POSIX pthread_cond_wait.
+ * The provided mutex *must* be acquired before calling this function, and
+ * released afterwards.
+ * The mutex will be released by this function while it must wait for the condition
+ * and reacquired afterwards.
+ * In some particular situations, the function might return even if the condition is not signaled
+ * with opj_cond_signal(), hence the need to check with an application level
+ * mechanism.
+ *
+ * Waiting thread :
+ * \code
+ * opj_mutex_lock(mutex);
+ * while( !some_application_level_condition )
+ * {
+ * opj_cond_wait(cond, mutex);
+ * }
+ * opj_mutex_unlock(mutex);
+ * \endcode
+ *
+ * Signaling thread :
+ * \code
+ * opj_mutex_lock(mutex);
+ * some_application_level_condition = TRUE;
+ * opj_cond_signal(cond);
+ * opj_mutex_unlock(mutex);
+ * \endcode
+ *
+ * @param cond the condition to wait.
+ * @param mutex the mutex (in acquired state before calling this function)
+ */
+void opj_cond_wait(opj_cond_t* cond, opj_mutex_t* mutex);
+
+/** Signal waiting threads on a condition.
+ * One of the thread waiting with opj_cond_wait() will be waken up.
+ * It is strongly advised that this call is done with the mutex that is used
+ * by opj_cond_wait(), in a acquired state.
+ * @param cond the condition to signal.
+ */
+void opj_cond_signal(opj_cond_t* cond);
+
+/** Destroy a condition
+ * @param cond the condition to destroy.
+ */
+void opj_cond_destroy(opj_cond_t* cond);
+
+/*@}*/
+
+/** @name Thread */
+/*@{*/
+
+/** Opaque type for a thread handle */
+typedef struct opj_thread_t opj_thread_t;
+
+/** User function to execute in a thread
+ * @param user_data user data provided with opj_thread_create()
+ */
+typedef void (*opj_thread_fn)(void* user_data);
+
+/** Creates a new thread.
+ * @param thread_fn Function to run in the new thread.
+ * @param user_data user data provided to the thread function. Might be NULL.
+ * @return a thread handle or NULL in case of failure (can for example happen if the library
+ * is built without thread support)
+ */
+opj_thread_t* opj_thread_create( opj_thread_fn thread_fn, void* user_data );
+
+/** Wait for a thread to be finished and release associated resources to the
+ * thread handle.
+ * @param thread the thread to wait for being finished.
+ */
+void opj_thread_join( opj_thread_t* thread );
+
+/*@}*/
+
+/** @name Thread local storage */
+/*@{*/
+/** Opaque type for a thread local storage */
+typedef struct opj_tls_t opj_tls_t;
+
+/** Get a thread local value corresponding to the provided key.
+ * @param tls thread local storage handle
+ * @param key key whose value to retrieve.
+ * @return value associated with the key, or NULL is missing.
+ */
+void* opj_tls_get(opj_tls_t* tls, int key);
+
+/** Type of the function used to free a TLS value */
+typedef void (*opj_tls_free_func)(void* value);
+
+/** Set a thread local value corresponding to the provided key.
+ * @param tls thread local storage handle
+ * @param key key whose value to set.
+ * @param value value to set (may be NULL).
+ * @param free_func function to call currently installed value.
+ * @return OPJ_TRUE if successful.
+ */
+OPJ_BOOL opj_tls_set(opj_tls_t* tls, int key, void* value, opj_tls_free_func free_func);
+
+/*@}*/
+
+/** @name Thread pool */
+/*@{*/
+
+/** Opaque type for a thread pool */
+typedef struct opj_thread_pool_t opj_thread_pool_t;
+
+/** Create a new thread pool.
+ * num_thread must nominally be >= 1 to create a real thread pool. If num_threads
+ * is negative or null, then a dummy thread pool will be created. All functions
+ * operating on the thread pool will work, but job submission will be run
+ * synchronously in the calling thread.
+ *
+ * @param num_threads the number of threads to allocate for this thread pool.
+ * @return a thread pool handle, or NULL in case of failure (can for example happen if the library
+ * is built without thread support)
+ */
+opj_thread_pool_t* opj_thread_pool_create(int num_threads);
+
+/** User function to execute in a thread
+ * @param user_data user data provided with opj_thread_create()
+ * @param tls handle to thread local storage
+ */
+typedef void (*opj_job_fn)(void* user_data, opj_tls_t* tls);
+
+
+/** Submit a new job to be run by one of the thread in the thread pool.
+ * The job ( thread_fn, user_data ) will be added in the queue of jobs managed
+ * by the thread pool, and run by the first thread that is no longer busy.
+ *
+ * @param tp the thread pool handle.
+ * @param job_fn Function to run. Must not be NULL.
+ * @param user_data User data provided to thread_fn.
+ * @return OPJ_TRUE if the job was successfully submitted.
+ */
+OPJ_BOOL opj_thread_pool_submit_job(opj_thread_pool_t* tp, opj_job_fn job_fn, void* user_data);
+
+/** Wait that no more than max_remaining_jobs jobs are remaining in the queue of
+ * the thread pool. The aim of this function is to avoid submitting too many
+ * jobs while the thread pool cannot cope fast enough with them, which would
+ * result potentially in out-of-memory situations with too many job descriptions
+ * being queued.
+ *
+ * @param tp the thread pool handle
+ * @param max_remaining_jobs maximum number of jobs allowed to be queued without waiting.
+ */
+void opj_thread_pool_wait_completion(opj_thread_pool_t* tp, int max_remaining_jobs);
+
+/** Return the number of threads associated with the thread pool.
+ *
+ * @param tp the thread pool handle.
+ * @return number of threads associated with the thread pool.
+ */
+int opj_thread_pool_get_thread_count(opj_thread_pool_t* tp);
+
+/** Destroy a thread pool.
+ * @param tp the thread pool handle.
+ */
+void opj_thread_pool_destroy(opj_thread_pool_t* tp);
+
+/*@}*/
+
+/*@}*/
+
+#endif /* THREAD_H */
diff --git a/openjpeg/src/lib/openjp2/tls_keys.h b/openjpeg/src/lib/openjp2/tls_keys.h
new file mode 100644
index 000000000..fb26498de
--- /dev/null
+++ b/openjpeg/src/lib/openjp2/tls_keys.h
@@ -0,0 +1,37 @@
+/*
+ * The copyright in this software is being made available under the 2-clauses
+ * BSD License, included below. This software may be subject to other third
+ * party and contributor rights, including patent rights, and no such rights
+ * are granted under this license.
+ *
+ * Copyright (c) 2016, Even Rouault
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TLS_KEYS_H
+#define TLS_KEYS_H
+
+#define OPJ_TLS_KEY_T1 0
+
+#endif