title: Jpeg2000 encoding/decoding of byte array in Java
body: <p>I am trying to encode/decode arbitrary raw data (a <code>byte[]</code>) to be able to read GRIB files which use JPEG2000 (<a href="https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-40.shtml" rel="nofollow noreferrer">https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-40.shtml</a>) in Java using OpenJpeg library (<code>de.digitalcollections.imageio:imageio-openjpeg:0.3.0</code>) but with no luck. Does any one have an idea how to achieve that? It does not have to be with the above library.</p>
  <p>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 <code>OpenJpeg().lib</code> instance to access lower level API.</p>
  <p>If I have an arbitrary data I can always say they are image data by saying that every 1st byte is <code>R</code>, 2nd is <code>G</code> and 3rd is <code>B</code> component of a <code>RGB</code> 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 <code>byte[]</code> 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.</p>
  <p>The problem I am facing is that an image (<code>BufferedImage</code> more specifically) contains additionally some meta-data.</p>
  <p>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)</p>
  <p>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, ...)</p>
  <p>What I did till now was to explore the <code>de.digitalcollections.openjpeg</code> package in the above library trying to find out where the compression happens.</p>
  <p>Did anyone had a similar issue or knows a direction here?</p>
  <p><strong>Update</strong></p>
  <p>As suggested in the comments I tried to read the JPEG 2000 code stream and decode it back into an image:</p>
  <pre class="lang-kotlin prettyprint-override"><code>val width = 31
  val height = 28
  
  // Image data
  val bytes = &quot;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&quot;
      .split(&quot; &quot;)
      .map { it.toInt(radix = 16).toByte() }
      .toByteArray()
  
  val bis = ByteArrayInputStream(bytes)
  val imageInputStream = ImageIO.createImageInputStream(bis)
  val imageReaders = ImageIO.getImageReadersByFormatName(&quot;JPEG2000&quot;)
  var bufferedImage: BufferedImage? = null
  if (imageReaders.hasNext()) {
      val imageReader = imageReaders.next()
      imageReader.input = imageInputStream
      bufferedImage = imageReader.read(0) // Exception
  }
  </code></pre>
  <p>But I get an exception:</p>
  <pre><code>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)
  </code></pre>
  <p>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.</p>
  <p>Thanks!</p>