예제 #1
0
        /// <summary> Apply the inverse component transformation associated with the current
        /// tile. If no component transformation has been requested by the user,
        /// data are not modified. Else, appropriate method is called (invRCT or
        /// invICT).
        ///
        /// </summary>
        /// <seealso cref="invRCT">
        ///
        /// </seealso>
        /// <seealso cref="invICT">
        ///
        /// </seealso>
        /// <param name="blk">Determines the rectangular area to return.
        ///
        /// </param>
        /// <param name="c">Index of the output component.
        ///
        /// </param>
        /// <returns> The requested DataBlk
        ///
        /// </returns>
        public virtual DataBlk getInternCompData(DataBlk blk, int c)
        {
            // if specified in the command line that no component transform should
            // be made, return original data
            if (noCompTransf)
            {
                return(src.getInternCompData(blk, c));
            }

            switch (transfType)
            {
            case NONE:
                return(src.getInternCompData(blk, c));


            case INV_RCT:
                return(invRCT(blk, c));

            case INV_ICT:
                return(invICT(blk, c));

            default:
                throw new System.ArgumentException("Non JPEG 2000 part I" + " component transformation");
            }
        }
예제 #2
0
 public virtual void set_Renamed(DataBlk db)
 {
     h      = db.h;
     w      = db.w;
     ulx    = db.ulx;
     uly    = db.uly;
     offset = db.offset;
     scanw  = db.scanw;
 }
예제 #3
0
        /// <summary> Returns a block of image data containing the specifed rectangular area,
        /// in the specified component, as a reference to the internal buffer (see
        /// below). The rectangular area is specified by the coordinates and
        /// dimensions of the 'blk' object.
        ///
        /// <p>The area to return is specified by the 'ulx', 'uly', 'w' and 'h'
        /// members of the 'blk' argument. These members are not modified by this
        /// method.</p>
        ///
        /// <p>The data returned by this method can be the data in the internal
        /// buffer of this object, if any, and thus can not be modified by the
        /// caller. The 'offset' and 'scanw' of the returned data can be
        /// arbitrary. See the 'DataBlk' class.</p>
        ///
        /// <p>The returned data has its 'progressive' attribute unset
        /// (i.e. false).</p>
        ///
        /// </summary>
        /// <param name="blk">Its coordinates and dimensions specify the area to return.
        ///
        /// </param>
        /// <param name="c">The index of the component from which to get the data.
        ///
        /// </param>
        /// <returns> The requested DataBlk
        ///
        /// </returns>
        /// <seealso cref="getInternCompData">
        ///
        /// </seealso>
        public override DataBlk getInternCompData(DataBlk blk, int c)
        {
            int tIdx = TileIdx;

            if (src.getSynSubbandTree(tIdx, c).HorWFilter == null)
            {
                dtype = DataBlk.TYPE_INT;
            }
            else
            {
                dtype = src.getSynSubbandTree(tIdx, c).HorWFilter.DataType;
            }

            //If the source image has not been decomposed
            if (reconstructedComps[c] == null)
            {
                //Allocate component data buffer
                switch (dtype)
                {
                case DataBlk.TYPE_FLOAT:
                    reconstructedComps[c] = new DataBlkFloat(0, 0, getTileCompWidth(tIdx, c), getTileCompHeight(tIdx, c));
                    break;

                case DataBlk.TYPE_INT:
                    reconstructedComps[c] = new DataBlkInt(0, 0, getTileCompWidth(tIdx, c), getTileCompHeight(tIdx, c));
                    break;
                }
                //Reconstruct source image
                waveletTreeReconstruction(reconstructedComps[c], src.getSynSubbandTree(tIdx, c), c);
                if (pw != null && c == src.NumComps - 1)
                {
                    pw.terminateProgressWatch();
                }
            }

            if (blk.DataType != dtype)
            {
                if (dtype == DataBlk.TYPE_INT)
                {
                    blk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h);
                }
                else
                {
                    blk = new DataBlkFloat(blk.ulx, blk.uly, blk.w, blk.h);
                }
            }
            // Set the reference to the internal buffer
            blk.Data        = reconstructedComps[c].Data;
            blk.offset      = reconstructedComps[c].w * blk.uly + blk.ulx;
            blk.scanw       = reconstructedComps[c].w;
            blk.progressive = false;
            return(blk);
        }
예제 #4
0
        /// <summary> Copy the DataBlk geometry from source to target
        /// DataBlk and assure that the target has an appropriate
        /// data buffer.
        /// </summary>
        /// <param name="tgt">has its geometry set.
        /// </param>
        /// <param name="src">used to get the new geometric parameters.
        /// </param>
        protected internal static void copyGeometry(DataBlk tgt, DataBlk src)
        {
            tgt.offset = 0;
            tgt.h      = src.h;
            tgt.w      = src.w;
            tgt.ulx    = src.ulx;
            tgt.uly    = src.uly;
            tgt.scanw  = src.w;

            // Create data array if necessary

            InternalBuffer = tgt;
        }
예제 #5
0
        public override DataBlk getInternCompData(DataBlk blk, int c)
        {
            if (c < 0 || c >= this.nc)
            {
                throw new ArgumentOutOfRangeException("c");
            }

            blk.offset      = 0;
            blk.scanw       = blk.w;
            blk.progressive = false;
            blk.Data        = this.GetDataArray(blk.ulx, blk.uly, blk.w, blk.h);

            return(blk);
        }
예제 #6
0
 /// <summary> Apply forward component transformation associated with the current
 /// tile. If no component transformation has been requested by the user,
 /// data are not modified.
 ///
 /// <p>This method calls the getInternCompData() method, but respects the
 /// definitions of the getCompData() method defined in the BlkImgDataSrc
 /// interface.</p>
 ///
 /// </summary>
 /// <param name="blk">Determines the rectangular area to return, and the data is
 /// returned in this object.
 ///
 /// </param>
 /// <param name="c">Index of the output component.
 ///
 /// </param>
 /// <returns> The requested DataBlk
 ///
 /// </returns>
 /// <seealso cref="BlkImgDataSrc.getCompData">
 ///
 /// </seealso>
 public virtual DataBlk getCompData(DataBlk blk, int c)
 {
     // If requesting a component whose index is greater than 3 or there is
     // no transform return a copy of data (getInternCompData returns the
     // actual data in those cases)
     if (c >= 3 || transfType == NONE)
     {
         return(src.getCompData(blk, c));
     }
     else
     {
         // We can use getInternCompData (since data is a copy anyways)
         return(getInternCompData(blk, c));
     }
 }
예제 #7
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 copy of the internal data, therefore the returned data
        /// can be modified "in place".
        ///
        /// <P> After being read the coefficients are level shifted by subtracting
        /// 2^(nominal bit range - 1)
        ///
        /// <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' of
        /// the returned data is 0, and the 'scanw' is the same as the block's
        /// width. See the 'DataBlk' class.
        ///
        /// <P>If the data array in 'blk' is 'null', then a new one is created. If
        /// the data array is not 'null' then it is reused, and it must be large
        /// enough to contain the block's data. Otherwise an 'ArrayStoreException'
        /// or an 'IndexOutOfBoundsException' is thrown by the Java system.
        ///
        /// <P>The returned data has its 'progressive' attribute unset
        /// (i.e. false).
        ///
        /// <P>When an I/O exception is encountered the JJ2KExceptionHandler is
        /// used. The exception is passed to its handleException method. The action
        /// that is taken depends on the action that has been registered in
        /// JJ2KExceptionHandler. See JJ2KExceptionHandler for details.
        ///
        /// </summary>
        /// <param name="blk">Its coordinates and dimensions specify the area to
        /// return. If it contains a non-null data array, then it must have the
        /// correct dimensions. If it contains a null data array a new one is
        /// created. The 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. Only
        /// 0,1 and 2 are valid.
        ///
        /// </param>
        /// <returns> The requested DataBlk
        ///
        /// </returns>
        /// <seealso cref="getInternCompData">
        ///
        /// </seealso>
        /// <seealso cref="JJ2KExceptionHandler">
        ///
        /// </seealso>
        public override DataBlk getCompData(DataBlk blk, int c)
        {
            // NOTE: can not directly call getInterCompData since that returns
            // internally buffered data.
            int ulx, uly, w, h;

            // Check type of block provided as an argument
            if (blk.DataType != DataBlk.TYPE_INT)
            {
                DataBlkInt tmp = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h);
                blk = tmp;
            }

            int[] bakarr = (int[])blk.Data;
            // Save requested block size
            ulx = blk.ulx;
            uly = blk.uly;
            w   = blk.w;
            h   = blk.h;
            // Force internal data buffer to be different from external
            blk.Data = null;
            getInternCompData(blk, c);
            // Copy the data
            if (bakarr == null)
            {
                bakarr = new int[w * h];
            }
            if (blk.offset == 0 && blk.scanw == w)
            {
                // Requested and returned block buffer are the same size
                // CONVERSION PROBLEM?
                Array.Copy((System.Array)blk.Data, 0, (System.Array)bakarr, 0, w * h);
            }
            else
            {
                // Requested and returned block are different
                for (int i = h - 1; i >= 0; i--)
                {
                    // copy line by line
                    // CONVERSION PROBLEM?
                    Array.Copy((System.Array)blk.Data, blk.offset + i * blk.scanw, (System.Array)bakarr, i * w, w);
                }
            }
            blk.Data   = bakarr;
            blk.offset = 0;
            blk.scanw  = blk.w;
            return(blk);
        }
