Closed SoLaRGit closed 1 month ago
Hi,
The main reason that support for mapping tables have never been implemented is the fact that there has never been a request for it.
The ISO/IEC 14495-1 documents in section C.2.4.1.2 only a palette use case::
This Recommendation | International Standard does not define an interpretation for the Wt bytes in an entry. NOTE – A possible interpretation is a vector in some colour space. For example, with Wt = 3, the 3 bytes in a table entry could be interpreted as R,G,B values in a colour palette.
Images that use a palette are rare however (MCGA video mode is very old). Medical standard like DICOM support also palette images, but DICOM requires that the palette table is stored in DICOM attributes and not in the encoded pixel data.
It is of course possible for certain types of images to create a mapping table that would allow the JPEG-LS algorithm to achieve a better compression ratio and even with the added mapping table data would result in a smaller image. I could imagine a 16-bit image that only is using a very small subset of certain pixel values and not the full 16-bit range would benefit from it.
Note: image data that needs to be encoded in 16 bits, but only uses a limit range could also use the option of custom JPEG-LS preset coding parameters to achieve better encoding (which is supported by CharLS).
The functional implementation of mapping tables would not be that big, but the effort to create all the unit tests and error handling code for all the exceptional cases would be significant. It is possible however to put this feature on the backlog if you expect that you have a real-world usage case for it.
Generally I agree, except that using preset to limit the RANGE would yield near-lossless images (loss in sample precision), while using Mapping Table can create lossless images (without any loss of sample precision), and still compress further the original data.
I've been testing this with NEAR = 0, and NEAR = 1 on 16-bit images. g16i03.RAW is 16-bit raw data obtained from Flat Panel Detector (14-bit precision of samples, but I am using full 16-bit, oddly I get larger file if I limit MAXVAL to 14-bit). g16i04.RAW is 16-bit raw data from post-processed g16i03.RAW to full 16-bit range and corrected the curve, extended the range and correct the histogram for visual representation (just for MT test purpose, I will perform more tests with actual medical images processor later on).
Yes my primary target are medical images, and devices storing them.
suffixes on files: n000 - lossless n001 - near lossless N=1 mt - encoded using mapping table
g16i03.RAW size : 16 588 800 out : g16i03n000.jls size : 6 802 044 (41.00 %) / encoded SOS[1]: 6 801 973 (41.00 %)
g16i03.RAW size : 16 588 800 out : g16i03n000mt.jls size : 6 824 534 (41.14 %) / encoded SOS[1]: 6 802 422 (41.01 %)
g16i03.RAW size : 16 588 800 out : g16i03n001.jls size : 5 162 696 (31.12 %) / encoded SOS[1]: 5 162 625 (31.12 %)
g16i03.RAW size : 16 588 800 out : g16i03n001mt.jls size : 5 185 020 (31.26 %) / encoded SOS[1]: 5 162 908 (31.12 %)
g16i04.RAW size : 16 588 800 out : g16i04n000.jls size : 9 850 686 (59.38 %) / encoded SOS[1]: 9 850 615 (59.38 %)
g16i04.RAW size : 16 588 800 out : g16i04n000mt.jls size : 6 090 990 (36.72 %) / encoded SOS[1]: 6 077 912 (36.64 %)
g16i04.RAW size : 16 588 800 out : g16i04n001.jls size : 8 259 185 (49.79 %) / encoded SOS[1]: 8 259 114 (49.79 %)
g16i04.RAW size : 16 588 800 out : g16i04n001mt.jls size : 4 479 229 (27.00 %) / encoded SOS[1]: 4 466 151 (26.92 %)
And if you notice on post-processed images compression goes additional ~22% when using Mapping Tables. Which is not small, considering that when you have casual 100 000 images in common PACS devices is huge saving. Allowing to store nearly two images when using mapping tables for the size one image when not using mapping tables. Effectively almost doubling the storage of such device. I would say this is significant.
True, I need more testing on bulk of non-post-processes and post-processed images to get final conclusion what is the real gain here.
My proposal to limit the range would be limited to the actual values that are used to ensure the compression remains lossless. If you know that you are storing 14-bits in a 16-bit image, settings MAXVAL to 2^14-1 should be able to help the algorithm.
It is of course also possible to scan the pixels and determine the actual MAXVAL, which may be helpful if you have images that are sometimes "dark" but not always.
Would it be possible to share some RAW images that generate a larger file when setting the limit to 14-bit. It is indeed strange that these files are larger, but I have never experimented with it.
Tried just now (on g16i03.raw), both MAXVAL = 11261, and MAXVAL = (1 << 14) - 1, gain is almost negligible:
Test[A] - in: g16i03.RAW 16 588 800, out: g16i03n000.jls 6 802 068 (41.00 %) / enc [c:1] 6 801 973 (41.00 %)
Test[B] - in: g16i03.RAW 16 588 800, out: g16i03n000-maxval11261.jls 6 800 425 (40.99 %) / enc [c:1] 6 800 330 (40.99 %)
Test[C] - in: g16i03.RAW 16 588 800, out: g16i03n000-maxval16367.jls 6 800 614 (41.00 %) / enc [c:1] 6 800 519 (40.99 %)
But I am not concern by those images as they are RAW images from the Flat Panel Detector, and are almost never stored to PACS devices. I am concern about post-processes image which have the full range of values [0..65535] and are 30% larger then the original (non-processed) images when compressed with the same NEAR=0. And I've just wanted to see will mapping table help and by how much. And it turns out it helps a lot.
I did some analysis on the development costs. Adding table support to the encoder would require 2 functions:
void encoder.write_mapping_table(const void* table_data, int32_t entry_width);
size_t encoder.encode_scan(const void* source_buffer, size_t source_size_bytes,
uint32_t stride = 0, int32_t component_count = 1, int32_t* table_ids = nullptr);
to cover all possible scenario's.
Adding support to the decoder would be much more complex however. Tables can be present or not and can be defined at several locations in the JPEG-LS stream (as long as they are defined before the scan that uses them).
Did you looked into the compressions gains that tables could bring for your use case?
sorry, was on something else in mean time.
I have done the following: On encoded process counted all values in input pixel buffer, and built mapping table LUT, remap input pixel buffer using Mapping Table LUT, and then encode input pixel buffer. On decode process: read mapping table, decode to output pixel buffer, and remap output pixel buffer. So I've kept original algorithms for encoding/decoding only added additional steps before and after. It only takes few milliseconds to execute, so it has not so much impact on performance (not counting that encoding less bits is faster as the result also of using mapping tables).
I've uploaded initial tests with post-processed X-RAY images without/with mapping tables at the following location:
JPEG-LS-TestGround > MappingTables
Explanation on suffixes on files (but it can be viewed in JLS headers also):
WL - Window Leveling is applied to pixel buffer (X-RAY image for presentation)
N0 - NEAR == 0 (JLS LOSSLESS compression)
MT - Using Mapping Tables during the compression
Also pasting here the JLS headers info and compression levels (less is better) from above files, and you'll notice huge difference between without/with mapping tables compression levels. Also note: not sure which viewer are you using, but irfanview knows crash when reading JLS files with mapping tables. And thinking on building my own viewer for JLS files (just maybe).
decoding : CHEST_0_WLN0.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:2848, Y:2480, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:0], NEAR:0, ILV:0, Ahl:0, EncodedData:L(11282803):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:2848x2480x16, LOSSLESS, ILV:0,
size : input:11 282 845 b, encoded:11 282 803 b, output:14 126 080 b
comp : input: 79.87 %, encoded: 79.87 %
time : decode: 0 ms, overhead: 31 ms
decoding : CHEST_0_WLN0MT.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:2848, Y:2480, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFF8:LSE:{ cb:1067, id:2, data:{TID:1,Wt:2,TABLEi:1062} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:1], NEAR:0, ILV:0, Ahl:0, EncodedData:L(5097108):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:2848x2480x16, LOSSLESS, ILV:0, MappingTable,
size : input:5 098 219 b, encoded:5 097 108 b, output:14 126 080 b
comp : input: 36.09 %, encoded: 36.08 %
time : decode: 0 ms, overhead: 42 ms
decoding : CHEST_1_WLN0.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:2388, Y:2476, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:0], NEAR:0, ILV:0, Ahl:0, EncodedData:L(7111108):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:2388x2476x16, LOSSLESS, ILV:0,
size : input:7 111 150 b, encoded:7 111 108 b, output:11 825 376 b
comp : input: 60.13 %, encoded: 60.13 %
time : decode: 0 ms, overhead: 40 ms
decoding : CHEST_1_WLN0MT.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:2388, Y:2476, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFF8:LSE:{ cb:1023, id:2, data:{TID:1,Wt:2,TABLEi:1018} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:1], NEAR:0, ILV:0, Ahl:0, EncodedData:L(2876124):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:2388x2476x16, LOSSLESS, ILV:0, MappingTable,
size : input:2 877 191 b, encoded:2 876 124 b, output:11 825 376 b
comp : input: 24.33 %, encoded: 24.32 %
time : decode: 0 ms, overhead: 9 ms
decoding : CHEST_2_WLN0.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:2848, Y:2480, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:0], NEAR:0, ILV:0, Ahl:0, EncodedData:L(9253117):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:2848x2480x16, LOSSLESS, ILV:0,
size : input:9 253 159 b, encoded:9 253 117 b, output:14 126 080 b
comp : input: 65.5 %, encoded: 65.5 %
time : decode: 0 ms, overhead: 18 ms
decoding : CHEST_2_WLN0MT.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:2848, Y:2480, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFF8:LSE:{ cb:681, id:2, data:{TID:1,Wt:2,TABLEi:676} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:1], NEAR:0, ILV:0, Ahl:0, EncodedData:L(3175252):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:2848x2480x16, LOSSLESS, ILV:0, MappingTable,
size : input:3 175 977 b, encoded:3 175 252 b, output:14 126 080 b
comp : input: 22.48 %, encoded: 22.48 %
time : decode: 0 ms, overhead: 9 ms
decoding : FOOT_0_WLN0.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:2040, Y:1284, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:0], NEAR:0, ILV:0, Ahl:0, EncodedData:L(3688693):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:2040x1284x16, LOSSLESS, ILV:0,
size : input:3 688 735 b, encoded:3 688 693 b, output:5 238 720 b
comp : input: 70.41 %, encoded: 70.41 %
time : decode: 0 ms, overhead: 9 ms
decoding : FOOT_0_WLN0MT.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:2040, Y:1284, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFF8:LSE:{ cb:1153, id:2, data:{TID:1,Wt:2,TABLEi:1148} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:1], NEAR:0, ILV:0, Ahl:0, EncodedData:L(1523562):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:2040x1284x16, LOSSLESS, ILV:0, MappingTable,
size : input:1 524 759 b, encoded:1 523 562 b, output:5 238 720 b
comp : input: 29.11 %, encoded: 29.08 %
time : decode: 0 ms, overhead: 6 ms
decoding : FOOT_1_WLN0.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:2052, Y:1276, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:0], NEAR:0, ILV:0, Ahl:0, EncodedData:L(3766411):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:2052x1276x16, LOSSLESS, ILV:0,
size : input:3 766 453 b, encoded:3 766 411 b, output:5 236 704 b
comp : input: 71.92 %, encoded: 71.92 %
time : decode: 0 ms, overhead: 12 ms
decoding : FOOT_1_WLN0MT.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:2052, Y:1276, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFF8:LSE:{ cb:1147, id:2, data:{TID:1,Wt:2,TABLEi:1142} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:1], NEAR:0, ILV:0, Ahl:0, EncodedData:L(1548975):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:2052x1276x16, LOSSLESS, ILV:0, MappingTable,
size : input:1 550 166 b, encoded:1 548 975 b, output:5 236 704 b
comp : input: 29.6 %, encoded: 29.58 %
time : decode: 0 ms, overhead: 7 ms
decoding : FOOT_2_WLN0.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:2340, Y:1416, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:0], NEAR:0, ILV:0, Ahl:0, EncodedData:L(4570677):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:2340x1416x16, LOSSLESS, ILV:0,
size : input:4 570 719 b, encoded:4 570 677 b, output:6 626 880 b
comp : input: 68.97 %, encoded: 68.97 %
time : decode: 0 ms, overhead: 14 ms
decoding : FOOT_2_WLN0MT.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:2340, Y:1416, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFF8:LSE:{ cb:1111, id:2, data:{TID:1,Wt:2,TABLEi:1106} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:1], NEAR:0, ILV:0, Ahl:0, EncodedData:L(1741121):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:2340x1416x16, LOSSLESS, ILV:0, MappingTable,
size : input:1 742 276 b, encoded:1 741 121 b, output:6 626 880 b
comp : input: 26.29 %, encoded: 26.27 %
time : decode: 0 ms, overhead: 6 ms
decoding : HANDS_0_WLN0.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:2076, Y:1756, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:0], NEAR:0, ILV:0, Ahl:0, EncodedData:L(4446334):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:2076x1756x16, LOSSLESS, ILV:0,
size : input:4 446 376 b, encoded:4 446 334 b, output:7 290 912 b
comp : input: 60.99 %, encoded: 60.98 %
time : decode: 0 ms, overhead: 10 ms
decoding : HANDS_0_WLN0MT.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:2076, Y:1756, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFF8:LSE:{ cb:1227, id:2, data:{TID:1,Wt:2,TABLEi:1222} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:1], NEAR:0, ILV:0, Ahl:0, EncodedData:L(1609597):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:2076x1756x16, LOSSLESS, ILV:0, MappingTable,
size : input:1 610 868 b, encoded:1 609 597 b, output:7 290 912 b
comp : input: 22.09 %, encoded: 22.08 %
time : decode: 0 ms, overhead: 5 ms
decoding : HANDS_1_WLN0.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:936, Y:1976, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:0], NEAR:0, ILV:0, Ahl:0, EncodedData:L(2674815):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:936x1976x16, LOSSLESS, ILV:0,
size : input:2 674 857 b, encoded:2 674 815 b, output:3 699 072 b
comp : input: 72.31 %, encoded: 72.31 %
time : decode: 0 ms, overhead: 7 ms
decoding : HANDS_1_WLN0MT.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:936, Y:1976, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFF8:LSE:{ cb:1081, id:2, data:{TID:1,Wt:2,TABLEi:1076} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:1], NEAR:0, ILV:0, Ahl:0, EncodedData:L(1075874):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:936x1976x16, LOSSLESS, ILV:0, MappingTable,
size : input:1 076 999 b, encoded:1 075 874 b, output:3 699 072 b
comp : input: 29.12 %, encoded: 29.08 %
time : decode: 0 ms, overhead: 4 ms
decoding : HANDS_2_WLN0.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:1416, Y:920, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:0], NEAR:0, ILV:0, Ahl:0, EncodedData:L(1959047):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:1416x920x16, LOSSLESS, ILV:0,
size : input:1 959 089 b, encoded:1 959 047 b, output:2 605 440 b
comp : input: 75.19 %, encoded: 75.19 %
time : decode: 0 ms, overhead: 5 ms
decoding : HANDS_2_WLN0MT.jls
FFD8:SOI
FFF7:SOF55:{ cb:11, bpp:16, X:1416, Y:920, Nf:1, Ci:1 }
FFF8:LSE:{ cb:13, id:1, data:{MAXVAL:0,T1:0,T2:0,T3:0,RESET:64} }
FFF8:LSE:{ cb:1069, id:2, data:{TID:1,Wt:2,TABLEi:1064} }
FFDA:SOS:{ cb:8, Ns:1, Ci:L(1):[Cs:1,Tmi:1], NEAR:0, ILV:0, Ahl:0, EncodedData:L(835460):... }
FFD9:EOI
-
output : NOT DECODED (DecodeHeaders)
params : image:1416x920x16, LOSSLESS, ILV:0, MappingTable,
size : input:836 573 b, encoded:835 460 b, output:2 605 440 b
comp : input: 32.11 %, encoded: 32.07 %
time : decode: 0 ms, overhead: 3 ms
I will have a look at the data\images.
Viewing JPEG-LS images I have created a WIC wrapper around CharLS, that makes it possible to use WIC enabled viewers to view JPEG-LS images on the Windows platform: https://github.com/team-charls/jpegls-wic-codec I use mostly WIC Explorer to debug this plug-in and to view the images.
It cannot handle tables at the moment, but as it just a wrapper around CharLS, you can point it to your CharLS submodule branch. Note that this WIC wrapper is still in development and not all things work.
Another solution would be to create a plug-in for Gimp, which could be a cross-platform solution. Never found the time to create such a plug-in however.
Support for mapping tables have been added with PR #302 Note: the actual meaning of a mapping table cannot be encoded in a JPEG-LS stream. This needs to be done in a SPIFF header or in the DICOM attributes when the JPEG-LS stream is embedded in a DICOM file.
Was reading wiki docs and noted you have stated the following: "How complete is CharLS? CharLS is a conforming ISO/IEC 14495-1:1999 implementation, with some exceptions that have little or no impact in real-world usage. All exceptions are listed in the README.md" And README.md has quite lengthy list: "The following JPEG-LS options are not supported by the CharLS implementation. Most of these options are rarely used in practice. No support for JPEG restart markers (RST). Restart markers make it possible to recover from corrupted JPEG files, but are seldom used for data recovery scenarios. No support for sub-sampled scans. Sub-sampling is a lossly encoding mechanism and not used in lossless scenarios. No support for multi component frames with mixed component counts in a single scan. While technical possible all known JPEG-LS codecs put multi-component (color) images in a single scan or in multiple scans, but not use a mix of these in one file. No support for oversize image dimension. Maximum supported image dimensions are [1, 65535] by [1, 65535]. No support for JPEG-LS mapping tables. No support for point transform. Point transform is a lossly encoding mechanism and not used in lossless scenarios."
JPEG-LS mapping tables are added to give better compression to both the lossless and near-lossless. It it's just mapping pixel value to mapping table index, and vice verso when decoding. It affects only function for retrieving Rx (Ra, Rb, Rc, Rd) values. So why not implementing it?
Note: I've already tested with lowering the MAXVAL to Mapping Table entries count - 1, resulting image is less compressed. This was tested on 16-bit image, 8-bit may have different results. But with 16-bit image I got 6% more compression,
`
I agree mapping table has more compression only with larger images using it on small images would actually produce larger files. But since JPEG-LS compression is for medical, astronomy and similar use, I doubt there will be small images. Also this 21st century (Phase One camera has 100 MP), everything these days has higher and higher resolution.