.. _raster.jp2grok:

================================================================================
JP2Grok -- JPEG2000 driver based on Grok library
================================================================================

.. shortname:: JP2Grok

.. build_dependencies:: Grok >= 20.2

.. versionadded:: 3.13

This driver is an implementation of a JPEG2000 reader/writer based on the
`Grok <https://github.com/GrokImageCompression/grok>`__ library.

The driver uses the VSI Virtual File API, so it can read JPEG2000
compressed NITF files. It also supports native S3 access through Grok's
built-in cloud I/O.

XMP metadata can be extracted from JPEG2000 files, and will be stored as
XML raw content in the xml:XMP metadata domain.

The driver supports writing georeferencing information as GeoJP2 and
GMLJP2 boxes.

The driver supports creating files with
transparency, arbitrary band count, and adding/reading metadata. Update
of georeferencing or metadata of existing file is also supported.
Optional intellectual property metadata can be read/written in the
xml:IPR box.

Driver capabilities
-------------------

.. supports_createcopy::

.. supports_georeferencing::

.. supports_virtualio::

Georeferencing
--------------

Georeferencing information can come from different sources : internal
(GeoJP2 or GMLJP2 boxes), worldfile .j2w/.wld sidecar files, or PAM
(Persistent Auxiliary metadata) .aux.xml sidecar files. By default,
information is fetched in following order (first listed is the highest
priority): PAM, GeoJP2, GMLJP2, WORLDFILE.

The allowed sources and their priority order can
be changed with the :config:`GDAL_GEOREF_SOURCES` configuration option (or
:oo:`GEOREF_SOURCES` open option) whose value is a comma-separated list of the
following keywords : PAM, GEOJP2, GMLJP2, INTERNAL (shortcut for
GEOJP2,GMLJP2), WORLDFILE, NONE. Earlier mentioned sources take
priority over later ones. A non mentioned source will be ignored.

For example setting it to "WORLDFILE,PAM,INTERNAL" will make a
geotransformation matrix from a potential worldfile priority over PAM
or internal JP2 boxes. Setting it to "PAM,WORLDFILE,GEOJP2" will use the
mentioned sources and ignore GMLJP2 boxes.

Thread support
--------------

The Grok library uses multi-threaded decompression internally via its own
thread pool. Multi-threaded encoding is also supported. The number of
threads is determined at runtime from GDALGetNumThreads.

When a JPEG2000 file contains multiple tiles, GDAL will additionally
dispatch tile processing across threads for parallel CopyTileData
operations during decoding.

Open Options
--------------

|about-open-options|
The following open options are available:

-  .. oo:: 1BIT_ALPHA_PROMOTION
      :choices: YES, NO
      :default: YES

      Whether a 1-bit alpha channel should be promoted to 8-bit.

-  .. oo:: GEOREF_SOURCES
      :since: 2.2

      Define which georeferencing
      sources are allowed and their priority order. See
      `Georeferencing`_ paragraph.

-  .. oo:: USE_TILE_AS_BLOCK
      :choices: YES, NO
      :default: NO
      :since: 2.2

      Whether to always use the JPEG-2000 block size as the GDAL block size. Setting
      this option can be useful when doing whole image decompression and
      the image is single-tiled. Note however that the tile size must not
      exceed 2 GB since that's the limit supported by GDAL.

Creation Options
----------------

|about-creation-options|
The following creation options are available:

-  .. co:: CODEC
      :choices: JP2, J2K

      JP2 will add JP2 boxes around the codestream
      data. The value is determined automatically from the file extension.
      If it is neither JP2 nor J2K, J2K codec is used.

-  .. co:: GMLJP2
      :choices: YES, NO
      :default: YES

      Indicates whether a GML
      box conforming to the OGC GML in JPEG2000 specification should be
      included in the file. Unless GMLJP2V2_DEF is used, the version of the
      GMLJP2 box will be version 1.

-  .. co:: GMLJP2V2_DEF
      :choices: YES, <filename>, <json>

      Indicates whether
      a GML box conforming to the `OGC GML in JPEG2000, version
      2.0.1 <http://docs.opengeospatial.org/is/08-085r5/08-085r5.html>`__
      specification should be included in the file. *filename* must point
      to a file with a JSON content that defines how the GMLJP2 v2 box
      should be built. See the :ref:`raster.jp2openjpeg` driver documentation
      for the syntax of the JSON configuration file. It is also possible to
      directly pass the JSON content inlined as a string. If filename is
      just set to YES, a minimal instance will be built.