예제 #8
0
        /// <summary> Apply the component transformation associated with the current tile. If
        /// no component transformation has been requested by the user, data are
        /// not modified. Else, appropriate method is called (forwRCT or forwICT).
        ///
        /// </summary>
        /// <seealso cref="forwRCT">
        ///
        /// </seealso>
        /// <seealso cref="forwICT">
        ///
        /// </seealso>
        /// <param name="blk">Determines the rectangular area to return.
        ///
        /// </param>
        /// <param name="c">Index of the output component.
        ///
        /// </param>
        /// <returns> The requested DataBlk
        ///
        /// </returns>
        public virtual DataBlk getInternCompData(DataBlk blk, int c)
        {
            switch (transfType)
            {
            case NONE:
                return(src.getInternCompData(blk, c));

            case FORW_RCT:
                return(forwRCT(blk, c));

            case FORW_ICT:
                return(forwICT(blk, c));

            default:
                throw new System.ArgumentException("Non JPEG 2000 part 1 " + "component" + " transformation for tile: " + tIdx);
            }
        }
예제 #9
0
        /// <summary> Returns a block of image data containing the specifed rectangular area,
        /// in the specified component, as a copy (see below). The rectangular area
        /// is specified by the coordinates and dimensions of the 'blk' object.
        ///
        /// <p>The area to return is specified by the 'ulx', 'uly', 'w' and 'h'
        /// members of the 'blk' argument. These members are not modified by this
        /// method.</p>
        ///
        /// <p>The data returned by this method is always a copy of the internal
        /// data of this object, if any, and it can be modified "in place" without
        /// any problems after being returned. The 'offset' of the returned data is
        /// 0, and the 'scanw' is the same as the block's width. See the 'DataBlk'
        /// class.</p>
        ///
        /// <p>If the data array in 'blk' is <tt>null</tt>, then a new one is
        /// created. If the data array is not <tt>null</tt> then it must be big
        /// enough to contain the requested area.</p>
        ///
        /// <p>The returned data always has its 'progressive' attribute unset (i.e
        /// false)</p>
        ///
        /// </summary>
        /// <param name="blk">Its coordinates and dimensions specify the area to
        /// return. If it contains a non-null data array, then it must be large
        /// enough. If it contains a null data array a new one is created. The
        /// 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 override DataBlk getCompData(DataBlk blk, int c)
        {
            //int j;
            System.Object dst_data;       // src_data removed
            int[]         dst_data_int;   // src_data_int removed
            float[]       dst_data_float; // src_data_float removed

            // To keep compiler happy
            dst_data = null;

            // Ensure output buffer
            switch (blk.DataType)
            {
            case DataBlk.TYPE_INT:
                dst_data_int = (int[])blk.Data;
                if (dst_data_int == null || dst_data_int.Length < blk.w * blk.h)
                {
                    dst_data_int = new int[blk.w * blk.h];
                }
                dst_data = dst_data_int;
                break;

            case DataBlk.TYPE_FLOAT:
                dst_data_float = (float[])blk.Data;
                if (dst_data_float == null || dst_data_float.Length < blk.w * blk.h)
                {
                    dst_data_float = new float[blk.w * blk.h];
                }
                dst_data = dst_data_float;
                break;
            }

            // Use getInternCompData() to get the data, since getInternCompData()
            // returns reference to internal buffer, we must copy it.
            blk = getInternCompData(blk, c);

            // Copy the data
            blk.Data   = dst_data;
            blk.offset = 0;
            blk.scanw  = blk.w;
            return(blk);
        }
예제 #10
0
        /// <summary> Performs the forward wavelet transform on the whole band. It
        /// iteratively decomposes the subbands from the top node to the leaves.
        ///
        /// </summary>
        /// <param name="band">The band containing the float data to decompose
        ///
        /// </param>
        /// <param name="subband">The structure containing the coordinates of the current
        /// subband in the whole band to decompose.
        ///
        /// </param>
        /// <param name="c">The index of the current component to decompose
        ///
        /// </param>
        private void waveletTreeDecomposition(DataBlk band, SubbandAn subband, int c)
        {
            //If the current subband is a leaf then nothing to be done (a leaf is
            //not decomposed).
            if (!subband.isNode)
            {
                return;
            }
            else
            {
                //Perform the 2D wavelet decomposition of the current subband
                wavelet2DDecomposition(band, (SubbandAn)subband, c);

                //Perform the decomposition of the four resulting subbands
                waveletTreeDecomposition(band, (SubbandAn)subband.HH, c);
                waveletTreeDecomposition(band, (SubbandAn)subband.LH, c);
                waveletTreeDecomposition(band, (SubbandAn)subband.HL, c);
                waveletTreeDecomposition(band, (SubbandAn)subband.LL, c);
            }
        }
예제 #11
0
        public DataBlk getInternCompData(DataBlk blk, int c)
        {
            if (c < 0 || c >= this.nc)
            {
                throw new ArgumentOutOfRangeException("c");
            }

            var data = new int[blk.w * blk.h];

            for (int y = blk.uly, k = 0; y < blk.uly + blk.h; ++y)
            {
                for (int x = blk.ulx, xy = blk.uly * this.w + blk.ulx; x < blk.ulx + blk.w; ++x, ++k, ++xy)
                {
                    data[k] = this.comps[c][xy];
                }
            }

            blk.offset      = 0;
            blk.scanw       = blk.w;
            blk.progressive = false;
            blk.Data        = data;

            return(blk);
        }
예제 #12
0
 public ComputedComponents(ColorSpaceMapper enclosingInstance, DataBlk db)
 {
     InitBlock(enclosingInstance);
     set_Renamed(db);
 }
예제 #13
0
        /// <summary> Returns the specified code-block in the current tile for the specified
        /// component (as a reference or copy).
        ///
        /// <p>The returned code-block may be progressive, which is indicated by
        /// the 'progressive' variable of the returned 'DataBlk' object. If a
        /// code-block is progressive it means that in a later request to this
        /// method for the same code-block it is possible to retrieve data which is
        /// a better approximation, since meanwhile more data to decode for the
        /// code-block could have been received. If the code-block is not
        /// progressive then later calls to this method for the same code-block
        /// will return the exact same data values.</p>
        ///
        /// <p>The data returned by this method can be the data in the internal
        /// buffer of this object, if any, and thus can not be modified by the
        /// caller. The 'offset' and 'scanw' of the returned data can be
        /// arbitrary. See the 'DataBlk' class.</p>
        ///
        /// <p>The 'ulx' and 'uly' members of the returned 'DataBlk' object contain
        /// the coordinates of the top-left corner of the block, with respect to
        /// the tile, not the subband.</p>
        ///
        /// </summary>
        /// <param name="c">The component for which to return the next code-block.
        ///
        /// </param>
        /// <param name="m">The vertical index of the code-block to return, in the
        /// specified subband.
        ///
        /// </param>
        /// <param name="n">The horizontal index of the code-block to return, in the
        /// specified subband.
        ///
        /// </param>
        /// <param name="sb">The subband in which the code-block to return is.
        ///
        /// </param>
        /// <param name="cblk">If non-null this object will be used to return the new
        /// code-block. If null a new one will be allocated and returned. If the
        /// "data" array of the object is non-null it will be reused, if possible,
        /// to return the data.
        ///
        /// </param>
        /// <returns> The requested code-block in the current tile for component 'c'.
        ///
        /// </returns>
        /// <seealso cref="DataBlk">
        ///
        /// </seealso>
        public virtual DataBlk getInternCodeBlock(int c, int m, int n, SubbandSyn sb, DataBlk cblk)
        {
            int i, j, k, wrap; // mi removed
            int ulx, uly, w, h;

            int[] data; // local copy of quantized data
            int   tmp;

            //int limit;

            // Get data block from entropy decoder
            cblk = src.getInternCodeBlock(c, m, n, sb, cblk);

            // If there are no ROIs in the tile, Or if we already got all blocks
            bool noRoiInTile = false;

            if (mss == null || mss.getTileCompVal(TileIdx, c) == null)
            {
                noRoiInTile = true;
            }

            if (noRoiInTile || cblk == null)
            {
                return(cblk);
            }
            data = (int[])cblk.Data;
            ulx  = cblk.ulx;
            uly  = cblk.uly;
            w    = cblk.w;
            h    = cblk.h;

            // Scale coefficients according to magnitude. If the magnitude of a
            // coefficient is lower than 2 pow 31-magbits then it is a background
            // coeff and should be up-scaled
            int boost = ((System.Int32)mss.getTileCompVal(TileIdx, c));
            int mask  = ((1 << sb.magbits) - 1) << (31 - sb.magbits);
            int mask2 = (~mask) & 0x7FFFFFFF;

            wrap = cblk.scanw - w;
            i    = cblk.offset + cblk.scanw * (h - 1) + w - 1;
            for (j = h; j > 0; j--)
            {
                for (k = w; k > 0; k--, i--)
                {
                    tmp = data[i];
                    if ((tmp & mask) == 0)
                    {
                        // BG
                        data[i] = (tmp & unchecked ((int)0x80000000)) | (tmp << boost);
                    }
                    else
                    {
                        // ROI
                        if ((tmp & mask2) != 0)
                        {
                            // decoded more than magbits bit-planes, set
                            // quantization mid-interval approx. bit just after
                            // the magbits.
                            data[i] = (tmp & (~mask2)) | (1 << (30 - sb.magbits));
                        }
                    }
                }
                i -= wrap;
            }
            return(cblk);
        }
