Beispiel #1
0
        /// <summary> Initializes the header writer with the references to the coding chain.
        /// 
        /// </summary>
        /// <param name="origsrc">The original image data (before any component mixing,
        /// tiling, etc.)
        /// 
        /// </param>
        /// <param name="isorigsig">An array specifying for each component if it was
        /// originally signed or not.
        /// 
        /// </param>
        /// <param name="dwt">The discrete wavelet transform module.
        /// 
        /// </param>
        /// <param name="tiler">The tiler module.
        /// 
        /// </param>
        /// <param name="encSpec">The encoder specifications
        /// 
        /// </param>
        /// <param name="roiSc">The ROI scaler module.
        /// 
        /// </param>
        /// <param name="ralloc">The post compression rate allocator.
        /// 
        /// </param>
        /// <param name="pl">ParameterList instance.
        /// 
        /// </param>
        public HeaderEncoder(ImgData origsrc, bool[] isorigsig, ForwardWT dwt, Tiler tiler, EncoderSpecs encSpec, ROIScaler roiSc, PostCompRateAllocator ralloc, ParameterList pl)
        {
            pl.checkList(OPT_PREFIX, CSJ2K.j2k.util.ParameterList.toNameArray(pinfo));
            if (origsrc.NumComps != isorigsig.Length)
            {
                throw new System.ArgumentException();
            }
            this.origSrc = origsrc;
            this.isOrigSig = isorigsig;
            this.dwt = dwt;
            this.tiler = tiler;
            this.encSpec = encSpec;
            this.roiSc = roiSc;
            this.ralloc = ralloc;

            baos = new System.IO.MemoryStream();
            //UPGRADE_TODO: Class 'java.io.DataOutputStream' was converted to 'System.IO.BinaryWriter' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioDataOutputStream'"
            hbuf = new CSJ2K.Util.EndianBinaryWriter(baos, true);
            nComp = origsrc.NumComps;
            enJJ2KMarkSeg = pl.getBooleanParameter("Hjj2000_COM");
            otherCOMMarkSeg = pl.getParameter("HCOM");
        }
