private void Run() { ThrowIfHasInnerTiles(_firstCodestream); ThrowIfTooManyTiles(); SizMarker siz = GetDestSiz(); // Lets generate a tile-part for each tile-resolution in the source images int tiles = _imageCount.Width * _imageCount.Height; int expectedTileParts = tiles * (_firstCodestream.DecompositionLevels + 1); CodMarker cod = _firstCodestream.Markers[MarkerType.COD] as CodMarker; QcdMarker qcd = _firstCodestream.Markers[MarkerType.QCD] as QcdMarker; WarnIfClipped(_firstCodestream, cod); ComMarker com = new ComMarker("https://github.com/plroit/Skyreach"); var markers = new List <MarkerSegment>() { siz, cod, qcd, com }; Jp2File dst = Jp2File.Create( markers, expectedTileParts, false, _dest); for (ushort tIdx = 0; tIdx < tiles; tIdx++) { CopyTile(tIdx, dst); } dst.Flush(); }
/// <summary> /// Choose between sRGB and Grey-scale. /// Implement something smarter when needed /// </summary> /// <param name="imageProperties"></param> /// <returns></returns> private static ColorSpace GetColorspace(SizMarker imageProperties) { switch (imageProperties.Components) { case 1: return(ColorSpace.Greyscale); case 3: return(ColorSpace.sRGB); default: throw new NotSupportedException("color-space"); } }
public ImageHeaderBox(SizMarker siz, bool hasPropertyRights) : base((uint)BoxTypes.ImageHeaderBox, 22L, 8) { ImageWidth = (uint)(siz.RefGridSize.Width - siz.ImageOffset.X); ImageHeight = (uint)(siz.RefGridSize.Height - siz.ImageOffset.Y); Components = siz.Components; byte firstPrecision = siz.Precisions.First(); bool samePrecision = siz.Precisions .All(prec => prec == firstPrecision); BitsPerComponent = samePrecision ? firstPrecision : USE_BPC_BOX; UnknownColorspace = 0; // it is known! IntellectualPropertyRights = (byte)(hasPropertyRights ? 1 : 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); }
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); }