예제 #14
0
 /// <summary> Returns the specified code-block in the current tile for the specified
 /// component, as a copy (see below).
 ///
 /// <p>The returned code-block may be progressive, which is indicated by
 /// the 'progressive' variable of the returned 'DataBlk' object. If a
 /// code-block is progressive it means that in a later request to this
 /// method for the same code-block it is possible to retrieve data which is
 /// a better approximation, since meanwhile more data to decode for the
 /// code-block could have been received. If the code-block is not
 /// progressive then later calls to this method for the same code-block
 /// will return the exact same data values.</p>
 ///
 /// <p>The data returned by this method is always a copy of the internal
 /// data of this object, if any, and it can be modified "in place" without
 /// any problems after being returned. The 'offset' of the returned data is
 /// 0, and the 'scanw' is the same as the code-block width. See the
 /// 'DataBlk' class.</p>
 ///
 /// <p>The 'ulx' and 'uly' members of the returned 'DataBlk' object contain
 /// the coordinates of the top-left corner of the block, with respect to
 /// the tile, not the subband.</p>
 ///
 /// </summary>
 /// <param name="c">The component for which to return the next code-block.
 ///
 /// </param>
 /// <param name="m">The vertical index of the code-block to return, in the
 /// specified subband.
 ///
 /// </param>
 /// <param name="n">The horizontal index of the code-block to return, in the
 /// specified subband.
 ///
 /// </param>
 /// <param name="sb">The subband in which the code-block to return is.
 ///
 /// </param>
 /// <param name="cblk">If non-null this object will be used to return the new
 /// code-block. If null a new one will be allocated and returned. If the
 /// "data" array of the object is non-null it will be reused, if possible,
 /// to return the data.
 ///
 /// </param>
 /// <returns> The next code-block in the current tile for component 'c', or
 /// null if all code-blocks for the current tile have been returned.
 ///
 /// </returns>
 /// <seealso cref="DataBlk">
 ///
 /// </seealso>
 public virtual DataBlk getCodeBlock(int c, int m, int n, SubbandSyn sb, DataBlk cblk)
 {
     return(getInternCodeBlock(c, m, n, sb, cblk));
 }
예제 #15
0
        public override DataBlk getCompData(DataBlk blk, int c)
        {
            var newBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h);

            return(this.getInternCompData(newBlk, c));
        }
예제 #16
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 copy of the internal data, therefore the returned data
        /// can be modified "in place".
        ///
        /// <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' of
        /// the returned data is 0, and the 'scanw' is the same as the block's
        /// width. See the 'DataBlk' class.
        ///
        /// <P>If the data array in 'blk' is 'null', then a new one is created. If
        /// the data array is not 'null' then it is reused, and it must be large
        /// enough to contain the block's data. Otherwise an 'ArrayStoreException'
        /// or an 'IndexOutOfBoundsException' is thrown by the Java system.
        ///
        /// <P>The returned data has its 'progressive' attribute set to that of the
        /// input data.
        ///
        /// </summary>
        /// <param name="out">Its coordinates and dimensions specify the area to
        /// return. If it contains a non-null data array, then it must have the
        /// correct dimensions. If it contains a null data array a new one is
        /// created. The 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. Only 0
        /// and 3 are valid.
        ///
        /// </param>
        /// <returns> The requested DataBlk
        ///
        /// </returns>
        /// <seealso cref="getInternCompData">
        ///
        /// </seealso>
        public override DataBlk getCompData(DataBlk outblk, int c)
        {
            try
            {
                if (ncomps != 1 && ncomps != 3)
                {
                    System.String msg = "ICCProfiler: icc profile _not_ applied to " + ncomps + " component image";
                    FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, msg);
                    return(src.getCompData(outblk, c));
                }

                int type = outblk.DataType;

                int leftedgeOut  = -1; // offset to the start of the output scanline
                int rightedgeOut = -1; // offset to the end of the output
                                       // scanline + 1
                int leftedgeIn  = -1;  // offset to the start of the input scanline
                int rightedgeIn = -1;  // offset to the end of the input
                                       // scanline + 1

                // Calculate all components:
                for (int i = 0; i < ncomps; ++i)
                {
                    int fixedPtBits = src.getFixedPoint(i);
                    int shiftVal    = shiftValueArray[i];
                    int maxVal      = maxValueArray[i];

                    // Initialize general input and output indexes
                    int kOut = -1;
                    int kIn  = -1;

                    switch (type)
                    {
                    // Int and Float data only
                    case DataBlk.TYPE_INT:

                        // Set up the DataBlk geometry
                        copyGeometry(workInt[i], outblk);
                        copyGeometry(tempInt[i], outblk);
                        copyGeometry(inInt[i], outblk);
                        InternalBuffer = outblk;

                        // Reference the output array
                        workDataInt[i] = (int[])workInt[i].Data;

                        // Request data from the source.
                        inInt[i]   = (DataBlkInt)src.getInternCompData(inInt[i], i);
                        dataInt[i] = inInt[i].DataInt;

                        // The nitty-gritty.

                        for (int row = 0; row < outblk.h; ++row)
                        {
                            leftedgeIn   = inInt[i].offset + row * inInt[i].scanw;
                            rightedgeIn  = leftedgeIn + inInt[i].w;
                            leftedgeOut  = outblk.offset + row * outblk.scanw;
                            rightedgeOut = leftedgeOut + outblk.w;

                            for (kOut = leftedgeOut, kIn = leftedgeIn; kIn < rightedgeIn; ++kIn, ++kOut)
                            {
                                int tmpInt = (dataInt[i][kIn] >> fixedPtBits) + shiftVal;
                                workDataInt[i][kOut] = ((tmpInt < 0) ? 0 : ((tmpInt > maxVal) ? maxVal : tmpInt));
                            }
                        }
                        break;


                    case DataBlk.TYPE_FLOAT:

                        // Set up the DataBlk geometry
                        copyGeometry(workFloat[i], outblk);
                        copyGeometry(tempFloat[i], outblk);
                        copyGeometry(inFloat[i], outblk);
                        InternalBuffer = outblk;

                        // Reference the output array
                        workDataFloat[i] = (float[])workFloat[i].Data;

                        // Request data from the source.
                        inFloat[i]   = (DataBlkFloat)src.getInternCompData(inFloat[i], i);
                        dataFloat[i] = inFloat[i].DataFloat;

                        // The nitty-gritty.

                        for (int row = 0; row < outblk.h; ++row)
                        {
                            leftedgeIn   = inFloat[i].offset + row * inFloat[i].scanw;
                            rightedgeIn  = leftedgeIn + inFloat[i].w;
                            leftedgeOut  = outblk.offset + row * outblk.scanw;
                            rightedgeOut = leftedgeOut + outblk.w;

                            for (kOut = leftedgeOut, kIn = leftedgeIn; kIn < rightedgeIn; ++kIn, ++kOut)
                            {
                                float tmpFloat = dataFloat[i][kIn] / (1 << fixedPtBits) + shiftVal;
                                workDataFloat[i][kOut] = ((tmpFloat < 0) ? 0 : ((tmpFloat > maxVal) ? maxVal : tmpFloat));
                            }
                        }
                        break;


                    case DataBlk.TYPE_SHORT:
                    case DataBlk.TYPE_BYTE:
                    default:
                        // Unsupported output type.
                        throw new System.ArgumentException("Invalid source " + "datablock type");
                    }
                }

                switch (type)
                {
                // Int and Float data only
                case DataBlk.TYPE_INT:

                    if (ncomps == 1)
                    {
                        ((MonochromeTransformTosRGB)xform).apply(workInt[c], tempInt[c]);
                    }
                    else
                    {
                        // ncomps == 3
                        ((MatrixBasedTransformTosRGB)xform).apply(workInt, tempInt);
                    }

                    outblk.progressive = inInt[c].progressive;
                    outblk.Data        = tempInt[c].Data;
                    break;


                case DataBlk.TYPE_FLOAT:

                    if (ncomps == 1)
                    {
                        ((MonochromeTransformTosRGB)xform).apply(workFloat[c], tempFloat[c]);
                    }
                    else
                    {
                        // ncomps == 3
                        ((MatrixBasedTransformTosRGB)xform).apply(workFloat, tempFloat);
                    }

                    outblk.progressive = inFloat[c].progressive;
                    outblk.Data        = tempFloat[c].Data;
                    break;


                case DataBlk.TYPE_SHORT:
                case DataBlk.TYPE_BYTE:
                default:
                    // Unsupported output type.
                    throw new System.ArgumentException("invalid source datablock" + " type");
                }

                // Initialize the output block geometry and set the profiled
                // data into the output block.
                outblk.offset = 0;
                outblk.scanw  = outblk.w;
            }
            catch (MatrixBasedTransformException e)
            {
                //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Throwable.getMessage' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
                FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.ERROR, "matrix transform problem:\n" + e.Message);
                if (pl.getParameter("debug").Equals("on"))
                {
                    SupportClass.WriteStackTrace(e, Console.Error);
                }
                else
                {
                    FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.ERROR, "Use '-debug' option for more details");
                }
                return(null);
            }
            catch (MonochromeTransformException e)
            {
                //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Throwable.getMessage' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
                FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.ERROR, "monochrome transform problem:\n" + e.Message);
                if (pl.getParameter("debug").Equals("on"))
                {
                    SupportClass.WriteStackTrace(e, Console.Error);
                }
                else
                {
                    FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.ERROR, "Use '-debug' option for more details");
                }
                return(null);
            }

            return(outblk);
        }