Beispiel #2
0
        /// <summary> Initializes the EBCOT rate allocator of entropy coded data. The layout
        /// of layers, and their bitrate constraints, is specified by the 'lyrs'
        /// parameter.
        /// 
        /// </summary>
        /// <param name="src">The source of entropy coded data.
        /// 
        /// </param>
        /// <param name="lyrs">The layers layout specification.
        /// 
        /// </param>
        /// <param name="writer">The bit stream writer.
        /// 
        /// </param>
        /// <seealso cref="ProgressionType">
        /// 
        /// </seealso>
        public EBCOTRateAllocator(CodedCBlkDataSrcEnc src, LayersInfo lyrs, CodestreamWriter writer, EncoderSpecs encSpec, ParameterList pl)
            : base(src, lyrs.TotNumLayers, writer, encSpec)
        {
            int minsbi, maxsbi;
            int i;
            SubbandAn sb, sb2;
            Coord ncblks = null;

            // If we do timing create necessary structures
            #if DO_TIMING
            // If we are timing make sure that 'finalize' gets called.
            //UPGRADE_ISSUE: Method 'java.lang.System.runFinalizersOnExit' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangSystem'"
            // CONVERSION PROBLEM?
            //System_Renamed.runFinalizersOnExit(true);
            // The System.runFinalizersOnExit() method is deprecated in Java
            // 1.2 since it can cause a deadlock in some cases. However, here
            // we use it only for profiling purposes and is disabled in
            // production code.
            initTime = 0L;
            buildTime = 0L;
            writeTime = 0L;
            #endif

            // Save the layer specs
            lyrSpec = lyrs;

            //Initialize the size of the RD slope rates array
            RDSlopesRates = new int[RD_SUMMARY_SIZE];

            //Get number of tiles, components
            int nt = src.getNumTiles();
            int nc = NumComps;

            //Allocate the coded code-blocks and truncation points indexes arrays
            cblks = new CBlkRateDistStats[nt][][][][];
            for (int i2 = 0; i2 < nt; i2++)
            {
                cblks[i2] = new CBlkRateDistStats[nc][][][];
            }
            truncIdxs = new int[nt][][][][][];
            for (int i3 = 0; i3 < nt; i3++)
            {
                truncIdxs[i3] = new int[num_Layers][][][][];
                for (int i4 = 0; i4 < num_Layers; i4++)
                {
                    truncIdxs[i3][i4] = new int[nc][][][];
                }
            }

            int cblkPerSubband; // Number of code-blocks per subband
            int mrl; // Number of resolution levels
            int l; // layer index
            int s; //subband index

            // Used to compute the maximum number of precincts for each resolution
            // level
            int tx0, ty0, tx1, ty1; // Current tile position in the reference grid
            int tcx0, tcy0, tcx1, tcy1; // Current tile position in the domain of
            // the image component
            int trx0, try0, trx1, try1; // Current tile position in the reduced
            // resolution image domain
            int xrsiz, yrsiz; // Component sub-sampling factors
            Coord tileI = null;
            Coord nTiles = null;
            int xsiz, ysiz, x0siz, y0siz;
            int xt0siz, yt0siz;
            int xtsiz, ytsiz;

            int cb0x = src.CbULX;
            int cb0y = src.CbULY;

            src.setTile(0, 0);
            for (int t = 0; t < nt; t++)
            {
                // Loop on tiles
                nTiles = src.getNumTiles(nTiles);
                tileI = src.getTile(tileI);
                x0siz = ImgULX;
                y0siz = ImgULY;
                xsiz = x0siz + ImgWidth;
                ysiz = y0siz + ImgHeight;
                xt0siz = src.TilePartULX;
                yt0siz = src.TilePartULY;
                xtsiz = src.NomTileWidth;
                ytsiz = src.NomTileHeight;

                // Tile's coordinates on the reference grid
                tx0 = (tileI.x == 0)?x0siz:xt0siz + tileI.x * xtsiz;
                ty0 = (tileI.y == 0)?y0siz:yt0siz + tileI.y * ytsiz;
                tx1 = (tileI.x != nTiles.x - 1)?xt0siz + (tileI.x + 1) * xtsiz:xsiz;
                ty1 = (tileI.y != nTiles.y - 1)?yt0siz + (tileI.y + 1) * ytsiz:ysiz;

                for (int c = 0; c < nc; c++)
                {
                    // loop on components

                    //Get the number of resolution levels
                    sb = src.getAnSubbandTree(t, c);
                    mrl = sb.resLvl + 1;

                    // Initialize maximum number of precincts per resolution array
                    if (numPrec == null)
                    {
                        Coord[][][] tmpArray = new Coord[nt][][];
                        for (int i5 = 0; i5 < nt; i5++)
                        {
                            tmpArray[i5] = new Coord[nc][];
                        }
                        numPrec = tmpArray;
                    }
                    if (numPrec[t][c] == null)
                    {
                        numPrec[t][c] = new Coord[mrl];
                    }

                    // Subsampling factors
                    xrsiz = src.getCompSubsX(c);
                    yrsiz = src.getCompSubsY(c);

                    // Tile's coordinates in the image component domain
                    //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                    tcx0 = (int) System.Math.Ceiling(tx0 / (double) (xrsiz));
                    //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                    tcy0 = (int) System.Math.Ceiling(ty0 / (double) (yrsiz));
                    //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                    tcx1 = (int) System.Math.Ceiling(tx1 / (double) (xrsiz));
                    //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                    tcy1 = (int) System.Math.Ceiling(ty1 / (double) (yrsiz));

                    cblks[t][c] = new CBlkRateDistStats[mrl][][];

                    for (l = 0; l < num_Layers; l++)
                    {
                        truncIdxs[t][l][c] = new int[mrl][][];
                    }

                    for (int r = 0; r < mrl; r++)
                    {
                        // loop on resolution levels

                        // Tile's coordinates in the reduced resolution image
                        // domain
                        //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                        trx0 = (int) System.Math.Ceiling(tcx0 / (double) (1 << (mrl - 1 - r)));
                        //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                        try0 = (int) System.Math.Ceiling(tcy0 / (double) (1 << (mrl - 1 - r)));
                        //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                        trx1 = (int) System.Math.Ceiling(tcx1 / (double) (1 << (mrl - 1 - r)));
                        //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                        try1 = (int) System.Math.Ceiling(tcy1 / (double) (1 << (mrl - 1 - r)));

                        // Calculate the maximum number of precincts for each
                        // resolution level taking into account tile specific
                        // options.
                        double twoppx = (double) encSpec.pss.getPPX(t, c, r);
                        double twoppy = (double) encSpec.pss.getPPY(t, c, r);
                        numPrec[t][c][r] = new Coord();
                        if (trx1 > trx0)
                        {
                            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                            numPrec[t][c][r].x = (int) System.Math.Ceiling((trx1 - cb0x) / twoppx) - (int) System.Math.Floor((trx0 - cb0x) / twoppx);
                        }
                        else
                        {
                            numPrec[t][c][r].x = 0;
                        }
                        if (try1 > try0)
                        {
                            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                            numPrec[t][c][r].y = (int) System.Math.Ceiling((try1 - cb0y) / twoppy) - (int) System.Math.Floor((try0 - cb0y) / (double) twoppy);
                        }
                        else
                        {
                            numPrec[t][c][r].y = 0;
                        }

                        minsbi = (r == 0)?0:1;
                        maxsbi = (r == 0)?1:4;

                        cblks[t][c][r] = new CBlkRateDistStats[maxsbi][];
                        for (l = 0; l < num_Layers; l++)
                        {
                            truncIdxs[t][l][c][r] = new int[maxsbi][];
                        }

                        for (s = minsbi; s < maxsbi; s++)
                        {
                            // loop on subbands
                            //Get the number of blocks in the current subband
                            sb2 = (SubbandAn) sb.getSubbandByIdx(r, s);
                            ncblks = sb2.numCb;
                            cblkPerSubband = ncblks.x * ncblks.y;
                            cblks[t][c][r][s] = new CBlkRateDistStats[cblkPerSubband];

                            for (l = 0; l < num_Layers; l++)
                            {
                                truncIdxs[t][l][c][r][s] = new int[cblkPerSubband];
                                for (i = 0; i < cblkPerSubband; i++)
                                {
                                    truncIdxs[t][l][c][r][s][i] = - 1;
                                }
                            }
                        } // End loop on subbands
                    } // End lopp on resolution levels
                } // End loop on components
                if (t != nt - 1)
                {
                    src.nextTile();
                }
            } // End loop on tiles

            //Initialize the packet encoder
            pktEnc = new PktEncoder(src, encSpec, numPrec, pl);

            // The layers array has to be initialized after the constructor since
            // it is needed that the bit stream header has been entirely written
        }
