corrade-vassal – Rev 1
?pathlinks?
/*
* CVS Identifier:
*
* $Id: ImgDataConverter.java,v 1.13 2001/02/27 19:16:03 grosbois Exp $
*
* Interface: ImgDataConverter
*
* Description: The abstract class for classes that provide
* Image Data Convertres (int -> float, float->int).
*
*
*
* COPYRIGHT:
*
* This software module was originally developed by Raphaël Grosbois and
* Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
* Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
* Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
* Centre France S.A) in the course of development of the JPEG2000
* standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
* software module is an implementation of a part of the JPEG 2000
* Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
* Systems AB and Canon Research Centre France S.A (collectively JJ2000
* Partners) agree not to assert against ISO/IEC and users of the JPEG
* 2000 Standard (Users) any of their rights under the copyright, not
* including other intellectual property rights, for this software module
* with respect to the usage by ISO/IEC and Users of this software module
* or modifications thereof for use in hardware or software products
* claiming conformance to the JPEG 2000 Standard. Those intending to use
* this software module in hardware or software products are advised that
* their use may infringe existing patents. The original developers of
* this software module, JJ2000 Partners and ISO/IEC assume no liability
* for use of this software module or modifications thereof. No license
* or right to this software module is granted for non JPEG 2000 Standard
* conforming products. JJ2000 Partners have full right to use this
* software module for his/her own purpose, assign or donate this
* software module to any third party and to inhibit third parties from
* using this software module for non JPEG 2000 Standard conforming
* products. This copyright notice must be included in all copies or
* derivative works of this software module.
*
* Copyright (c) 1999/2000 JJ2000 Partners.
* */
using System;
using CSJ2K.j2k.image;
using CSJ2K.j2k;
namespace CSJ2K.j2k.image
{
/// <summary> This class is responsible of all data type conversions. It should be used,
/// at encoder side, between Tiler and ForwardWT modules and, at decoder side,
/// between InverseWT/CompDemixer and ImgWriter modules. The conversion is
/// realized when a block of data is requested: if source and destination data
/// type are the same one, it does nothing, else appropriate cast is done. All
/// the methods of the 'ImgData' interface are implemented by the
/// 'ImgDataAdapter' class that is the superclass of this one, so they don't
/// need to be reimplemented by subclasses.
///
/// </summary>
public class ImgDataConverter:ImgDataAdapter, BlkImgDataSrc
{
/// <summary>The block used to request data from the source in the case that a
/// conversion seems necessary. It can be either int or float at
/// initialization time. It will be checked (and corrected if necessary) by
/// the source whenever necessary
/// </summary>
private DataBlk srcBlk = new DataBlkInt();
/// <summary>The source of image data </summary>
private BlkImgDataSrc src;
/// <summary>The number of fraction bits in the casted ints </summary>
private int fp;
/// <summary> Constructs a new ImgDataConverter object that operates on the specified
/// source of image data.
///
/// </summary>
/// <param name="imgSrc">The source from where to get the data to be transformed
///
/// </param>
/// <param name="fp">The number of fraction bits in the casted ints
///
/// </param>
/// <seealso cref="BlkImgDataSrc">
///
/// </seealso>
public ImgDataConverter(BlkImgDataSrc imgSrc, int fp):base(imgSrc)
{
src = imgSrc;
this.fp = fp;
}
/// <summary> Constructs a new ImgDataConverter object that operates on the specified
/// source of image data.
///
/// </summary>
/// <param name="imgSrc">The source from where to get the data to be transformed
///
/// </param>
/// <seealso cref="BlkImgDataSrc">
///
/// </seealso>
public ImgDataConverter(BlkImgDataSrc imgSrc):base(imgSrc)
{
src = imgSrc;
fp = 0;
}
/// <summary> Returns the position of the fixed point in the specified
/// component. This is the position of the least significant integral
/// (i.e. non-fractional) bit, which is equivalent to the number of
/// fractional bits. For instance, for fixed-point values with 2 fractional
/// bits, 2 is returned. For floating-point data this value does not apply
/// and 0 should be returned. Position 0 is the position of the least
/// significant bit in the data.
///
/// </summary>
/// <param name="c">The index of the component.
///
/// </param>
/// <returns> The position of the fixed-point, which is the same as the
/// number of fractional bits.
///
/// </returns>
public virtual int getFixedPoint(int c)
{
return fp;
}
/// <summary> Returns, in the blk argument, a block of image data containing the
/// specifed rectangular area, in the specified component, using the
/// 'transfer type' specified in the block given as argument. 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>This method, in general, is less efficient than the
/// 'getInternCompData()' method since, in general, it copies the
/// data. However if the array of returned data is to be modified by the
/// caller then this method is preferable.
///
/// <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 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. 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. 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>
/// <seealso cref="getInternCompData">
///
/// </seealso>
public virtual DataBlk getCompData(DataBlk blk, int c)
{
return getData(blk, c, false);
}
/// <summary> Returns, in the blk argument, a block of image data containing the
/// specifed rectangular area, in the specified component, using the
/// 'transfer type' defined in the block given as argument. 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> If source data and expected data (blk) are using the same type,
/// block returned without any modification. If not appropriate cast is
/// used.
///
/// <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 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 DataBlk getInternCompData(DataBlk blk, int c)
{
return getData(blk, c, true);
}
/// <summary> Implements the 'getInternCompData()' and the 'getCompData()'
/// methods. The 'intern' flag signals which of the two methods should run
/// as.
///
/// </summary>
/// <param name="blk">The data block to get.
///
/// </param>
/// <param name="c">The index of the component from which to get the data.
///
/// </param>
/// <param name="intern">If true behave as 'getInternCompData(). Otherwise behave
/// as 'getCompData()'
///
/// </param>
/// <returns> The requested data block
///
/// </returns>
/// <seealso cref="getInternCompData">
///
/// </seealso>
/// <seealso cref="getCompData">
///
/// </seealso>
private DataBlk getData(DataBlk blk, int c, bool intern)
{
DataBlk reqBlk; // Reference to block used in request to source
// Keep request data type
int otype = blk.DataType;
if (otype == srcBlk.DataType)
{
// Probably requested type is same as source type
reqBlk = blk;
}
else
{
// Probably requested type is not the same as source type
reqBlk = srcBlk;
// We need to copy requested coordinates and size
reqBlk.ulx = blk.ulx;
reqBlk.uly = blk.uly;
reqBlk.w = blk.w;
reqBlk.h = blk.h;
}
// Get source data block
if (intern)
{
// We can use the intern variant
srcBlk = src.getInternCompData(reqBlk, c);
}
else
{
// Do not use the intern variant. Note that this is not optimal
// since if we are going to convert below then we could have used
// the intern variant. But there is currently no way to know if we
// will need to do conversion or not before getting the data.
srcBlk = src.getCompData(reqBlk, c);
}
// Check if casting is needed
if (srcBlk.DataType == otype)
{
return srcBlk;
}
int i;
int k, kSrc, kmin;
float mult;
int w = srcBlk.w;
int h = srcBlk.h;
switch (otype)
{
case DataBlk.TYPE_FLOAT: // Cast INT -> FLOAT
float[] farr;
int[] srcIArr;
// Get data array from resulting blk
farr = (float[]) blk.Data;
if (farr == null || farr.Length < w * h)
{
farr = new float[w * h];
blk.Data = farr;
}
blk.scanw = srcBlk.w;
blk.offset = 0;
blk.progressive = srcBlk.progressive;
srcIArr = (int[]) srcBlk.Data;
// Cast data from source to blk
fp = src.getFixedPoint(c);
if (fp != 0)
{
mult = 1.0f / (1 << fp);
for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; i >= 0; i--)
{
for (kmin = k - w; k > kmin; k--, kSrc--)
{
farr[k] = ((srcIArr[kSrc] * mult));
}
// Jump to geggining of next line in source
kSrc -= (srcBlk.scanw - w);
}
}
else
{
for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; i >= 0; i--)
{
for (kmin = k - w; k > kmin; k--, kSrc--)
{
//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'"
farr[k] = ((float) (srcIArr[kSrc]));
}
// Jump to geggining of next line in source
kSrc -= (srcBlk.scanw - w);
}
}
break; // End of cast INT-> FLOAT
case DataBlk.TYPE_INT: // cast FLOAT -> INT
int[] iarr;
float[] srcFArr;
// Get data array from resulting blk
iarr = (int[]) blk.Data;
if (iarr == null || iarr.Length < w * h)
{
iarr = new int[w * h];
blk.Data = iarr;
}
blk.scanw = srcBlk.w;
blk.offset = 0;
blk.progressive = srcBlk.progressive;
srcFArr = (float[]) srcBlk.Data;
// Cast data from source to blk
if (fp != 0)
{
//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'"
mult = (float) (1 << fp);
for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; i >= 0; i--)
{
for (kmin = k - w; k > kmin; k--, kSrc--)
{
if (srcFArr[kSrc] > 0.0f)
{
//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'"
iarr[k] = (int) (srcFArr[kSrc] * mult + 0.5f);
}
else
{
//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'"
iarr[k] = (int) (srcFArr[kSrc] * mult - 0.5f);
}
}
// Jump to geggining of next line in source
kSrc -= (srcBlk.scanw - w);
}
}
else
{
for (i = h - 1, k = w * h - 1, kSrc = srcBlk.offset + (h - 1) * srcBlk.scanw + w - 1; i >= 0; i--)
{
for (kmin = k - w; k > kmin; k--, kSrc--)
{
if (srcFArr[kSrc] > 0.0f)
{
//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'"
iarr[k] = (int) (srcFArr[kSrc] + 0.5f);
}
else
{
//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'"
iarr[k] = (int) (srcFArr[kSrc] - 0.5f);
}
}
// Jump to geggining of next line in source
kSrc -= (srcBlk.scanw - w);
}
}
break; // End cast FLOAT -> INT
default:
throw new System.ArgumentException("Only integer and float data " + "are " + "supported by JJ2000");
}
return blk;
}
}
}
Generated by GNU Enscript 1.6.5.90.