예제 #17
0
        /// <summary> Returns, in the blk argument, the 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> After being read the coefficients are level shifted by subtracting
        /// 2^(nominal bit range - 1)
        ///
        /// <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>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>The returned data always has its 'progressive' attribute unset
        /// (i.e. false).
        ///
        /// <P>When an I/O exception is encountered the JJ2KExceptionHandler is
        /// used. The exception is passed to its handleException method. The action
        /// that is taken depends on the action that has been registered in
        /// JJ2KExceptionHandler. See JJ2KExceptionHandler for details.
        ///
        /// <P>This method implements buffering for the 3 components: When the
        /// first one is asked, all the 3 components are read and stored until they
        /// are needed.
        ///
        /// </summary>
        /// <param name="blk">Its coordinates and dimensions specify the area to
        /// return. 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. Only 0,
        /// 1 and 3 are valid.
        ///
        /// </param>
        /// <returns> The requested DataBlk
        ///
        /// </returns>
        /// <seealso cref="getCompData">
        ///
        /// </seealso>
        /// <seealso cref="JJ2KExceptionHandler">
        ///
        /// </seealso>
        public override DataBlk getInternCompData(DataBlk blk, int c)
        {
            // Check component index
            if (c < 0 || c > 2)
            {
                throw new System.ArgumentException();
            }

            // Check type of block provided as an argument
            if (blk.DataType != DataBlk.TYPE_INT)
            {
                if (intBlk == null)
                {
                    intBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h);
                }
                else
                {
                    intBlk.ulx = blk.ulx;
                    intBlk.uly = blk.uly;
                    intBlk.w   = blk.w;
                    intBlk.h   = blk.h;
                }
                blk = intBlk;
            }

            // If asking a component for the first time for this block, read the 3
            // components
            if ((barr[c] == null) || (dbi.ulx > blk.ulx) || (dbi.uly > blk.uly) || (dbi.ulx + dbi.w < blk.ulx + blk.w) || (dbi.uly + dbi.h < blk.uly + blk.h))
            {
                int   k, j, i, mi;
                int[] red, green, blue;

                // Reset data arrays if needed
                if (barr[c] == null || barr[c].Length < blk.w * blk.h)
                {
                    barr[c] = new int[blk.w * blk.h];
                }
                blk.Data = barr[c];

                i = (c + 1) % 3;
                if (barr[i] == null || barr[i].Length < blk.w * blk.h)
                {
                    barr[i] = new int[blk.w * blk.h];
                }
                i = (c + 2) % 3;
                if (barr[i] == null || barr[i].Length < blk.w * blk.h)
                {
                    barr[i] = new int[blk.w * blk.h];
                }

                // set attributes of the DataBlk used for buffering
                dbi.ulx = blk.ulx;
                dbi.uly = blk.uly;
                dbi.w   = blk.w;
                dbi.h   = blk.h;

                // Check line buffer
                if (buf == null || buf.Length < 3 * blk.w)
                {
                    buf = new byte[3 * blk.w];
                }

                red   = barr[0];
                green = barr[1];
                blue  = barr[2];

                try
                {
                    // Read line by line
                    mi = blk.uly + blk.h;
                    for (i = blk.uly; i < mi; i++)
                    {
                        // Reposition in input offset takes care of
                        // header offset
                        in_Renamed.Seek(offset + i * 3 * w + 3 * blk.ulx, System.IO.SeekOrigin.Begin);
                        in_Renamed.Read(buf, 0, 3 * blk.w);

                        for (k = (i - blk.uly) * blk.w + blk.w - 1, j = 3 * blk.w - 1; j >= 0; k--)
                        {
                            // Read every third sample
                            blue[k]  = (((byte)buf[j--]) & 0xFF) - DC_OFFSET;
                            green[k] = (((byte)buf[j--]) & 0xFF) - DC_OFFSET;
                            red[k]   = (((byte)buf[j--]) & 0xFF) - DC_OFFSET;
                        }
                    }
                }
                catch (System.IO.IOException e)
                {
                    JJ2KExceptionHandler.handleException(e);
                }
                barr[0] = red;
                barr[1] = green;
                barr[2] = blue;

                // Set buffer attributes
                blk.Data   = barr[c];
                blk.offset = 0;
                blk.scanw  = blk.w;
            }
            else
            {
                //Asking for the 2nd or 3rd block component
                blk.Data   = barr[c];
                blk.offset = (blk.ulx - dbi.ulx) * dbi.w + blk.ulx - dbi.ulx;
                blk.scanw  = dbi.scanw;
            }

            // Turn off the progressive attribute
            blk.progressive = false;
            return(blk);
        }
예제 #18
0
 public abstract DataBlk getInternCompData(DataBlk blk, int c);
        /// <summary> Returns, in the blk argument, the 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>After being read the coefficients are level shifted by subtracting
        /// 2^(nominal bit range - 1)<p>
        ///
        /// <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>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 always has its 'progressive' attribute unset
        /// (i.e. false).</p>
        ///
        /// <p>When an I/O exception is encountered the JJ2KExceptionHandler is
        /// used. The exception is passed to its handleException method. The action
        /// that is taken depends on the action that has been registered in
        /// JJ2KExceptionHandler. See JJ2KExceptionHandler for details.</p>
        ///
        /// </summary>
        /// <param name="blk">Its coordinates and dimensions specify the area to
        /// return. 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. Only 0
        /// is valid.
        ///
        /// </param>
        /// <returns> The requested DataBlk
        ///
        /// </returns>
        /// <seealso cref="getCompData">
        /// </seealso>
        /// <seealso cref="JJ2KExceptionHandler">
        ///
        /// </seealso>
        public override DataBlk getInternCompData(DataBlk blk, int c)
        {
            int k, j, i, mi;             // counters
            int levShift = 1 << (bitDepth - 1);

            // Check component index
            if (c != 0)
            {
                throw new System.ArgumentException();
            }

            // Check type of block provided as an argument
            if (blk.DataType != DataBlk.TYPE_INT)
            {
                if (intBlk == null)
                {
                    intBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h);
                }
                else
                {
                    intBlk.ulx = blk.ulx;
                    intBlk.uly = blk.uly;
                    intBlk.w   = blk.w;
                    intBlk.h   = blk.h;
                }
                blk = intBlk;
            }

            // Get data array
            int[] barr = (int[])blk.Data;
            if (barr == null || barr.Length < blk.w * blk.h * packBytes)
            {
                barr     = new int[blk.w * blk.h];
                blk.Data = barr;
            }

            int paddingLength = (32 - bitDepth);

            if (buf == null || buf.Length < packBytes * blk.w)
            {
                buf = new byte[packBytes * blk.w];
            }
            try
            {
                switch (packBytes)
                {
                // Switch between one of the 3 byte packet type
                case 1:                          // Samples packed into 1 byte
                    // Read line by line
                    mi = blk.uly + blk.h;
                    if (isSigned)
                    {
                        for (i = blk.uly; i < mi; i++)
                        {
                            // Reposition in input
                            in_Renamed.Seek(offset + i * w + blk.ulx, System.IO.SeekOrigin.Begin);
                            in_Renamed.Read(buf, 0, blk.w);
                            for (k = (i - blk.uly) * blk.w + blk.w - 1, j = blk.w - 1; j >= 0; k--)
                            {
                                barr[k] = (((buf[j--] & 0xFF) << paddingLength) >> paddingLength);
                            }
                        }
                    }
                    else
                    {
                        // Not signed
                        for (i = blk.uly; i < mi; i++)
                        {
                            // Reposition in input
                            in_Renamed.Seek(offset + i * w + blk.ulx, System.IO.SeekOrigin.Begin);
                            in_Renamed.Read(buf, 0, blk.w);
                            for (k = (i - blk.uly) * blk.w + blk.w - 1, j = blk.w - 1; j >= 0; k--)
                            {
                                barr[k] = (SupportClass.URShift(((buf[j--] & 0xFF) << paddingLength), paddingLength)) - levShift;
                            }
                        }
                    }
                    break;


                case 2:                          // Samples packed into 2 bytes
                    // Read line by line
                    mi = blk.uly + blk.h;
                    if (isSigned)
                    {
                        for (i = blk.uly; i < mi; i++)
                        {
                            // Reposition in input
                            in_Renamed.Seek(offset + 2 * (i * w + blk.ulx), System.IO.SeekOrigin.Begin);
                            in_Renamed.Read(buf, 0, blk.w << 1);
                            switch (byteOrder)
                            {
                            case CSJ2K.j2k.io.EndianType_Fields.LITTLE_ENDIAN:
                                for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 1) - 1; j >= 0; k--)
                                {
                                    barr[k] = ((((buf[j--] & 0xFF) << 8) | (buf[j--] & 0xFF)) << paddingLength) >> paddingLength;
                                }
                                break;

                            case CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN:
                                for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 1) - 1; j >= 0; k--)
                                {
                                    barr[k] = (((buf[j--] & 0xFF) | ((buf[j--] & 0xFF) << 8)) << paddingLength) >> paddingLength;
                                }
                                break;

                            default:
                                throw new System.ApplicationException("Internal JJ2000 bug");
                            }
                        }
                    }
                    else
                    {
                        // If not signed
                        for (i = blk.uly; i < mi; i++)
                        {
                            // Reposition in input
                            in_Renamed.Seek(offset + 2 * (i * w + blk.ulx), System.IO.SeekOrigin.Begin);
                            in_Renamed.Read(buf, 0, blk.w << 1);
                            switch (byteOrder)
                            {
                            case CSJ2K.j2k.io.EndianType_Fields.LITTLE_ENDIAN:
                                for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 1) - 1; j >= 0; k--)
                                {
                                    barr[k] = (SupportClass.URShift(((((buf[j--] & 0xFF) << 8) | (buf[j--] & 0xFF)) << paddingLength), paddingLength)) - levShift;
                                }
                                break;

                            case CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN:
                                for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 1) - 1; j >= 0; k--)
                                {
                                    barr[k] = (SupportClass.URShift((((buf[j--] & 0xFF) | ((buf[j--] & 0xFF) << 8)) << paddingLength), paddingLength)) - levShift;
                                }
                                break;

                            default:
                                throw new System.ApplicationException("Internal JJ2000 bug");
                            }
                        }
                    }
                    break;


                case 4:                          // Samples packed into 4 bytes
                    // Read line by line
                    mi = blk.uly + blk.h;
                    if (isSigned)
                    {
                        for (i = blk.uly; i < mi; i++)
                        {
                            // Reposition in input
                            in_Renamed.Seek(offset + 4 * (i * w + blk.ulx), System.IO.SeekOrigin.Begin);
                            in_Renamed.Read(buf, 0, blk.w << 2);
                            switch (byteOrder)
                            {
                            case CSJ2K.j2k.io.EndianType_Fields.LITTLE_ENDIAN:
                                for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 2) - 1; j >= 0; k--)
                                {
                                    barr[k] = ((((buf[j--] & 0xFF) << 24) | ((buf[j--] & 0xFF) << 16) | ((buf[j--] & 0xFF) << 8) | (buf[j--] & 0xFF)) << paddingLength) >> paddingLength;
                                }
                                break;

                            case CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN:
                                for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 2) - 1; j >= 0; k--)
                                {
                                    barr[k] = (((buf[j--] & 0xFF) | ((buf[j--] & 0xFF) << 8) | ((buf[j--] & 0xFF) << 16) | ((buf[j--] & 0xFF) << 24)) << paddingLength) >> paddingLength;
                                }
                                break;

                            default:
                                throw new System.ApplicationException("Internal JJ2000 bug");
                            }
                        }
                    }
                    else
                    {
                        for (i = blk.uly; i < mi; i++)
                        {
                            // Reposition in input
                            in_Renamed.Seek(offset + 4 * (i * w + blk.ulx), System.IO.SeekOrigin.Begin);
                            in_Renamed.Read(buf, 0, blk.w << 2);
                            switch (byteOrder)
                            {
                            case CSJ2K.j2k.io.EndianType_Fields.LITTLE_ENDIAN:
                                for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 2) - 1; j >= 0; k--)
                                {
                                    barr[k] = (SupportClass.URShift(((((buf[j--] & 0xFF) << 24) | ((buf[j--] & 0xFF) << 16) | ((buf[j--] & 0xFF) << 8) | (buf[j--] & 0xFF)) << paddingLength), paddingLength)) - levShift;
                                }
                                break;

                            case CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN:
                                for (k = (i - blk.uly) * blk.w + blk.w - 1, j = (blk.w << 2) - 1; j >= 0; k--)
                                {
                                    barr[k] = (SupportClass.URShift((((buf[j--] & 0xFF) | ((buf[j--] & 0xFF) << 8) | ((buf[j--] & 0xFF) << 16) | ((buf[j--] & 0xFF) << 24)) << paddingLength), paddingLength)) - levShift;
                                }
                                break;

                            default:
                                throw new System.ApplicationException("Internal JJ2000 bug");
                            }
                        }
                    }
                    break;


                default:
                    throw new System.IO.IOException("PGX supports only bit-depth between" + " 1 and 31");
                }
            }
            catch (System.IO.IOException e)
            {
                JJ2KExceptionHandler.handleException(e);
            }

            // Turn off the progressive attribute
            blk.progressive = false;
            // Set buffer attributes
            blk.offset = 0;
            blk.scanw  = blk.w;
            return(blk);
        }
