This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
commit 255d12c4b66ac722d9e831a15c985f08ebe7593e Author: jsorel <[email protected]> AuthorDate: Tue Jun 2 14:51:47 2026 +0200 Basic support of some compression in GeoHEIF files: - Add `CompressionConfiguration`, `CompressedUnitsItemInfo`, `CompressionAV1`, `CompressionJP2K`, `HevcConfigurationItem` and `CleanAperture` boxes. - Add "auxl", "base", "prem" and "thmb" image references. - Support signed integer component, added in ISO:23001-17 amendment 2. - Support single chunk of zlib compressed tiles. The compression boxes such as AV1 and JP2K are mostly empty for now, but these boxes were nevertheless added for metadata purpose and also for making possible (in a next commit) to provide better error message. --- .../org/apache/sis/image/StatisticsCalculator.java | 8 +- .../org/apache/sis/io/stream/ChannelDataInput.java | 15 ++- .../apache/sis/io/stream/HyperRectangleReader.java | 1 - .../main/org/apache/sis/io/stream/Region.java | 2 +- .../sis/storage/geoheif/CoverageBuilder.java | 70 ++++++++++-- .../apache/sis/storage/geoheif/GeoHeifStore.java | 20 ++-- .../main/org/apache/sis/storage/geoheif/Image.java | 2 +- .../sis/storage/geoheif/UncompressedImage.java | 27 ++++- .../sis/storage/isobmff/MainBoxRegistry.java | 10 ++ .../org/apache/sis/storage/isobmff/Reader.java | 4 +- .../isobmff/image/AuxiliaryImageReference.java | 54 +++++++++ .../storage/isobmff/image/BaseImageReference.java | 53 +++++++++ .../isobmff/image/PremultipliedImageReference.java | 53 +++++++++ .../storage/isobmff/image/ThumbnailReference.java | 53 +++++++++ .../sis/storage/isobmff/mpeg/CleanAperture.java | 57 ++++++++++ .../apache/sis/storage/isobmff/mpeg/Component.java | 5 +- .../isobmff/mpeg/CompressedUnitsItemInfo.java | 122 +++++++++++++++++++++ .../sis/storage/isobmff/mpeg/CompressionAV1.java | 57 ++++++++++ .../isobmff/mpeg/CompressionConfiguration.java | 80 ++++++++++++++ .../sis/storage/isobmff/mpeg/CompressionJP2K.java | 57 ++++++++++ .../isobmff/mpeg/HevcConfigurationItem.java | 57 ++++++++++ .../apache/sis/storage/isobmff/mpeg/UnitType.java | 71 ++++++++++++ 22 files changed, 849 insertions(+), 29 deletions(-) diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/StatisticsCalculator.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/StatisticsCalculator.java index 3d480b20c6..61cf0a5288 100644 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/StatisticsCalculator.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/StatisticsCalculator.java @@ -168,9 +168,11 @@ final class StatisticsCalculator extends AnnotatedImage { * Clones the given array and all values in the array. */ static Statistics[] clone(Statistics[] result) { - result = result.clone(); - for (int i=0; i<result.length; i++) { - result[i] = result[i].clone(); + if (result != null) { + result = result.clone(); + for (int i=0; i<result.length; i++) { + result[i] = result[i].clone(); + } } return result; } diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/ChannelDataInput.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/ChannelDataInput.java index bb819a57e4..53999a9f56 100644 --- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/ChannelDataInput.java +++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/ChannelDataInput.java @@ -1155,7 +1155,7 @@ loop: while (hasRemaining()) { /** * Skips over and discards exactly <var>n</var> bytes of data from this input stream. * - * @param n number of bytes to skip. Can be negative. + * @param n number of bytes to skip. Can be negative for moving backward. * @throws IOException if an error occurred while reading. */ public final void skipNBytes(int n) throws IOException { @@ -1165,6 +1165,19 @@ loop: while (hasRemaining()) { } } + /** + * Skips over and discards exactly <var>n</var> bytes of data from this input stream. + * + * @param n number of bytes to skip. Can be negative for moving backward. + * @throws IOException if an error occurred while reading. + */ + public final void skipNBytes(long n) throws IOException { + n -= skipBytes((int) Math.min(n, Integer.MAX_VALUE)); + if (n != 0) { + seek(Math.addExact(position(), n)); + } + } + /** * Moves to the given position in this stream. * diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/HyperRectangleReader.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/HyperRectangleReader.java index 512e06d849..0f1e7fbd24 100644 --- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/HyperRectangleReader.java +++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/HyperRectangleReader.java @@ -51,7 +51,6 @@ public class HyperRectangleReader { /** * The {@code input} position of the first sample (ignoring sub-area and subsampling). - * This is initially the {@code origin} argument given to the constructor, copied verbatim. * * @see #getOrigin() */ diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/Region.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/Region.java index 5d1da03a63..4a7bd9442f 100644 --- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/Region.java +++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/Region.java @@ -267,7 +267,7 @@ public final class Region { /** * Compares this region with the given object for equality. * - * @return the object to compare with this region. + * @param obj the object to compare with this region. * @return whether this region and the given object are equal. */ @Override diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/CoverageBuilder.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/CoverageBuilder.java index f72a91de76..c16745d0e4 100644 --- a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/CoverageBuilder.java +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/CoverageBuilder.java @@ -45,6 +45,8 @@ import org.apache.sis.coverage.grid.GridExtent; import org.apache.sis.coverage.grid.GridGeometry; import org.apache.sis.coverage.grid.PixelInCell; import org.apache.sis.storage.DataStoreException; +import org.apache.sis.storage.DataStoreContentException; +import org.apache.sis.storage.UnsupportedEncodingException; import org.apache.sis.storage.metadata.MetadataBuilder; import org.apache.sis.storage.modifier.CoverageModifier; import org.apache.sis.storage.isobmff.Box; @@ -56,7 +58,10 @@ import org.apache.sis.storage.isobmff.mpeg.Component; import org.apache.sis.storage.isobmff.mpeg.ComponentType; import org.apache.sis.storage.isobmff.mpeg.ComponentPalette; import org.apache.sis.storage.isobmff.mpeg.ComponentDefinition; +import org.apache.sis.storage.isobmff.mpeg.CompressedUnitsItemInfo; +import org.apache.sis.storage.isobmff.mpeg.CompressionConfiguration; import org.apache.sis.storage.isobmff.mpeg.UncompressedFrameConfig; +import org.apache.sis.storage.isobmff.mpeg.UnitType; import org.apache.sis.storage.isobmff.mpeg.InterleavingMode; import org.apache.sis.storage.isobmff.image.ImageSpatialExtents; import org.apache.sis.storage.isobmff.image.PixelInformation; @@ -116,6 +121,24 @@ final class CoverageBuilder implements Emptiable { */ private ModelCRS crsDefinition; + /** + * Identification of the compression algorithm. + */ + private CompressionConfiguration compression; + + /** + * Locations in the file where to find compressed data. + */ + private CompressedUnitsItemInfo compressedUnits; + + /** + * Information about the sample model (data type, <i>etc.</i>). + * May be {@code null} if no such information was found. + * This is actually a mandatory information according ISO/IEC 23001-17:2024, + * but this class is nevertheless tolerant to its absence. + */ + private UncompressedFrameConfig model; + /** * How pixel data should be displayed. * Values are instance of {@link ComponentType}, {@link URI} or {@link Integer}, in preference order. @@ -131,14 +154,6 @@ final class CoverageBuilder implements Emptiable { */ private byte[] bitsPerChannel; - /** - * Information about the sample model (data type, <i>etc.</i>). - * May be {@code null} if no such information was found. - * This is actually a mandatory information according ISO/IEC 23001-17:2024, - * but this class is nevertheless tolerant to its absence. - */ - private UncompressedFrameConfig model; - /** * The color palette of an indexed color model. * May be {@code null} if no such information was found. @@ -264,6 +279,18 @@ final class CoverageBuilder implements Emptiable { if (!duplicated) crsDefinition = c; break; } + case CompressionConfiguration.BOXTYPE: { + var c = (CompressionConfiguration) property; + duplicated = (compression != null); + if (!duplicated) compression = c; + break; + } + case CompressedUnitsItemInfo.BOXTYPE: { + var c = (CompressedUnitsItemInfo) property; + duplicated = (compressedUnits != null); + if (!duplicated) compressedUnits = c; + break; + } case UncompressedFrameConfig.BOXTYPE: { var c = (UncompressedFrameConfig) property; duplicated = (model != null); @@ -290,6 +317,33 @@ final class CoverageBuilder implements Emptiable { } } + /** + * Returns the compression units which contains all image data, or {@code null} if the image is uncompressed. + * This method requires that the compression unit is {@link UnitType#IMAGE_TILE}. + * + * @return the compression units for the whole image, or {@code null}. + * @throws UnsupportedEncodingException if the compression configuration is unsupported. + * @throws DataStoreContentException if the compression cannot be decoded for another reason. + */ + final CompressedUnitsItemInfo.Unit getCompressedImageUnit() throws DataStoreContentException { + if (compression == null) { + return null; + } + if (compression.unitType == UnitType.IMAGE_TILE) { + if (compressedUnits == null) { + throw new DataStoreContentException("Missing compressed unit."); + } + final CompressedUnitsItemInfo.Unit[] units = compressedUnits.units; + if (units.length == 1) { + // Current implementation supports only ZLIB, we may add more in the future. + if (compression.compressionType == CompressionConfiguration.COMPRESSION_ZLIB) { + return units[0]; + } + } + } + throw new UnsupportedEncodingException("Unsupported compression."); + } + /** * If any boxes were unrecognized, reports these boxes in a warning. * If at least one ignored box was flagged as essential, then this method returns {@code true} diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/GeoHeifStore.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/GeoHeifStore.java index 0a1643f888..91a945075b 100644 --- a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/GeoHeifStore.java +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/GeoHeifStore.java @@ -70,12 +70,12 @@ public class GeoHeifStore extends DataStore implements Aggregate { /** * Same value as {@link #location} but as a path, or {@code null} if none. - * Stored separately because conversion from path to URI then back to path - * is not looseness (relative paths become absolutes). + * Stored separately because conversion from path to <abbr>URI</abbr> then + * back to path is not looseness (relative paths become absolutes). * * @see #getFileSet() */ - private final Path path; + private final Path locationAsPath; /** * The data store identifier created from the filename, or {@code null} if none. @@ -141,11 +141,11 @@ public class GeoHeifStore extends DataStore implements Aggregate { */ public GeoHeifStore(final DataStoreProvider provider, final StorageConnector connector) throws DataStoreException { super(provider, connector); - location = connector.getStorageAs(URI.class); - path = connector.getStorageAs(Path.class); - input = connector.commit(ChannelImageInputStream.class, GeoHeifStoreProvider.NAME); - customizer = CoverageModifier.getOrDefault(connector); - nameFactory = DefaultNameFactory.provider(); + location = connector.getStorageAs(URI.class); + locationAsPath = connector.getStorageAs(Path.class); + input = connector.commit(ChannelImageInputStream.class, GeoHeifStoreProvider.NAME); + customizer = CoverageModifier.getOrDefault(connector); + nameFactory = DefaultNameFactory.provider(); if (location != null) { String filename = IOUtilities.filenameWithoutExtension(input.filename); namespace = nameFactory.createNameSpace(nameFactory.createLocalName(null, filename), null); @@ -176,8 +176,8 @@ public class GeoHeifStore extends DataStore implements Aggregate { */ @Override public Optional<FileSet> getFileSet() throws DataStoreException { - if (path != null) { - return Optional.of(new FileSet(path)); + if (locationAsPath != null) { + return Optional.of(new FileSet(locationAsPath)); } return Optional.empty(); } diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/Image.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/Image.java index 5db1afde60..39813392f9 100644 --- a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/Image.java +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/Image.java @@ -28,7 +28,7 @@ import org.apache.sis.storage.isobmff.ByteRanges; /** - * A single image ({@code 'unci'} item type) from the HEIF file. + * A single image ({@code 'unci'} item type) from the <abbr>HEIF</abbr> file. * An image may be used as a tile in a larger image ({@code 'grid'} item type). * In the uncompressed case, the image may be implicitly tiled if {@link #numXTiles} is greater than 1. * diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/UncompressedImage.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/UncompressedImage.java index 8d65edfa79..df4d47afc4 100644 --- a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/UncompressedImage.java +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/UncompressedImage.java @@ -17,6 +17,8 @@ package org.apache.sis.storage.geoheif; import java.util.Arrays; +import java.util.zip.InflaterInputStream; +import java.io.ByteArrayInputStream; import static java.lang.Math.addExact; import static java.lang.Math.multiplyExact; import java.awt.image.DataBuffer; @@ -30,7 +32,9 @@ import org.apache.sis.io.stream.ChannelDataInput; import org.apache.sis.io.stream.HyperRectangleReader; import org.apache.sis.io.stream.Region; import org.apache.sis.storage.DataStoreException; +import org.apache.sis.storage.StorageConnector; import org.apache.sis.storage.isobmff.ByteRanges; +import org.apache.sis.storage.isobmff.mpeg.CompressedUnitsItemInfo; /** @@ -38,6 +42,10 @@ import org.apache.sis.storage.isobmff.ByteRanges; * An image may be used as a tile in a larger image ({@code 'grid'} item type). * The image may be implicitly tiled if {@link #numXTiles} is greater than 1. * + * <p>This class is named "uncompressed" image because the <abbr>HEIF</abbr> format uses that name. + * Nevertheless, the data may be composed of compressed units. A compressed unit may be the whole + * image or only part of it (tile, row or pixel).</p> + * * <h4>Requirement</h4> * This class requires that {@link CoverageBuilder#sampleModel()} can build a sample model. * In other words, the boxes such as {@code UncompressedFrameConfig} must have been found. @@ -58,6 +66,11 @@ final class UncompressedImage extends Image { */ private final SampleModel sampleModel; + /** + * The compression units which contains all image data, or {@code null} if the image is uncompressed. + */ + private final CompressedUnitsItemInfo.Unit compressedImageUnit; + /** * Creates a new tile. * @@ -72,6 +85,7 @@ final class UncompressedImage extends Image { super(builder, locator, name); sampleModel = builder.sampleModel(); dataType = builder.dataType(); // Shall be after `sampleModel()`. + compressedImageUnit = builder.getCompressedImageUnit(); } /** @@ -122,7 +136,16 @@ final class UncompressedImage extends Image { final long tileIndex = addExact(multiplyExact(context.subTileY, numXTiles), context.subTileX); final long offset = addExact(multiplyExact(tileIndex, tileSize), skipBytes); locator.resolve(offset, tileSize - skipBytes, context); - return (final ChannelDataInput input) -> { + return (ChannelDataInput input) -> { + long origin = context.offset() - skipBytes; + final CompressedUnitsItemInfo.Unit unit = compressedImageUnit; + if (unit != null) { + input.skipNBytes(unit.offset); + final byte[] compressedChunk = input.readBytes((int) unit.size); + InflaterInputStream iis = new InflaterInputStream(new ByteArrayInputStream(compressedChunk)); + input = new StorageConnector(iis).getStorageAs(ChannelDataInput.class); + origin = 0; + } /* * Now read all banks and store the values in the image buffer. * If there is many banks (`InterleavingMode.COMPONENT`), these @@ -130,7 +153,7 @@ final class UncompressedImage extends Image { */ input.buffer.order(byteOrder); final var hr = new HyperRectangleReader(ImageUtilities.toNumberEnum(dataType), input); - hr.setOrigin(context.offset() - skipBytes); + hr.setOrigin(origin); final WritableRaster raster = context.createRaster(); final long[] rasterSize = size(raster.getSampleModel()); final Region rasterRegion = Arrays.equals(sourceSize, rasterSize) ? region : region(sourceSize, rasterSize); diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/MainBoxRegistry.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/MainBoxRegistry.java index 86a0236970..c0e7730736 100644 --- a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/MainBoxRegistry.java +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/MainBoxRegistry.java @@ -78,13 +78,20 @@ final class MainBoxRegistry extends BoxRegistry { @Override public Box create(final Reader reader, final int fourCC) throws IOException, DataStoreException { switch (fourCC) { + case AuxiliaryImageReference.BOXTYPE: return new AuxiliaryImageReference(reader); + case BaseImageReference.BOXTYPE: return new BaseImageReference(reader); case ChromaLocation.BOXTYPE: return new ChromaLocation(reader); + case CleanAperture.BOXTYPE: return new CleanAperture(reader); case ColourInformation.BOXTYPE: return new ColourInformation(reader); case CombinaisonType.BOXTYPE: return new CombinaisonType(reader); case ComponentDefinition.BOXTYPE: return reader.componentDefinition = new ComponentDefinition(reader); case ComponentPalette.BOXTYPE: return new ComponentPalette(reader, reader.componentDefinition); case ComponentPatternDefinition.BOXTYPE: return new ComponentPatternDefinition(reader, reader.componentDefinition); case ComponentReferenceLevel.BOXTYPE: return new ComponentReferenceLevel(reader); + case CompressedUnitsItemInfo.BOXTYPE: return new CompressedUnitsItemInfo(reader); + case CompressionAV1.BOXTYPE: return new CompressionAV1(reader); + case CompressionConfiguration.BOXTYPE: return new CompressionConfiguration(reader); + case CompressionJP2K.BOXTYPE: return new CompressionJP2K(reader); case ContentDescribes.BOXTYPE: return new ContentDescribes(reader); case Copyright.BOXTYPE: return new Copyright(reader); case CreationTime.BOXTYPE: return new CreationTime(reader); @@ -101,6 +108,7 @@ final class MainBoxRegistry extends BoxRegistry { case FreeSpace.BOXTYPE: return new FreeSpace(); case GroupList.BOXTYPE: return new GroupList(reader); case HandlerReference.BOXTYPE: return new HandlerReference(reader); + case HevcConfigurationItem.BOXTYPE: return new HevcConfigurationItem(reader); case IdentifiedMediaData.BOXTYPE: return new IdentifiedMediaData(reader); case ImagePyramid.BOXTYPE: return new ImagePyramid(reader); case ImageSpatialExtents.BOXTYPE: return new ImageSpatialExtents(reader); @@ -123,12 +131,14 @@ final class MainBoxRegistry extends BoxRegistry { case OriginalFileType.BOXTYPE: return new OriginalFileType(reader); case PixelInformation.BOXTYPE: return new PixelInformation(reader); case PolarizationPatternDefinition.BOXTYPE: return new PolarizationPatternDefinition(reader); + case PremultipliedImageReference.BOXTYPE: return new PremultipliedImageReference(reader); case PrimaryItem.BOXTYPE: return new PrimaryItem(reader); case ProgressiveDownloadInfo.BOXTYPE: return new ProgressiveDownloadInfo(reader); case SensorBadPixelsMap.BOXTYPE: return new SensorBadPixelsMap(reader); case SensorNonUniformityCorrection.BOXTYPE: return new SensorNonUniformityCorrection(reader); case TAIClockInfo.BOXTYPE: return new TAIClockInfo(reader); case TAITimeStamp.BOXTYPE: return new TAITimeStamp(reader); + case ThumbnailReference.BOXTYPE: return new ThumbnailReference(reader); case TiledImageConfiguration.BOXTYPE: return new TiledImageConfiguration(reader); case Track.BOXTYPE: return new Track(reader); case TrackHeader.BOXTYPE: return new TrackHeader(reader, reader.movieHeader); diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/Reader.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/Reader.java index fab31bd934..3e66f51870 100644 --- a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/Reader.java +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/Reader.java @@ -214,7 +214,9 @@ public final class Reader implements Cloneable { } } endOfCurrentBox = end; // May have been modified by recursive invocations. - assert (end < 0) || input.getStreamPosition() <= end : Box.formatFourCC(box.type()); + if (end >= 0 && input.getStreamPosition() > end) { + throw new DataStoreContentException("The \"" + Box.formatFourCC(box.type()) + "\" box is longer than expected."); + } return box; } diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/image/AuxiliaryImageReference.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/image/AuxiliaryImageReference.java new file mode 100644 index 0000000000..37828c2d18 --- /dev/null +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/image/AuxiliaryImageReference.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed withz + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.storage.isobmff.image; + +import java.io.IOException; +import org.apache.sis.storage.isobmff.Reader; +import org.apache.sis.storage.isobmff.base.SingleItemTypeReference; + + +/** + * Image other than thumbnail which is related to a master image. + * Example: an alpha plane. + * + * @author Johann Sorel (Geomatys) + */ +public final class AuxiliaryImageReference extends SingleItemTypeReference { + /** + * Numerical representation of the {@code "auxl"} box type. + */ + public static final int BOXTYPE = ((((('a' << 8) | 'u') << 8) | 'x') << 8) | 'l'; + + /** + * Returns the four-character type of this box. + * This value is fixed to {@link #BOXTYPE}. + */ + @Override + public final int type() { + return BOXTYPE; + } + + /** + * Creates a new box and loads the payload from the given reader. + * + * @param reader the reader from which to read the payload. + * @throws IOException if an error occurred while reading the payload. + */ + public AuxiliaryImageReference(final Reader reader) throws IOException { + super(reader, false); + } +} diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/image/BaseImageReference.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/image/BaseImageReference.java new file mode 100644 index 0000000000..35aafce21a --- /dev/null +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/image/BaseImageReference.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed withz + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.storage.isobmff.image; + +import java.io.IOException; +import org.apache.sis.storage.isobmff.Reader; +import org.apache.sis.storage.isobmff.base.SingleItemTypeReference; + + +/** + * Base image reference. + * + * @author Johann Sorel (Geomatys) + */ +public final class BaseImageReference extends SingleItemTypeReference { + /** + * Numerical representation of the {@code "base"} box type. + */ + public static final int BOXTYPE = ((((('b' << 8) | 'a') << 8) | 's') << 8) | 'e'; + + /** + * Returns the four-character type of this box. + * This value is fixed to {@link #BOXTYPE}. + */ + @Override + public final int type() { + return BOXTYPE; + } + + /** + * Creates a new box and loads the payload from the given reader. + * + * @param reader the reader from which to read the payload. + * @throws IOException if an error occurred while reading the payload. + */ + public BaseImageReference(final Reader reader) throws IOException { + super(reader, false); + } +} diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/image/PremultipliedImageReference.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/image/PremultipliedImageReference.java new file mode 100644 index 0000000000..61a86bd1b2 --- /dev/null +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/image/PremultipliedImageReference.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed withz + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.storage.isobmff.image; + +import java.io.IOException; +import org.apache.sis.storage.isobmff.Reader; +import org.apache.sis.storage.isobmff.base.SingleItemTypeReference; + + +/** + * Color values in an image have been premultiplied with alpha values. + * + * @author Johann Sorel (Geomatys) + */ +public final class PremultipliedImageReference extends SingleItemTypeReference { + /** + * Numerical representation of the {@code "prem"} box type. + */ + public static final int BOXTYPE = ((((('p' << 8) | 'r') << 8) | 'e') << 8) | 'm'; + + /** + * Returns the four-character type of this box. + * This value is fixed to {@link #BOXTYPE}. + */ + @Override + public final int type() { + return BOXTYPE; + } + + /** + * Creates a new box and loads the payload from the given reader. + * + * @param reader the reader from which to read the payload. + * @throws IOException if an error occurred while reading the payload. + */ + public PremultipliedImageReference(final Reader reader) throws IOException { + super(reader, false); + } +} diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/image/ThumbnailReference.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/image/ThumbnailReference.java new file mode 100644 index 0000000000..da99569fca --- /dev/null +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/image/ThumbnailReference.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed withz + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.storage.isobmff.image; + +import java.io.IOException; +import org.apache.sis.storage.isobmff.Reader; +import org.apache.sis.storage.isobmff.base.SingleItemTypeReference; + + +/** + * Image is a thumbnail of another image. + * + * @author Johann Sorel (Geomatys) + */ +public final class ThumbnailReference extends SingleItemTypeReference { + /** + * Numerical representation of the {@code "thmb"} box type. + */ + public static final int BOXTYPE = ((((('t' << 8) | 'h') << 8) | 'm') << 8) | 'b'; + + /** + * Returns the four-character type of this box. + * This value is fixed to {@link #BOXTYPE}. + */ + @Override + public final int type() { + return BOXTYPE; + } + + /** + * Creates a new box and loads the payload from the given reader. + * + * @param reader the reader from which to read the payload. + * @throws IOException if an error occurred while reading the payload. + */ + public ThumbnailReference(final Reader reader) throws IOException { + super(reader, false); + } +} diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/CleanAperture.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/CleanAperture.java new file mode 100644 index 0000000000..d55594e389 --- /dev/null +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/CleanAperture.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS,z + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.storage.isobmff.mpeg; + +import java.io.IOException; +import org.apache.sis.storage.isobmff.Box; +import org.apache.sis.storage.isobmff.Incomplete; +import org.apache.sis.storage.isobmff.Reader; + + +/** + * Cropping transformation of the input image. + * <b>Not yet implemented.</b> + * + * @author Johann Sorel (Geomatys) + * @author Martin Desruisseaux (Geomatys) + */ +@Incomplete +public final class CleanAperture extends Box { + /** + * Numerical representation of the {@code "clap"} box type. + */ + public static final int BOXTYPE = ((((('c' << 8) | 'l') << 8) | 'a') << 8) | 'p'; + + /** + * Returns the four-character type of this box. + * This value is fixed to {@link #BOXTYPE}. + */ + @Override + public final int type() { + return BOXTYPE; + } + + /** + * Creates a new box and loads the payload from the given reader. + * + * @param reader the reader from which to read the payload. + * @throws IOException if an error occurred while reading the payload. + */ + public CleanAperture(final Reader reader) { + // TODO + } +} diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/Component.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/Component.java index 0abf1ec19d..70146b2c57 100644 --- a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/Component.java +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/Component.java @@ -72,6 +72,7 @@ public final class Component extends TreeNode { * <li>0: unsigned integer coded on {@link #bitDepth} bits.</li> * <li>1: IEEE 754 floating point coded on {@link #bitDepth} bits: 16, 32, 64, 128 or 256.</li> * <li>2: complex number where the real and imaginary parts are coded on {@link #bitDepth} bits each.</li> + * <li>3: signed integer coded on {@link #bitDepth} bits. Added in ISO/IEC 23001-17:2024/Amd 2:2025.</li> * </ul> * * Other values are reserved by ISO/IEC for future definitions. @@ -128,12 +129,14 @@ public final class Component extends TreeNode { * @throws RasterFormatException if the {@link #format} value is unsupported. */ public DataType getDataType() { + boolean signed = false; boolean real = false; switch (format) { case 0: break; case 1: real = true; break; + case 3: signed = true; break; default: throw new RasterFormatException(Errors.format(Errors.Keys.UnsupportedFormat_1, format)); } - return DataType.forNumberOfBits(Short.toUnsignedInt(bitDepth), real, false); + return DataType.forNumberOfBits(Short.toUnsignedInt(bitDepth), real, signed); } } diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/CompressedUnitsItemInfo.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/CompressedUnitsItemInfo.java new file mode 100644 index 0000000000..7385bb2752 --- /dev/null +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/CompressedUnitsItemInfo.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS,z + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.storage.isobmff.mpeg; + +import java.io.IOException; +import org.apache.sis.io.stream.ChannelDataInput; +import org.apache.sis.storage.isobmff.FullBox; +import org.apache.sis.storage.isobmff.Reader; +import org.apache.sis.storage.isobmff.TreeNode; +import org.apache.sis.storage.isobmff.UnsupportedVersionException; + + +/** + * Compressed units item info. + * + * <p><b>Source:</b> ISO/IEC 23001-17:2024/Amd 2:2025</p> + * + * @author Johann Sorel (Geomatys) + * @author Martin Desruisseaux (Geomatys) + */ +public final class CompressedUnitsItemInfo extends FullBox { + /** + * Numerical representation of the {@code "icef"} box type. + */ + public static final int BOXTYPE = ((((('i' << 8) | 'c') << 8) | 'e') << 8) | 'f'; + + /** + * Returns the four-character type of this box. + * This value is fixed to {@link #BOXTYPE}. + */ + @Override + public final int type() { + return BOXTYPE; + } + + /** + * Mapping from the 3 bits encoded in the stream to the actual unit offset size. + */ + private static final byte[] OFFSET_LENGTHS = new byte[] {0, Short.SIZE, 3*Byte.SIZE, Integer.SIZE, Long.SIZE}; + + /** + * Mapping from the 3 bits encoded in the stream to the actual unit size value. + */ + private static final byte[] SIZE_LENGTHS = new byte[] {Byte.SIZE, Short.SIZE, 3*Byte.SIZE, Integer.SIZE, Long.SIZE}; + + /** + * Number of bits used to encode the offset of an unit. + * This information is not needed after the box has been read, but is kept for metadata purpose. + */ + @Interpretation(Type.UNSIGNED) + public final byte offsetFieldLength; + + /** + * Number of bits used to encode the size of an unit, or 0. + * This information is not needed after the box has been read, but is kept for metadata purpose. + * + * @todo What is the meaning of 0? Does it means that the size has the same size as the offset? + */ + @Interpretation(Type.UNSIGNED) + public final byte sizeFieldLength; + + /** + * Compressed units offsets and sizes. + * The number of compressed units is the length of this array. + */ + public final Unit[] units; + + /** + * A unit specified by an offset and a size. + */ + public static final class Unit extends TreeNode { + /** The offset in bytes, or 0 if unspecified. */ + @Interpretation(Type.UNSIGNED) + public final long offset; + + /** The size in bytes. */ + @Interpretation(Type.UNSIGNED) + public final long size; + + /** Creates a new unit with the given offset and size. */ + Unit(final long offset, final long size) { + this.offset = offset; + this.size = size; + } + } + + /** + * Creates a new box and loads the payload from the given reader. + * + * @param reader the reader from which to read the payload. + * @throws IOException if an error occurred while reading the payload. + */ + public CompressedUnitsItemInfo(final Reader reader) throws IOException, UnsupportedVersionException { + super(reader); + requireVersionZero(); + final ChannelDataInput input = reader.input; + final int unitLayout = input.readUnsignedByte(); + offsetFieldLength = OFFSET_LENGTHS[(unitLayout >>> (Byte.SIZE - 3)) & 0b111]; + sizeFieldLength = SIZE_LENGTHS[(unitLayout >>> (Byte.SIZE - 6)) & 0b111]; + final int numCompressedUnits = input.readInt(); + units = new Unit[numCompressedUnits]; + for (int i = 0; i < numCompressedUnits; i++) { + units[i] = new Unit(input.readBits(offsetFieldLength), + input.readBits(sizeFieldLength)); + } + input.skipRemainingBits(); + } +} diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/CompressionAV1.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/CompressionAV1.java new file mode 100644 index 0000000000..3d802c4fb5 --- /dev/null +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/CompressionAV1.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS,z + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.storage.isobmff.mpeg; + +import java.io.IOException; +import org.apache.sis.storage.isobmff.Box; +import org.apache.sis.storage.isobmff.Incomplete; +import org.apache.sis.storage.isobmff.Reader; + + +/** + * AV1 compression. + * <b>Not yet implemented.</b> + * + * @author Johann Sorel (Geomatys) + * @author Martin Desruisseaux (Geomatys) + */ +@Incomplete +public final class CompressionAV1 extends Box { + /** + * Numerical representation of the {@code "av1C"} box type. + */ + public static final int BOXTYPE = ((((('a' << 8) | 'v') << 8) | '1') << 8) | 'C'; + + /** + * Returns the four-character type of this box. + * This value is fixed to {@link #BOXTYPE}. + */ + @Override + public final int type() { + return BOXTYPE; + } + + /** + * Creates a new box and loads the payload from the given reader. + * + * @param reader the reader from which to read the payload. + * @throws IOException if an error occurred while reading the payload. + */ + public CompressionAV1(final Reader reader) { + // TODO + } +} diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/CompressionConfiguration.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/CompressionConfiguration.java new file mode 100644 index 0000000000..abe2a52fd1 --- /dev/null +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/CompressionConfiguration.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS,z + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.storage.isobmff.mpeg; + +import java.io.IOException; +import org.apache.sis.io.stream.ChannelDataInput; +import org.apache.sis.storage.isobmff.FullBox; +import org.apache.sis.storage.isobmff.Reader; +import org.apache.sis.storage.isobmff.UnsupportedVersionException; + + +/** + * Compression configuration box. + * + * <p><b>Source:</b> ISO/IEC 23001-17:2024/Amd 2:2025</p> + * + * @author Johann Sorel (Geomatys) + * @author Martin Desruisseaux (Geomatys) + */ +public final class CompressionConfiguration extends FullBox { + /** + * Numerical representation of the {@code "cmpC"} box type. + */ + public static final int BOXTYPE = ((((('c' << 8) | 'm') << 8) | 'p') << 8) | 'C'; + + /** + * The {@code "zlib"} value for {@link #compressionType}. + */ + public static final int COMPRESSION_ZLIB = ((((('z' << 8) | 'l') << 8) | 'i') << 8) | 'b'; + + /** + * Returns the four-character type of this box. + * This value is fixed to {@link #BOXTYPE}. + */ + @Override + public final int type() { + return BOXTYPE; + } + + /** + * Identifier of the compression. + * + * @see #COMPRESSION_ZLIB + */ + @Interpretation(Type.FOURCC) + public final int compressionType; + + /** + * Identifier of which data are in a unit, or {@code null} if unknown. + */ + public final UnitType unitType; + + /** + * Creates a new box and loads the payload from the given reader. + * + * @param reader the reader from which to read the payload. + * @throws IOException if an error occurred while reading the payload. + */ + public CompressionConfiguration(final Reader reader) throws IOException, UnsupportedVersionException { + super(reader); + requireVersionZero(); + final ChannelDataInput input = reader.input; + compressionType = input.readInt(); + unitType = UnitType.valueOf(input.readUnsignedByte()); + } +} diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/CompressionJP2K.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/CompressionJP2K.java new file mode 100644 index 0000000000..024fbde4a7 --- /dev/null +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/CompressionJP2K.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS,z + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.storage.isobmff.mpeg; + +import java.io.IOException; +import org.apache.sis.storage.isobmff.Box; +import org.apache.sis.storage.isobmff.Incomplete; +import org.apache.sis.storage.isobmff.Reader; + + +/** + * <abbr>JPEG</abbr> 2000 compression. + * <b>Not yet implemented.</b> + * + * @author Johann Sorel (Geomatys) + * @author Martin Desruisseaux (Geomatys) + */ +@Incomplete +public final class CompressionJP2K extends Box { + /** + * Numerical representation of the {@code "j2kH"} box type. + */ + public static final int BOXTYPE = ((((('j' << 8) | '2') << 8) | 'k') << 8) | 'H'; + + /** + * Returns the four-character type of this box. + * This value is fixed to {@link #BOXTYPE}. + */ + @Override + public final int type() { + return BOXTYPE; + } + + /** + * Creates a new box and loads the payload from the given reader. + * + * @param reader the reader from which to read the payload. + * @throws IOException if an error occurred while reading the payload. + */ + public CompressionJP2K(final Reader reader) { + // TODO + } +} diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/HevcConfigurationItem.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/HevcConfigurationItem.java new file mode 100644 index 0000000000..70b3f8149c --- /dev/null +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/HevcConfigurationItem.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS,z + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.storage.isobmff.mpeg; + +import java.io.IOException; +import org.apache.sis.storage.isobmff.Box; +import org.apache.sis.storage.isobmff.Incomplete; +import org.apache.sis.storage.isobmff.Reader; + + +/** + * <abbr>HEVC</abbr> configuration item. + * <b>Not yet implemented.</b> + * + * @author Johann Sorel (Geomatys) + * @author Martin Desruisseaux (Geomatys) + */ +@Incomplete +public final class HevcConfigurationItem extends Box { + /** + * Numerical representation of the {@code "hvcC"} box type. + */ + public static final int BOXTYPE = ((((('h' << 8) | 'v') << 8) | 'c') << 8) | 'C'; + + /** + * Returns the four-character type of this box. + * This value is fixed to {@link #BOXTYPE}. + */ + @Override + public final int type() { + return BOXTYPE; + } + + /** + * Creates a new box and loads the payload from the given reader. + * + * @param reader the reader from which to read the payload. + * @throws IOException if an error occurred while reading the payload. + */ + public HevcConfigurationItem(final Reader reader) { + // TODO + } +} diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/UnitType.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/UnitType.java new file mode 100644 index 0000000000..e91ad57747 --- /dev/null +++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/isobmff/mpeg/UnitType.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.storage.isobmff.mpeg; + + +/** + * Identifies which data are in a unit. + * + * In the current version, the ordinal of each enumeration value is the numerical code stored + * in <abbr>HEIF</abbr> files, but this is not yet a requirement and may change in the future. + * + * @author Johann Sorel (Geomatys) + * @author Martin Desruisseaux (Geomatys) + */ +public enum UnitType { + /** + * The unit contains the full item. + */ + FULL_ITEM, + + /** + * The unit contains an image. + */ + IMAGE, + + /** + * The unit contains an image tile. + */ + IMAGE_TILE, + + /** + * The unit contains a row of an image time. + */ + IMAGE_ROW, + + /** + * The unit contains a pixel of a row. + */ + IMAGE_PIXEL; + + /** + * Returns the enumeration value for the given code, or {@code null} if unknown. + * + * @param code code stored in <abbr>HEIF</abbr> file. + * @return enumeration value for the given code, or {@code null} if unknown. + */ + public static UnitType valueOf(final int code) { + switch (code) { + case 0: return FULL_ITEM; + case 1: return IMAGE; + case 2: return IMAGE_TILE; + case 3: return IMAGE_ROW; + case 4: return IMAGE_PIXEL; + default: return null; + } + } +}