-  .. co:: GeoJP2
      :choices: YES, NO
      :default: YES

      Indicates whether a
      UUID/GeoTIFF box conforming to the GeoJP2 (GeoTIFF in JPEG2000)
      specification should be included in the file.

-  .. co:: QUALITY
      :choices: <float_value\,float_value\,...>

      Percentage between 0 and
      100. A value of 50 means the file will be half-size in comparison to
      uncompressed data, 33 means 1/3, etc.. Defaults to 25 (unless the
      dataset is made of a single band with color table, in which case the
      default quality is 100). It is possible to
      specify several quality values (comma separated) to ask for several
      quality layers. Quality values should be increasing.

-  .. co:: REVERSIBLE
      :choices: YES, NO

      YES means use of reversible 5x3 integer-only
      filter, NO use of the irreversible DWT 9-7. Defaults to NO (unless
      the dataset is made of a single band with color table, in which case
      reversible filter is used).

-  .. co:: RESOLUTIONS
      :choices: <integer>

      Number of resolution levels. Default
      value is selected such the smallest overview of a tile is no bigger
      than 128x128.

-  .. co:: BLOCKXSIZE
      :choices: <integer>
      :default: 1024

      Tile width.

-  .. co:: BLOCKYSIZE
      :choices: <integer>
      :default: 1024

      Tile height.

-  .. co:: PROGRESSION
      :choices: LRCP, RLCP, RPCL, PCRL, CPRL
      :default: LRCP

      Progression order.

-  .. co:: SOP
      :choices: YES, NO
      :default: NO

      YES means generate SOP (Start Of Packet) marker segments.

-  .. co:: EPH
      :choices: YES, NO
      :default: NO

      YES means generate EPH (End of Packet Header) marker segments.

-  .. co:: YCBCR420
      :choices: YES, NO
      :default: NO

      YES if RGB must be resampled to YCbCr 4:2:0.

-  .. co:: YCC
      :choices: YES, NO
      :default: YES

      YES if RGB must be transformed to YCC
      color space ("MCT transform", i.e. internal transform, without visual
      degradation).

-  .. co:: NBITS
      :choices: <integer>

      Bits (precision) for sub-byte
      files (1-7), sub-uint16 (9-15), sub-uint32 (17-31).