Beispiel #3
0
        /// <summary> Creates a new packet encoder object, using the information from the
        /// 'infoSrc' object. 
        /// 
        /// </summary>
        /// <param name="infoSrc">The source of information to construct the object.
        /// 
        /// </param>
        /// <param name="encSpec">The encoding parameters.
        /// 
        /// </param>
        /// <param name="numPrec">Maximum number of precincts in each tile, component
        /// and resolution level.
        /// 
        /// </param>
        /// <param name="pl">ParameterList instance that holds command line options
        /// 
        /// </param>
        public PktEncoder(CodedCBlkDataSrcEnc infoSrc, EncoderSpecs encSpec, Coord[][][] numPrec, ParameterList pl)
        {
            this.infoSrc = infoSrc;
            this.encSpec = encSpec;

            // Check parameters
            pl.checkList(OPT_PREFIX, CSJ2K.j2k.util.ParameterList.toNameArray(pinfo));

            // Get number of components and tiles
            int nc = infoSrc.NumComps;
            int nt = infoSrc.getNumTiles();

            // Do initial allocation
            ttIncl = new TagTreeEncoder[nt][][][][];
            for (int i = 0; i < nt; i++)
            {
                ttIncl[i] = new TagTreeEncoder[nc][][][];
            }
            ttMaxBP = new TagTreeEncoder[nt][][][][];
            for (int i2 = 0; i2 < nt; i2++)
            {
                ttMaxBP[i2] = new TagTreeEncoder[nc][][][];
            }
            lblock = new int[nt][][][][];
            for (int i3 = 0; i3 < nt; i3++)
            {
                lblock[i3] = new int[nc][][][];
            }
            prevtIdxs = new int[nt][][][][];
            for (int i4 = 0; i4 < nt; i4++)
            {
                prevtIdxs[i4] = new int[nc][][][];
            }
            ppinfo = new PrecInfo[nt][][][];
            for (int i5 = 0; i5 < nt; i5++)
            {
                ppinfo[i5] = new PrecInfo[nc][][];
            }

            // Finish allocation
            SubbandAn root, sb;
            int maxs, mins;
            int mrl;
            //Coord tmpCoord = null;
            int numcb; // Number of code-blocks
            //System.Collections.ArrayList cblks = null;
            infoSrc.setTile(0, 0);
            for (int t = 0; t < nt; t++)
            {
                // Loop on tiles
                for (int c = 0; c < nc; c++)
                {
                    // Loop on components
                    // Get number of resolution levels
                    root = infoSrc.getAnSubbandTree(t, c);
                    mrl = root.resLvl;

                    lblock[t][c] = new int[mrl + 1][][];
                    ttIncl[t][c] = new TagTreeEncoder[mrl + 1][][];
                    ttMaxBP[t][c] = new TagTreeEncoder[mrl + 1][][];
                    prevtIdxs[t][c] = new int[mrl + 1][][];
                    ppinfo[t][c] = new PrecInfo[mrl + 1][];

                    for (int r = 0; r <= mrl; r++)
                    {
                        // Loop on resolution levels
                        mins = (r == 0)?0:1;
                        maxs = (r == 0)?1:4;

                        int maxPrec = numPrec[t][c][r].x * numPrec[t][c][r].y;

                        ttIncl[t][c][r] = new TagTreeEncoder[maxPrec][];
                        for (int i6 = 0; i6 < maxPrec; i6++)
                        {
                            ttIncl[t][c][r][i6] = new TagTreeEncoder[maxs];
                        }
                        ttMaxBP[t][c][r] = new TagTreeEncoder[maxPrec][];
                        for (int i7 = 0; i7 < maxPrec; i7++)
                        {
                            ttMaxBP[t][c][r][i7] = new TagTreeEncoder[maxs];
                        }
                        prevtIdxs[t][c][r] = new int[maxs][];
                        lblock[t][c][r] = new int[maxs][];

                        // Precincts and code-blocks
                        ppinfo[t][c][r] = new PrecInfo[maxPrec];
                        fillPrecInfo(t, c, r);

                        for (int s = mins; s < maxs; s++)
                        {
                            // Loop on subbands
                            sb = (SubbandAn) root.getSubbandByIdx(r, s);
                            numcb = sb.numCb.x * sb.numCb.y;

                            lblock[t][c][r][s] = new int[numcb];
                            ArrayUtil.intArraySet(lblock[t][c][r][s], INIT_LBLOCK);

                            prevtIdxs[t][c][r][s] = new int[numcb];
                            ArrayUtil.intArraySet(prevtIdxs[t][c][r][s], - 1);
                        }
                    }
                }
                if (t != nt - 1)
                    infoSrc.nextTile();
            }
        }
Beispiel #4
0
		/// <summary> Initializes this object with the given source of image data and with
		/// all the decompositon parameters
		/// 
		/// </summary>
		/// <param name="src">From where the image data should be obtained.
		/// 
		/// </param>
		/// <param name="encSpec">The encoder specifications
		/// 
		/// </param>
		/// <param name="cb0x">The horizontal coordinate of the code-block partition
		/// origin on the reference grid.
		/// 
		/// </param>
		/// <param name="cb0y">The vertical coordinate of the code-block partition origin
		/// on the reference grid.
		/// 
		/// </param>
		/// <seealso cref="ForwardWT">
		/// 
		/// </seealso>
		public ForwWTFull(BlkImgDataSrc src, EncoderSpecs encSpec, int cb0x, int cb0y):base(src)
		{
			this.src = src;
			this.cb0x = cb0x;
			this.cb0y = cb0y;
			this.dls = encSpec.dls;
			this.filters = encSpec.wfs;
			this.cblks = encSpec.cblks;
			this.pss = encSpec.pss;
			
			int ncomp = src.NumComps;
			int ntiles = src.getNumTiles();
			
			currentSubband = new SubbandAn[ncomp];
			decomposedComps = new DataBlk[ncomp];
			subbTrees = new SubbandAn[ntiles][];
			for (int i = 0; i < ntiles; i++)
			{
				subbTrees[i] = new SubbandAn[ncomp];
			}
			lastn = new int[ncomp];
			lastm = new int[ncomp];
		}