예제 #20
0
        /// <summary> Return a DataBlk containing the requested component
        /// upsampled by the scale factor applied to the particular
        /// scaling direction
        ///
        /// 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 copy of the internal data, therefore the returned data
        /// can be modified "in place".
        ///
        /// <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' of
        /// the returned data is 0, and the 'scanw' is the same as the block's
        /// width. See the 'DataBlk' class.
        ///
        /// <P>If the data array in 'blk' is 'null', then a new one is created. If
        /// the data array is not 'null' then it is reused, and it must be large
        /// enough to contain the block's data. Otherwise an 'ArrayStoreException'
        /// or an 'IndexOutOfBoundsException' is thrown by the Java system.
        ///
        /// <P>The returned data has its 'progressive' attribute set to that of the
        /// input data.
        ///
        /// </summary>
        /// <param name="blk">Its coordinates and dimensions specify the area to
        /// return. If it contains a non-null data array, then it must have the
        /// correct dimensions. If it contains a null data array a new one is
        /// created. The 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. Only 0
        /// and 3 are valid.
        ///
        /// </param>
        /// <returns> The requested DataBlk
        ///
        /// </returns>
        /// <seealso cref="getCompData">
        /// </seealso>
        public override DataBlk getInternCompData(DataBlk outblk, int c)
        {
            // If the scaling factor of this channel is 1 in both
            // directions, simply return the source DataBlk.

            if (src.getCompSubsX(c) == 1 && src.getCompSubsY(c) == 1)
            {
                return(src.getInternCompData(outblk, c));
            }

            int wfactor = src.getCompSubsX(c);
            int hfactor = src.getCompSubsY(c);

            if ((wfactor != 2 && wfactor != 1) || (hfactor != 2 && hfactor != 1))
            {
                throw new System.ArgumentException("Upsampling by other than 2:1" + " not supported");
            }

            int leftedgeOut  = -1;            // offset to the start of the output scanline
            int rightedgeOut = -1;            // offset to the end of the output
            // scanline + 1
            int leftedgeIn  = -1;             // offset to the start of the input scanline
            int rightedgeIn = -1;             // offset to the end of the input scanline + 1


            int y0In, y1In, y0Out, y1Out;
            int x0In, x1In, x0Out, x1Out;

            y0Out = outblk.uly;
            y1Out = y0Out + outblk.h - 1;

            x0Out = outblk.ulx;
            x1Out = x0Out + outblk.w - 1;

            y0In = y0Out / hfactor;
            y1In = y1Out / hfactor;

            x0In = x0Out / wfactor;
            x1In = x1Out / wfactor;


            // Calculate the requested height and width, requesting an extra
            // row and or for upsampled channels.
            int reqW = x1In - x0In + 1;
            int reqH = y1In - y0In + 1;

            // Initialize general input and output indexes
            int kOut = -1;
            int kIn  = -1;
            int yIn;

            switch (outblk.DataType)
            {
            case DataBlk.TYPE_INT:

                DataBlkInt inblkInt = new DataBlkInt(x0In, y0In, reqW, reqH);
                inblkInt   = (DataBlkInt)src.getInternCompData(inblkInt, c);
                dataInt[c] = inblkInt.DataInt;

                // Reference the working array
                int[] outdataInt = (int[])outblk.Data;

                // Create data array if necessary
                if (outdataInt == null || outdataInt.Length != outblk.w * outblk.h)
                {
                    outdataInt  = new int[outblk.h * outblk.w];
                    outblk.Data = outdataInt;
                }

                // The nitty-gritty.

                for (int yOut = y0Out; yOut <= y1Out; ++yOut)
                {
                    yIn = yOut / hfactor;


                    leftedgeIn   = inblkInt.offset + (yIn - y0In) * inblkInt.scanw;
                    rightedgeIn  = leftedgeIn + inblkInt.w;
                    leftedgeOut  = outblk.offset + (yOut - y0Out) * outblk.scanw;
                    rightedgeOut = leftedgeOut + outblk.w;

                    kIn  = leftedgeIn;
                    kOut = leftedgeOut;

                    if ((x0Out & 0x1) == 1)
                    {
                        // first is odd do the pixel once.
                        outdataInt[kOut++] = dataInt[c][kIn++];
                    }

                    if ((x1Out & 0x1) == 0)
                    {
                        // last is even adjust loop bounds
                        rightedgeOut--;
                    }

                    while (kOut < rightedgeOut)
                    {
                        outdataInt[kOut++] = dataInt[c][kIn];
                        outdataInt[kOut++] = dataInt[c][kIn++];
                    }

                    if ((x1Out & 0x1) == 0)
                    {
                        // last is even do the pixel once.
                        outdataInt[kOut++] = dataInt[c][kIn];
                    }
                }

                outblk.progressive = inblkInt.progressive;
                break;


            case DataBlk.TYPE_FLOAT:

                DataBlkFloat inblkFloat = new DataBlkFloat(x0In, y0In, reqW, reqH);
                inblkFloat   = (DataBlkFloat)src.getInternCompData(inblkFloat, c);
                dataFloat[c] = inblkFloat.DataFloat;

                // Reference the working array
                float[] outdataFloat = (float[])outblk.Data;

                // Create data array if necessary
                if (outdataFloat == null || outdataFloat.Length != outblk.w * outblk.h)
                {
                    outdataFloat = new float[outblk.h * outblk.w];
                    outblk.Data  = outdataFloat;
                }

                // The nitty-gritty.

                for (int yOut = y0Out; yOut <= y1Out; ++yOut)
                {
                    yIn = yOut / hfactor;


                    leftedgeIn   = inblkFloat.offset + (yIn - y0In) * inblkFloat.scanw;
                    rightedgeIn  = leftedgeIn + inblkFloat.w;
                    leftedgeOut  = outblk.offset + (yOut - y0Out) * outblk.scanw;
                    rightedgeOut = leftedgeOut + outblk.w;

                    kIn  = leftedgeIn;
                    kOut = leftedgeOut;

                    if ((x0Out & 0x1) == 1)
                    {
                        // first is odd do the pixel once.
                        outdataFloat[kOut++] = dataFloat[c][kIn++];
                    }

                    if ((x1Out & 0x1) == 0)
                    {
                        // last is even adjust loop bounds
                        rightedgeOut--;
                    }

                    while (kOut < rightedgeOut)
                    {
                        outdataFloat[kOut++] = dataFloat[c][kIn];
                        outdataFloat[kOut++] = dataFloat[c][kIn++];
                    }

                    if ((x1Out & 0x1) == 0)
                    {
                        // last is even do the pixel once.
                        outdataFloat[kOut++] = dataFloat[c][kIn];
                    }
                }

                outblk.progressive = inblkFloat.progressive;
                break;


            case DataBlk.TYPE_SHORT:
            case DataBlk.TYPE_BYTE:
            default:
                // Unsupported output type.
                throw new System.ArgumentException("invalid source datablock " + "type");
            }

            return(outblk);
        }
