PDS_JP2
|
#include "uuid++.hh"
#include "PDS_Converters.hh"
#include "PVL.hh"
#include "PDS_Projection_Data.hh"
#include "JP2_Encoder.hh"
#include "Dimensions.hh"
#include "Files.hh"
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <cctype>
#include <string>
#include <cstring>
#include <vector>
#include <utility>
#include <stdexcept>
Defines | |
#define | PRODUCER_UUID |
#define | _VERSION_ " " |
#define | FILESYSTEM_PATHNAME_DELIMITER '/' |
Functions | |
int | recommended_resolution_levels (int width, int height) |
Determines the recommended number of resolution levels. | |
unsigned char * | UUID (const char *signature) |
Provides a UUID for a signature string. | |
void | usage (int exit_status=BAD_SYNTAX, bool list_descriptions=false) |
PDS_to_JP2 command line syntax and usage. | |
int | main (int argument_count, char **arguments) |
PDS_to_JP2 application. | |
Variables | |
const char *const | LABEL_EXTENSION = ".LBL" |
The filename extension for the output PDS label file. | |
const char *const | JP2_EXTENSION = ".JP2" |
The filename extension for the output JPEG2000 JP2 file. | |
const int | DEFAULT_TILE_SIZE = 0 |
The default tile size. | |
const int | MIN_RESOLUTION_SIZE = 64 |
The minimum image dimension at lowest resolution. | |
const char *const | DEFAULT_PROGRESSION_ORDER = "PCRL" |
The default progression order, optimized for very large images. | |
const int | DEFAULT_SIGNED_DATA = -1 |
The default data signedness if it can't be determined from the input. | |
const int | DEFAULT_DATA_ORDER = 1 |
The default data order if it can't be determined from the input. | |
const int | DEFAULT_PRECINCT_SIZE = 256 |
The default precinct size. | |
const int | DEFAULT_CODE_BLOCK_SIZE = 64 |
The default code block size. | |
const char * | DEFAULT_PRODUCER_SIGNATURE = NULL |
unsigned char | DEFAULT_PRODUCER_UUID [] = {PRODUCER_UUID} |
const int | SUCCESS = 0 |
Exit status values. | |
const int | BAD_SYNTAX = 1 |
const int | INVALID_ARGUMENT = 11 |
const int | PDS_LABEL_ERROR = 12 |
const int | NO_IMAGE_DATA = 13 |
const int | LOGIC_ERROR = 19 |
const int | NO_INPUT_FILE = 20 |
const int | EXISTING_OUTPUT_FILE = 21 |
const int | IO_FAILURE = 29 |
const int | PVL_ERROR = 30 |
const int | ENCODER_ERROR = JP2_Encoder::ENCODER_EXCEPTION |
const int | UNKNOWN_ERROR = -1 |
const char * | ID = "(1.56 2016/09/26 23:05:38)" |
Application identification name with source code version and date. | |
const char * | SOFTWARE_NAME_PARAMETER = "SOFTWARE_NAME" |
The label parameter to have its value set to the ID. | |
const int | MAX_RESOLUTION_LEVELS = 32 |
The maximum number of resolution levels allowed. | |
const int | MAX_QUALITY_LAYERS = 16384 |
The maximum number of quality layers allowed. | |
const int | DEFAULT_LOSSY_QUALITY_LAYERS = 20 |
Default lossy encoding quality layers. | |
const char | PATHNAME_DELIMITER = FILESYSTEM_PATHNAME_DELIMITER |
Host filesystem pathname delimiter. | |
const int | LABEL_WIDTH = 24 |
Listing format widths. | |
const int | VALUE_WIDTH = 9 |
char * | Program_Name |
The runtime command name. |
#define PRODUCER_UUID |
#define _VERSION_ " " |
#define FILESYSTEM_PATHNAME_DELIMITER '/' |
int recommended_resolution_levels | ( | int | width, |
int | height | ||
) |
Determines the recommended number of resolution levels.
The minimum of the image width and height is used to determine the number of resolution levels. While the minimum dimension value is larger than the MIN_RESOLUTION_SIZE the dimension value is halved and the number of resolution levels is increased from its intial value of zero. When the dimension value falls below the minimum the the final resolution values is returned, or one if the initial minimum dimension was less than the MIN_RESOLUTION_SIZE.
width | The image width. |
height | The image height. |
References MAX_RESOLUTION_LEVELS, and MIN_RESOLUTION_SIZE.
Referenced by main().
unsigned char * UUID | ( | const char * | signature ) |
Provides a UUID for a signature string.
A version 3 URL namespace UUID is generated from the signature string.
signature | The signature string. |
Referenced by main().
void usage | ( | int | exit_status = BAD_SYNTAX , |
bool | list_descriptions = false |
||
) |
PDS_to_JP2 command line syntax and usage.
PDS_to_JP2 [options] [-Input] <pathname>
Input PDS image file pathname.
If the pathname does not refer to a directory then it is the output JP2 file pathname. Otherwise the directory pathname and input filename are used with the JP2_EXTENSION replacing any existing extension or being appended. The output PDS label pathname is always the JP2 pathname with the LABEL_EXTENSION replacing any existing extension or being appended. The pathnames may be absolute or relative (to the current working directory).
Default: The directory where the input file is located.
No ouput file will be written. The input files will be examined and prepared for conversion with all the reports listed. This is a convenient way to see the source file structure and check that the expected output will be produced without having to process the files.
Default: Output is produced.
If the output files already exist, they will be overwritten.
Default: Do not overwrite existing files.
The order in which the JPEG2000 codestream is written. A JPEG2000 codestream has Position (image area), Component (image band), Resolution and Layer (quality) dimensions. The codestream progression order is specified as the first letters of each dimension in the order in which they are to be written; the first dimension specified varies the most slowly while the last dimension specified varies the most quickly.
Default: PCRL
The JPEG2000 image data is organized into tiles. The size of these tiles is specified in width,height pixels. If only the first tile size dimension is sepecified the tile will be square. The tile dimensions will be limited to the image dimensions. A tile size of 0 means that the corresponding dimension of the image is to be used. Thus if a single 0 is specified the tile size will be the same as the image which is conceptually an untiled JP2 file.
Default: 0
The JPEG2000 codestream provides access to the image at multiple resolution levels. The image is always available at full resolution. The next level is half resolution, then half of that, etc. No more than 31 resolutions are allowed. If not specified, the number of resolution levels will be chosen such that the minimum dimension of the image at lowest resolution is not less than 64 pixels, unless the minimum dimension at full resolution is less than twice this size in which case only the first full resolution will be provided.
Default: Depends on the minimum image dimension.
The JPEG2000 codestream may contain multiple quality layers when progressive quality rendering is desired. A minimum of one quality layer is required, and this is generally sufficient when lossless encoding is used to preserve scientific data accuracy. For lossy (irreversible) encoding multiple quality layers (typically 20) may be appropriate. A maximum of 16384 quality layers is allowed.
Default: 1 for lossless encoding (-Bit_rate of zero); 20 for lossy encoding (non-zero -Bit_rate)
The JPEG2000 codestream may be generated using lossless encoding
Default: 0.0 (lossless encoding)
The JPEG2000 image data is precinct structured. The size of these precincts is specified in width,height pixels. If only the first precinct size dimension is sepecified the precinct will be square. The precinct dimensions must be powers of 2. Precinct sizes may be specfied for each resolution level (the first resolution level is full resolution). If fewer precinct sizes have been specified than the number of resolution levels, the last precinct size specified will be used for all remaining resolution levels.
Default: 256
The basic structural unit of JPEG2000 image data is a code block. This unit contains the image information for a small area of the image, which will not be greater than 64 by 64 pixels. If only one code block dimension is specified the code block size will be square.
Default: 64
Normally the image data values are treated as signed or unsigned based on information from the input file PDS label: If the SAMPLE_TYPE
parameter is present and its value contains the "UNSIGNED" string, the image data is treated as unsigned; if the value contains the "SIGNED" string the data is treated as signed. This option determines the effective signedness of the image data values regardless of the PDS label parameter value.
Default: Pixel data of unknown signedness is unsigned.
Normally the image data values are treated as MSB or LSB ordered based on information from the input file PDS label: If the SAMPLE_TYPE
parameter is present and its value contains the "MSB" string, the image data is treated as MSB ordered; if the value contains the "LSB" string the data is treated as LSB ordered. This option determines the effective byte order of multi-byte image data values regardless of the PDS label parameter value.
Default: Pixel data of unknown data order is MSB.
The data producer ID is stored in a UUID box of the JP2 file alongside the URL box that contains the relative file URL for the PDS label file. These boxes are encapsulated inside a UUID Info box. A Universally Unique IDentifier (UUID; see http://www.webdav.org/specs/draft-leach-uuids-guids-01.txt) is 16, comma separated (no spaces) 8-bit values that are intended to uniquely identify the data producer. Software for producing UUIDs is available on line (e.g. http://www.ossp.org/pkg/lib/uuid/). If a single 0, or the word "none", is specified a null (all zeros) UUID will be used.
If the OSSP UUID library support is available (OSSP_UUID
was defined at compile time) the ID may alternatively be specified as a signature string; this is usually a URL such as "http://hirise.lpl.arizona.edu/". In this case the UUID values will be determined from the signature string.
Default: The default UUID is sepecified at compile time by the PRODUCER_SIGNATURE
or PRODUCER_UUID
value.
Add a GeoTIFF UUID box to the JP2 file if the necessary image projection parameters are available in the input file PDS label. The GeoTIFF UUID signature is -
0xb1, 0x4b, 0xf8, 0xbd, 0x08, 0x3d, 0x4b, 0x43, 0xa5, 0xae, 0x8c, 0xd7, 0xd5, 0xa6, 0xce, 0x03
Default: No GeoTIFF box
Note: This feature is optionally included at compile-time and requires a GDAL library compiled with OGR support.
Add GML boxes to the JP2 file if the necessary image projection parameters are available in the input file PDS label. The GML boxes are contained in an Association ("asoc") super-box with an initial Label ("lbl ") box with the text "gml.data", followed by an Association with a "gml.root-instance" label and an XML box with the "gml:FeatureCollection" specifications, and then an Association with a "CRSDictionary.gml" label and an XML box with the "gml:Dictionary" specifications.
Warning: This is an experimental feature. It has not been shown to produce correct results. It will have no affect on any other operation of the program nor on any other content of the JP2 file that is produced.
Default: No GML box
Note: This feature, optionally included at compile time (if GDAL
was defined), requires the use of a GDAL library compiled with OGR support.
Prints this usage description.
exit_status | This method always results in program exit. If the exit status value is not specified the BAD_SYNTAX value will be used. |
list_descriptions | If true, long option descriptions will be listed; otherwise only the brief option syntax is listed. |
References DEFAULT_CODE_BLOCK_SIZE, DEFAULT_DATA_ORDER, DEFAULT_PRECINCT_SIZE, DEFAULT_PRODUCER_SIGNATURE, DEFAULT_PRODUCER_UUID, DEFAULT_PROGRESSION_ORDER, DEFAULT_SIGNED_DATA, DEFAULT_TILE_SIZE, MAX_RESOLUTION_LEVELS, MIN_RESOLUTION_SIZE, Program_Name, and UUID_SIZE.
int main | ( | int | argument_count, |
char ** | arguments | ||
) |
PDS_to_JP2 application.
Converts a PDS image file having a label attached to uncompressed image data to a detached PDS label file and a JP2 image data file.
In input PDS file is required. The output PDS label file pathname always follows the JP2 file pathname but with the LABEL_EXTENSION replacing the JP2 filename extension, or appended to it if it does not have an extension. If the -Output pathname is specified and does not refer to a directory, then that is the JP2 file pathname. If it does refer to a directory, then the input filename is used with the directory pathname but with the JP2_EXTENSION replacing the input filename extension, or appended to it if it does not have an extension. If no -Output pathname is specified then the input pathname is used but with the JP2_EXTENSION. Pathnames may be absolute or relative (to the current working directory). If files at either the output PDS label or JP2 pathnames exist and the -Force option has not been specified the program will exit with an EXISTING_OUTPUT_FILE status; a warning will be provided in this case if the -Force option has been specified.
A report listing the input and output files, the image data specifications and the JP2 configuration will be written to stdout before the input file is processed to generate the output files.
A PDS_Converter object instantiated on the input file is used to convert the input file PDS label to the new detatched label file. The selection of the appropriate PDS label converter is done by each registered PDS label converter examining the file's label and deciding if it is suitable for handling the conversion; the first one to indicate that it is appropriate for the input file is used. Product specific converters are queried first until finally the Generic_PDS_Converter is tried.
If the label converter is unable to locate a group of parameters in the label that describes the IMAGE
data block the program will exit with a PDS_LABEL_ERROR status. If the Image_Data_Block does not report a non-zero size, as determined from the BANDS
, LINES
, LINE_SAMPLES
and SAMPLE_BITS
parameters (the corresponding values default to zero if the parameter is not present, except BANDS
which defaults to one), the program will exit with a NO_IMAGE_DATA status. If LINE_PREFIX_BYTES
or LINE_SUFFIX_BYTES
are specified, they will be skipped during input image encoding. The image description parameters are used to set the JP2 encoder configuration. The SAMPLE_BITS
parameter determines the number of bits per pixel unless a SAMPLE_BIT_MASK
parameter is provided. The JP2 encoder is capable of processing from 1 to 16 bits per pixel. Source image pixel data is expected to be contained in whole bytes; thus an image with 10 bits per pixel will use 2 bytes of storage per pixel and the extra bits will be ignored by the JP2_Encoder.
Product specific PDS label converters may apply any label changes deemed appropriate in addition to, or instead of, using the Generic_PDS_Converter. The generic label converter ensures that a standard compliant PDS/JP2 label is generated. N.B.: the generic label converter will remove all data block descriptions from the label except the IMAGE
description which is moved to its appropriate location in the new label.
Note: Before the PDS label converter is requested to write the new label file the SOFTWARE_NAME
parameter in the label, if it exists, is updated with the application identification.
A JP2_Encoder object is used to generate the JP2 file containing the compressed image data from the input file. The JP2 file conforms to the JPEG2000 Part 1 standard (ISO/IEC 15444-1:2004). The input image data will be written as a losslessly compressed JPEG2000 codestream contained in the JP2 file. The input image data must be organized as column major band sequential pixels. If LINE_PREFIX_BYTES
and/or LINE_SUFFIX_BYTES
parameters are present in the PDS label the corresponding bytes in the input file will be skipped. The encoder is given the input file pathname and the starting location of the image data in the input file and image data description provided by the PDS_Converter. The encoder is configured with additional codestream structural information - tile, precinct and code block sizes, progression order and resolution levels - provided by command line options or default values. N.B.: The default values have been chosen to produce a JPEG2000 codestream that should be optimally structured for most JP2 file readers. However, the choice of precinct sizes and, in particular, tiling may have a significant effect for some readers. The encoder will include both tile and packet location markers in the JPEG2000 codestream to assist rendering software in accessing the image data from large files as quickly as possible. Nevertheless, some rendering software will not recognize these markers; and some software may be overwhelmed by large images that are not tiled.
In addition to the JPEG2000 codestream the JP2 file contains metadata "boxes" that describe the image data. A UUID List box will always be included that contains a UUID box with the producer signature specifed by the -ID option or the default value alongside a URL box which names the detatched PDS label file. If the -Geotiff and/or -GML command line options have been specified a PDS_Projection_Data object will be instantiated on the PDS_Converter object. This will use the IMAGE_MAP_PROJECTION
parameters of the PDS label to construct a spatial reference description from which GeoTIFF and/or GML formatted data content is produced and then encapsulated in appropriate JP2 boxes that are passed to the encoder for inclusion in the JP2 file.
Note: Generating the JPEG2000 codestream can be a very resource intensive process. In particular, unless incremental codestream flushing was enabled when the software was compiled (which is generally not recommened due to the codestream structural complications this creates) the entire codestream is held in memory until it is complete before being written to the JP2 file.
argument_count | The number of command line arguments. |
arguments | The array of command line arguments. |
References Aggregate::add(), UA::HiRISE::converter_for(), DEFAULT_CODE_BLOCK_SIZE, DEFAULT_DATA_ORDER, DEFAULT_LOSSY_QUALITY_LAYERS, DEFAULT_PRECINCT_SIZE, DEFAULT_PRODUCER_SIGNATURE, DEFAULT_PRODUCER_UUID, DEFAULT_PROGRESSION_ORDER, DEFAULT_SIGNED_DATA, DEFAULT_TILE_SIZE, JP2_Encoder::encode(), ENCODER_ERROR, JP2_Encoder::encoder_error(), EXISTING_OUTPUT_FILE, PIRL::file_basename(), PIRL::file_directory(), PIRL::file_exists(), PIRL::file_is_directory(), PIRL::file_is_readable(), PIRL::file_name(), PIRL::file_pathname(), Size_2D::Height, PIRL::hostname(), ID, Image_Data_Block::image_bands(), PDS_Converter::image_data(), PDS_Data::IMAGE_DATA_BLOCK_NAME, Image_Data_Block::image_height(), Image_Data_Block::image_width(), UA::HiRISE::indent(), INVALID_ARGUMENT, IO_FAILURE, JP2_EXTENSION, PDS_Projection_Data::JP2_GeoTIFF(), PDS_Projection_Data::JP2_GML(), LABEL_EXTENSION, LABEL_WIDTH, Image_Data_Block::line_prefix_bytes(), Image_Data_Block::line_suffix_bytes(), PDS_Data_Block::location(), LOGIC_ERROR, MAX_QUALITY_LAYERS, MAX_RESOLUTION_LEVELS, Image_Data_Block::MSB_data(), NO_IMAGE_DATA, NO_INPUT_FILE, PDS_Data::parameter_value(), PDS_LABEL_ERROR, Image_Data_Block::pixel_bits(), Image_Data_Block::pixel_bytes(), UA::HiRISE::power_of_2(), PDS_Converter::product_names(), Program_Name, PVL_ERROR, recommended_resolution_levels(), Image_Data_Block::signed_data(), PDS_Data_Block::size(), SOFTWARE_NAME_PARAMETER, JP2_Encoder::source(), Image_Data_Block::source_filename(), SUCCESS, UNKNOWN_ERROR, usage(), UUID(), UUID_SIZE, VALUE_WIDTH, Size_2D::Width, and PDS_Converter::write_PDS_JP2_label().
const char* const LABEL_EXTENSION = ".LBL" |
The filename extension for the output PDS label file.
const char* const JP2_EXTENSION = ".JP2" |
The filename extension for the output JPEG2000 JP2 file.
const int DEFAULT_TILE_SIZE = 0 |
const int MIN_RESOLUTION_SIZE = 64 |
The minimum image dimension at lowest resolution.
Referenced by recommended_resolution_levels(), and usage().
const char* const DEFAULT_PROGRESSION_ORDER = "PCRL" |
const int DEFAULT_SIGNED_DATA = -1 |
const int DEFAULT_DATA_ORDER = 1 |
The default data order if it can't be determined from the input.
Positive is MSB; negative is LSB.
const int DEFAULT_PRECINCT_SIZE = 256 |
const int DEFAULT_CODE_BLOCK_SIZE = 64 |
const char* DEFAULT_PRODUCER_SIGNATURE = NULL |
unsigned char DEFAULT_PRODUCER_UUID[] = {PRODUCER_UUID} |
const int SUCCESS = 0 |
Exit status values.
const int BAD_SYNTAX = 1 |
const int INVALID_ARGUMENT = 11 |
const int PDS_LABEL_ERROR = 12 |
const int NO_IMAGE_DATA = 13 |
const int LOGIC_ERROR = 19 |
const int NO_INPUT_FILE = 20 |
const int EXISTING_OUTPUT_FILE = 21 |
const int IO_FAILURE = 29 |
const int PVL_ERROR = 30 |
const int ENCODER_ERROR = JP2_Encoder::ENCODER_EXCEPTION |
Referenced by main().
const int UNKNOWN_ERROR = -1 |
const char* ID = "(1.56 2016/09/26 23:05:38)" |
Application identification name with source code version and date.
const char* SOFTWARE_NAME_PARAMETER = "SOFTWARE_NAME" |
The label parameter to have its value set to the ID.
const int MAX_RESOLUTION_LEVELS = 32 |
The maximum number of resolution levels allowed.
Referenced by main(), recommended_resolution_levels(), JP2_Encoder::resolution_levels(), and usage().
const int MAX_QUALITY_LAYERS = 16384 |
The maximum number of quality layers allowed.
Referenced by main(), and JP2_Encoder::quality_layers().
const int DEFAULT_LOSSY_QUALITY_LAYERS = 20 |
Default lossy encoding quality layers.
Referenced by main().
const char PATHNAME_DELIMITER = FILESYSTEM_PATHNAME_DELIMITER |
Host filesystem pathname delimiter.
const int LABEL_WIDTH = 24 |
Listing format widths.
const int VALUE_WIDTH = 9 |
char* Program_Name |
The runtime command name.