Пример #1
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);
        }
        /// <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);
        }
Пример #3
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);
        }