private void ConstructTilesFromCodestream() { if (_sotOffset == 0) { throw new InvalidOperationException( "SOT offset uninitialized, cannot traverse tile-parts " + "before main header was parsed and first tile part" + " was encountered"); } int tileCount = Tiles.Count(); UnderlyingIO.Seek(Position + _sotOffset, SeekOrigin.Begin); long offset = _sotOffset; MarkerType type; while ((type = MarkerSegment.Peek(UnderlyingIO)) != MarkerType.EOC) { if (type != MarkerType.SOT) { throw new InvalidOperationException( "Expected only SOT markers in codestream traversal"); } // get the length of the tile part from the SOT and continue as // if we have read a TLM entry. SotMarker sot = MarkerSegment.Open(UnderlyingIO) as SotMarker; if (sot.TileIndex >= tileCount) { throw new ArgumentOutOfRangeException( "SOT TileIndex is too large for number of tiles" + " calculated from SIZ tile and image size"); } AddTilePart(offset, sot.TileIndex, sot.TilePartLength); offset += sot.TilePartLength; // skip to the next marker segment, // account for the already read SOT_MARKER long skip = sot.TilePartLength; skip -= SotMarker.SOT_MARKER_LENGTH; skip -= MarkerSegment.MarkerLength; UnderlyingIO.Seek(skip, SeekOrigin.Current); } return; }
internal override CodestreamNode Open() { if (IsOpened) { return(this); } UnderlyingIO.Seek(Position, SeekOrigin.Begin); MarkerType marker = MarkerSegment.Peek(UnderlyingIO); if (marker != MarkerType.SOT) { throw new ArgumentException( "SOT marker expected but was not found"); } List <PltMarker> pltMarkers = new List <PltMarker>(); int zIdx = -1; // current z-idx of plt markers bool isZOrderConsistent = true; // true iff every consequent plt // maintains ascending order from zero, without gaps. long offset = 0; while (MarkerSegment.Peek(UnderlyingIO) != MarkerType.SOD) { MarkerSegment ms = MarkerSegment.Open(UnderlyingIO); switch (ms.Type) { case MarkerType.SOT: _sot = ms as SotMarker; break; case MarkerType.PLT: var plt = ms as PltMarker; isZOrderConsistent &= (++zIdx) == plt.ZIndex; pltMarkers.Add(plt); break; case MarkerType.COD: case MarkerType.COC: case MarkerType.QCD: case MarkerType.QCC: throw new NotSupportedException( "Codestream and quantization markers are " + " not supported in tile part header"); default: break; } offset += MarkerSegment.MarkerLength + ms.Length; } _sodOffset = offset; if (!isZOrderConsistent) { // needs sorting! pltMarkers.Sort((PltMarker pltX, PltMarker pltY) => pltX.ZIndex.CompareTo(pltY.ZIndex)); } if (!pltMarkers.Any() && Length > EMPTY_TILEPART_LENGTH) { throw new NotSupportedException( "packet lengths are not specified in a non empty tile-part" + " decoding packet headers is not supported yet"); } _pltMarkers = pltMarkers; // flatten uint packOffset = 0; foreach (var plt in pltMarkers) { foreach (var packLength in plt) { packOffset += packLength; _packetOffsets.Add(packOffset); } } // read and parsed successfully. IsOpened = true; return(this); }
internal override CodestreamNode Open() { if (IsOpened) { return(this); } UnderlyingIO.Seek(Position, SeekOrigin.Begin); if (MarkerSegment.Peek(UnderlyingIO) != MarkerType.SOC) { throw new ArgumentException( "expected SOC marker at stream position: " + Position); } var markers = new Dictionary <MarkerType, MarkerSegment>(); bool isZOrderConsistent = true; // true iff every consequent tlm // maintains ascending order from zero, without gaps. int zIdx = -1; // current z-index of plt markers List <TlmMarker> tlmMarkers = new List <TlmMarker>(); MarkerSegment ms; long offset = 0; // offset from the beginning of the codestream while (MarkerSegment.Peek(UnderlyingIO) != MarkerType.SOT) { ms = MarkerSegment.Open(UnderlyingIO); switch (ms.Type) { case MarkerType.SIZ: case MarkerType.COD: case MarkerType.QCD: if (markers.ContainsKey(ms.Type)) { throw new InvalidDataException( "Already have a " + ms.Type + "marker"); } markers[ms.Type] = ms; break; case MarkerType.TLM: var tlm = ms as TlmMarker; isZOrderConsistent &= (++zIdx) == tlm.ZIndex; tlmMarkers.Add(tlm); break; case MarkerType.COC: case MarkerType.QCC: throw new NotSupportedException( "Codestream and Quantization markers for specific" + " components are not supported in main header"); default: break; } offset += MarkerSegment.MarkerLength + ms.Length; } _sotOffset = offset; Markers = markers; if (!isZOrderConsistent) { // need sorting! tlmMarkers.Sort((TlmMarker tlmX, TlmMarker tlmY) => tlmX.ZIndex.CompareTo(tlmY.ZIndex)); } Tiles = ConstructTiles(); if (tlmMarkers.Any()) { ConstructTilesFromTlm(tlmMarkers); } else { ConstructTilesFromCodestream(); } // parsed and opened successfully. IsOpened = true; return(this); }