Ejemplo n.º 1
0
        /// <summary> Creates a new writer to the specified File object, to write data from
        /// the specified component.
        ///
        /// <p>The size of the image that is written to the file is the size of the
        /// component from which to get the data, specified by b, not the size of
        /// the source image (they differ if there is some sub-sampling).</p>
        ///
        /// </summary>
        /// <param name="out">The file where to write the data
        ///
        /// </param>
        /// <param name="imgSrc">The source from where to get the image data to write.
        ///
        /// </param>
        /// <param name="c">The index of the component from where to get the data.
        ///
        /// </param>
        public ImgWriterPGM(IFileInfo out_Renamed, BlkImgDataSrc imgSrc, int c)
        {
            // Check that imgSrc is of the correct type
            // Check that the component index is valid
            if (c < 0 || c >= imgSrc.NumComps)
            {
                throw new System.ArgumentException("Invalid number of components");
            }

            // Check that imgSrc is of the correct type
            if (imgSrc.getNomRangeBits(c) > 8)
            {
                FacilityManager.getMsgLogger().println("Warning: Component " + c + " has nominal bitdepth " + imgSrc.getNomRangeBits(c) + ". Pixel values will be " + "down-shifted to fit bitdepth of 8 for PGM file", 8, 8);
            }

            // Initialize
            if (out_Renamed.Exists && !out_Renamed.Delete())
            {
                throw new System.IO.IOException("Could not reset file");
            }
            this.out_Renamed = SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(out_Renamed, "rw");
            src      = imgSrc;
            this.c   = c;
            w        = imgSrc.ImgWidth;
            h        = imgSrc.ImgHeight;
            fb       = imgSrc.getFixedPoint(c);
            levShift = 1 << (imgSrc.getNomRangeBits(c) - 1);

            writeHeaderInfo();
        }
Ejemplo n.º 2
0
        /// <summary> Creates a new writer to the specified File object, to write data from
        /// the specified component.
        ///
        /// <p>The size of the image that is written to the file is the size of the
        /// component from which to get the data, specified by b, not the size of
        /// the source image (they differ if there is some sub-sampling).</p>
        ///
        /// <p>All the header informations are given by the BlkImgDataSrc source
        /// (component width, component height, bit-depth) and sign flag, which are
        /// provided to the constructor. The endianness is always big-endian (MSB
        /// first).</p>
        ///
        /// </summary>
        /// <param name="out">The file where to write the data
        ///
        /// </param>
        /// <param name="imgSrc">The source from where to get the image data to write.
        ///
        /// </param>
        /// <param name="c">The index of the component from where to get the data.
        ///
        /// </param>
        /// <param name="isSigned">Whether the datas are signed or not (needed only when
        /// writing header).
        ///
        /// </param>
        /// <seealso cref="DataBlk">
        ///
        /// </seealso>
        public ImgWriterPGX(IFileInfo out_Renamed, BlkImgDataSrc imgSrc, int c, bool isSigned)
        {
            //Initialize
            this.c = c;
            if (out_Renamed.Exists && !out_Renamed.Delete())
            {
                throw new System.IO.IOException("Could not reset file");
            }
            this.out_Renamed = SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(out_Renamed, "rw");
            this.isSigned    = isSigned;
            src = imgSrc;
            w   = src.ImgWidth;
            h   = src.ImgHeight;
            fb  = imgSrc.getFixedPoint(c);

            bitDepth = src.getNomRangeBits(this.c);
            if ((bitDepth <= 0) || (bitDepth > 31))
            {
                throw new System.IO.IOException("PGX supports only bit-depth between " + "1 and 31");
            }
            if (bitDepth <= 8)
            {
                packBytes = 1;
            }
            else if (bitDepth <= 16)
            {
                packBytes = 2;
            }
            else
            {
                // <= 31
                packBytes = 4;
            }

            // Writes PGX header
            System.String tmpString = "PG " + "ML " + ((this.isSigned)?"- ":"+ ") + bitDepth + " " + w + " " + h + "\n";             // component height

            byte[] tmpByte = System.Text.Encoding.UTF8.GetBytes(tmpString);
            for (int i = 0; i < tmpByte.Length; i++)
            {
                this.out_Renamed.WriteByte((byte)tmpByte[i]);
            }

            offset = tmpByte.Length;
            maxVal = this.isSigned?((1 << (src.getNomRangeBits(c) - 1)) - 1):((1 << src.getNomRangeBits(c)) - 1);
            minVal = this.isSigned?((-1) * (1 << (src.getNomRangeBits(c) - 1))):0;

            levShift = (this.isSigned)?0:1 << (src.getNomRangeBits(c) - 1);
        }
