Example #1
0
        /// <summary> Constructs a new tiler with the specified 'BlkImgDataSrc' source,
        /// image origin, tiling origin and nominal tile size.
        ///
        /// </summary>
        /// <param name="src">The 'BlkImgDataSrc' source from where to get the image
        /// data. It must not be tiled and the image origin must be at '(0,0)' on
        /// its canvas.
        ///
        /// </param>
        /// <param name="ax">The horizontal coordinate of the image origin in the canvas
        /// system, on the reference grid (i.e. the image's top-left corner in the
        /// reference grid).
        ///
        /// </param>
        /// <param name="ay">The vertical coordinate of the image origin in the canvas
        /// system, on the reference grid (i.e. the image's top-left corner in the
        /// reference grid).
        ///
        /// </param>
        /// <param name="px">The horizontal tiling origin, in the canvas system, on the
        /// reference grid. It must satisfy 'px<=ax'.
        ///
        /// </param>
        /// <param name="py">The vertical tiling origin, in the canvas system, on the
        /// reference grid. It must satisfy 'py<=ay'.
        ///
        /// </param>
        /// <param name="nw">The nominal tile width, on the reference grid. If 0 then
        /// there is no tiling in that direction.
        ///
        /// </param>
        /// <param name="nh">The nominal tile height, on the reference grid. If 0 then
        /// there is no tiling in that direction.
        ///
        /// </param>
        /// <exception cref="IllegalArgumentException">If src is tiled or "canvased", or
        /// if the arguments do not satisfy the specified constraints.
        ///
        /// </exception>
        public Tiler(BlkImgDataSrc src, int ax, int ay, int px, int py, int nw, int nh) : base(src)
        {
            // Initialize
            this.src    = src;
            this.x0siz  = ax;
            this.y0siz  = ay;
            this.xt0siz = px;
            this.yt0siz = py;
            this.xtsiz  = nw;
            this.ytsiz  = nh;

            // Verify that input is not tiled
            if (src.getNumTiles() != 1)
            {
                throw new System.ArgumentException("Source is tiled");
            }
            // Verify that source is not "canvased"
            if (src.ImgULX != 0 || src.ImgULY != 0)
            {
                throw new System.ArgumentException("Source is \"canvased\"");
            }
            // Verify that arguments satisfy trivial requirements
            if (x0siz < 0 || y0siz < 0 || xt0siz < 0 || yt0siz < 0 || xtsiz < 0 || ytsiz < 0 || xt0siz > x0siz || yt0siz > y0siz)
            {
                throw new System.ArgumentException("Invalid image origin, " + "tiling origin or nominal " + "tile size");
            }

            // If no tiling has been specified, creates a unique tile with maximum
            // dimension.
            if (xtsiz == 0)
            {
                xtsiz = x0siz + src.ImgWidth - xt0siz;
            }
            if (ytsiz == 0)
            {
                ytsiz = y0siz + src.ImgHeight - yt0siz;
            }

            // Automatically adjusts xt0siz,yt0siz so that tile (0,0) always
            // overlaps with the image.
            if (x0siz - xt0siz >= xtsiz)
            {
                xt0siz += ((x0siz - xt0siz) / xtsiz) * xtsiz;
            }
            if (y0siz - yt0siz >= ytsiz)
            {
                yt0siz += ((y0siz - yt0siz) / ytsiz) * ytsiz;
            }
            if (x0siz - xt0siz >= xtsiz || y0siz - yt0siz >= ytsiz)
            {
                FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, "Automatically adjusted tiling " + "origin to equivalent one (" + xt0siz + "," + yt0siz + ") so that " + "first tile overlaps the image");
            }

            // Calculate the number of tiles
            //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'"
            ntX = (int)System.Math.Ceiling((x0siz + src.ImgWidth) / (double)xtsiz);
            //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'"
            ntY = (int)System.Math.Ceiling((y0siz + src.ImgHeight) / (double)ytsiz);
        }
Example #2
0
        /// <summary> Writes the entire image or only specified tiles to the output. The
        /// implementation in this class calls the write() method for each tile
        /// starting with the upper-left one and proceding in standard scanline
        /// order. It changes the current tile of the source data.
        ///
        /// </summary>
        /// <exception cref="IOException">If an I/O error occurs.
        ///
        /// </exception>
        /// <seealso cref="DataBlk">
        ///
        /// </seealso>
        public virtual void  writeAll()
        {
            // Find the list of tile to decode.
            Coord nT = src.getNumTiles(null);

            // Loop on vertical tiles
            for (int y = 0; y < nT.y; y++)
            {
                // Loop on horizontal tiles
                for (int x = 0; x < nT.x; x++)
                {
                    src.setTile(x, y);
                    write();
                }         // End loop on horizontal tiles
            }             // End loop on vertical tiles
        }
