I am trying to encode/decode arbitrary raw data (a byte[]
) to be able to read GRIB files which use JPEG2000 (https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-40.shtml) in Java using OpenJpeg library (de.digitalcollections.imageio:imageio-openjpeg:0.3.0
) but with no luck. Does any one have an idea how to achieve that? It does not have to be with the above library.
Jpeg2000 offers both, lossy and lossless compression. The library above and the ImageIO need an Image (BufferedImage) as an input/output. I was trying to use OpenJpeg().lib
instance to access lower level API.
If I have an arbitrary data I can always say they are image data by saying that every 1st byte is R
, 2nd is G
and 3rd is B
component of a RGB
color. Maybe padding the end of the array to be dividable by 3. Therefore it should be possible to compress and then decompress any arbitrary byte[]
using Jpeg2000 lossless compression. If my data are somewhat resembling an image/gradient and I do accept certain error after compression, even lossy compression may find its use-case.
The problem I am facing is that an image (BufferedImage
more specifically) contains additionally some meta-data.
While compressing arbitrary data one can do by simply creating an image object and filling its bitmap with desired data, the challenge is to then extract only the part from the resulted compressed image which contains only the payload (not the image's meta-data)
On the other hand when wanting to decompress such payload it needs to look like a Jpeg2000 image (including image's meta-data, some wrappings, ...)
What I did till now was to explore the de.digitalcollections.openjpeg
package in the above library trying to find out where the compression happens.
Did anyone had a similar issue or knows a direction here?
Update
As suggested in the comments I tried to read the JPEG 2000 code stream and decode it back into an image:
val width = 31
val height = 28
// Image data
val bytes = "FF 4F FF 51 00 29 00 00 00 00 01 70 00 00 00 01 00 00 00 00 00 00 00 00 00 00 01 70 00 00 00 01 00 00 00 00 00 00 00 00 00 01 0F 01 01 FF 64 00 23 00 01 43 72 65 61 74 6F 72 3A 20 4A 61 73 50 65 72 20 56 65 72 73 69 6F 6E 20 31 2E 39 30 30 2E 31 FF 52 00 0C 00 00 00 01 00 05 04 04 00 01 FF 5C 00 13 40 80 88 88 90 88 88 90 88 88 90 88 88 90 88 88 90 FF 90 00 0A 00 00 00 00 02 B9 00 01 FF 5D 00 14 00 40 80 88 00 00 88 00 00 88 00 00 88 00 00 88 00 00 FF 93 C7 FE 0C 2E 05 86 91 1F C4 06 14 1A 5C 03 F9 84 81 FB 90 FF 7C D2 3E AD E6 73 77 C1 FF 40 05 00 06 57 AA 30 E5 88 7C 4C F6 A1 31 5C 67 38 53 F7 29 AE 07 CC C3 FF 03 16 80 2E 54 0D 34 CA A5 48 53 3D 34 A2 8E E9 08 18 9B 86 07 B3 1E 8D C3 FF 46 B8 95 A3 A2 A8 C3 12 87 A7 DF 22 70 E3 51 80 49 13 87 FE B6 93 C7 FE 18 A8 07 B9 F0 EB 40 D1 36 1F 20 FF 70 96 73 5F 1B 93 E4 FE AB F7 79 6D B9 4C 5D 55 CB 00 CF D1 F2 D3 E1 25 79 B3 41 44 7F D6 39 0C D9 14 CD 57 B3 3A 14 5D E4 D0 ED 73 22 3A 39 F2 10 A8 E2 36 57 41 6A C7 03 87 0C 46 CA 15 4A B2 8A C3 67 9B 0D 23 9A 1F 2B DF E3 FF 43 1B BF F8 61 90 25 E8 E7 C9 13 AB 76 7A 8E B5 9A 9F F2 4A 66 DE 8B 20 59 1A 29 E1 A4 BB 7C 6C 8D F7 FB F7 D6 05 A3 FC 98 61 97 63 EC 05 C6 4A 86 B6 30 3E 3C 47 50 D7 6F C5 B0 CA 24 EF E6 36 8E E0 B3 BB AA 85 B2 05 38 5D B0 91 00 C3 99 F5 CF 65 65 29 1E E4 98 D4 A3 8E BC A6 A4 7E 12 2C B7 3C 4D A7 BA 33 4E DF D7 E6 6A 29 61 D8 A4 5B 56 7D 51 7F 12 95 72 F9 A4 73 58 32 E4 6A 66 95 0B 3B 80 8A 7F C5 82 C1 6F 96 25 6F 59 29 2A 86 4C 88 1A A8 85 F0 21 75 30 12 48 E4 7C A2 EC D2 62 60 27 D6 4F 12 F1 FF 70 C5 E9 FF 40 19 7F FE 18 C0 42 7B 05 78 6F 6C 22 51 5A 18 9D CA 4A 09 21 AD D3 D6 C8 1D 31 0A 5F 1B FC 73 6B 58 FF 38 0E C1 8D 5E DD 02 BA F9 23 4F C6 1D FF 1B CB 00 60 A7 ED 31 08 28 CD 97 D4 E0 A9 92 B9 F8 C4 63 4A F1 70 0B D2 9A D8 41 76 21 AD 4E 62 D2 80 D2 42 70 0B 52 3A 0E C7 DE 71 B4 10 4A 55 7B E6 C5 22 9C 09 B7 DE F7 28 F8 F4 F4 0A 05 D8 C1 12 6E BB 30 28 AE 34 C1 8D 93 3E D7 FF 0B C5 74 E8 AB EB F7 26 7E 30 28 30 D3 F1 C8 26 1E CA 31 B5 B1 FB 45 12 DF A9 98 B2 6C AF E9 8D D1 B0 17 25 54 72 25 3E 46 A9 BC 5A BA A3 9C 5A 24 D4 13 AD 14 B8 6A 15 C7 EE 70 8E E3 67 F7 64 1B A2 1C 14 94 6E 11 E5 62 67 06 2B BD D1 02 1F 2B 97 72 1D 09 54 76 65 65 41 31 E9 DC 1A 08 F1 40 D3 E8 60 6C D3 9E BA E9 12 37 76 53 EB 32 38 6B A1 F3 65 76 88 7A BF 9F 09 E5 B9 9E 0C 24 CB CF 87 B0 CA 6A FC D4 4E CE A5 2C 8F DB 4D 72 CA DA 81 F7 1F 9B D1 F2 23 FE DF 4D D0 D0 EC EC 21 86 65 3E E6 64 5F 3F 2B 2D E9 FF D9"
.split(" ")
.map { it.toInt(radix = 16).toByte() }
.toByteArray()
val bis = ByteArrayInputStream(bytes)
val imageInputStream = ImageIO.createImageInputStream(bis)
val imageReaders = ImageIO.getImageReadersByFormatName("JPEG2000")
var bufferedImage: BufferedImage? = null
if (imageReaders.hasNext()) {
val imageReader = imageReaders.next()
imageReader.input = imageInputStream
bufferedImage = imageReader.read(0) // Exception
}
But I get an exception:
java.lang.NullPointerException
at de.digitalcollections.openjpeg.imageio.OpenJp2ImageReader.checkIndex(OpenJp2ImageReader.java:63)
at de.digitalcollections.openjpeg.imageio.OpenJp2ImageReader.read(OpenJp2ImageReader.java:134)
at java.desktop/javax.imageio.ImageReader.read(ImageReader.java:938)
The problem is that the OpenJpeg lib cannot find any header. If I understand it correctly, there is not any header in the JPEG2000 code stream.
Thanks!