Beispiel #1
0
        /// <summary>
        /// Parses the JPEG2000 file by traversing the boxes from the
        /// underlying IO stream.
        /// </summary>
        /// <returns> A reference to itself for convenience</returns>
        protected Jp2File Open()
        {
            if (_isRaw)
            {
                Codestream = new JP2Codestream(_stream, 0, _stream.Length);
                return(this);
            }

            _boxes = Jp2Box.TraverseBoxes(_stream, _stream.Length).ToList();

            long boxPosition = GetCodestreamOffset();

            if (boxPosition < 0)
            {
                throw new ArgumentException(
                          "File does not contain JPEG2000 codestream box");
            }

            var ccBox = _boxes.First(box => box.Type == BoxTypes.CodestreamBox);

            Codestream = new JP2Codestream(
                _stream,
                boxPosition,
                (long)ccBox.ContentLength);
            return(this);
        }
Beispiel #2
0
        public QueryContext(JP2Codestream cs, ushort tileIdx)
        {
            if (cs == null || !cs.IsOpened)
            {
                throw new ArgumentNullException("cs null or not opened");
            }

            if (tileIdx >= (cs.TileCount.Width * cs.TileCount.Height))
            {
                throw new ArgumentOutOfRangeException("tileIdx");
            }

            Codestream = cs;
            TileIdx    = tileIdx;
            Image      = new Rectangle(Codestream.ImageOffset, Codestream.ImageSize);
            Tile       = new Rectangle[Codestream.DecompositionLevels + 1];
            Precincts  = new Size[Codestream.DecompositionLevels + 1];
            CodMarker cod = Codestream.Markers[MarkerType.COD] as CodMarker;

            Log2Partitions = cod.PrecinctPartitions;
            for (int r = 0; r <= Codestream.DecompositionLevels; r++)
            {
                Tile[r]      = CalculateTileRect(TileIdx, r);
                Precincts[r] = CalculatePrecinctCount(TileIdx, r);
            }
        }
Beispiel #3
0
        private static void WarnIfClipped(JP2Codestream src, CodMarker cod)
        {
            bool tileSizePow2       = true;
            bool isClippedCodeblock = false;
            int  diffTileCblk;

            tileSizePow2       &= BitHacks.IsPowerOf2((uint)src.TileSize.Width);
            tileSizePow2       &= BitHacks.IsPowerOf2((uint)src.TileSize.Height);
            diffTileCblk        = BitHacks.LogFloor2((uint)src.TileSize.Width);
            diffTileCblk       -= cod.CodeblockWidth;
            isClippedCodeblock |= diffTileCblk < cod.DecompositionLevels;
            diffTileCblk        = BitHacks.LogFloor2((uint)src.TileSize.Height);
            diffTileCblk       -= cod.CodeblockHeight;
            isClippedCodeblock |= diffTileCblk < cod.DecompositionLevels;
            if (isClippedCodeblock && !tileSizePow2)
            {
                var sb = new StringBuilder();
                Console.WriteLine(sb
                                  .AppendLine(
                                      "Codeblock in one of the subbands is clipped by the ")
                                  .AppendLine(
                                      "actual subband dimensions, to perform merging well ")
                                  .AppendLine(
                                      "input origin must be aligned at the same position ")
                                  .AppendLine(
                                      "as their output coordinates")
                                  .ToString());
            }
        }
Beispiel #4
0
 private void ThrowIfHasInnerTiles(JP2Codestream src)
 {
     if (src.ImageSize != src.TileSize)
     {
         throw new NotImplementedException(
                   "Inner tiling in source images");
     }
 }
Beispiel #5
0
        public void Initialize()
        {
            string testFile = "test_RtPCL_L4R5P128T200.jp2";

            _rpclStream     = File.OpenRead(testFile);
            _rpclCodestream = Jp2File.Open(_rpclStream).OpenCodestream();
            _queryContext   = new QueryContext(_rpclCodestream, _tileIdx);
        }
Beispiel #6
0
        public void Initialize()
        {
            string testFile = "test_LRtCP_L2R3T512.jp2";

            _lrcpStream     = File.OpenRead(testFile);
            _lrcpCodestream = Jp2File.Open(_lrcpStream).OpenCodestream();
            _queryContext   = new QueryContext(_lrcpCodestream, _tileIdx);
        }
 public ContiguousCodestreamBox(JP2Codestream codestream)
     : base((uint)BoxTypes.CodestreamBox)
 {
     Codestream = codestream;
     Length     = 0; // explicitly do not specify length
     // If advertised length sis zero, then it is assumed
     // that this is the last box in the file
     // and its length is all of the remaining bytes
 }