Beispiel #5
0
		/// <summary> Calculates the maximum amount of magnitude bits for each
		/// tile-component, and stores it in the 'maxMagBits' array. This is called
		/// by the constructor
		/// 
		/// </summary>
		/// <param name="encSpec">The encoder specifications for addition of roi specs
		/// 
		/// </param>
		private void  calcMaxMagBits(EncoderSpecs encSpec)
		{
			int tmp;
			MaxShiftSpec rois = encSpec.rois;
			
			int nt = src.getNumTiles();
			int nc = src.NumComps;
			
			maxMagBits = new int[nt][];
			for (int i = 0; i < nt; i++)
			{
				maxMagBits[i] = new int[nc];
			}
			
			src.setTile(0, 0);
			for (int t = 0; t < nt; t++)
			{
				for (int c = nc - 1; c >= 0; c--)
				{
					tmp = src.getMaxMagBits(c);
					maxMagBits[t][c] = tmp;
					rois.setTileCompVal(t, c, (System.Object) tmp);
				}
				if (t < nt - 1)
					src.nextTile();
			}
			// Reset to current initial tile position
			src.setTile(0, 0);
		}
Beispiel #6
0
		/// <summary> Creates a ForwardWT object with the specified filters, and with other
		/// options specified in the parameter list 'pl'.
		/// 
		/// </summary>
		/// <param name="src">The source of data to be transformed
		/// 
		/// </param>
		/// <param name="pl">The parameter list (or options).
		/// 
		/// </param>
		/// <param name="kers">The encoder specifications.
		/// 
		/// </param>
		/// <returns> A new ForwardWT object with the specified filters and options
		/// from 'pl'.
		/// 
		/// </returns>
		/// <exception cref="IllegalArgumentException">If mandatory parameters are missing 
		/// or if invalid values are given.
		/// 
		/// </exception>
		public static ForwardWT createInstance(BlkImgDataSrc src, ParameterList pl, EncoderSpecs encSpec)
		{
            int deflev; // defdec removed
			//System.String decompstr;
			//System.String wtstr;
			//System.String pstr;
			//SupportClass.StreamTokenizerSupport stok;
			//SupportClass.Tokenizer strtok;
			//int prefx, prefy; // Partitioning reference point coordinates
			
			// Check parameters
			pl.checkList(OPT_PREFIX, CSJ2K.j2k.util.ParameterList.toNameArray(pinfo));
			
			deflev = ((System.Int32) encSpec.dls.getDefault());
			
			// Code-block partition origin
			System.String str = "";
			if (pl.getParameter("Wcboff") == null)
			{
				throw new System.ApplicationException("You must specify an argument to the '-Wcboff' " + "option. See usage with the '-u' option");
			}
			SupportClass.Tokenizer stk = new SupportClass.Tokenizer(pl.getParameter("Wcboff"));
			if (stk.Count != 2)
			{
				throw new System.ArgumentException("'-Wcboff' option needs two" + " arguments. See usage with " + "the '-u' option.");
			}
			int cb0x = 0;
			str = stk.NextToken();
			try
			{
				cb0x = (System.Int32.Parse(str));
			}
			catch (System.FormatException)
			{
				throw new System.ArgumentException("Bad first parameter for the " + "'-Wcboff' option: " + str);
			}
			if (cb0x < 0 || cb0x > 1)
			{
				throw new System.ArgumentException("Invalid horizontal " + "code-block partition origin.");
			}
			int cb0y = 0;
			str = stk.NextToken();
			try
			{
				cb0y = (System.Int32.Parse(str));
			}
			catch (System.FormatException)
			{
				throw new System.ArgumentException("Bad second parameter for the " + "'-Wcboff' option: " + str);
			}
			if (cb0y < 0 || cb0y > 1)
			{
				throw new System.ArgumentException("Invalid vertical " + "code-block partition origin.");
			}
			if (cb0x != 0 || cb0y != 0)
			{
				FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Code-blocks partition origin is " + "different from (0,0). This is defined in JPEG 2000" + " part 2 and may be not supported by all JPEG 2000 " + "decoders.");
			}
			
			return new ForwWTFull(src, encSpec, cb0x, cb0y);
		}
Beispiel #7
0
		/// <summary> Constructor of the ROI scaler, takes a Quantizer as source of data to
		/// scale.
		/// 
		/// </summary>
		/// <param name="src">The quantizer that is the source of data.
		/// 
		/// </param>
		/// <param name="mg">The mask generator that will be used for all components
		/// 
		/// </param>
		/// <param name="roi">Flag indicating whether there are rois specified.
		/// 
		/// </param>
		/// <param name="sLev">The resolution levels that belong entirely to ROI
		/// 
		/// </param>
		/// <param name="uba">Flag indicating whether block aligning is used.
		/// 
		/// </param>
		/// <param name="encSpec">The encoder specifications for addition of roi specs
		/// 
		/// </param>
		public ROIScaler(Quantizer src, ROIMaskGenerator mg, bool roi, int sLev, bool uba, EncoderSpecs encSpec):base(src)
		{
			this.src = src;
			this.roi = roi;
			this.useStartLevel = sLev;
			if (roi)
			{
				// If there is no ROI, no need to do this
				this.mg = mg;
				roiMask = new DataBlkInt();
				calcMaxMagBits(encSpec);
				blockAligned = uba;
			}
		}
