Beispiel #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;
        }
Beispiel #2
0
        /// <summary>
        /// Create tilepart using reference to the parent codestream and indices
        /// of the tile and tilepart. Used when creating new tileparts from scratch
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="tileIdx"></param>
        /// <param name="tpIdx"></param>
        internal JP2TilePart(
            JP2Codestream parent,
            ushort tileIdx,
            byte tpIdx,
            bool createPacketIndex)
            : base(parent)
        {
            // packet offsets always has (packets + 1) elements it keeps the
            // next offset at the last element
            _packetOffsets = new List <uint>()
            {
                0
            };

            _sot        = new SotMarker(tileIdx, tpIdx);
            _pltMarkers = new List <PltMarker>()
            {
                new PltMarker(0)
            };
        }
Beispiel #3
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);
        }