Skip to content

Commit

Permalink
st0602: initial implementation work
Browse files Browse the repository at this point in the history
  • Loading branch information
bradh committed Nov 28, 2021
1 parent d1d84c5 commit 1a555a5
Show file tree
Hide file tree
Showing 59 changed files with 4,889 additions and 6 deletions.
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,18 @@ The MISB has been quite prolific in creation of new standards since its
inception in 2000. As of April 2021, over four dozen standards are listed
on its web site. While the scope of the jmisb project is to support as many of
these standards as possible, the initial focus will be on those
in most widespread use.
in most widespread use.

The table below lists the status of currently-supported standards:

| Identifier | Name | Implementation Status | Known Issues |
| ---------- | ---- | --------------------- | ------------ |
| ST 0102 | Security Metadata Universal and Local Sets for Digital Motion Imagery | Implemented as of ST 0102.12. There is read-only support for some tags (not UMID) that were removed in ST 0102.12. | |
| EG 0104 | Predator UAV Basic Universal Metadata Set | Read only support for EG 0104.5. Writing is not planned, since this metadata set is deprecated by MISB. | |
| ST 0601 | UAS Datalink Local Set | Mostly implemented as of ST 0601.17. | [#140](https://github.com/WestRidgeSystems/jmisb/issues/140) |
| ST 0603 | MISP Time System and Timestamps | Partly implemented as of ST 0603.5. | [#97](https://github.com/WestRidgeSystems/jmisb/issues/97) |
| ST 0604 | Timestamps for Class 1 / Class 2 Motion Imagery | Partly implemented as of ST 0604.6. No support for Nano Precision Time Stamp, or Commercial Time Stamp. | [#102](https://github.com/WestRidgeSystems/jmisb/issues/102) |
| ST 0601 | UAS Datalink Local Set | Mostly implemented as of ST 0601.17. | [#140](https://github.com/WestRidgeSystems/jmisb/issues/140) |
| ST 0602 | Annotation Metadata Set | Partly implemented as of ST 0602.4. Limited support for CGM annotations. | |
| ST 0603 | MISP Time System and Timestamps | Partly implemented as of ST 0603.5. | [#97](https://github.com/WestRidgeSystems/jmisb/issues/97) |
| ST 0604 | Timestamps for Class 1 / Class 2 Motion Imagery | Partly implemented as of ST 0604.6. | [#102](https://github.com/WestRidgeSystems/jmisb/issues/102) |
| ST 0805 | KLV to Cursor-on-Target (CoT) Conversions | Implemented as of ST 0805.1. Interoperability testing with FalconView and CoT Debug Tool. | |
| ST 0806 | Remote Video Terminal Metadata Set | Implemented as of ST 0806.5. Unit tests only, no interoperability testing. | |
| ST 0808 | Ancillary Text Metadata Sets | Implemented as of ST 0808.2. Local Set support only, no universal set support. Deprecated by MISB. | |
Expand All @@ -51,7 +52,7 @@ The table below lists the status of currently-supported standards:
| ST 1201 | Floating Point to Integer Mapping | Fully implemented per ST 1201.5. | |
| ST 1204 | Motion Imagery Identification System (MIIS) Core Identifier | Implemented as of ST 1204.3. | |
| ST 1206 | Synthetic Aperture Radar (SAR) Motion Imagery Metadata | Implemented as of ST 1206.1. Unit tests only, no interoperability testing. | |
| ST 1303 | Multi-Dimensional Array Pack (MDAP) | Partly implemented as of ST 1303.2. Only formats and dimensions known to be used are available. Limited testing. | [#198](https://github.com/WestRidgeSystems/jmisb/issues/198) |
| ST 1303 | Multi-Dimensional Array Pack (MDAP) | Partly implemented as of ST 1303.2. Only formats and dimensions known to be used are available. Limited testing. | [#198](https://github.com/WestRidgeSystems/jmisb/issues/198) |
| ST 1402 | MPEG-2 Transport Stream for Class 1/Class 2 Motion Imagery, Audio, and Metadata | Mostly implemented, support for Sync and Asynchronous multiplexing. | |
| ST 1902 | Motion Imagery Metadata (MIMD): Model-to-KLV Transmutation Instructions | Implemented as of ST 1902.1. No interoperability testing. | |
| ST 1903 | Motion Imagery Metadata (MIMD): Model | Implemented as of ST 1903.1. No interoperability testing. | |
Expand Down
1 change: 1 addition & 0 deletions api/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
exports org.jmisb.api.klv.st0102.universalset;
exports org.jmisb.api.klv.st0601;
exports org.jmisb.api.klv.st0601.dto;
exports org.jmisb.api.klv.st0602;
exports org.jmisb.api.klv.st0603;
exports org.jmisb.api.klv.st0604;
exports org.jmisb.api.klv.st0805;
Expand Down
39 changes: 39 additions & 0 deletions api/src/main/java/org/jmisb/api/klv/KlvConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,43 @@ private KlvConstants() {}
0x06, 0x0E, 0x2B, 0x34, 0x02, 0x03, 0x01, 0x01, 0x0E, 0x01, 0x03, 0x03,
0x1C, 0x00, 0x00, 0x00
});

/**
* Universal label for Byte Order preface item for Annotation Universal Metadata Set (ST 0602).
*/
public static final UniversalLabel AnnotationByteOrderUl =
new UniversalLabel(
new byte[] {
0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x02, 0x01,
0x02, 0x00, 0x00, 0x00
});

/**
* Universal label for Active Lines per Frame preface item for Annotation Universal Metadata Set
* (ST 0602).
*/
public static final UniversalLabel AnnotationActiveLinesPerFrameUl =
new UniversalLabel(
new byte[] {
0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x03, 0x02,
0x02, 0x00, 0x00, 0x00
});
/**
* Universal label for Active Samples per Line preface item for Annotation Universal Metadata
* Set (ST 0602).
*/
public static final UniversalLabel AnnotationActiveSamplesPerLineUl =
new UniversalLabel(
new byte[] {
0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x05, 0x01,
0x02, 0x00, 0x00, 0x00
});

/** Universal label for Annotation Universal Metadata Set (ST 0602). */
public static final UniversalLabel AnnotationUniversalSetUl =
new UniversalLabel(
new byte[] {
0x06, 0x0E, 0x2B, 0x34, 0x02, 0x01, 0x01, 0x01, 0x0E, 0x01, 0x03, 0x03,
0x01, 0x00, 0x00, 0x00
});
}
13 changes: 13 additions & 0 deletions api/src/main/java/org/jmisb/api/klv/MisbMessageFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
import org.jmisb.api.klv.st0102.localset.SecurityMetadataLocalSetFactory;
import org.jmisb.api.klv.st0102.universalset.SecurityMetadataUniversalSetFactory;
import org.jmisb.api.klv.st0601.UasDatalinkMessageFactory;
import org.jmisb.api.klv.st0602.AnnotationActiveLinesPerFrameFactory;
import org.jmisb.api.klv.st0602.AnnotationActiveSamplesPerLineFactory;
import org.jmisb.api.klv.st0602.AnnotationByteOrderFactory;
import org.jmisb.api.klv.st0602.AnnotationMetadataUniversalSetFactory;
import org.jmisb.api.klv.st0808.AncillaryTextLocalSetFactory;
import org.jmisb.api.klv.st0903.vtrack.VTrackLocalSetFactory;
import org.jmisb.api.klv.st1108.InterpretabilityQualityLocalSetFactory;
Expand Down Expand Up @@ -38,6 +42,15 @@ private MisbMessageFactory() {
registerHandler(
KlvConstants.InterpretabilityQualityLocalSetUl,
new InterpretabilityQualityLocalSetFactory());
registerHandler(KlvConstants.AnnotationByteOrderUl, new AnnotationByteOrderFactory());
registerHandler(
KlvConstants.AnnotationActiveLinesPerFrameUl,
new AnnotationActiveLinesPerFrameFactory());
registerHandler(
KlvConstants.AnnotationActiveSamplesPerLineUl,
new AnnotationActiveSamplesPerLineFactory());
registerHandler(
KlvConstants.AnnotationUniversalSetUl, new AnnotationMetadataUniversalSetFactory());
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package org.jmisb.api.klv.st0602;

import org.jmisb.api.common.KlvParseException;
import org.jmisb.core.klv.PrimitiveConverter;

/**
* Active Lines per Frame.
*
* <p>Total number of active lines (rows) in a frame of an image matrix.
*/
public class ActiveLinesPerFrame implements IAnnotationMetadataValue {
private int number;

/**
* Create from value.
*
* @param lines the number of lines per frame (in the range [0, 65535]).
* @throws KlvParseException if {@code lines} is not in the valid range
*/
public ActiveLinesPerFrame(int lines) throws KlvParseException {
if ((lines < 0) || (lines > 65535)) {
throw new KlvParseException("Active Lines Per Frame must be in the range [0, 65535]");
}
number = lines;
}

/**
* Create from encoded bytes.
*
* @param bytes Byte array of length 2
* @throws KlvParseException if the length is not valid
*/
public ActiveLinesPerFrame(byte[] bytes) throws KlvParseException {
if (bytes.length != 2) {
throw new KlvParseException(
"Active Lines Per Frame encoding is a two-byte unsigned int");
}
number = PrimitiveConverter.toUint16(bytes);
}

/**
* Get the number of lines per frame.
*
* @return The number of lines (rows) as an unsigned integer
*/
public int getNumber() {
return number;
}

@Override
public byte[] getBytes() {
return PrimitiveConverter.uint16ToBytes(number);
}

@Override
public String getDisplayableValue() {
return String.format("%d", number);
}

@Override
public String getDisplayName() {
return "Active Lines Per Frame";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package org.jmisb.api.klv.st0602;

import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import org.jmisb.api.common.KlvParseException;
import org.jmisb.api.klv.ArrayBuilder;
import org.jmisb.api.klv.IKlvKey;
import org.jmisb.api.klv.IKlvValue;
import org.jmisb.api.klv.IMisbMessage;
import org.jmisb.api.klv.KlvConstants;
import org.jmisb.api.klv.UniversalLabel;

/**
* Active Lines Per Frame prefix message.
*
* <p>This message conceptually wraps an {@code ActiveLinesPerFrame} instance so it can appear as a
* top level entity in a KLV stream.
*/
public class ActiveLinesPerFrameMessage implements IMisbMessage {

private final ActiveLinesPerFrame activeLinesPerFrame;
private static final int UNIVERSAL_LABEL_BYTE_OFFSET = 0;
private static final int UNIVERSAL_LABEL_LEN =
KlvConstants.AnnotationActiveLinesPerFrameUl.getBytes().length;
private static final int LEN_BYTE_OFFSET = UNIVERSAL_LABEL_BYTE_OFFSET + UNIVERSAL_LABEL_LEN;
private static final int LEN_REQUIRED_LEN = 1;
private static final int VALUE_BYTE_OFFSET = LEN_BYTE_OFFSET + LEN_REQUIRED_LEN;
private static final int VALUE_REQUIRED_LEN = 2;
private static final int TOTAL_REQUIRED_LEN =
UNIVERSAL_LABEL_LEN + LEN_REQUIRED_LEN + VALUE_REQUIRED_LEN;

/**
* Construct an {@code ActiveLinesPerFrameMessage} by wrapping an {@link ActiveLinesPerFrame}
* instance.
*
* @param linesPerFrame the wrapped object
*/
public ActiveLinesPerFrameMessage(ActiveLinesPerFrame linesPerFrame) {
this.activeLinesPerFrame = linesPerFrame;
}

/**
* Construct an {@code ActiveLinesPerFrameMessage} from a serialised representation.
*
* <p>The serialised representation is the universal label, the length, and the two byte value.
*
* @param bytes byte array containing the serialised representation.
* @throws KlvParseException if the label or length are not as expected.
*/
public ActiveLinesPerFrameMessage(byte[] bytes) throws KlvParseException {
verifyLength(bytes);
verifyUniversalLabel(bytes);
activeLinesPerFrame =
new ActiveLinesPerFrame(
Arrays.copyOfRange(
bytes, VALUE_BYTE_OFFSET, VALUE_BYTE_OFFSET + VALUE_REQUIRED_LEN));
}

private void verifyUniversalLabel(byte[] bytes) throws KlvParseException {
if (!Arrays.equals(
bytes,
0,
UNIVERSAL_LABEL_LEN,
KlvConstants.AnnotationActiveLinesPerFrameUl.getBytes(),
0,
UNIVERSAL_LABEL_LEN)) {
throw new KlvParseException(
"Unexpected Annotation Active Lines per Frame Universal Label passed in");
}
}

private void verifyLength(byte[] bytes) throws KlvParseException {
if (bytes.length != TOTAL_REQUIRED_LEN) {
throw new KlvParseException(
"Annotation Active Lines per Frame Universal Label must have length 19");
}
if (bytes[LEN_BYTE_OFFSET] != VALUE_REQUIRED_LEN) {
throw new KlvParseException(
"Annotation Active Lines per Frame Universal Label must be specified as length 2");
}
}

@Override
public UniversalLabel getUniversalLabel() {
return KlvConstants.AnnotationActiveLinesPerFrameUl;
}

@Override
public byte[] frameMessage(boolean isNested) {
if (isNested) {
throw new IllegalArgumentException("ST 0602 active lines per frame cannot be nested");
}
byte[] linesBytes = activeLinesPerFrame.getBytes();
ArrayBuilder arrayBuilder = new ArrayBuilder();
arrayBuilder.append(KlvConstants.AnnotationActiveLinesPerFrameUl);
arrayBuilder.appendAsBerLength(linesBytes.length);
arrayBuilder.append(linesBytes);
return arrayBuilder.toBytes();
}

@Override
public String displayHeader() {
return "ST 0602, Active Lines per Frame";
}

@Override
public IKlvValue getField(IKlvKey tag) {
if (tag.equals(AnnotationMetadataKey.ActiveLinesPerFrame)) {
return this.activeLinesPerFrame;
} else {
return null;
}
}

@Override
public Set<? extends IKlvKey> getIdentifiers() {
if (activeLinesPerFrame != null) {
return Collections.singleton(AnnotationMetadataKey.ActiveLinesPerFrame);
} else {
return Collections.emptySet();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package org.jmisb.api.klv.st0602;

import org.jmisb.api.common.KlvParseException;
import org.jmisb.core.klv.PrimitiveConverter;

/**
* Active Samples per Line.
*
* <p>Total number of active samples (columns) in a line of an image matrix.
*/
public class ActiveSamplesPerLine implements IAnnotationMetadataValue {
private int number;

/**
* Create from value.
*
* @param samples the number of samples per line (in the range [0, 65535]).
* @throws KlvParseException if {@code samples} is not in the valid range
*/
public ActiveSamplesPerLine(int samples) throws KlvParseException {
if ((samples < 0) || (samples > 65535)) {
throw new KlvParseException("Active Samples Per Line must be in the range [0, 65535]");
}
number = samples;
}

/**
* Create from encoded bytes.
*
* @param bytes Byte array of length 2
* @throws KlvParseException if the length is not valid
*/
public ActiveSamplesPerLine(byte[] bytes) throws KlvParseException {
if (bytes.length != 2) {
throw new KlvParseException(
"Active Samples Per Line encoding is a two-byte unsigned int");
}
number = PrimitiveConverter.toUint16(bytes);
}

/**
* Get the number of samples per line.
*
* @return The number of samples (columns) as an unsigned integer
*/
public int getNumber() {
return number;
}

@Override
public byte[] getBytes() {
return PrimitiveConverter.uint16ToBytes(number);
}

@Override
public String getDisplayableValue() {
return String.format("%d", number);
}

@Override
public String getDisplayName() {
return "Active Samples Per Line";
}
}
Loading

0 comments on commit 1a555a5

Please sign in to comment.