Beispiel #8
0
		/// <summary> Creates a ROIScaler object. The Quantizer is the source of data to
		/// scale.
		/// 
		/// <p>The ROI Scaler creates a ROIMaskGenerator depending on what ROI
		/// information is in the ParameterList. If only rectangular ROI are used,
		/// the fast mask generator for rectangular ROI can be used.</p>
		/// 
		/// </summary>
		/// <param name="src">The source of data to scale
		/// 
		/// </param>
		/// <param name="pl">The parameter list (or options).
		/// 
		/// </param>
		/// <param name="encSpec">The encoder specifications for addition of roi specs
		/// 
		/// </param>
		/// <exception cref="IllegalArgumentException">If an error occurs while parsing
		/// the options in 'pl'
		/// 
		/// </exception>
		public static ROIScaler createInstance(Quantizer src, ParameterList pl, EncoderSpecs encSpec)
		{
			System.Collections.ArrayList roiVector = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
			ROIMaskGenerator maskGen = null;
			
			// Check parameters
			pl.checkList(OPT_PREFIX, CSJ2K.j2k.util.ParameterList.toNameArray(pinfo));
			
			// Get parameters and check if there are and ROIs specified 
			System.String roiopt = pl.getParameter("Rroi");
			if (roiopt == null)
			{
				// No ROIs specified! Create ROIScaler with no mask generator
				return new ROIScaler(src, null, false, - 1, false, encSpec);
			}
			
			// Check if the lowest resolution levels should belong to the ROI 
			int sLev = pl.getIntParameter("Rstart_level");
			
			// Check if the ROIs are block-aligned
			bool useBlockAligned = pl.getBooleanParameter("Ralign");
			
			// Check if generic mask generation is specified 
			bool onlyRect = !pl.getBooleanParameter("Rno_rect");
			
			// Parse the ROIs
			parseROIs(roiopt, src.NumComps, roiVector);
			ROI[] roiArray = new ROI[roiVector.Count];
			roiVector.CopyTo(roiArray);
			
			// If onlyRect has been forced, check if there are any non-rectangular
			// ROIs specified.  Currently, only the presence of circular ROIs will
			// make this false
			if (onlyRect)
			{
				for (int i = roiArray.Length - 1; i >= 0; i--)
					if (!roiArray[i].rect)
					{
						onlyRect = false;
						break;
					}
			}
			
			if (onlyRect)
			{
				// It's possible to use the fast ROI mask generation when only
				// rectangular ROIs are specified.
				maskGen = new RectROIMaskGenerator(roiArray, src.NumComps);
			}
			else
			{
				// It's necessary to use the generic mask generation
				maskGen = new ArbROIMaskGenerator(roiArray, src.NumComps, src);
			}
			return new ROIScaler(src, maskGen, true, sLev, useBlockAligned, encSpec);
		}
Beispiel #9
0
		/// <summary> Creates a Quantizer object for the appropriate type of quantization
		/// specified in the options in the parameter list 'pl', and having 'src'
		/// as the source of data to be quantized. The 'rev' flag indicates if the
		/// quantization should be reversible.
		/// 
		/// NOTE: At the moment only sources of wavelet data that implement the
		/// 'CBlkWTDataSrc' interface are supported.
		/// 
		/// </summary>
		/// <param name="src">The source of data to be quantized
		/// 
		/// </param>
		/// <param name="encSpec">Encoder specifications
		/// 
		/// </param>
		/// <exception cref="IllegalArgumentException">If an error occurs while parsing
		/// the options in 'pl'
		/// 
		/// </exception>
		public static Quantizer createInstance(CBlkWTDataSrc src, EncoderSpecs encSpec)
		{
			// Instantiate quantizer
			return new StdQuantizer(src, encSpec);
		}
Beispiel #10
0
        public static byte[] EncodeJPEG(Image jpgImage)
        {
            Tiler imgtiler;
            ForwCompTransf fctransf;
            ImgDataConverter converter;
            EncoderSpecs encSpec;
            ForwardWT dwt;
            Quantizer quant;
            ROIScaler rois;
            EntropyCoder ecoder;
            PostCompRateAllocator ralloc;
            HeaderEncoder headenc;
            CodestreamWriter bwriter;

            float rate = Single.MaxValue;

            ImgReaderGDI imgsrc = new ImgReaderGDI(jpgImage);

            imgtiler = new Tiler(imgsrc, 0, 0, 0, 0, jpgImage.Width, jpgImage.Height);
            int ntiles = imgtiler.getNumTiles();

            encSpec = new EncoderSpecs(ntiles, 3, imgsrc, pl);

            fctransf = new ForwCompTransf(imgtiler, encSpec);
            converter = new ImgDataConverter(fctransf);
            dwt = ForwardWT.createInstance(converter, pl, encSpec);
            quant = Quantizer.createInstance(dwt, encSpec);
            rois = ROIScaler.createInstance(quant, pl, encSpec);
            ecoder = EntropyCoder.createInstance(rois, pl, encSpec.cblks,
                encSpec.pss, encSpec.bms,
                encSpec.mqrs, encSpec.rts,
                encSpec.css, encSpec.sss,
                encSpec.lcs, encSpec.tts);

            using (MemoryStream stream = new MemoryStream())
            {
                bwriter = new FileCodestreamWriter(stream, Int32.MaxValue);
                ralloc = PostCompRateAllocator.createInstance(ecoder, pl, rate, bwriter, encSpec);

                headenc = new HeaderEncoder(imgsrc, new bool[3], dwt, imgtiler, encSpec, rois, ralloc, pl);
                ralloc.HeaderEncoder = headenc;
                headenc.encodeMainHeader();
                ralloc.initialize();
                headenc.reset();
                headenc.encodeMainHeader();
                bwriter.commitBitstreamHeader(headenc);

                ralloc.runAndWrite();
                bwriter.close();

                return stream.ToArray();
            }
        }