Ejemplo n.º 3
0
        /// <summary>General utility used by ctors </summary>
        private void initialize()
        {
            this.pl     = csMap.pl;
            this.ncomps = src.NumComps;

            shiftValueArray  = new int[ncomps];
            maxValueArray    = new int[ncomps];
            fixedPtBitsArray = new int[ncomps];

            srcBlk        = new DataBlk[ncomps];
            inInt         = new DataBlkInt[ncomps];
            inFloat       = new DataBlkFloat[ncomps];
            workInt       = new DataBlkInt[ncomps];
            workFloat     = new DataBlkFloat[ncomps];
            dataInt       = new int[ncomps][];
            dataFloat     = new float[ncomps][];
            workDataInt   = new int[ncomps][];
            workDataFloat = new float[ncomps][];
            dataInt       = new int[ncomps][];
            dataFloat     = new float[ncomps][];


            /* For each component, get a reference to the pixel data and
             * set up working DataBlks for both integer and float output.
             */
            for (int i = 0; i < ncomps; ++i)
            {
                shiftValueArray[i]  = 1 << (src.getNomRangeBits(i) - 1);
                maxValueArray[i]    = (1 << src.getNomRangeBits(i)) - 1;
                fixedPtBitsArray[i] = src.getFixedPoint(i);

                inInt[i]                 = new DataBlkInt();
                inFloat[i]               = new DataBlkFloat();
                workInt[i]               = new DataBlkInt();
                workInt[i].progressive   = inInt[i].progressive;
                workFloat[i]             = new DataBlkFloat();
                workFloat[i].progressive = inFloat[i].progressive;
            }
        }
Ejemplo n.º 4
0
        /// <summary> Creates a new writer to the specified File object, to write data from
        /// the specified component.
        ///
        /// <p>The three components that will be written as R, G and B must be
        /// specified through the b1, b2 and b3 arguments.</p>
        ///
        /// </summary>
        /// <param name="out">The file where to write the data
        ///
        /// </param>
        /// <param name="imgSrc">The source from where to get the image data to write.
        ///
        /// </param>
        /// <param name="n1">The index of the first component from where to get the data,
        /// that will be written as the red channel.
        ///
        /// </param>
        /// <param name="n2">The index of the second component from where to get the data,
        /// that will be written as the green channel.
        ///
        /// </param>
        /// <param name="n3">The index of the third component from where to get the data,
        /// that will be written as the green channel.
        ///
        /// </param>
        /// <seealso cref="DataBlk">
        ///
        /// </seealso>
        public ImgWriterPPM(IFileInfo out_Renamed, BlkImgDataSrc imgSrc, int n1, int n2, int n3)
        {
            // Check that imgSrc is of the correct type
            // Check that the component index is valid
            if ((n1 < 0) || (n1 >= imgSrc.NumComps) || (n2 < 0) || (n2 >= imgSrc.NumComps) || (n3 < 0) || (n3 >= imgSrc.NumComps) || (imgSrc.getNomRangeBits(n1) > 8) || (imgSrc.getNomRangeBits(n2) > 8) || (imgSrc.getNomRangeBits(n3) > 8))
            {
                throw new System.ArgumentException("Invalid component indexes");
            }
            // Initialize
            w = imgSrc.getCompImgWidth(n1);
            h = imgSrc.getCompImgHeight(n1);
            // Check that all components have same width and height
            if (w != imgSrc.getCompImgWidth(n2) || w != imgSrc.getCompImgWidth(n3) || h != imgSrc.getCompImgHeight(n2) || h != imgSrc.getCompImgHeight(n3))
            {
                throw new System.ArgumentException("All components must have the" + " same dimensions and no" + " subsampling");
            }
            w = imgSrc.ImgWidth;
            h = imgSrc.ImgHeight;

            // Continue initialization
            if (out_Renamed.Exists && !out_Renamed.Delete())
            {
                throw new System.IO.IOException("Could not reset file");
            }
            this.out_Renamed = SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(out_Renamed, "rw");
            src    = imgSrc;
            cps[0] = n1;
            cps[1] = n2;
            cps[2] = n3;
            fb[0]  = imgSrc.getFixedPoint(n1);
            fb[1]  = imgSrc.getFixedPoint(n2);
            fb[2]  = imgSrc.getFixedPoint(n3);

            levShift[0] = 1 << (imgSrc.getNomRangeBits(n1) - 1);
            levShift[1] = 1 << (imgSrc.getNomRangeBits(n2) - 1);
            levShift[2] = 1 << (imgSrc.getNomRangeBits(n3) - 1);

            writeHeaderInfo();
        }