Example #3
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];
        }
Example #4
0
        public static Image FromStream(Stream stream)
        {
            RandomAccessIO in_stream = new ISRandomAccessIO(stream);

            // Initialize default parameters
            ParameterList defpl = GetDefaultParameterList(decoder_pinfo);

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

            // **** File Format ****
            // If the codestream is wrapped in the jp2 fileformat, Read the
            // file format wrapper
            FileFormatReader ff = new FileFormatReader(in_stream);

            ff.readFileFormat();
            if (ff.JP2FFUsed)
            {
                in_stream.seek(ff.FirstCodeStreamPos);
            }

            // +----------------------------+
            // | Instantiate decoding chain |
            // +----------------------------+

            // **** Header decoder ****
            // Instantiate header decoder and read main header
            HeaderInfo    hi = new HeaderInfo();
            HeaderDecoder hd;

            try
            {
                hd = new HeaderDecoder(in_stream, pl, hi);
            }
            catch (EndOfStreamException e)
            {
                throw new ApplicationException("Codestream too short or bad header, unable to decode.", e);
            }

            int          nCompCod = hd.NumComps;
            int          nTiles   = hi.sizValue.NumTiles;
            DecoderSpecs decSpec  = hd.DecoderSpecs;

            // Get demixed bitdepths
            int[] depth = new int[nCompCod];
            for (int i = 0; i < nCompCod; i++)
            {
                depth[i] = hd.getOriginalBitDepth(i);
            }

            // **** Bit stream reader ****
            BitstreamReaderAgent breader;

            try
            {
                breader = BitstreamReaderAgent.
                          createInstance(in_stream, hd, pl, decSpec,
                                         false, hi);
            }
            catch (IOException e)
            {
                throw new ApplicationException("Error while reading bit stream header or parsing packets.", e);
            }
            catch (ArgumentException e)
            {
                throw new ApplicationException("Cannot instantiate bit stream reader.", e);
            }

            // **** Entropy decoder ****
            EntropyDecoder entdec;

            try
            {
                entdec = hd.createEntropyDecoder(breader, pl);
            }
            catch (ArgumentException e)
            {
                throw new ApplicationException("Cannot instantiate entropy decoder.", e);
            }

            // **** ROI de-scaler ****
            ROIDeScaler roids;

            try
            {
                roids = hd.createROIDeScaler(entdec, pl, decSpec);
            }
            catch (ArgumentException e)
            {
                throw new ApplicationException("Cannot instantiate roi de-scaler.", e);
            }

            // **** Dequantizer ****
            Dequantizer deq;

            try
            {
                deq = hd.createDequantizer(roids, depth, decSpec);
            }
            catch (ArgumentException e)
            {
                throw new ApplicationException("Cannot instantiate dequantizer.", e);
            }

            // **** Inverse wavelet transform ***
            InverseWT invWT;

            try
            {
                // full page inverse wavelet transform
                invWT = InverseWT.createInstance(deq, decSpec);
            }
            catch (ArgumentException e)
            {
                throw new ApplicationException("Cannot instantiate inverse wavelet transform.", e);
            }

            int res = breader.ImgRes;

            invWT.ImgResLevel = res;

            // **** Data converter **** (after inverse transform module)
            ImgDataConverter converter = new ImgDataConverter(invWT, 0);

            // **** Inverse component transformation ****
            InvCompTransf ictransf = new InvCompTransf(converter, decSpec, depth, pl);

            // **** Color space mapping ****
            BlkImgDataSrc color;

            if (ff.JP2FFUsed && pl.getParameter("nocolorspace").Equals("off"))
            {
                try
                {
                    ColorSpace    csMap      = new ColorSpace(in_stream, hd, pl);
                    BlkImgDataSrc channels   = hd.createChannelDefinitionMapper(ictransf, csMap);
                    BlkImgDataSrc resampled  = hd.createResampler(channels, csMap);
                    BlkImgDataSrc palettized = hd.createPalettizedColorSpaceMapper(resampled, csMap);
                    color = hd.createColorSpaceMapper(palettized, csMap);
                }
                catch (ArgumentException e)
                {
                    throw new ApplicationException("Could not instantiate ICC profiler.", e);
                }
                catch (ColorSpaceException e)
                {
                    throw new ApplicationException("Error processing ColorSpace information.", e);
                }
            }
            else
            { // Skip colorspace mapping
                color = ictransf;
            }

            // This is the last image in the decoding chain and should be
            // assigned by the last transformation:
            BlkImgDataSrc decodedImage = color;

            if (color == null)
            {
                decodedImage = ictransf;
            }
            int numComps      = decodedImage.NumComps;
            int bytesPerPixel = numComps; // Assuming 8-bit components

            // **** Copy to Bitmap ****
            PixelFormat pixelFormat;

            switch (numComps)
            {
            case 1:
                pixelFormat = PixelFormat.Format24bppRgb; break;

            case 3:
                pixelFormat = PixelFormat.Format24bppRgb; break;

            case 4:
            case 5:
                pixelFormat = PixelFormat.Format32bppArgb; break;

            default:
                throw new ApplicationException("Unsupported PixelFormat.  " + numComps + " components.");
            }

            Bitmap dst = new Bitmap(decodedImage.ImgWidth, decodedImage.ImgHeight, pixelFormat);

            Coord numTiles = decodedImage.getNumTiles(null);

            int tIdx = 0;

            for (int y = 0; y < numTiles.y; y++)
            {
                // Loop on horizontal tiles
                for (int x = 0; x < numTiles.x; x++, tIdx++)
                {
                    decodedImage.setTile(x, y);

                    int height = decodedImage.getTileCompHeight(tIdx, 0);
                    int width  = decodedImage.getTileCompWidth(tIdx, 0);

                    int tOffx = decodedImage.getCompULX(0) -
                                (int)Math.Ceiling(decodedImage.ImgULX /
                                                  (double)decodedImage.getCompSubsX(0));

                    int tOffy = decodedImage.getCompULY(0) -
                                (int)Math.Ceiling(decodedImage.ImgULY /
                                                  (double)decodedImage.getCompSubsY(0));

                    DataBlkInt[] db = new DataBlkInt[numComps];
                    int[]        ls = new int[numComps];
                    int[]        mv = new int[numComps];
                    int[]        fb = new int[numComps];
                    for (int i = 0; i < numComps; i++)
                    {
                        db[i] = new DataBlkInt();
                        ls[i] = 1 << (decodedImage.getNomRangeBits(0) - 1);
                        mv[i] = (1 << decodedImage.getNomRangeBits(0)) - 1;
                        fb[i] = decodedImage.getFixedPoint(0);
                    }
                    for (int l = 0; l < height; l++)
                    {
                        for (int i = numComps - 1; i >= 0; i--)
                        {
                            db[i].ulx = 0;
                            db[i].uly = l;
                            db[i].w   = width;
                            db[i].h   = 1;
                            decodedImage.getInternCompData(db[i], i);
                        }
                        int[] k = new int[numComps];
                        for (int i = numComps - 1; i >= 0; i--)
                        {
                            k[i] = db[i].offset + width - 1;
                        }

                        int    outputBytesPerPixel = Math.Max(3, Math.Min(4, bytesPerPixel));
                        byte[] rowvalues           = new byte[width * outputBytesPerPixel];

                        for (int i = width - 1; i >= 0; i--)
                        {
                            int[] tmp = new int[numComps];
                            for (int j = numComps - 1; j >= 0; j--)
                            {
                                tmp[j] = (db[j].data_array[k[j]--] >> fb[j]) + ls[j];
                                tmp[j] = (tmp[j] < 0) ? 0 : ((tmp[j] > mv[j]) ? mv[j] : tmp[j]);

                                if (decodedImage.getNomRangeBits(j) != 8)
                                {
                                    tmp[j] = (int)Math.Round(((double)tmp[j] / Math.Pow(2D, (double)decodedImage.getNomRangeBits(j))) * 255D);
                                }
                            }
                            int offset = i * outputBytesPerPixel;
                            switch (numComps)
                            {
                            case 1:
                                rowvalues[offset + 0] = (byte)tmp[0];
                                rowvalues[offset + 1] = (byte)tmp[0];
                                rowvalues[offset + 2] = (byte)tmp[0];
                                break;

                            case 3:
                                rowvalues[offset + 0] = (byte)tmp[2];
                                rowvalues[offset + 1] = (byte)tmp[1];
                                rowvalues[offset + 2] = (byte)tmp[0];
                                break;

                            case 4:
                            case 5:
                                rowvalues[offset + 0] = (byte)tmp[2];
                                rowvalues[offset + 1] = (byte)tmp[1];
                                rowvalues[offset + 2] = (byte)tmp[0];
                                rowvalues[offset + 3] = (byte)tmp[3];
                                break;
                            }
                        }

                        BitmapData dstdata = dst.LockBits(
                            new System.Drawing.Rectangle(tOffx, tOffy + l, width, 1),
                            ImageLockMode.WriteOnly, pixelFormat);

                        IntPtr ptr = dstdata.Scan0;
                        System.Runtime.InteropServices.Marshal.Copy(rowvalues, 0, ptr, rowvalues.Length);
                        dst.UnlockBits(dstdata);
                    }
                }
            }
            return(dst);
        }
Example #5
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];
		}
Example #6
0
		/// <summary> Constructs a new tiler with the specified 'BlkImgDataSrc' source,
		/// image origin, tiling origin and nominal tile size.
		/// 
		/// </summary>
		/// <param name="src">The 'BlkImgDataSrc' source from where to get the image
		/// data. It must not be tiled and the image origin must be at '(0,0)' on
		/// its canvas.
		/// 
		/// </param>
		/// <param name="ax">The horizontal coordinate of the image origin in the canvas
		/// system, on the reference grid (i.e. the image's top-left corner in the
		/// reference grid).
		/// 
		/// </param>
		/// <param name="ay">The vertical coordinate of the image origin in the canvas
		/// system, on the reference grid (i.e. the image's top-left corner in the
		/// reference grid).
		/// 
		/// </param>
		/// <param name="px">The horizontal tiling origin, in the canvas system, on the
		/// reference grid. It must satisfy 'px<=ax'.
		/// 
		/// </param>
		/// <param name="py">The vertical tiling origin, in the canvas system, on the
		/// reference grid. It must satisfy 'py<=ay'.
		/// 
		/// </param>
		/// <param name="nw">The nominal tile width, on the reference grid. If 0 then
		/// there is no tiling in that direction.
		/// 
		/// </param>
		/// <param name="nh">The nominal tile height, on the reference grid. If 0 then
		/// there is no tiling in that direction.
		/// 
		/// </param>
		/// <exception cref="IllegalArgumentException">If src is tiled or "canvased", or
		/// if the arguments do not satisfy the specified constraints.
		/// 
		/// </exception>
		public Tiler(BlkImgDataSrc src, int ax, int ay, int px, int py, int nw, int nh):base(src)
		{
			
			// Initialize
			this.src = src;
			this.x0siz = ax;
			this.y0siz = ay;
			this.xt0siz = px;
			this.yt0siz = py;
			this.xtsiz = nw;
			this.ytsiz = nh;
			
			// Verify that input is not tiled
			if (src.getNumTiles() != 1)
			{
				throw new System.ArgumentException("Source is tiled");
			}
			// Verify that source is not "canvased"
			if (src.ImgULX != 0 || src.ImgULY != 0)
			{
				throw new System.ArgumentException("Source is \"canvased\"");
			}
			// Verify that arguments satisfy trivial requirements
			if (x0siz < 0 || y0siz < 0 || xt0siz < 0 || yt0siz < 0 || xtsiz < 0 || ytsiz < 0 || xt0siz > x0siz || yt0siz > y0siz)
			{
				throw new System.ArgumentException("Invalid image origin, " + "tiling origin or nominal " + "tile size");
			}
			
			// If no tiling has been specified, creates a unique tile with maximum
			// dimension.
			if (xtsiz == 0)
				xtsiz = x0siz + src.ImgWidth - xt0siz;
			if (ytsiz == 0)
				ytsiz = y0siz + src.ImgHeight - yt0siz;
			
			// Automatically adjusts xt0siz,yt0siz so that tile (0,0) always
			// overlaps with the image.
			if (x0siz - xt0siz >= xtsiz)
			{
				xt0siz += ((x0siz - xt0siz) / xtsiz) * xtsiz;
			}
			if (y0siz - yt0siz >= ytsiz)
			{
				yt0siz += ((y0siz - yt0siz) / ytsiz) * ytsiz;
			}
			if (x0siz - xt0siz >= xtsiz || y0siz - yt0siz >= ytsiz)
			{
				FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, "Automatically adjusted tiling " + "origin to equivalent one (" + xt0siz + "," + yt0siz + ") so that " + "first tile overlaps the image");
			}
			
			// Calculate the number of tiles
			//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'"
			ntX = (int) System.Math.Ceiling((x0siz + src.ImgWidth) / (double) xtsiz);
			//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'"
			ntY = (int) System.Math.Ceiling((y0siz + src.ImgHeight) / (double) ytsiz);
		}