Beispiel #11
0
		/// <summary> Constructs a new ForwCompTransf object that operates on the specified
		/// source of image data.
		/// 
		/// </summary>
		/// <param name="imgSrc">The source from where to get the data to be transformed
		/// 
		/// </param>
		/// <param name="encSpec">The encoder specifications
		/// 
		/// </param>
		/// <seealso cref="BlkImgDataSrc">
		/// 
		/// </seealso>
		public ForwCompTransf(BlkImgDataSrc imgSrc, EncoderSpecs encSpec):base(imgSrc)
		{
			this.cts = encSpec.cts;
			this.wfs = encSpec.wfs;
			src = imgSrc;
		}
		/// <summary> Creates a PostCompRateAllocator object for the appropriate rate
		/// allocation parameters in the parameter list 'pl', having 'src' as the
		/// source of entropy coded data, 'rate' as the target bitrate and 'bw' as
		/// the bit stream writer object.
		/// 
		/// </summary>
		/// <param name="src">The source of entropy coded data.
		/// 
		/// </param>
		/// <param name="pl">The parameter lis (or options).
		/// 
		/// </param>
		/// <param name="rate">The target bitrate for the rate allocation
		/// 
		/// </param>
		/// <param name="bw">The bit stream writer object, where the bit stream data will
		/// be written.
		/// 
		/// </param>
		public static PostCompRateAllocator createInstance(CodedCBlkDataSrcEnc src, ParameterList pl, float rate, CodestreamWriter bw, EncoderSpecs encSpec)
		{
			// Check parameters
			pl.checkList(OPT_PREFIX, CSJ2K.j2k.util.ParameterList.toNameArray(pinfo));
			
			// Construct the layer specification from the 'Alayers' option
			LayersInfo lyrs = parseAlayers(pl.getParameter("Alayers"), rate);
			
			int nTiles = encSpec.nTiles;
			int nComp = encSpec.nComp;
			int numLayers = lyrs.TotNumLayers;
			
			// Parse the progressive type
			encSpec.pocs = new ProgressionSpec(nTiles, nComp, numLayers, encSpec.dls, ModuleSpec.SPEC_TYPE_TILE_COMP, pl);
			
			return new EBCOTRateAllocator(src, lyrs, bw, encSpec, pl);
		}
		/// <summary> Initializes the source of entropy coded data.
		/// 
		/// </summary>
		/// <param name="src">The source of entropy coded data.
		/// 
		/// </param>
		/// <param name="ln">The number of layers to create
		/// 
		/// </param>
		/// <param name="pt">The progressive type, as defined in 'ProgressionType'.
		/// 
		/// </param>
		/// <param name="bw">The packet bit stream writer.
		/// 
		/// </param>
		/// <seealso cref="ProgressionType">
		/// 
		/// </seealso>
		public PostCompRateAllocator(CodedCBlkDataSrcEnc src, int nl, CodestreamWriter bw, EncoderSpecs encSpec):base(src)
		{
			this.src = src;
			this.encSpec = encSpec;
			num_Layers = nl;
			bsWriter = bw;
		}
Beispiel #14
0
		/// <summary> Initializes the source of wavelet transform coefficients. The
		/// constructor takes information on whether the quantizer is in
		/// reversible, derived or expounded mode. If the quantizer is reversible
		/// the value of 'derived' is ignored. If the source data is not integer
		/// (int) then the quantizer can not be reversible.
		/// 
		/// <p>After initializing member attributes, getAnSubbandTree is called for
		/// all components setting the 'stepWMSE' for all subbands in the current
		/// tile.</p>
		/// 
		/// </summary>
		/// <param name="src">The source of wavelet transform coefficients.
		/// 
		/// </param>
		/// <param name="encSpec">The encoder specifications
		/// 
		/// </param>
		public StdQuantizer(CBlkWTDataSrc src, EncoderSpecs encSpec):base(src)
		{
			qts = encSpec.qts;
			qsss = encSpec.qsss;
			gbs = encSpec.gbs;
		}