예제 #21
0
        /// <summary> Returns the specified code-block in the current tile for the specified
        /// component (as a reference or copy).
        ///
        /// <p>The returned code-block may be progressive, which is indicated by
        /// the 'progressive' variable of the returned 'DataBlk'
        /// object. If a code-block is progressive it means that in a later request
        /// to this method for the same code-block it is possible to retrieve data
        /// which is a better approximation, since meanwhile more data to decode
        /// for the code-block could have been received. If the code-block is not
        /// progressive then later calls to this method for the same code-block
        /// will return the exact same data values.</p>
        ///
        /// <p>The data returned by this method can be the data in the internal
        /// buffer of this object, if any, and thus can not be modified by the
        /// caller. The 'offset' and 'scanw' of the returned data can be
        /// arbitrary. See the 'DataBlk' class.</p>
        ///
        /// </summary>
        /// <param name="c">The component for which to return the next code-block.
        ///
        /// </param>
        /// <param name="m">The vertical index of the code-block to return, in the
        /// specified subband.
        ///
        /// </param>
        /// <param name="n">The horizontal index of the code-block to return, in the
        /// specified subband.
        ///
        /// </param>
        /// <param name="sb">The subband in which the code-block to return is.
        ///
        /// </param>
        /// <param name="cblk">If non-null this object will be used to return the new
        /// code-block. If null a new one will be allocated and returned. If the
        /// "data" array of the object is non-null it will be reused, if possible,
        /// to return the data.
        ///
        /// </param>
        /// <returns> The next code-block in the current tile for component 'n', or
        /// null if all code-blocks for the current tile have been returned.
        ///
        /// </returns>
        /// <seealso cref="DataBlk">
        ///
        /// </seealso>
        public override DataBlk getInternCodeBlock(int c, int m, int n, SubbandSyn sb, DataBlk cblk)
        {
            // This method is declared final since getNextCodeBlock() relies on
            // the actual implementation of this method.
            int   j, jmin, k;
            int   temp;
            float step;
            int   shiftBits;
            int   magBits;

            int[]   outiarr, inarr;
            float[] outfarr;
            int     w, h;
            bool    reversible = qts.isReversible(tIdx, c);
            bool    derived    = qts.isDerived(tIdx, c);
            StdDequantizerParams params_Renamed = (StdDequantizerParams)qsss.getTileCompVal(tIdx, c);
            int G = ((System.Int32)gbs.getTileCompVal(tIdx, c));

            outdtype = cblk.DataType;

            if (reversible && outdtype != DataBlk.TYPE_INT)
            {
                throw new System.ArgumentException("Reversible quantizations " + "must use int data");
            }

            // To get compiler happy
            outiarr = null;
            outfarr = null;
            inarr   = null;

            // Get source data and initialize output DataBlk object.
            switch (outdtype)
            {
            case DataBlk.TYPE_INT:
                // With int data we can use the same DataBlk object to get the
                // data from the source and return the dequantized data, and we
                // can also work "in place" (i.e. same buffer).
                cblk = src.getCodeBlock(c, m, n, sb, cblk);
                // Input and output arrays are the same
                outiarr = (int[])cblk.Data;
                break;

            case DataBlk.TYPE_FLOAT:
                // With float data we must use a different DataBlk objects to get
                // the data from the source and to return the dequantized data.
                inblk = (DataBlkInt)src.getInternCodeBlock(c, m, n, sb, inblk);
                inarr = inblk.DataInt;
                if (cblk == null)
                {
                    cblk = new DataBlkFloat();
                }
                // Copy the attributes of the CodeBlock object
                cblk.ulx         = inblk.ulx;
                cblk.uly         = inblk.uly;
                cblk.w           = inblk.w;
                cblk.h           = inblk.h;
                cblk.offset      = 0;
                cblk.scanw       = cblk.w;
                cblk.progressive = inblk.progressive;
                // Get output data array and check its size
                outfarr = (float[])cblk.Data;
                if (outfarr == null || outfarr.Length < cblk.w * cblk.h)
                {
                    outfarr   = new float[cblk.w * cblk.h];
                    cblk.Data = outfarr;
                }
                break;
            }

            magBits = sb.magbits;

            // Calculate quantization step and number of magnitude bits
            // depending on reversibility and derivedness and perform
            // inverse quantization
            if (reversible)
            {
                shiftBits = 31 - magBits;
                // For int data Inverse quantization happens "in-place". The input
                // array has an offset of 0 and scan width equal to the code-block
                // width.
                for (j = outiarr.Length - 1; j >= 0; j--)
                {
                    temp       = outiarr[j]; // input array is same as output one
                    outiarr[j] = (temp >= 0) ? (temp >> shiftBits) : -((temp & 0x7FFFFFFF) >> shiftBits);
                }
            }
            else
            {
                // Not reversible
                if (derived)
                {
                    // Max resolution level
                    int mrl = src.getSynSubbandTree(TileIdx, c).resLvl;
                    step = params_Renamed.nStep[0][0] * (1L << (rb[c] + sb.anGainExp + mrl - sb.level));
                }
                else
                {
                    step = params_Renamed.nStep[sb.resLvl][sb.sbandIdx] * (1L << (rb[c] + sb.anGainExp));
                }
                shiftBits = 31 - magBits;

                // Adjust step to the number of shiftBits
                step /= (1 << shiftBits);

                switch (outdtype)
                {
                case DataBlk.TYPE_INT:
                    // For int data Inverse quantization happens "in-place". The
                    // input array has an offset of 0 and scan width equal to the
                    // code-block width.
                    for (j = outiarr.Length - 1; j >= 0; j--)
                    {
                        temp = outiarr[j];     // input array is same as output one
                                               //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'"
                        outiarr[j] = (int)(((float)((temp >= 0) ? temp : -(temp & 0x7FFFFFFF))) * step);
                    }
                    break;

                case DataBlk.TYPE_FLOAT:
                    // For float data the inverse quantization can not happen
                    // "in-place".
                    w = cblk.w;
                    h = cblk.h;
                    for (j = w * h - 1, k = inblk.offset + (h - 1) * inblk.scanw + w - 1, jmin = w * (h - 1); j >= 0; jmin -= w)
                    {
                        for (; j >= jmin; k--, j--)
                        {
                            temp = inarr[k];
                            //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'"
                            outfarr[j] = ((float)((temp >= 0) ? temp : -(temp & 0x7FFFFFFF))) * step;
                        }
                        // Jump to beggining of previous line in input
                        k -= (inblk.scanw - w);
                    }
                    break;
                }
            }
            // Return the output code-block
            return(cblk);
        }
예제 #22
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>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>If possible, the data in the returned 'DataBlk' should be the
 /// internal data itself, instead of a copy, in order to increase the data
 /// transfer efficiency. However, this depends on the particular
 /// implementation (it may be more convenient to just return a copy of the
 /// data). This is the reason why the returned data should not be modified.
 ///
 /// <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>The returned data may have its 'progressive' attribute set. In this
 /// case the returned data is only an approximation of the "final" data.
 ///
 /// </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 override DataBlk getInternCompData(DataBlk out_Renamed, int c)
 {
     return(getCompData(out_Renamed, c));
 }
예제 #23
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>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>If possible, the data in the returned 'DataBlk' should be the
 /// internal data itself, instead of a copy, in order to increase the data
 /// transfer efficiency. However, this depends on the particular
 /// implementation (it may be more convenient to just return a copy of the
 /// data). This is the reason why the returned data should not be modified.
 ///
 /// <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>The returned data may have its 'progressive' attribute set. In this
 /// case the returned data is only an approximation of the "final" data.
 ///
 /// </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 virtual DataBlk getInternCompData(DataBlk out_Renamed, int c)
 {
     return(src.getInternCompData(out_Renamed, c));
 }