Beispiel #8
0
        private void CopyTile(ushort tIdx, Jp2File dstJp2)
        {
            JP2Codestream src = OpenJp2(tIdx).OpenCodestream();
            JP2Codestream dst = dstJp2.OpenCodestream();

            ThrowIfDifferentInputs(_firstCodestream, src);
            for (int r = 0; r <= src.DecompositionLevels; r++)
            {
                CopyTileResLevel(dst, src, tIdx, r);
            }
        }
Beispiel #9
0
        private void CopyTileResLevel(JP2Codestream dst, JP2Codestream src, ushort tIdx, int r)
        {
            int decomps     = src.DecompositionLevels;
            var dstTilePart = dst.CreateTilePart(tIdx, r == decomps);

            // get all packets for this resolution level and source tile
            // currently support only a single tile in source image for every
            // destination tile.
            QueryContext queryContext = new QueryContext(src, 0);
            PreciseQuery preciseQuery = PreciseQuery.Create(queryContext);
            var          intervals    = preciseQuery
                                        .Resolution(r)
                                        .Execute();
            JP2Tile srcTile = src.Tiles[0];
            // add packet lengths
            Func <JP2TilePart, int, int, int, int> addPacketLengths =
                (tpSrc, pckStart, pckCount, voidParam) =>
            {
                var lengths = tpSrc.GetPacketLengths(pckStart, pckCount);
                dstTilePart.AddPacketLengths(lengths);
                return(voidParam);
            };

            EnumerateIntervals <int>(intervals, srcTile, addPacketLengths);

            // bulk transfer packet data
            dstTilePart.Flush();
            byte[] buffer = new byte[1 << 16];
            Func <JP2TilePart, int, int, uint, uint> bulkTransfer =
                (tpSrc, pckStart, pckCount, dstOffset) =>
            {
                uint dataCount = JP2TilePart.BulkTransferData(
                    dstTilePart,
                    dstOffset,
                    tpSrc,
                    pckStart,
                    pckCount,
                    buffer);
                return(dstOffset + dataCount);
            };

            EnumerateIntervals <uint>(
                intervals,
                srcTile,
                bulkTransfer);
            dstTilePart.Close();
            srcTile.Close();
        }
Beispiel #10
0
        public Program(MergeOptions opts)
        {
            string[] paths = File.ReadAllLines(opts.InputPathsAsTextFile);
            if (!paths.Any())
            {
                Console.Error.Write(opts.GetUsage());
                return;
            }

            string outputPath = paths.First();

            _paths = paths.Skip(1).ToArray();
            if (!string.IsNullOrEmpty(opts.MergedOutputPath))
            {
                _paths     = paths.ToArray();
                outputPath = opts.MergedOutputPath;
            }

            _dest = new FileStream(outputPath,
                                   FileMode.Create,
                                   FileAccess.Write,
                                   FileShare.Read,
                                   1 << 20 /* 1MB */);

            _imageCount = new Size(opts.TilesX, opts.TilesY);
            if (_imageCount.IsEmpty)
            {
                Console.Error.Write(opts.GetUsage());
                return;
            }
            int inputCount = _imageCount.Width * _imageCount.Height;

            if (inputCount != _paths.Length)
            {
                Console.Error.Write(opts.GetUsage());
                return;
            }

            _files = new FileStream[inputCount];
            _jp2s  = new Jp2File[inputCount];

            _firstCodestream = OpenJp2(0).OpenCodestream();
        }
Beispiel #11
0
        /// <summary>
        /// Private constructor, open JP2File objects using the static
        /// factory methods Open or Create
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="isRaw"></param>
        protected Jp2File(Stream stream, IEnumerable <Jp2Box> boxes)
        {
            _stream = stream;
            _boxes  = boxes;
            _isRaw  = false;
            var csBoxes =
                boxes.Where(box => box.Type == BoxTypes.CodestreamBox);

            if (!csBoxes.Any())
            {
                throw new InvalidOperationException(
                          "Must create JP2File from a codestream box");
            }
            var  csBox    = csBoxes.First() as ContiguousCodestreamBox;
            long csOffset = GetCodestreamOffset();

            csBox.Codestream.Bind(_stream, csOffset);
            Codestream = csBox.Codestream;
        }