-  .. co:: 1BIT_ALPHA
      :choices: YES, NO

      Whether to encode the alpha
      channel as a 1-bit channel (when there's an alpha channel). Defaults
      to NO, unless :co:`INSPIRE_TG=YES`. Enabling this option might cause
      compatibility problems with some readers.

-  .. co:: ALPHA
      :choices: YES, NO
      :default: NO

      Whether to force encoding last
      channel as alpha channel. Only useful if the color interpretation of
      that channel is not already Alpha.

-  .. co:: PROFILE
      :choices: AUTO, UNRESTRICTED, PROFILE_1
      :default: AUTO

      Determine
      which codestream profile to use. UNRESTRICTED corresponds to the
      "Unrestricted JPEG 2000 Part 1 codestream" (RSIZ=0). PROFILE_1
      corresponds to the "JPEG 2000 Part 1 Profile 1 codestream" (RSIZ=2),
      which add constraints on tile dimensions and number of resolutions.
      In AUTO mode, the driver will determine if the :co:`BLOCKXSIZE`,
      :co:`BLOCKYSIZE`, :co:`RESOLUTIONS`, :co:`CODEBLOCK_WIDTH` and :co:`CODEBLOCK_HEIGHT` values
      are compatible with PROFILE_1 and advertise it in the relevant case.
      Note that the default values of those options are compatible with
      PROFILE_1. Otherwise UNRESTRICTED is advertised.

-  .. co:: INSPIRE_TG
      :choices: YES, NO
      :default: NO

      Whether to use JPEG2000 features
      that comply with `Inspire Orthoimagery Technical
      Guidelines <http://inspire.ec.europa.eu/documents/Data_Specifications/INSPIRE_DataSpecification_OI_v3.0.pdf>`__.
      When set to YES, implies :co:`PROFILE=PROFILE_1`,
      :co:`1BIT_ALPHA=YES`, :co:`GEOBOXES_AFTER_JP2C=YES`. The :co:`CODEC`, :co:`BLOCKXSIZE`,
      :co:`BLOCKYSIZE`, :co:`RESOLUTIONS`, :co:`NBITS`, :co:`PROFILE`, :co:`CODEBLOCK_WIDTH` and
      :co:`CODEBLOCK_HEIGHT` options will be checked against the requirements and
      recommendations of the Technical Guidelines.

-  .. co:: JPX
      :choices: YES, NO
      :default: YES

      Whether to advertise JPX features, and
      add a Reader requirement box, when a GMLJP2 box is written.
      This option should not be used unless compatibility problems
      with a reader occur.

-  .. co:: GEOBOXES_AFTER_JP2C
      :choices: YES, NO

      Whether to place
      GeoJP2/GMLJP2 boxes after the code-stream. Defaults to NO, unless
      :co:`INSPIRE_TG=YES`. This option should not be used unless compatibility
      problems with a reader occur.

-  .. co:: PRECINCTS
      :choices: <{prec_w\,prec_h}\,{prec_w\,prec_h},...>

      A list of {precincts width,precincts height} tuples to specify
      precincts size. Each value should be a multiple of 2. The maximum
      number of tuples used will be the number of resolutions. The first
      tuple corresponds to the higher resolution level, and the following
      ones to the lower resolution levels. If less tuples are specified,
      the last one is used by dividing its values by 2 for each extra lower
      resolution level. The default value used is
      {512,512},{256,512},{128,512},{64,512},{32,512},{16,512},{8,512},{4,512},{2,512}.
      An empty string may be used to disable precincts ( i.e. the default
      {32767,32767},{32767,32767}, ... will then be used).

-  .. co:: TILEPARTS
      :choices: DISABLED, RESOLUTIONS, LAYERS, COMPONENTS
      :default: DISABLED

      Whether to generate tile-parts and according to which criterion.

-  .. co:: CODEBLOCK_WIDTH
      :choices: <integer>
      :default: 64

      Codeblock width: power
      of two value between 4 and 1024. Note that
      CODEBLOCK_WIDTH \* CODEBLOCK_HEIGHT must not be greater than 4096.
      For PROFILE_1 compatibility, CODEBLOCK_WIDTH must not be greater than
      64.

-  .. co:: CODEBLOCK_HEIGHT
      :choices: <integer>
      :default: 64

      Codeblock height: power
      of two value between 4 and 1024. Note that
      CODEBLOCK_WIDTH \* CODEBLOCK_HEIGHT must not be greater than 4096.
      For PROFILE_1 compatibility, CODEBLOCK_HEIGHT must not be greater
      than 64.

-  .. co:: CODEBLOCK_STYLE

      Style
      of the code-block coding passes. The following 6 independent settings
      can be combined together (values should be comma separated):

      -  *BYPASS* (1): enable selective arithmetic coding bypass (can
         substantially improve coding/decoding speed, at the expense of
         larger file size)
      -  *RESET* (2): reset context probabilities on coding pass boundaries
      -  *TERMALL* (4): enable termination on each coding pass
      -  *VSC* (8): enable vertically causal context
      -  *PREDICTABLE* (16): enable predictable termination (helps for
         error detection)
      -  *SEGSYM* (32): enable segmentation symbols (helps for error
         detection)

      Instead of specifying them by text, it is also possible to give the
      corresponding numeric value of the global codeblock style, by adding
      the selected options (for example "BYPASS,TERMALL" is equivalent to
      "5"=1+4)

      By default, none of them are enabled. Enabling them will generally
      increase codestream size, but improve either coding/decoding speed or
      resilience/error detection.

-  .. co:: PLT
      :choices: YES, NO
      :default: NO

      Whether to write a PLT (Packet Length) marker segment in
      tile-part headers.

-  .. co:: TLM
      :choices: YES, NO
      :default: NO

      Whether to write a TLM (Tile-part Length) marker segment
      in main header.

-  .. co:: WRITE_METADATA
      :choices: YES, NO
      :default: NO

      Whether metadata should be
      written, in a dedicated JP2 'xml ' box. The content
      of the 'xml ' box will be like:

      ::

         <GDALMultiDomainMetadata>
           <Metadata>
             <MDI key="foo">bar</MDI>
           </Metadata>
           <Metadata domain='aux_domain'>
             <MDI key="foo">bar</MDI>
           </Metadata>
           <Metadata domain='a_xml_domain' format='xml'>
             <arbitrary_xml_content>
             </arbitrary_xml_content>
           </Metadata>
         </GDALMultiDomainMetadata>

      If there are metadata domain whose name starts with "xml:BOX\_", they
      will be written each as separate JP2 'xml ' box.

      If there is a metadata domain whose name is "xml:XMP", its content
      will be written as a JP2 'uuid' XMP box.

      If there is a metadata domain whose name is "xml:IPR", its content
      will be written as a JP2 'jp2i' box.

-  .. co:: MAIN_MD_DOMAIN_ONLY
      :choices: YES, NO
      :default: NO

      (Only if :co:`WRITE_METADATA=YES`)
      Whether only metadata from the main domain should
      be written.

-  .. co:: USE_SRC_CODESTREAM
      :Choices: YES, NO

      (EXPERIMENTAL!) When
      source dataset is JPEG2000, whether to reuse the codestream of the
      source dataset unmodified. Defaults to NO. Note that enabling that
      feature might result in inconsistent content of the JP2 boxes w.r.t.
      to the content of the source codestream. Most other creation options
      will be ignored in that mode. Can be useful in some use cases when
      adding/correcting georeferencing, metadata, ...

-  .. co:: TRANSCODE
      :choices: YES, NO
      :default: NO

      When the source dataset is JPEG 2000, transcode the codestream
      without a full decompression/recompression round-trip. The
      underlying codestream data is copied verbatim while the following
      options may be used to modify markers or progression:

      - :co:`PLT` – insert PLT (Packet Length, Tile-part) marker segments
      - :co:`TLM` – insert TLM (Tile-part Length) marker segments
      - :co:`SOP` – insert SOP (Start Of Packet) marker segments
      - :co:`EPH` – insert EPH (End of Packet Header) marker segments
      - :co:`PROGRESSION` – change the progression order
        (``LRCP``, ``RLCP``, ``RPCL``, ``PCRL``, ``CPRL``)

      JP2 metadata boxes (GeoTIFF UUID, XMP, GMLJP2, IPR, GDAL xml) are
      regenerated from the current dataset metadata.

      Because the codestream coefficients are copied rather than
      re-encoded, creation options that would affect the pixel data
      (``QUALITY``, ``REVERSIBLE``, ``BLOCKXSIZE``, ``BLOCKYSIZE``,
      ``RESOLUTIONS``, ``YCBCR420``, ``YCC``, ``NBITS``, ``1BIT_ALPHA``,
      ``PRECINCTS``, ``TILEPARTS``, ``CODEBLOCK_WIDTH``,
      ``CODEBLOCK_HEIGHT``, ``CODEBLOCK_STYLE``, ``USE_SRC_CODESTREAM``)
      are ignored — a warning is emitted if any are supplied.

      Example:

      ::

          gdal_translate -of JP2Grok -co TRANSCODE=YES \
              -co PLT=YES -co TLM=YES -co PROGRESSION=RPCL \
              input.jp2 output.jp2

-  .. co:: COMMENT
      :choices: <string>

      Content of the comment (COM) marker in the codestream.

Lossless compression
~~~~~~~~~~~~~~~~~~~~

Lossless compression can be achieved if ALL the following creation
options are defined :

-  :co:`QUALITY=100`
-  :co:`REVERSIBLE=YES`
-  :co:`YCBCR420=NO` (which is the default)

Standalone plugin compilation
-----------------------------

While this driver may be built as part of a whole GDAL build, either in libgdal
itself, or as a plugin, it is also possible to only build this driver as a plugin,
against an already built libgdal.

The version of the GDAL sources used to build the driver must match the version
of the libgdal it is built against.

For example, from a "build_grok" directory under the root of the GDAL source tree:

::

    cmake -S ../frmts/grok -DCMAKE_PREFIX_PATH=/path/to/GDAL_installation_prefix -DGROK_ROOT=/path/to/grok_install_prefix
    cmake --build .

Note that such a plugin, when used against a libgdal not aware of it, will be
systematically loaded at GDAL driver initialization time, and will not benefit from
`deferred plugin loading capabilities <rfc-96>`. For that, libgdal itself must be built with the
CMake variable GDAL_REGISTER_DRIVER_JP2GROK_FOR_LATER_PLUGIN=ON set.

See Also
---------

-  Implemented as :source_file:`frmts/grok/grokdataset.cpp`.

-  `The Grok library home
   page <https://github.com/GrokImageCompression/grok>`__

Other JPEG2000 GDAL drivers :

-  :ref:`JP2OpenJPEG: based on OpenJPEG library (open
   source) <raster.jp2openjpeg>`

-  :ref:`JP2ECW: based on Erdas ECW library
   (proprietary) <raster.jp2ecw>`

-  :ref:`JP2MRSID: based on LizardTech MrSID library
   (proprietary) <raster.jp2mrsid>`

-  :ref:`JP2KAK: based on Kakadu library (proprietary) <raster.jp2kak>`