Beispiel #15
0
        public static byte[] ToBytes(BlkImgDataSrc imgsrc, ParameterList parameters = null)
        {
            // Initialize default parameters
            ParameterList defpl = GetDefaultEncoderParameterList(encoder_pinfo);

            // Create parameter list using defaults
            ParameterList pl = parameters ?? new ParameterList(defpl);

            bool useFileFormat = false;
            bool pphTile = false;
            bool pphMain = false;
            bool tempSop = false;
            bool tempEph = false;

            // **** Get general parameters ****

            if (pl.getParameter("file_format").Equals("on"))
            {
                useFileFormat = true;
                if (pl.getParameter("rate") != null && pl.getFloatParameter("rate") != defpl.getFloatParameter("rate"))
                {
                    warning("Specified bit-rate applies only on the codestream but not on the whole file.");
                }
            }

            if (pl.getParameter("tiles") == null)
            {
                error("No tiles option specified", 2);
                return null;
            }

            if (pl.getParameter("pph_tile").Equals("on"))
            {
                pphTile = true;

                if (pl.getParameter("Psop").Equals("off"))
                {
                    pl["Psop"] = "on";
                    tempSop = true;
                }
                if (pl.getParameter("Peph").Equals("off"))
                {
                    pl["Peph"] = "on";
                    tempEph = true;
                }
            }

            if (pl.getParameter("pph_main").Equals("on"))
            {
                pphMain = true;

                if (pl.getParameter("Psop").Equals("off"))
                {
                    pl["Psop"] = "on";
                    tempSop = true;
                }
                if (pl.getParameter("Peph").Equals("off"))
                {
                    pl["Peph"] = "on";
                    tempEph = true;
                }
            }

            if (pphTile && pphMain) error("Can't have packed packet headers in both main and" + " tile headers", 2);

            if (pl.getBooleanParameter("lossless") && pl.getParameter("rate") != null
                && pl.getFloatParameter("rate") != defpl.getFloatParameter("rate")) throw new ArgumentException("Cannot use '-rate' and " + "'-lossless' option at " + " the same time.");

            if (pl.getParameter("rate") == null)
            {
                error("Target bitrate not specified", 2);
                return null;
            }
            float rate;
            try
            {
                rate = pl.getFloatParameter("rate");
                if (rate == -1)
                {
                    rate = float.MaxValue;
                }
            }
            catch (FormatException e)
            {
                error("Invalid value in 'rate' option: " + pl.getParameter("rate"), 2);
                return null;
            }
            int pktspertp;
            try
            {
                pktspertp = pl.getIntParameter("tile_parts");
                if (pktspertp != 0)
                {
                    if (pl.getParameter("Psop").Equals("off"))
                    {
                        pl["Psop"] = "on";
                        tempSop = true;
                    }
                    if (pl.getParameter("Peph").Equals("off"))
                    {
                        pl["Peph"] = "on";
                        tempEph = true;
                    }
                }
            }
            catch (FormatException e)
            {
                error("Invalid value in 'tile_parts' option: " + pl.getParameter("tile_parts"), 2);
                return null;
            }

            // **** ImgReader ****
            var ncomp = imgsrc.NumComps;
            var ppminput = imgsrc.NumComps > 1;

            // **** Tiler ****
            // get nominal tile dimensions
            SupportClass.StreamTokenizerSupport stok =
                new SupportClass.StreamTokenizerSupport(new StringReader(pl.getParameter("tiles")));
            stok.EOLIsSignificant(false);

            stok.NextToken();
            if (stok.ttype != SupportClass.StreamTokenizerSupport.TT_NUMBER)
            {
                error("An error occurred while parsing the tiles option: " + pl.getParameter("tiles"), 2);
                return null;
            }
            var tw = (int)stok.nval;
            stok.NextToken();
            if (stok.ttype != SupportClass.StreamTokenizerSupport.TT_NUMBER)
            {
                error("An error occurred while parsing the tiles option: " + pl.getParameter("tiles"), 2);
                return null;
            }
            var th = (int)stok.nval;

            // Get image reference point
            var refs = pl.getParameter("ref").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            int refx;
            int refy;
            try
            {
                refx = Int32.Parse(refs[0]);
                refy = Int32.Parse(refs[1]);
            }
            catch (IndexOutOfRangeException e)
            {
                throw new ArgumentException("Error while parsing 'ref' " + "option");
            }
            catch (FormatException e)
            {
                throw new ArgumentException("Invalid number type in " + "'ref' option");
            }
            if (refx < 0 || refy < 0)
            {
                throw new ArgumentException("Invalid value in 'ref' " + "option ");
            }

            // Get tiling reference point
            var trefs = pl.getParameter("tref").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            int trefx;
            int trefy;
            try
            {
                trefx = Int32.Parse(trefs[0]);
                trefy = Int32.Parse(trefs[1]);
            }
            catch (IndexOutOfRangeException e)
            {
                throw new ArgumentException("Error while parsing 'tref' " + "option");
            }
            catch (FormatException e)
            {
                throw new ArgumentException("Invalid number type in " + "'tref' option");
            }
            if (trefx < 0 || trefy < 0 || trefx > refx || trefy > refy)
            {
                throw new ArgumentException("Invalid value in 'tref' " + "option ");
            }

            // Instantiate tiler
            Tiler imgtiler;
            try
            {
                imgtiler = new Tiler(imgsrc, refx, refy, trefx, trefy, tw, th);
            }
            catch (ArgumentException e)
            {
                error("Could not tile image" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2);
                return null;
            }
            int ntiles = imgtiler.getNumTiles();

            // **** Encoder specifications ****
            var encSpec = new EncoderSpecs(ntiles, ncomp, imgsrc, pl);

            // **** Component transformation ****
            if (ppminput && pl.getParameter("Mct") != null && pl.getParameter("Mct").Equals("off"))
            {
                FacilityManager.getMsgLogger()
                    .printmsg(
                        MsgLogger_Fields.WARNING,
                        "Input image is RGB and no color transform has "
                        + "been specified. Compression performance and "
                        + "image quality might be greatly degraded. Use "
                        + "the 'Mct' option to specify a color transform");
            }
            ForwCompTransf fctransf;
            try
            {
                fctransf = new ForwCompTransf(imgtiler, encSpec);
            }
            catch (ArgumentException e)
            {
                error(
                    "Could not instantiate forward component " + "transformation"
                    + ((e.Message != null) ? (":\n" + e.Message) : ""),
                    2);
                return null;
            }

            // **** ImgDataConverter ****
            var converter = new ImgDataConverter(fctransf);

            // **** ForwardWT ****
            ForwardWT dwt;
            try
            {
                dwt = ForwardWT.createInstance(converter, pl, encSpec);
            }
            catch (ArgumentException e)
            {
                error("Could not instantiate wavelet transform" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2);
                return null;
            }

            // **** Quantizer ****
            Quantizer quant;
            try
            {
                quant = Quantizer.createInstance(dwt, encSpec);
            }
            catch (ArgumentException e)
            {
                error("Could not instantiate quantizer" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2);
                return null;
            }

            // **** ROIScaler ****
            ROIScaler rois;
            try
            {
                rois = ROIScaler.createInstance(quant, pl, encSpec);
            }
            catch (ArgumentException e)
            {
                error("Could not instantiate ROI scaler" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2);
                return null;
            }

            // **** EntropyCoder ****
            EntropyCoder ecoder;
            try
            {
                ecoder = EntropyCoder.createInstance(
                    rois,
                    pl,
                    encSpec.cblks,
                    encSpec.pss,
                    encSpec.bms,
                    encSpec.mqrs,
                    encSpec.rts,
                    encSpec.css,
                    encSpec.sss,
                    encSpec.lcs,
                    encSpec.tts);
            }
            catch (ArgumentException e)
            {
                error("Could not instantiate entropy coder" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2);
                return null;
            }

            // **** CodestreamWriter ****
            using (var outStream = new MemoryStream())
            {
                CodestreamWriter bwriter;
                try
                {
                    // Rely on rate allocator to limit amount of data
                    bwriter = new FileCodestreamWriter(outStream, Int32.MaxValue);
                }
                catch (IOException e)
                {
                    error("Could not open output file" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2);
                    return null;
                }

                // **** Rate allocator ****
                PostCompRateAllocator ralloc;
                try
                {
                    ralloc = PostCompRateAllocator.createInstance(ecoder, pl, rate, bwriter, encSpec);
                }
                catch (ArgumentException e)
                {
                    error("Could not instantiate rate allocator" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2);
                    return null;
                }

                // **** HeaderEncoder ****
                var imsigned = Enumerable.Repeat(false, ncomp).ToArray();   // TODO Consider supporting signed components.
                var headenc = new HeaderEncoder(imgsrc, imsigned, dwt, imgtiler, encSpec, rois, ralloc, pl);
                ralloc.HeaderEncoder = headenc;

                // **** Write header to be able to estimate header overhead ****
                headenc.encodeMainHeader();

                // **** Initialize rate allocator, with proper header
                // overhead. This will also encode all the data ****
                ralloc.initialize();

                // **** Write header (final) ****
                headenc.reset();
                headenc.encodeMainHeader();

                // Insert header into the codestream
                bwriter.commitBitstreamHeader(headenc);

                // **** Now do the rate-allocation and write result ****
                ralloc.runAndWrite();

                // **** Done ****
                bwriter.close();

                // **** Calculate file length ****
                int fileLength = bwriter.Length;

                // **** Tile-parts and packed packet headers ****
                if (pktspertp > 0 || pphTile || pphMain)
                {
                    try
                    {
                        CodestreamManipulator cm = new CodestreamManipulator(
                            outStream,
                            ntiles,
                            pktspertp,
                            pphMain,
                            pphTile,
                            tempSop,
                            tempEph);
                        fileLength += cm.doCodestreamManipulation();
                        //String res="";
                        if (pktspertp > 0)
                        {
                            FacilityManager.getMsgLogger()
                                .println(
                                    "Created tile-parts " + "containing at most " + pktspertp + " packets per tile.",
                                    4,
                                    6);
                        }
                        if (pphTile)
                        {
                            FacilityManager.getMsgLogger().println("Moved packet headers " + "to tile headers", 4, 6);
                        }
                        if (pphMain)
                        {
                            FacilityManager.getMsgLogger().println("Moved packet headers " + "to main header", 4, 6);
                        }
                    }
                    catch (IOException e)
                    {
                        error(
                            "Error while creating tileparts or packed packet" + " headers"
                            + ((e.Message != null) ? (":\n" + e.Message) : ""),
                            2);
                        return null;
                    }
                }

                // **** File Format ****
                if (useFileFormat)
                {
                    try
                    {
                        int nc = imgsrc.NumComps;
                        int[] bpc = new int[nc];
                        for (int comp = 0; comp < nc; comp++)
                        {
                            bpc[comp] = imgsrc.getNomRangeBits(comp);
                        }

                        outStream.Seek(0, SeekOrigin.Begin);
                        var ffw = new FileFormatWriter(
                            outStream,
                            imgsrc.ImgHeight,
                            imgsrc.ImgWidth,
                            nc,
                            bpc,
                            fileLength);
                        fileLength += ffw.writeFileFormat();
                    }
                    catch (IOException e)
                    {
                        throw new InvalidOperationException("Error while writing JP2 file format: " + e.Message);
                    }
                }

                // **** Close image readers ***
                imgsrc.close();

                return outStream.ToArray();
            }
        }