Beispiel #12
0
        /// <summary>
        /// Creates from scratch a JPEG2000 conforming file
        /// with a JPEG2000 codestream skeleton.
        ///
        /// </summary>
        /// <param name="siz"></param>
        /// <param name="cod"></param>
        /// <param name="qcd"></param>
        /// <param name="reservedTileparts"></param>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static Jp2File Create(
            IEnumerable <MarkerSegment> markers,
            int reservedTileparts,
            bool hasPropertyRights,
            Stream stream)
        {
            var sizs = markers.Where(mrk => mrk.Type == MarkerType.SIZ);
            var cods = markers.Where(mrk => mrk.Type == MarkerType.SIZ);
            var qcds = markers.Where(mrk => mrk.Type == MarkerType.QCD);

            if (!sizs.Any() || !cods.Any() || !qcds.Any())
            {
                throw new ArgumentException(
                          "Must supply SIZ, COD and QCD markers");
            }
            SizMarker siz = sizs.First() as SizMarker;
            CodMarker cod = cods.First() as CodMarker;
            QcdMarker qcd = qcds.First() as QcdMarker;

            ColorSpace     colorspace = GetColorspace(siz);
            Jp2Box         signBox    = new Jp2SignatureBox();
            Jp2Box         ftypBox    = new FileTypeBox();
            Jp2Box         jp2hBox    = new Jp2Box((uint)BoxTypes.JP2HeaderBox);
            ImageHeaderBox ihdrBox    = new ImageHeaderBox(siz, hasPropertyRights);
            Jp2Box         colrBox    = new ColorspaceSpecificationBox(colorspace);
            var            codestream = new JP2Codestream(markers, reservedTileparts);
            var            csBox      = new ContiguousCodestreamBox(codestream);

            if (ihdrBox.BitsPerComponent == ImageHeaderBox.USE_BPC_BOX)
            {
                throw new NotSupportedException(
                          "Create image with bit per component specification box");
            }

            jp2hBox.Add(new List <Jp2Box> {
                ihdrBox, colrBox
            });
            Jp2File jp2File = new Jp2File(stream, new List <Jp2Box> {
                signBox, ftypBox, jp2hBox, csBox
            });

            return(jp2File);
        }
Beispiel #13
0
        private void CopyImage()
        {
            var cs        = _jp2.OpenCodestream();
            int tileparts = cs.OpenChildren().Count();
            var markers   = cs.Markers.Values
                            .Where(ms => ms.Type != MarkerType.TLM);
            var csout = new JP2Codestream(markers, tileparts);

            csout.Bind(_mem, 0);
            JP2TilePart tpin  = cs.OpenTilePart(0, 0);
            JP2TilePart tpout = csout.CreateTilePart(0, true);

            tpout.AddPacketLengths(
                tpin.GetPacketLengths(0, tpin.Packets));
            tpout.Flush();
            uint dataCount =
                JP2TilePart.BulkTransferData(tpout, 0, tpin, 0, tpin.Packets);

            csout.Flush();
        }
Beispiel #14
0
        private SizMarker GetDestSiz()
        {
            Size          dstRefSize = new Size();
            JP2Codestream src        = _firstCodestream;

            dstRefSize.Width   = _imageCount.Width * src.ImageSize.Width;
            dstRefSize.Width  += src.ImageOffset.X;
            dstRefSize.Height  = _imageCount.Height * src.ImageSize.Height;
            dstRefSize.Height += src.ImageOffset.Y;
            SizMarker siz = new SizMarker(
                dstRefSize,
                _firstCodestream.ImageOffset,
                _firstCodestream.TileSize,
                _firstCodestream.TileOffset,
                _firstCodestream.Components,
                _firstCodestream.Precisions,
                _firstCodestream.SubSamplingX,
                _firstCodestream.SubSamplingY);

            return(siz);
        }