Ejemplo n.º 5
0
        /// <summary> Initialize some variables used with RCT. It must be called, at least,
        /// at the beginning of each new tile.
        ///
        /// </summary>
        private void  initForwRCT()
        {
            int i;
            int tIdx = TileIdx;

            if (src.NumComps < 3)
            {
                throw new System.ArgumentException();
            }
            // Check that the 3 components have the same dimensions
            if (src.getTileCompWidth(tIdx, 0) != src.getTileCompWidth(tIdx, 1) || src.getTileCompWidth(tIdx, 0) != src.getTileCompWidth(tIdx, 2) || src.getTileCompHeight(tIdx, 0) != src.getTileCompHeight(tIdx, 1) || src.getTileCompHeight(tIdx, 0) != src.getTileCompHeight(tIdx, 2))
            {
                throw new System.ArgumentException("Can not use RCT " + "on components with different " + "dimensions");
            }
            // Initialize bitdepths
            int[] utd;             // Premix bitdepths
            utd = new int[src.NumComps];
            for (i = utd.Length - 1; i >= 0; i--)
            {
                utd[i] = src.getNomRangeBits(i);
            }
            tdepth = calcMixedBitDepths(utd, FORW_RCT, null);
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
0
        /// <summary> Creates a new writer to the specified File object, to write data from
        /// the specified component.
        /// 
        /// <p>The three components that will be written as R, G and B must be
        /// specified through the b1, b2 and b3 arguments.</p>
        /// 
        /// </summary>
        /// <param name="out">The file where to write the data
        /// 
        /// </param>
        /// <param name="imgSrc">The source from where to get the image data to write.
        /// 
        /// </param>
        /// <param name="n1">The index of the first component from where to get the data,
        /// that will be written as the red channel.
        /// 
        /// </param>
        /// <param name="n2">The index of the second component from where to get the data,
        /// that will be written as the green channel.
        /// 
        /// </param>
        /// <param name="n3">The index of the third component from where to get the data,
        /// that will be written as the green channel.
        /// 
        /// </param>
        /// <seealso cref="DataBlk">
        /// 
        /// </seealso>
        public ImgWriterPPM(IFileInfo out_Renamed, BlkImgDataSrc imgSrc, int n1, int n2, int n3)
        {
            // Check that imgSrc is of the correct type
            // Check that the component index is valid
            if ((n1 < 0) || (n1 >= imgSrc.NumComps) || (n2 < 0) || (n2 >= imgSrc.NumComps) || (n3 < 0) || (n3 >= imgSrc.NumComps) || (imgSrc.getNomRangeBits(n1) > 8) || (imgSrc.getNomRangeBits(n2) > 8) || (imgSrc.getNomRangeBits(n3) > 8))
            {
                throw new System.ArgumentException("Invalid component indexes");
            }
            // Initialize
            w = imgSrc.getCompImgWidth(n1);
            h = imgSrc.getCompImgHeight(n1);
            // Check that all components have same width and height
            if (w != imgSrc.getCompImgWidth(n2) || w != imgSrc.getCompImgWidth(n3) || h != imgSrc.getCompImgHeight(n2) || h != imgSrc.getCompImgHeight(n3))
            {
                throw new System.ArgumentException("All components must have the" + " same dimensions and no" + " subsampling");
            }
            w = imgSrc.ImgWidth;
            h = imgSrc.ImgHeight;

            // Continue initialization
            if (out_Renamed.Exists && !out_Renamed.Delete())
            {
                throw new System.IO.IOException("Could not reset file");
            }
            this.out_Renamed = SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(out_Renamed, "rw");
            src = imgSrc;
            cps[0] = n1;
            cps[1] = n2;
            cps[2] = n3;
            fb[0] = imgSrc.getFixedPoint(n1);
            fb[1] = imgSrc.getFixedPoint(n2);
            fb[2] = imgSrc.getFixedPoint(n3);

            levShift[0] = 1 << (imgSrc.getNomRangeBits(n1) - 1);
            levShift[1] = 1 << (imgSrc.getNomRangeBits(n2) - 1);
            levShift[2] = 1 << (imgSrc.getNomRangeBits(n3) - 1);

            writeHeaderInfo();
        }
Ejemplo n.º 8
0
		/// <summary> Creates a new writer to the specified File object, to write data from
		/// the specified component.
		/// 
		/// <p>The size of the image that is written to the file is the size of the
		/// component from which to get the data, specified by b, not the size of
		/// the source image (they differ if there is some sub-sampling).</p>
		/// 
		/// <p>All the header informations are given by the BlkImgDataSrc source
		/// (component width, component height, bit-depth) and sign flag, which are
		/// provided to the constructor. The endianness is always big-endian (MSB
		/// first).</p>
		/// 
		/// </summary>
		/// <param name="out">The file where to write the data
		/// 
		/// </param>
		/// <param name="imgSrc">The source from where to get the image data to write.
		/// 
		/// </param>
		/// <param name="c">The index of the component from where to get the data.
		/// 
		/// </param>
		/// <param name="isSigned">Whether the datas are signed or not (needed only when
		/// writing header).
		/// 
		/// </param>
		/// <seealso cref="DataBlk">
		/// 
		/// </seealso>
		public ImgWriterPGX(System.IO.FileInfo out_Renamed, BlkImgDataSrc imgSrc, int c, bool isSigned)
		{
			//Initialize
			this.c = c;
			bool tmpBool;
			if (System.IO.File.Exists(out_Renamed.FullName))
				tmpBool = true;
			else
				tmpBool = System.IO.Directory.Exists(out_Renamed.FullName);
			bool tmpBool2;
			if (System.IO.File.Exists(out_Renamed.FullName))
			{
				System.IO.File.Delete(out_Renamed.FullName);
				tmpBool2 = true;
			}
			else if (System.IO.Directory.Exists(out_Renamed.FullName))
			{
				System.IO.Directory.Delete(out_Renamed.FullName);
				tmpBool2 = true;
			}
			else
				tmpBool2 = false;
			if (tmpBool && !tmpBool2)
			{
				throw new System.IO.IOException("Could not reset file");
			}
			this.out_Renamed = SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(out_Renamed, "rw");
			this.isSigned = isSigned;
			src = imgSrc;
			w = src.ImgWidth;
			h = src.ImgHeight;
			fb = imgSrc.getFixedPoint(c);
			
			bitDepth = src.getNomRangeBits(this.c);
			if ((bitDepth <= 0) || (bitDepth > 31))
			{
				throw new System.IO.IOException("PGX supports only bit-depth between " + "1 and 31");
			}
			if (bitDepth <= 8)
			{
				packBytes = 1;
			}
			else if (bitDepth <= 16)
			{
				packBytes = 2;
			}
			else
			{
				// <= 31
				packBytes = 4;
			}
			
			// Writes PGX header
			System.String tmpString = "PG " + "ML " + ((this.isSigned)?"- ":"+ ") + bitDepth + " " + w + " " + h + "\n"; // component height
			
			byte[] tmpByte = System.Text.ASCIIEncoding.ASCII.GetBytes(tmpString);
			for (int i = 0; i < tmpByte.Length; i++)
			{
				this.out_Renamed.WriteByte((byte) tmpByte[i]);
			}
			
			offset = tmpByte.Length;
			maxVal = this.isSigned?((1 << (src.getNomRangeBits(c) - 1)) - 1):((1 << src.getNomRangeBits(c)) - 1);
			minVal = this.isSigned?((- 1) * (1 << (src.getNomRangeBits(c) - 1))):0;
			
			levShift = (this.isSigned)?0:1 << (src.getNomRangeBits(c) - 1);
		}
Ejemplo n.º 9
0
        /// <summary> Creates a new writer to the specified File object, to write data from
        /// the specified component.
        /// 
        /// <p>The size of the image that is written to the file is the size of the
        /// component from which to get the data, specified by b, not the size of
        /// the source image (they differ if there is some sub-sampling).</p>
        /// 
        /// </summary>
        /// <param name="out">The file where to write the data
        /// 
        /// </param>
        /// <param name="imgSrc">The source from where to get the image data to write.
        /// 
        /// </param>
        /// <param name="c">The index of the component from where to get the data.
        /// 
        /// </param>
        public ImgWriterPGM(IFileInfo out_Renamed, BlkImgDataSrc imgSrc, int c)
        {
            // Check that imgSrc is of the correct type
            // Check that the component index is valid
            if (c < 0 || c >= imgSrc.NumComps)
            {
                throw new System.ArgumentException("Invalid number of components");
            }

            // Check that imgSrc is of the correct type
            if (imgSrc.getNomRangeBits(c) > 8)
            {
                FacilityManager.getMsgLogger().println("Warning: Component " + c + " has nominal bitdepth " + imgSrc.getNomRangeBits(c) + ". Pixel values will be " + "down-shifted to fit bitdepth of 8 for PGM file", 8, 8);
            }

            // Initialize
            if (out_Renamed.Exists && !out_Renamed.Delete())
            {
                throw new System.IO.IOException("Could not reset file");
            }
            this.out_Renamed = SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(out_Renamed, "rw");
            src = imgSrc;
            this.c = c;
            w = imgSrc.ImgWidth;
            h = imgSrc.ImgHeight;
            fb = imgSrc.getFixedPoint(c);
            levShift = 1 << (imgSrc.getNomRangeBits(c) - 1);

            writeHeaderInfo();
        }
Ejemplo n.º 10
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();
            }
        }