Class TLcdJPIPModelDecoder

java.lang.Object
com.luciad.format.jpeg2000.TLcdJPIPModelDecoder
All Implemented Interfaces:
ILcdModelDecoder

@LcdService(service=ILcdModelDecoder.class, priority=20000) public class TLcdJPIPModelDecoder extends Object implements ILcdModelDecoder
This model decoder decodes georeferenced JPEG2000 images retrieved through the JPEG2000 Interactive Protocol (JPIP).

Input sources

The model decoder can only recognize a URI that points to a JPEG2000 image (ex. http://host:port/path/to/image.jp2).

Supported transfer protocols

  • This model decoder only supports "http" or "jpip".

Model structure

  • This model decoder creates a model per JPIP source.
  • All models returned by this model decoder implement ILcd2DBoundsIndexedModel.

Model descriptor

  • All models returned by this model decoder have a TLcdJPIPModelDescriptor.
  • The type name of the model descriptor is the display name of this decoder.

Model reference

If present the raster data contains embedded GeoTIFF tags (geoJP2) then the model reference and raster bounds are decoded from it. If the image does not specify a model reference, it is retrieved with the help of the getModelReferenceDecoder() or as the getDefaultModelReference() of this decoder. If the image does not specify raster bounds, it is retrieved from the getDefaultBounds() property of this decoder.

Model elements

  • Each decoded model contains one object: an ALcdImage (and ILcdMultilevelRaster) instance.

Releasing resources

A JPIP model and its elements allocate a number of resources (ex. memory, network connections, ...). These are automatically released when they are garbage collected. However in some cases it is necessary to release these resources immediately. For example if the JPIP server limits the number of sessions per client. The resources can be released by invoking ILcdDisposable.dispose() on all model elements. Note that the caller must ensure that the elements are not used after they are disposed. Typically this means removing all layers that use the model from their view before disposing the elements.

Useful settings

  • The property getDefaultValue() allows the specify the default value that is assigned to decoded rasters.

Customization

  • The ILcdTransport used for communicating with a JPIP server can be customized by using the setTransportFactory(com.luciad.io.transport.ILcdTransportFactory) method.
  • The decodeRasterReference(com.luciad.format.jpeg2000.TLcdJPIPModelDescriptor) method can be overridden to customize the decoding of the georeferencing information of the raster. This is for example necessary if this information is embedded as application-specific XML.
  • Sample code

    
     ILcdModelDecoder decoder = new TLcdJPIPModelDecoder();
     ILcdModel model = decoder.decode("http://localhost:8080/image.jp2");
     

    Performance tips

    • The decoded rasters load their data lazily. The encoding parameters of the JPEG2000 image may affect the run-time performance.
    • The image cache size affects how much data needs to be retrieved from the server. Typically some of the data retrieved for an image region can be reused in subsequent requests for nearby image regions. A larger cache size increases the chance that data can be read from the cache instead of retrieving it again from the server.

    Thread safety

    • The decoding of models is thread-safe, as long as no properties are changed during the decoding.
    • The decoded models are thread-safe for read access.

    Supported versions and specifications

    Known limitations

    • Some rare EPSG model references are not supported.
    • If present, the geoJP2 transformation matrix may only contain translation, rotation and scale (for example no shear). Other transformations can be approximated by encoding tie points instead. Note that the decoding may fail when using tie points if the residual error is above the threshold.
    • This decoder uses the Kakadu JPEG2000 native library for actual decoding. The native library can allocate significant amount of memory. On 32 bit platforms, when several JPEG2000 images are opened and accessed in parallel, the required memory may exceed the limit of virtual memory space (2 GBytes on Windows, 3 GBytes on Linux), which may crash the application. To prevent that from happening, the Java code limits the number of JPEG2000 streams opened in parallel to 10. In practice this means that if more than 10 JPEG2000 images are open at the same time the performance of the decoder will decrease visibly, because the native library will have to switch between the images, each time cleaning its internal caches.

      The number of native decoders allowed to work in parallel can be controlled by setting the jpeg2000.pool.size system property (for example: java -Djpeg2000.pool.size=2 MyApplication).

    • Via the ALcdImage API it is possible to decode monochrome, RGB and multi band images. Each band of the image may contain <= 16 bits, which will not be scaled. Further, it is assumed that all data is unsigned.
    • to lower precision. You can obtain the precision in the image from the model descriptor and the precision in the ILcdRaster from its ILcdRaster.getColorModel() color model. The raster component is either 8 or 16 bits and the total number of bits per raster pixel is at most 32bits. Image components is obtained by scaling the image components. For example, an RGB JPIP image with 11 bits per component will be converted to an RGB raster with 8 bits per component where each component is scaled by (2^11 - 1) / (2^8 - 1).

    Requirements

    • The native JPEG2000 library has to be installed in order to be able to use this decoder.
    Since:
    2012.1
    • Constructor Details

      • TLcdJPIPModelDecoder

        public TLcdJPIPModelDecoder()
        Creates a new TLcdJPIPModelDecoder, with a globally shared buffer for caching pixel data.
        See Also:
      • TLcdJPIPModelDecoder

        public TLcdJPIPModelDecoder(ILcdBuffer aBuffer)
        Creates a new TLcdJPIPModelDecoder with the given buffer.
        Parameters:
        aBuffer - the buffer in which pixel data can be decoded and cached.
    • Method Details

      • setModelReferenceDecoder

        public void setModelReferenceDecoder(ILcdModelReferenceDecoder aModelReferenceDecoder)
        Sets the model reference decoder that will be used for decoded models whose images don't specify model references.

        The default value is null.

        Parameters:
        aModelReferenceDecoder - the model reference decoder.
      • getModelReferenceDecoder

        public ILcdModelReferenceDecoder getModelReferenceDecoder()
        Returns the model reference decoder that is used for decoded models whose images don't specify model references.
        Returns:
        the model reference decoder
        See Also:
      • setDefaultModelReference

        public void setDefaultModelReference(ILcdModelReference aDefaultModelReference)
        Sets the default model reference that will be assigned to decoded models whose images don't specify model references.

        The default value is null.

        Parameters:
        aDefaultModelReference - the default model reference.
      • getDefaultModelReference

        public ILcdModelReference getDefaultModelReference()
        Returns the default model reference that is assigned to decoded models whose images don't specify model references.
        Returns:
        the default model reference
        See Also:
      • setDefaultBounds

        public void setDefaultBounds(ILcdBounds aBounds)
        Sets the default model bounds that will be assigned to rasters of the decoded models whose images don't specify bounds.

        The default value is null.

        Parameters:
        aBounds - the default model bounds.
      • getDefaultBounds

        public ILcdBounds getDefaultBounds()
        Sets the default model bounds that is assigned to rasters of the decoded models whose images don't specify bounds.
        Returns:
        the bounds
        See Also:
      • setMinimumTiePointCount

        public void setMinimumTiePointCount(int aMinimumTiePointCount)
        Sets the minimum number of tie points required for positioning images that provide tie points instead of scaling information or transformation matrices.

        A value of 3 can be used, if the assumption is made that 3 tie points always define an affine transformation (which is not strictly guaranteed by the GeoTIFF specifications).

        A value of 2 can be used, if the assumption is made that 2 tie points always define an affine transformation without rotation.

        The default is 3.

        Parameters:
        aMinimumTiePointCount - the minimum number of tie points.
        See Also:
      • getMinimumTiePointCount

        public int getMinimumTiePointCount()
        Returns the minimum number of tie points required for positioning images that provide tie points.
        Returns:
        the minimum number of tie points
        See Also:
      • setAllowOrthographicReferencing

        public void setAllowOrthographicReferencing(boolean aAllowOrthographicReferencing)
        Specifies whether images that are positioned in geodetic references using tie points may be put in approximating orthographic grid references that are centered around the images.

        The default is true.

      • isAllowOrthographicReferencing

        public boolean isAllowOrthographicReferencing()
        Returns whether images that are positioned in geodetic references using tie points may be put in approximating orthographic grid references that are centered around the images.
        Returns:
        whether orthographic referencing is allowed
        See Also:
      • setMaximumResidualTiePointError

        public void setMaximumResidualTiePointError(double aMaximumResidualTiePointError)
        Sets the maximum acceptable average residual error for tie points, when positioning images that provide tie points instead of scaling information or transformation matrices.

        A raster is always positioned by means of an affine transformation in its coordinate system. For tie points that define an affine transformation, the residual error should therefore be 0. For tie points that define more complex, non-linear warping of the image, it will be larger than 0.

        The residual error is computed in image coordinates and expressed in pixels. The default is 10.

        Parameters:
        aMaximumResidualTiePointError - the maximum residual error, expressed in pixels.
        See Also:
      • getMaximumResidualTiePointError

        public double getMaximumResidualTiePointError()
        Returns the maximum acceptable average residual error for tie points.
        Returns:
        the maximum acceptable average residual error for tie points
        See Also:
      • setRasterReferencer

        public void setRasterReferencer(ILcdRasterReferencer aRasterReferencer)
        Sets the raster referencer that will be used when positioning images based on tie points. If it is set, it replaces the more basic settings minimumTiePointCount, allowOrthographicReferencing, and maximumResidualTiePointError, which are used by default.

        The initial value is null.

        Parameters:
        aRasterReferencer - the raster referencer, which will create model references and raster bounds based on tie points.
      • getRasterReferencer

        public ILcdRasterReferencer getRasterReferencer()
        Returns the raster referencer that is used when positioning images based on tie points.
        Returns:
        the raster referencer
        See Also:
      • setDefaultValue

        public void setDefaultValue(int aDefaultValue)
        Sets the default pixel value that will be assigned to the rasters of the decoded models.

        The initial value is 0.

        Parameters:
        aDefaultValue - the default pixel value.
        See Also:
      • getDefaultValue

        public int getDefaultValue()
        Returns the default pixel value that is assigned to the rasters of the decoded models.
        Returns:
        the default value.
        See Also:
      • getTransportFactory

        public ILcdTransportFactory getTransportFactory()
        Returns the transport factory that will construct the ILcdTransport used for communicating with a JPIP server.
        Returns:
        the transport
        See Also:
      • setTransportFactory

        public void setTransportFactory(ILcdTransportFactory aTransportFactory)
        Sets the transport factory that will construct the ILcdTransport used for communicating with a JPIP server.

        The default transport factory creates ILcdTransports based on the Apache HttpClient library. This factory uses the proxy configuration from the system-wide proxy selector

        The transports created by the factory should implement ILcdDisposable if they hold any resources (ex. network connections).

        This setter does not affect already decoded models.

        Parameters:
        aTransportFactory - the transport factory, must not be null
      • getImageCacheSize

        public int getImageCacheSize()
        Returns the size (in bytes) of the image cache.
        Returns:
        the cache size in bytes
        See Also:
      • setImageCacheSize

        public void setImageCacheSize(int aCacheSize)
        Sets the size (in bytes) of the image cache.

        A larger cache size results in lower bandwidth usage (the server does not need to resend data) but a higher memory consumption.

        The default cache size is 64MB.

        This setter does not affect already decoded models.

        The cache size will be clamped to the minimal cache size if it is too small.

        Parameters:
        aCacheSize - the cache size in bytes
      • isQueryServerOnCanDecode

        public boolean isQueryServerOnCanDecode()
        Returns whether the server should be queried in the canDecodeSource(String) method.
        Returns:
        true if the server should be queried
        See Also:
      • setQueryServerOnCanDecode

        public void setQueryServerOnCanDecode(boolean aQueryServerOnCanDecode)
        Sets whether the server should be queried in the canDecodeSource(String) method.

        If enabled, the server will be queried in the canDecode method to verify that it is a valid JPIP server, otherwise this method will only verify that the provided source name is a valid URI.

        This is enabled by default.

        Parameters:
        aQueryServerOnCanDecode - true if the server should be queried
      • getDisplayName

        public String getDisplayName()
        Description copied from interface: ILcdModelDecoder
        Returns a short, displayable name for the format that is decoded by this ILcdModelDecoder.
        Specified by:
        getDisplayName in interface ILcdModelDecoder
        Returns:
        the displayable name of this ILcdModelDecoder.
      • canDecodeSource

        public boolean canDecodeSource(String aSourceName)
        Checks whether TLcdJPIPModelDecoder can decode the given data. The source name should be a URI with one of the supported schemes.

        This method verifies that the specified source name is a valid URI. If isQueryServerOnCanDecode() is enabled then this method will also verify that the specified the server exists and is a valid JPIP server.

        Specified by:
        canDecodeSource in interface ILcdModelDecoder
        Parameters:
        aSourceName - the url of the image that is to be tested
        Returns:
        true if TLcdJPIPModelDecoder can decode the data specified by the source name, false otherwise.
        See Also:
      • decode

        public ILcdModel decode(String aSourceName) throws IOException
        Description copied from interface: ILcdModelDecoder
        Creates a new model from the given data source.
        Specified by:
        decode in interface ILcdModelDecoder
        Parameters:
        aSourceName - the data source to be decoded; typically a file name or a URL.
        Returns:
        A model containing the decoded data. While null is allowed, implementors are advised to throw an error instead.
        Throws:
        IOException - for any exceptions caused by IO problems or invalid data. Since decoding invalid data almost always results in RunTimeExceptions (NullPointerException, IndexOutOfBoundsException, IllegalArgumentException, ...) on unexpected places, implementations are advised to catch RuntimeExceptions in their decode() method, and wrap them into an IOException, as illustrated in the code snippet below.
        
           public ILcdModel decode( String aSourceName ) throws IOException {
              try (InputStream input = fInputStreamFactory.createInputStream(aSourceName)) {
                 // Perform decoding ...
              } catch (RuntimeException e) {
                 throw new IOException(e);
              }
           }
         
        See Also:
      • decodeRasterReference

        protected ILcdRasterReference decodeRasterReference(TLcdJPIPModelDescriptor aModelDescriptor) throws IOException
        Decodes the raster reference based on the metadata.

        The default implementation does a best effort using:

        1. the UUID metadata if it is present
        2. the default model reference decoder
        3. the default model reference and/or bounds

        You typically override this method if the raster reference is encoded in a custom way such as an XML metadata box.

        Parameters:
        aModelDescriptor - the model descriptor
        Returns:
        the raster reference
        Throws:
        IOException - if the raster reference could not be decoded