Beispiel #1
0
        internal long AssignOffset(JP2TilePart tp)
        {
            bool rc = _nextUnboundTilepartIdx < _tileparts.Count;

            rc = rc && tp == _tileparts[_nextUnboundTilepartIdx];
            if (!rc)
            {
                throw new InvalidOperationException(String.Concat(
                                                        "Must add the tile-part to the codestream before assigning",
                                                        " offsets. Call FlushHeaders in the same order that the ",
                                                        " tile-parts were inserted into the codestream"));
            }

            long tpOffset = FirstChildOffset;

            if (_nextUnboundTilepartIdx > 0)
            {
                int prevIdx = _nextUnboundTilepartIdx - 1;
                var prev    = _tileparts[prevIdx];
                tpOffset  = prev.Position - Position;
                tpOffset += prev.Length;
                if (prev.Length <= 0)
                {
                    throw new InvalidOperationException(string.Format(
                                                            "tilepart at position {0}, was not sealed", prevIdx));
                }
            }
            _nextUnboundTilepartIdx++;
            return(tpOffset);
        }
Beispiel #2
0
        /// <summary>
        /// Creates a new tile-part instance and adds it to
        /// an ordered list of tile-parts that compose this codestream.
        /// </summary>
        /// <param name="tileIdx">
        /// The tile index that the tile-part belongs to
        /// </param>
        /// <param name="isLastInTile">
        /// True if this should be the last tile-part
        /// for this tile. Needed for the TNsot field in the
        /// SOT marker.
        /// </param>
        /// <returns>
        /// A tile-part instance which is added to this codestream.
        /// </returns>
        public JP2TilePart CreateTilePart(ushort tileIdx, bool isLastInTile)
        {
            if (IsFlushed)
            {
                throw new InvalidOperationException(String.Concat(
                                                        "Cannot add tile-parts to a codestream that ",
                                                        "has already been flushed to the underlying IO ",
                                                        "stream. You should call Flush only after you have ",
                                                        "added all tile-parts and all packets"));
            }

            if (!IsOpened)
            {
                throw new InvalidOperationException(String.Concat(
                                                        "Cannot add tile-parts to a codestream that has ",
                                                        "been closed. You can add tile-parts only to a ",
                                                        "codestream which has been newly created"));
            }
            byte        tpIdx = Tiles[tileIdx].TilePartCount;
            JP2TilePart tp    = new JP2TilePart(this, tileIdx, tpIdx, true);

            Tiles[tileIdx].Add(tp, isLastInTile);
            _tileparts.Add(tp);
            AddToTlm(tp);
            return(tp);
        }
Beispiel #3
0
        private long AddTilePart(long offset, ushort tileIdx, long tpLength)
        {
            var tp = new JP2TilePart(this, offset, tpLength);

            Tiles[tileIdx].Add(tp, false);
            _tileparts.Add(tp);
            offset += tpLength;
            return(offset);
        }
Beispiel #4
0
        /// <summary>
        /// Bulk transfer of source tile-part content to destination tile-part.
        /// </summary>
        /// <param name="dst">Destination tile-part</param>
        /// <param name="dstOffset">
        /// Offset in the destination tile-part in bytes from the start of the FirstChildOffset
        /// </param>
        /// <param name="src">Source tile-part</param>
        /// <param name="startPacket">inclusive index</param>
        /// <param name="endPacket">exclusive index</param>
        /// <param name="buffer">optional buffer</param>
        /// <returns>The number of bytes transferred</returns>
        public static uint BulkTransferData(
            JP2TilePart dst,
            uint dstOffset,
            JP2TilePart src,
            int startPacket,
            int packetCount,
            byte[] buffer = null)
        {
            if (!dst.IsFlushed)
            {
                throw new InvalidOperationException(String.Concat(
                                                        "trying to transfer data between IO streams ",
                                                        "without sealing the destination tile-part to ",
                                                        "further addition of packets. ",
                                                        "Must call to JP2TilePart.Flush()"));
            }
            if (!dst.IsOpened || !src.IsOpened)
            {
                throw new InvalidOperationException(String.Concat(
                                                        "Trying to transfer data between unopened ",
                                                        "tile-parts. Call OpenTilePart on the source ",
                                                        "or destination codestreams"));
            }
            if (buffer == null)
            {
                buffer = new byte[1 << 16];
            }
            int  endPacket = startPacket + packetCount;
            uint srcOffset = src._packetOffsets[startPacket];
            uint endOffset = src._packetOffsets[endPacket];
            uint dataCount = endOffset - srcOffset;
            // make it signed integer for bounds checking
            long left   = dataCount;
            long srcPos = src.Position + src.FirstChildOffset + srcOffset;
            long dstPos = dst.Position + dst.FirstChildOffset + dstOffset;

            src.UnderlyingIO.Seek(srcPos, SeekOrigin.Begin);
            dst.UnderlyingIO.Seek(dstPos, SeekOrigin.Begin);
            while (left > 0)
            {
                // a tile-part can theoretically have 2^32 bytes but a byte
                // buffer is limited to Int32.MaxValue which is only 2^31 - 1.
                long countL = Math.Min(buffer.Length, left);
                int  count  = (int)countL;
                src.UnderlyingIO.Read(buffer, 0, count);
                dst.UnderlyingIO.Write(buffer, 0, count);
                left -= count;
            }
            return(dataCount);
        }
Beispiel #5
0
        private void AddToTlm(JP2TilePart tp)
        {
            TlmMarker tlm = _tlmMarkers.Last();

            if (tlm.IsFull)
            {
                if (_tlmMarkers.Count >= TlmMarker.MaxMarkers)
                {
                    throw new InvalidOperationException(String.Concat(
                                                            "Cannot add more tile-parts, Exceeded the ",
                                                            "limit of TLM markers in codestream"));
                }

                _tlmMarkers.Add(new TlmMarker((byte)_tlmMarkers.Count));
                tlm = _tlmMarkers.Last();
            }
            tlm.Add(tp);
        }
Beispiel #6
0
        internal void Add(JP2TilePart tilePart, bool isLast)
        {
            if (_isSealed)
            {
                throw new InvalidOperationException(
                          "this tile has been sealed, tileIdx: " + TileIndex);
            }
            if (_tileParts.Count() > MAX_TILEPARTS)
            {
                throw new InvalidOperationException(
                          "Tile-parts limit per tile has been reached");
            }

            if (isLast)
            {
                tilePart.TilePartCount = (byte)(_tileParts.Count + 1);
            }
            _tileParts.Add(tilePart);
            _packetCounts.Add(PACKET_COUNT_NOT_SET);
        }
Beispiel #7
0
 internal JP2Packet(JP2TilePart parent, long offset, long length)
     : base(parent, offset, length)
 {
 }