Renamed ispeWidth/ispeHeight to containerWidth/containerHeight; they now can hold tkhd's width/height
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ad80749..1e982e4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,8 @@
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
+### Changed
+- Renamed ispeWidth/ispeHeight to containerWidth/containerHeight; they now can hold tkhd's width/height
## [0.3.11] - 2019-09-26
### Added
diff --git a/include/avif/avif.h b/include/avif/avif.h
index 4427e30..f69a833 100644
--- a/include/avif/avif.h
+++ b/include/avif/avif.h
@@ -370,10 +370,15 @@
double duration; // in seconds (durationInTimescales / timescale)
uint64_t durationInTimescales; // duration in "timescales"
- // If decoding an "item" (instead of tracks) and the item is associated with an ImageSpatialExtentsBox,
- // its values will be reflected here after a call to avifDecoderParse(), otherwise they will be set to 0.
- uint32_t ispeWidth;
- uint32_t ispeHeight;
+ // The width and height as reported by the AVIf container, if any. There is no guarantee
+ // these match the decoded images; they are merely reporting what is independently offered
+ // from the container's boxes.
+ // * If decoding an "item" and the item is associated with an ImageSpatialExtentsBox,
+ // it will use the box's width/height
+ // * Else if decoding tracks, these will be the integer portions of the TrackHeaderBox width/height
+ // * Else both will be set to 0.
+ uint32_t containerWidth;
+ uint32_t containerHeight;
// stats from the most recent read, possibly 0s if reading an image sequence
avifIOStats ioStats;
diff --git a/src/read.c b/src/read.c
index 13b40fa..93feb80 100644
--- a/src/read.c
+++ b/src/read.c
@@ -194,6 +194,8 @@
uint32_t auxForID; // if non-zero, this item is an auxC plane for Track #{auxForID}
uint32_t mediaTimescale;
uint64_t mediaDuration;
+ uint32_t width;
+ uint32_t height;
avifSampleTable * sampleTable;
} avifTrack;
AVIF_ARRAY_DECLARE(avifTrackArray, avifTrack, track);
@@ -743,15 +745,35 @@
CHECK(avifROStreamReadU64(&s, &ignored64)); // unsigned int(64) creation_time;
CHECK(avifROStreamReadU64(&s, &ignored64)); // unsigned int(64) modification_time;
CHECK(avifROStreamReadU32(&s, &trackID)); // unsigned int(32) track_ID;
+ CHECK(avifROStreamReadU32(&s, &ignored32)); // const unsigned int(32) reserved = 0;
+ CHECK(avifROStreamReadU64(&s, &ignored64)); // unsigned int(64) duration;
} else if (version == 0) {
CHECK(avifROStreamReadU32(&s, &ignored32)); // unsigned int(32) creation_time;
CHECK(avifROStreamReadU32(&s, &ignored32)); // unsigned int(32) modification_time;
CHECK(avifROStreamReadU32(&s, &trackID)); // unsigned int(32) track_ID;
+ CHECK(avifROStreamReadU32(&s, &ignored32)); // const unsigned int(32) reserved = 0;
+ CHECK(avifROStreamReadU32(&s, &ignored32)); // unsigned int(32) duration;
} else {
// Unsupported version
return AVIF_FALSE;
}
+ // Skipping the following 52 bytes here:
+ // ------------------------------------
+ // const unsigned int(32)[2] reserved = 0;
+ // template int(16) layer = 0;
+ // template int(16) alternate_group = 0;
+ // template int(16) volume = {if track_is_audio 0x0100 else 0};
+ // const unsigned int(16) reserved = 0;
+ // template int(32)[9] matrix= { 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 }; // unity matrix
+ CHECK(avifROStreamSkip(&s, 52));
+
+ uint32_t width, height;
+ CHECK(avifROStreamReadU32(&s, &width)); // unsigned int(32) width;
+ CHECK(avifROStreamReadU32(&s, &height)); // unsigned int(32) height;
+ track->width = width >> 16;
+ track->height = height >> 16;
+
// TODO: support scaling based on width/height track header info?
track->id = trackID;
@@ -1372,9 +1394,8 @@
}
memset(&decoder->imageTiming, 0, sizeof(decoder->imageTiming)); // to be set in avifDecoderNextImage()
- // No ispe inside of a track
- decoder->ispeWidth = 0;
- decoder->ispeHeight = 0;
+ decoder->containerWidth = colorTrack->width;
+ decoder->containerHeight = colorTrack->height;
} else {
// Create from items
@@ -1467,11 +1488,11 @@
decoder->ioStats.alphaOBUSize = alphaOBU.size;
if (colorOBUItem->ispePresent) {
- decoder->ispeWidth = colorOBUItem->ispe.width;
- decoder->ispeHeight = colorOBUItem->ispe.height;
+ decoder->containerWidth = colorOBUItem->ispe.width;
+ decoder->containerHeight = colorOBUItem->ispe.height;
} else {
- decoder->ispeWidth = 0;
- decoder->ispeHeight = 0;
+ decoder->containerWidth = 0;
+ decoder->containerHeight = 0;
}
}
@@ -1572,7 +1593,7 @@
if (requestedIndex == decoder->imageIndex) {
break;
}
- };
+ }
return AVIF_RESULT_OK;
}
diff --git a/tests/aviffuzz.c b/tests/aviffuzz.c
index 7704682..2db18ff 100644
--- a/tests/aviffuzz.c
+++ b/tests/aviffuzz.c
@@ -45,6 +45,7 @@
// avifDecoderSetSource(decoder, AVIF_DECODER_SOURCE_PRIMARY_ITEM);
avifResult result = avifDecoderParse(decoder, (avifROData *)&raw);
if (result == AVIF_RESULT_OK) {
+ printf("AVIF container reports dimensions: %ux%u\n", decoder->containerWidth, decoder->containerHeight);
for (int loop = 0; loop < 2; ++loop) {
printf("Image decoded: %s\n", inputFilename);
printf(" * %2.2f seconds, %d images\n", decoder->duration, decoder->imageCount);