Beispiel #15
0
        public void OpenImage()
        {
            Jp2File jp2 = Jp2File.Open(_fs);

            Assert.IsNotNull(jp2);
            JP2Codestream cs = jp2.OpenCodestream();

            Assert.IsNotNull(cs);
            Assert.IsNull(cs.Parent);
            Assert.AreEqual <Size>(cs.ImageSize, Image.Default.ImageSize);
            Assert.AreEqual <Size>(cs.TileSize, Image.Default.ImageSize);
            Assert.AreEqual(cs.TileCount, new Size(1, 1));
            Assert.AreEqual(cs.Components, Image.Default.Components);
            Assert.AreEqual(cs.Progression, Image.Default.Progression);
            Assert.AreEqual(cs.ImageOffset, Point.Empty);
            Assert.AreEqual(cs.TileOffset, Point.Empty);
            Assert.AreEqual(cs.DecompositionLevels, Image.Default.Decompositions);
            Assert.AreEqual(cs.QualityLayers, 1);

            int tileparts = cs.OpenChildren().Count();

            Assert.AreEqual(1, tileparts);

            _fs.Seek(0, SeekOrigin.Begin);
            long socOffset = Find(_fs, (ushort)MarkerType.SOC);
            long sizOffset = Find(_fs, (ushort)MarkerType.SIZ);
            long sotOffset = Find(_fs, (ushort)MarkerType.SOT);
            long sodOffset = Find(_fs, (ushort)MarkerType.SOD);
            long eocOffset = Find(_fs, (ushort)MarkerType.EOC);

            Assert.AreEqual(socOffset, cs.Position);
            Assert.AreEqual(sizOffset, cs.Position + 2);
            Assert.AreEqual(sotOffset, cs.Position + cs.FirstChildOffset);
            long sodOffsetFromCs = cs.Position + cs.FirstChildOffset;

            sodOffsetFromCs += cs.OpenTilePart(0, 0).FirstChildOffset - 2;
            Assert.AreEqual(sodOffset, sodOffsetFromCs);
            Assert.AreEqual(eocOffset, cs.Position + cs.Length - 2);
        }
Beispiel #16
0
        public void Initialize()
        {
            _fs   = File.OpenRead("test.jp2");
            _mem  = new MemoryStream();
            _csin = Jp2File.Open(_fs).OpenCodestream();
            var siz   = _csin.Markers[MarkerType.SIZ] as SizMarker;
            var cod   = _csin.Markers[MarkerType.COD] as CodMarker;
            var qcd   = _csin.Markers[MarkerType.QCD] as QcdMarker;
            var tpin  = _csin.OpenTilePart(0, 0);
            var csout = new JP2Codestream(new List <MarkerSegment>()
            {
                siz, cod, qcd
            }, 1);

            csout.Bind(_mem, 0);
            var tpout   = csout.CreateTilePart(0, true);
            var lengths = tpin.GetPacketLengths(0, tpin.Packets);

            tpout.AddPacketLengths(lengths);
            tpout.Flush();
            csout.Flush();
            _mem.Seek(0, SeekOrigin.Begin);
        }
Beispiel #17
0
        private void ThrowIfDifferentInputs(
            JP2Codestream src, JP2Codestream lhs)
        {
            bool rc = true;

            rc = rc && src.ImageSize == lhs.ImageSize;
            rc = rc && src.TileSize == lhs.TileSize;
            rc = rc && src.Components == lhs.Components;
            rc = rc && src.DecompositionLevels == lhs.DecompositionLevels;
            rc = rc && src.QualityLayers == lhs.QualityLayers;
            rc = rc && src.SubSamplingX.SequenceEqual(lhs.SubSamplingX);
            rc = rc && src.SubSamplingY.SequenceEqual(lhs.SubSamplingY);
            rc = rc && src.Progression == lhs.Progression;
            rc = rc && src.Precisions.SequenceEqual(lhs.Precisions);
            // I should also check precinct partition and codeblock size
            // equality. Generally speaking, COD and QCD markers should be identical.
            if (!rc)
            {
                throw new ArgumentException(String.Concat(
                                                "One of the images provided did not match the first ",
                                                "image in one of the encoding parameters. COD and QCD ",
                                                "markers in every image should be identical"));
            }
        }
 public void Initialize()
 {
     _fs  = File.OpenRead("test_LRtCP_L2R3T512.jp2");
     _jp2 = Jp2File.Open(_fs);
     _cs  = _jp2.OpenCodestream();
 }
Beispiel #19
0
 private bool HasBorders(JP2Codestream cs)
 {
     return
         (cs.ImageSize.Width % cs.TileSize.Width == 0 &&
          cs.ImageSize.Height % cs.TileSize.Height == 0);
 }