Esempio n. 1
0
        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;
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }