Ejemplo n.º 1
0
        /// <summary> Ctor resamples a BlkImgDataSrc so that all components
        /// have the same number of samples.
        ///
        /// Note the present implementation does only two to one
        /// respampling in either direction (row, column).
        ///
        /// </summary>
        /// <param name="src">-- Source of image data
        /// </param>
        /// <param name="csm">-- provides colorspace info
        /// </param>
        protected internal Resampler(BlkImgDataSrc src, ColorSpace csMap) : base(src, csMap)
        {
            int c;

            // Calculate the minimum and maximum subsampling factor
            // across all channels.

            int minX = src.getCompSubsX(0);
            int minY = src.getCompSubsY(0);
            int maxX = minX;
            int maxY = minY;

            for (c = 1; c < ncomps; ++c)
            {
                minX = System.Math.Min(minX, src.getCompSubsX(c));
                minY = System.Math.Min(minY, src.getCompSubsY(c));
                maxX = System.Math.Max(maxX, src.getCompSubsX(c));
                maxY = System.Math.Max(maxY, src.getCompSubsY(c));
            }

            // Throw an exception for other than 2:1 sampling.
            if ((maxX != 1 && maxX != 2) || (maxY != 1 && maxY != 2))
            {
                throw new ColorSpaceException("Upsampling by other than 2:1 not" + " supported");
            }

            minCompSubsX = minX;
            minCompSubsY = minY;
            maxCompSubsX = maxX;
            maxCompSubsY = maxY;

            /* end Resampler ctor */
        }
Ejemplo n.º 2
0
		/// <summary> Ctor resamples a BlkImgDataSrc so that all components
		/// have the same number of samples.
		/// 
		/// Note the present implementation does only two to one
		/// respampling in either direction (row, column).
		/// 
		/// </summary>
		/// <param name="src">-- Source of image data
		/// </param>
		/// <param name="csm">-- provides colorspace info
		/// </param>
		protected internal Resampler(BlkImgDataSrc src, ColorSpace csMap):base(src, csMap)
		{
			
			int c;
			
			// Calculate the minimum and maximum subsampling factor
			// across all channels.
			
			int minX = src.getCompSubsX(0);
			int minY = src.getCompSubsY(0);
			int maxX = minX;
			int maxY = minY;
			
			for (c = 1; c < ncomps; ++c)
			{
				minX = System.Math.Min(minX, src.getCompSubsX(c));
				minY = System.Math.Min(minY, src.getCompSubsY(c));
				maxX = System.Math.Max(maxX, src.getCompSubsX(c));
				maxY = System.Math.Max(maxY, src.getCompSubsY(c));
			}
			
			// Throw an exception for other than 2:1 sampling.
			if ((maxX != 1 && maxX != 2) || (maxY != 1 && maxY != 2))
			{
				throw new ColorSpaceException("Upsampling by other than 2:1 not" + " supported");
			}
			
			minCompSubsX = minX;
			minCompSubsY = minY;
			maxCompSubsX = maxX;
			maxCompSubsY = maxY;
			
			/* end Resampler ctor */
		}
Ejemplo n.º 3
0
        /// <summary> Returns, in the blk argument, a block of image data containing the
        /// specifed rectangular area, in the specified component. The data is
        /// returned, as a reference to the internal data, if any, instead of as a
        /// copy, therefore the returned data should not be modified.
        ///
        /// <p>The rectangular area to return is specified by the 'ulx', 'uly', 'w'
        /// and 'h' members of the 'blk' argument, relative to the current
        /// tile. These members are not modified by this method. The 'offset' and
        /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk'
        /// class.</p>
        ///
        /// <p>This method, in general, is more efficient than the 'getCompData()'
        /// method since it may not copy the data. However if the array of returned
        /// data is to be modified by the caller then the other method is probably
        /// preferable.</p>
        ///
        /// <p>If the data array in <tt>blk</tt> is <tt>null</tt>, then a new one
        /// is created if necessary. The implementation of this interface may
        /// choose to return the same array or a new one, depending on what is more
        /// efficient. Therefore, the data array in <tt>blk</tt> prior to the
        /// method call should not be considered to contain the returned data, a
        /// new array may have been created. Instead, get the array from
        /// <tt>blk</tt> after the method has returned.</p>
        ///
        /// <p>The returned data may have its 'progressive' attribute set. In this
        /// case the returned data is only an approximation of the "final"
        /// data.</p>
        ///
        /// </summary>
        /// <param name="blk">Its coordinates and dimensions specify the area to return,
        /// relative to the current tile. Some fields in this object are modified
        /// to return the data.
        ///
        /// </param>
        /// <param name="c">The index of the component from which to get the data.
        ///
        /// </param>
        /// <returns> The requested DataBlk
        ///
        /// </returns>
        /// <seealso cref="getCompData">
        ///
        /// </seealso>
        public DataBlk getInternCompData(DataBlk blk, int c)
        {
            // Check that block is inside tile
            if (blk.ulx < 0 || blk.uly < 0 || blk.w > compW[c] || blk.h > compH[c])
            {
                throw new System.ArgumentException("Block is outside the tile");
            }
            // Translate to the sources coordinates
            //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'"
            int incx = (int)System.Math.Ceiling(x0siz / (double)src.getCompSubsX(c));
            //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'"
            int incy = (int)System.Math.Ceiling(y0siz / (double)src.getCompSubsY(c));

            blk.ulx -= incx;
            blk.uly -= incy;
            blk      = src.getInternCompData(blk, c);
            // Translate back to the tiled coordinates
            blk.ulx += incx;
            blk.uly += incy;
            return(blk);
        }
Ejemplo n.º 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);
        }