예제 #24
0
        /// <summary> Returns, in the blk argument, the 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> After being read the coefficients are level shifted by subtracting
        /// 2^(nominal bit range - 1)
        ///
        /// <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>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>The returned data always has its 'progressive' attribute unset
        /// (i.e. false).
        ///
        /// <P>When an I/O exception is encountered the JJ2KExceptionHandler is
        /// used. The exception is passed to its handleException method. The action
        /// that is taken depends on the action that has been registered in
        /// JJ2KExceptionHandler. See JJ2KExceptionHandler for details.
        ///
        /// <P>This method implements buffering for the 3 components: When the
        /// first one is asked, all the 3 components are read and stored until they
        /// are needed.
        ///
        /// </summary>
        /// <param name="blk">Its coordinates and dimensions specify the area to
        /// return. 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. Only 0,
        /// 1 and 3 are valid.
        ///
        /// </param>
        /// <returns> The requested DataBlk
        ///
        /// </returns>
        /// <seealso cref="getCompData">
        ///
        /// </seealso>
        /// <seealso cref="JJ2KExceptionHandler">
        ///
        /// </seealso>
        public override DataBlk getInternCompData(DataBlk blk, int c)
        {
            // Check component index
            if (c < 0 || c > 2)
            {
                throw new System.ArgumentException();
            }

            // Check type of block provided as an argument
            if (blk.DataType != DataBlk.TYPE_INT)
            {
                if (intBlk == null)
                {
                    intBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h);
                }
                else
                {
                    intBlk.ulx = blk.ulx;
                    intBlk.uly = blk.uly;
                    intBlk.w   = blk.w;
                    intBlk.h   = blk.h;
                }
                blk = intBlk;
            }

            // If asking a component for the first time for this block, read all of the components
            if ((barr == null) || (dbi.ulx > blk.ulx) || (dbi.uly > blk.uly) || (dbi.ulx + dbi.w < blk.ulx + blk.w) || (dbi.uly + dbi.h < blk.uly + blk.h))
            {
                int   i;
                int[] red, green, blue, alpha;
                int   componentCount = (image.PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3;

                barr = new int[componentCount][];

                // Reset data arrays if needed
                if (barr[c] == null || barr[c].Length < blk.w * blk.h)
                {
                    barr[c] = new int[blk.w * blk.h];
                }
                blk.Data = barr[c];

                i = (c + 1) % 3;
                if (barr[i] == null || barr[i].Length < blk.w * blk.h)
                {
                    barr[i] = new int[blk.w * blk.h];
                }
                i = (c + 2) % 3;
                if (barr[i] == null || barr[i].Length < blk.w * blk.h)
                {
                    barr[i] = new int[blk.w * blk.h];
                }

                if (componentCount == 4)
                {
                    if (barr[3] == null || barr[3].Length < blk.w * blk.h)
                    {
                        barr[3] = new int[blk.w * blk.h];
                    }
                }

                // set attributes of the DataBlk used for buffering
                dbi.ulx = blk.ulx;
                dbi.uly = blk.uly;
                dbi.w   = blk.w;
                dbi.h   = blk.h;

                red   = barr[0];
                green = barr[1];
                blue  = barr[2];
                alpha = (componentCount == 4) ? barr[3] : null;

                Bitmap     bitmap = (Bitmap)image;
                BitmapData data   = bitmap.LockBits(new Rectangle(blk.ulx, blk.uly, blk.w, blk.h), ImageLockMode.ReadOnly,
                                                    (componentCount == 3) ? PixelFormat.Format24bppRgb : PixelFormat.Format32bppArgb);
                unsafe
                {
                    byte *ptr = (byte *)data.Scan0.ToPointer();

                    int k = 0;
                    for (int j = 0; j < blk.w * blk.h; j++)
                    {
                        blue[k]  = ((byte)*(ptr + 0) & 0xFF) - 128;
                        green[k] = ((byte)*(ptr + 1) & 0xFF) - 128;
                        red[k]   = ((byte)*(ptr + 2) & 0xFF) - 128;
                        if (componentCount == 4)
                        {
                            alpha[k] = ((byte)*(ptr + 3) & 0xFF) - 128;
                        }

                        ++k;
                        ptr += 3;
                    }
                }
                bitmap.UnlockBits(data);

                barr[0] = red;
                barr[1] = green;
                barr[2] = blue;
                if (componentCount == 4)
                {
                    barr[3] = alpha;
                }

                // Set buffer attributes
                blk.Data   = barr[c];
                blk.offset = 0;
                blk.scanw  = blk.w;
            }
            else
            {
                //Asking for the 2nd or 3rd (or 4th) block component
                blk.Data   = barr[c];
                blk.offset = (blk.ulx - dbi.ulx) * dbi.w + blk.ulx - dbi.ulx;
                blk.scanw  = dbi.scanw;
            }

            // Turn off the progressive attribute
            blk.progressive = false;
            return(blk);
        }
예제 #25
0
        /// <summary> Apply forward component transformation to obtain requested component
        /// from specified block of data. Whatever the type of requested DataBlk,
        /// it always returns a DataBlkInt.
        ///
        /// </summary>
        /// <param name="blk">Determine the rectangular area to return
        ///
        /// </param>
        /// <param name="c">The index of the requested component
        ///
        /// </param>
        /// <returns> Data of requested component
        ///
        /// </returns>
        private DataBlk forwRCT(DataBlk blk, int c)
        {
            int k, k0, k1, k2, mink, i;
            int w = blk.w;             //width of output block
            int h = blk.h;             //height of ouput block

            int[] outdata;             //array of output data

            //If asking for Yr, Ur or Vr do transform
            if (c >= 0 && c <= 2)
            {
                // Check that request data type is int
                if (blk.DataType != DataBlk.TYPE_INT)
                {
                    if (outBlk == null || outBlk.DataType != DataBlk.TYPE_INT)
                    {
                        outBlk = new DataBlkInt();
                    }
                    outBlk.w   = w;
                    outBlk.h   = h;
                    outBlk.ulx = blk.ulx;
                    outBlk.uly = blk.uly;
                    blk        = outBlk;
                }

                //Reference to output block data array
                outdata = (int[])blk.Data;

                //Create data array of blk if necessary
                if (outdata == null || outdata.Length < h * w)
                {
                    outdata  = new int[h * w];
                    blk.Data = outdata;
                }

                // Block buffers for input RGB data
                int[] data0, data1, bdata;                 // input data arrays

                if (block0 == null)
                {
                    block0 = new DataBlkInt();
                }
                if (block1 == null)
                {
                    block1 = new DataBlkInt();
                }
                if (block2 == null)
                {
                    block2 = new DataBlkInt();
                }
                block0.w   = block1.w = block2.w = blk.w;
                block0.h   = block1.h = block2.h = blk.h;
                block0.ulx = block1.ulx = block2.ulx = blk.ulx;
                block0.uly = block1.uly = block2.uly = blk.uly;

                //Fill in buffer blocks (to be read only)
                // Returned blocks may have different size and position
                block0 = (DataBlkInt)src.getInternCompData(block0, 0);
                data0  = (int[])block0.Data;
                block1 = (DataBlkInt)src.getInternCompData(block1, 1);
                data1  = (int[])block1.Data;
                block2 = (DataBlkInt)src.getInternCompData(block2, 2);
                bdata  = (int[])block2.Data;

                // Set the progressiveness of the output data
                blk.progressive = block0.progressive || block1.progressive || block2.progressive;
                blk.offset      = 0;
                blk.scanw       = w;

                //Perform conversion

                // Initialize general indexes
                k  = w * h - 1;
                k0 = block0.offset + (h - 1) * block0.scanw + w - 1;
                k1 = block1.offset + (h - 1) * block1.scanw + w - 1;
                k2 = block2.offset + (h - 1) * block2.scanw + w - 1;

                switch (c)
                {
                case 0:                          //RGB to Yr conversion
                    for (i = h - 1; i >= 0; i--)
                    {
                        for (mink = k - w; k > mink; k--, k0--, k1--, k2--)
                        {
                            // Use int arithmetic with 12 fractional bits
                            // and rounding
                            outdata[k] = (data0[k] + 2 * data1[k] + bdata[k]) >> 2;                                     // Same as / 4
                        }
                        // Jump to beggining of previous line in input
                        k0 -= (block0.scanw - w);
                        k1 -= (block1.scanw - w);
                        k2 -= (block2.scanw - w);
                    }
                    break;


                case 1:                          //RGB to Ur conversion
                    for (i = h - 1; i >= 0; i--)
                    {
                        for (mink = k - w; k > mink; k--, k1--, k2--)
                        {
                            // Use int arithmetic with 12 fractional bits
                            // and rounding
                            outdata[k] = bdata[k2] - data1[k1];
                        }
                        // Jump to beggining of previous line in input
                        k1 -= (block1.scanw - w);
                        k2 -= (block2.scanw - w);
                    }
                    break;


                case 2:                          //RGB to Vr conversion
                    for (i = h - 1; i >= 0; i--)
                    {
                        for (mink = k - w; k > mink; k--, k0--, k1--)
                        {
                            // Use int arithmetic with 12 fractional bits
                            // and rounding
                            outdata[k] = data0[k0] - data1[k1];
                        }
                        // Jump to beggining of previous line in input
                        k0 -= (block0.scanw - w);
                        k1 -= (block1.scanw - w);
                    }
                    break;
                }
            }
            else if (c >= 3)
            {
                // Requesting a component which is not Y, Ur or Vr =>
                // just pass the data
                return(src.getInternCompData(blk, c));
            }
            else
            {
                // Requesting a non valid component index
                throw new System.ArgumentException();
            }
            return(blk);
        }
 /// <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 copy of the internal data, therefore the returned data
 /// can be modified "in place".
 ///
 /// <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' of
 /// the returned data is 0, and the 'scanw' is the same as the block's
 /// width. See the 'DataBlk' class.
 ///
 /// <P>If the data array in 'blk' is 'null', then a new one is created. If
 /// the data array is not 'null' then it is reused, and it must be large
 /// enough to contain the block's data. Otherwise an 'ArrayStoreException'
 /// or an 'IndexOutOfBoundsException' is thrown by the Java system.
 ///
 /// <P>The returned data has its 'progressive' attribute set to that of the
 /// input data.
 ///
 /// </summary>
 /// <param name="blk">Its coordinates and dimensions specify the area to
 /// return. If it contains a non-null data array, then it must have the
 /// correct dimensions. If it contains a null data array a new one is
 /// created. The 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. Only 0
 /// and 3 are valid.
 ///
 /// </param>
 /// <returns> The requested DataBlk
 ///
 /// </returns>
 /// <seealso cref="getInternCompData">
 ///
 /// </seealso>
 public override DataBlk getCompData(DataBlk out_Renamed, int c)
 {
     return(src.getCompData(out_Renamed, csMap.getChannelDefinition(c)));
 }
 /// <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 copy of the internal data, therefore the returned data
 /// can be modified "in place".
 ///
 /// <p>After being read the coefficients are level shifted by subtracting
 /// 2^(nominal bit range - 1)
 ///
 /// <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' of
 /// the returned data is 0, and the 'scanw' is the same as the block's
 /// width. See the 'DataBlk' class.</p>
 ///
 /// <p>If the data array in 'blk' is 'null', then a new one is created. If
 /// the data array is not 'null' then it is reused, and it must be large
 /// enough to contain the block's data. Otherwise an 'ArrayStoreException'
 /// or an 'IndexOutOfBoundsException' is thrown by the Java system.</p>
 ///
 /// <p>The returned data has its 'progressive' attribute unset
 /// (i.e. false).</p>
 ///
 /// <p>This method just calls 'getInternCompData(blk,c)'.</p>
 ///
 /// <P>When an I/O exception is encountered the JJ2KExceptionHandler is
 /// used. The exception is passed to its handleException method. The action
 /// that is taken depends on the action that has been registered in
 /// JJ2KExceptionHandler. See JJ2KExceptionHandler for details.
 ///
 /// </summary>
 /// <param name="blk">Its coordinates and dimensions specify the area to
 /// return. If it contains a non-null data array, then it must have the
 /// correct dimensions. If it contains a null data array a new one is
 /// created. The 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. Only 0
 /// is valid.
 ///
 /// </param>
 /// <returns> The requested DataBlk
 ///
 /// </returns>
 /// <seealso cref="getInternCompData">
 /// </seealso>
 /// <seealso cref="JJ2KExceptionHandler">
 ///
 /// </seealso>
 public override DataBlk getCompData(DataBlk blk, int c)
 {
     return(getInternCompData(blk, c));
 }
예제 #28
0
        /// <summary> Apply forward irreversible component transformation to obtain requested
        /// component from specified block of data. Whatever the type of requested
        /// DataBlk, it always returns a DataBlkFloat.
        ///
        /// </summary>
        /// <param name="blk">Determine the rectangular area to return
        ///
        /// </param>
        /// <param name="c">The index of the requested component
        ///
        /// </param>
        /// <returns> Data of requested component
        ///
        /// </returns>
        private DataBlk forwICT(DataBlk blk, int c)
        {
            int k, k0, k1, k2, mink, i;
            int w = blk.w;             //width of output block
            int h = blk.h;             //height of ouput block

            float[] outdata;           //array of output data

            if (blk.DataType != DataBlk.TYPE_FLOAT)
            {
                if (outBlk == null || outBlk.DataType != DataBlk.TYPE_FLOAT)
                {
                    outBlk = new DataBlkFloat();
                }
                outBlk.w   = w;
                outBlk.h   = h;
                outBlk.ulx = blk.ulx;
                outBlk.uly = blk.uly;
                blk        = outBlk;
            }

            //Reference to output block data array
            outdata = (float[])blk.Data;

            //Create data array of blk if necessary
            if (outdata == null || outdata.Length < w * h)
            {
                outdata  = new float[h * w];
                blk.Data = outdata;
            }

            //If asking for Y, Cb or Cr do transform
            if (c >= 0 && c <= 2)
            {
                int[] data0, data1, data2;                 // input data arrays

                if (block0 == null)
                {
                    block0 = new DataBlkInt();
                }
                if (block1 == null)
                {
                    block1 = new DataBlkInt();
                }
                if (block2 == null)
                {
                    block2 = new DataBlkInt();
                }
                block0.w   = block1.w = block2.w = blk.w;
                block0.h   = block1.h = block2.h = blk.h;
                block0.ulx = block1.ulx = block2.ulx = blk.ulx;
                block0.uly = block1.uly = block2.uly = blk.uly;

                // Returned blocks may have different size and position
                block0 = (DataBlkInt)src.getInternCompData(block0, 0);
                data0  = (int[])block0.Data;
                block1 = (DataBlkInt)src.getInternCompData(block1, 1);
                data1  = (int[])block1.Data;
                block2 = (DataBlkInt)src.getInternCompData(block2, 2);
                data2  = (int[])block2.Data;

                // Set the progressiveness of the output data
                blk.progressive = block0.progressive || block1.progressive || block2.progressive;
                blk.offset      = 0;
                blk.scanw       = w;

                //Perform conversion

                // Initialize general indexes
                k  = w * h - 1;
                k0 = block0.offset + (h - 1) * block0.scanw + w - 1;
                k1 = block1.offset + (h - 1) * block1.scanw + w - 1;
                k2 = block2.offset + (h - 1) * block2.scanw + w - 1;

                switch (c)
                {
                case 0:
                    //RGB to Y conversion
                    for (i = h - 1; i >= 0; i--)
                    {
                        for (mink = k - w; k > mink; k--, k0--, k1--, k2--)
                        {
                            outdata[k] = 0.299f * data0[k0] + 0.587f * data1[k1] + 0.114f * data2[k2];
                        }
                        // Jump to beggining of previous line in input
                        k0 -= (block0.scanw - w);
                        k1 -= (block1.scanw - w);
                        k2 -= (block2.scanw - w);
                    }
                    break;


                case 1:
                    //RGB to Cb conversion
                    for (i = h - 1; i >= 0; i--)
                    {
                        for (mink = k - w; k > mink; k--, k0--, k1--, k2--)
                        {
                            outdata[k] = (-0.16875f) * data0[k0] - 0.33126f * data1[k1] + 0.5f * data2[k2];
                        }
                        // Jump to beggining of previous line in input
                        k0 -= (block0.scanw - w);
                        k1 -= (block1.scanw - w);
                        k2 -= (block2.scanw - w);
                    }
                    break;


                case 2:
                    //RGB to Cr conversion
                    for (i = h - 1; i >= 0; i--)
                    {
                        for (mink = k - w; k > mink; k--, k0--, k1--, k2--)
                        {
                            outdata[k] = 0.5f * data0[k0] - 0.41869f * data1[k1] - 0.08131f * data2[k2];
                        }
                        // Jump to beggining of previous line in input
                        k0 -= (block0.scanw - w);
                        k1 -= (block1.scanw - w);
                        k2 -= (block2.scanw - w);
                    }
                    break;
                }
            }
            else if (c >= 3)
            {
                // Requesting a component which is not Y, Cb or Cr =>
                // just pass the data

                // Variables
                DataBlkInt indb = new DataBlkInt(blk.ulx, blk.uly, w, h);
                int[]      indata;            // input data array

                // Get the input data
                // (returned block may be larger than requested one)
                src.getInternCompData(indb, c);
                indata = (int[])indb.Data;

                // Copy the data converting from int to float
                k  = w * h - 1;
                k0 = indb.offset + (h - 1) * indb.scanw + w - 1;
                for (i = h - 1; i >= 0; i--)
                {
                    for (mink = k - w; k > mink; k--, k0--)
                    {
                        //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'"
                        outdata[k] = (float)indata[k0];
                    }
                    // Jump to beggining of next line in input
                    k0 += indb.w - w;
                }

                // Set the progressivity
                blk.progressive = indb.progressive;
                blk.offset      = 0;
                blk.scanw       = w;
                return(blk);
            }
            else
            {
                // Requesting a non valid component index
                throw new System.ArgumentException();
            }
            return(blk);
        }
예제 #29
0
 public abstract DataBlk getCompData(DataBlk blk, int c);
예제 #30
0
        /// <summary> Returns, in the blk argument, the 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> After being read the coefficients are level shifted by subtracting
        /// 2^(nominal bit range - 1)
        ///
        /// <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>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>The returned data always has its 'progressive' attribute unset
        /// (i.e. false).
        ///
        /// <P>When an I/O exception is encountered the JJ2KExceptionHandler is
        /// used. The exception is passed to its handleException method. The action
        /// that is taken depends on the action that has been registered in
        /// JJ2KExceptionHandler. See JJ2KExceptionHandler for details.
        ///
        /// </summary>
        /// <param name="blk">Its coordinates and dimensions specify the area to
        /// return. 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. Only 0
        /// is valid.
        ///
        /// </param>
        /// <returns> The requested DataBlk
        ///
        /// </returns>
        /// <seealso cref="getCompData">
        ///
        /// </seealso>
        /// <seealso cref="JJ2KExceptionHandler">
        ///
        /// </seealso>
        public override DataBlk getInternCompData(DataBlk blk, int c)
        {
            int k, j, i, mi;

            int[] barr;

            // Check component index
            if (c != 0)
            {
                throw new System.ArgumentException();
            }

            // Check type of block provided as an argument
            if (blk.DataType != DataBlk.TYPE_INT)
            {
                if (intBlk == null)
                {
                    intBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h);
                }
                else
                {
                    intBlk.ulx = blk.ulx;
                    intBlk.uly = blk.uly;
                    intBlk.w   = blk.w;
                    intBlk.h   = blk.h;
                }
                blk = intBlk;
            }

            // Get data array
            barr = (int[])blk.Data;
            if (barr == null || barr.Length < blk.w * blk.h)
            {
                barr     = new int[blk.w * blk.h];
                blk.Data = barr;
            }

            // Check line buffer
            if (buf == null || buf.Length < blk.w)
            {
                buf = new byte[blk.w];
            }

            try
            {
                // Read line by line
                mi = blk.uly + blk.h;
                for (i = blk.uly; i < mi; i++)
                {
                    // Reposition in input
                    in_Renamed.Seek(offset + i * w + blk.ulx, System.IO.SeekOrigin.Begin);
                    in_Renamed.Read(buf, 0, blk.w);
                    for (k = (i - blk.uly) * blk.w + blk.w - 1, j = blk.w - 1; j >= 0; j--, k--)
                    {
                        barr[k] = (((int)buf[j]) & 0xFF) - DC_OFFSET;
                    }
                }
            }
            catch (System.IO.IOException e)
            {
                JJ2KExceptionHandler.handleException(e);
            }

            // Turn off the progressive attribute
            blk.progressive = false;
            // Set buffer attributes
            blk.offset = 0;
            blk.scanw  = blk.w;
            return(blk);
        }