diff --git a/CSJ2K/CSJ2K.csproj b/CSJ2K/CSJ2K.csproj index d82766d9..6e023a13 100644 --- a/CSJ2K/CSJ2K.csproj +++ b/CSJ2K/CSJ2K.csproj @@ -1,749 +1,768 @@ - - - Local - 14.0.25123 - 2.0 - {C276743B-0000-0000-0000-000000000000} - Debug - - - - CSJ2K - JScript - Grid - IE50 - false - v4.0 - Library - - CSJ2K - - - - - - - True - 285212672 - False - - - TRACE;DEBUG - - True - 4096 - False - ..\bin\ - False - False - False - 4 - False - 1591,1574,0419 - AnyCPU - - - True - 285212672 - False - - - TRACE - - False - 4096 - True - ..\bin\ - False - False - False - 4 - False - 1591,1574,0419 - AnyCPU - - - - System - False - - - System.Drawing - False - - - - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - - - - - - - + + + Local + 14.0.25123 + 2.0 + {C276743B-0000-0000-0000-000000000000} + Debug + + + + + CSJ2K + JScript + Grid + IE50 + false + v4.0 + Library + + + CSJ2K + + + + + + + + + True + 285212672 + False + + + TRACE;DEBUG + + + True + 4096 + False + ..\bin\ + False + False + False + 4 + False + 1591,1574,0419 + AnyCPU + + + True + 285212672 + False + + + TRACE + + + False + 4096 + True + ..\bin\ + False + False + False + 4 + False + 1591,1574,0419 + AnyCPU + + + + System + False + + + System.Drawing + False + + + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + + + + + + Code + + + Code + + + + + + + + + + + + + + + Code + + + + + + + + + + \ No newline at end of file diff --git a/CSJ2K/Color/ColorSpace.cs b/CSJ2K/Color/ColorSpace.cs index 20c4892b..f9023cb0 100644 --- a/CSJ2K/Color/ColorSpace.cs +++ b/CSJ2K/Color/ColorSpace.cs @@ -321,7 +321,8 @@ namespace CSJ2K.Color /// public virtual bool debugging() { - return pl.Get("colorspace_debug") != null && pl.Get("colorspace_debug").ToUpper().Equals("on".ToUpper()); + string tmp; + return pl.TryGetValue("colorspace_debug", out tmp) && tmp.ToUpper().Equals("ON"); } diff --git a/CSJ2K/Color/ColorSpaceException.cs b/CSJ2K/Color/ColorSpaceException.cs index 6fb401ee..6026192c 100644 --- a/CSJ2K/Color/ColorSpaceException.cs +++ b/CSJ2K/Color/ColorSpaceException.cs @@ -21,7 +21,6 @@ namespace CSJ2K.Color /// Bruce A. Kern /// - [Serializable] public class ColorSpaceException:System.Exception { diff --git a/CSJ2K/Color/ColorSpaceMapper.cs b/CSJ2K/Color/ColorSpaceMapper.cs index 58f9acd1..3a28d310 100644 --- a/CSJ2K/Color/ColorSpaceMapper.cs +++ b/CSJ2K/Color/ColorSpaceMapper.cs @@ -10,252 +10,281 @@ using System; using CSJ2K.j2k.image; using CSJ2K.j2k.util; using CSJ2K.Icc; + namespace CSJ2K.Color { - - /// This is the base class for all modules in the colorspace and icc - /// profiling steps of the decoding chain. It is responsible for the - /// allocation and iniitialization of all working storage. It provides - /// several utilities which are of generic use in preparing DataBlks - /// for use and provides default implementations for the getCompData - /// and getInternCompData methods. - /// - /// - /// - /// - /// 1.0 - /// - /// Bruce A. Kern - /// - public abstract class ColorSpaceMapper:ImgDataAdapter, BlkImgDataSrc - { - private void InitBlock() - { - computed = new ComputedComponents(this); - } - /// Returns the parameters that are used in this class and implementing - /// classes. It returns a 2D String array. Each of the 1D arrays is for a - /// different option, and they have 3 elements. The first element is the - /// option name, the second one is the synopsis and the third one is a long - /// description of what the parameter is. The synopsis or description may - /// be 'null', in which case it is assumed that there is no synopsis or - /// description of the option, respectively. Null may be returned if no - /// options are supported. - /// - /// - /// the options name, their synopsis and their explanation, or null - /// if no options are supported. - /// - /// - public static System.String[][] ParameterInfo - { - get - { - return pinfo; - } - - } - /// Arrange for the input DataBlk to receive an - /// appropriately sized and typed data buffer - /// - /// input DataBlk - /// - /// - /// - protected internal static DataBlk InternalBuffer - { - set - { - switch (value.DataType) - { - - - case DataBlk.TYPE_INT: - if (value.Data == null || ((int[]) value.Data).Length < value.w * value.h) - value.Data = new int[value.w * value.h]; - break; - - - case DataBlk.TYPE_FLOAT: - if (value.Data == null || ((float[]) value.Data).Length < value.w * value.h) - { - value.Data = new float[value.w * value.h]; - } - break; - - - default: - throw new System.ArgumentException("Invalid output datablock" + " type"); - - } - } - - } - - /// The prefix for ICC Profiler options - public const char OPT_PREFIX = 'I'; - - /// Platform dependant end of line String. - //UPGRADE_NOTE: Final was removed from the declaration of 'eol '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - protected internal static readonly System.String eol = System.Environment.NewLine; - - // Temporary data buffers needed during profiling. - protected internal DataBlkInt[] inInt; // Integer input data. - protected internal DataBlkFloat[] inFloat; // Floating point input data. - protected internal DataBlkInt[] workInt; // Input data shifted to zero-offset - protected internal DataBlkFloat[] workFloat; // Input data shifted to zero-offset. - protected internal int[][] dataInt; // Points to input data. - protected internal float[][] dataFloat; // Points to input data. - protected internal float[][] workDataFloat; // References working data pixels. - protected internal int[][] workDataInt; // References working data pixels. - - - /* input data parameters by component */ - protected internal int[] shiftValueArray = null; - protected internal int[] maxValueArray = null; - protected internal int[] fixedPtBitsArray = null; - - /// The list of parameters that are accepted for ICC profiling. - //UPGRADE_NOTE: Final was removed from the declaration of 'pinfo'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private static readonly System.String[][] pinfo = new System.String[][]{new System.String[]{"IcolorSpacedebug", null, "Print debugging messages during colorspace mapping.", "off"}}; - - /// Parameter Specs - protected internal ParameterList pl = null; - - /// ColorSpace info - protected internal ColorSpace csMap = null; - - /// Number of image components - protected internal int ncomps = 0; - - /// The image source. - protected internal BlkImgDataSrc src = null; - - /// The image source data per component. - protected internal DataBlk[] srcBlk = null; - - - //UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'ComputedComponents' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'" - protected internal class ComputedComponents - { - private void InitBlock(ColorSpaceMapper enclosingInstance) - { - this.enclosingInstance = enclosingInstance; - } - private ColorSpaceMapper enclosingInstance; - public ColorSpaceMapper Enclosing_Instance - { - get - { - return enclosingInstance; - } - - } - //private int tIdx = - 1; - private int h = - 1; - private int w = - 1; - private int ulx = - 1; - private int uly = - 1; - private int offset = - 1; - private int scanw = - 1; - - public ComputedComponents(ColorSpaceMapper enclosingInstance) - { - InitBlock(enclosingInstance); - clear(); - } - - public ComputedComponents(ColorSpaceMapper enclosingInstance, DataBlk db) - { - InitBlock(enclosingInstance); - set_Renamed(db); - } - - 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; - } - - public virtual void clear() - { - h = w = ulx = uly = offset = scanw = - 1; - } - - public bool Equals(ComputedComponents cc) - { - return (h == cc.h && w == cc.w && ulx == cc.ulx && uly == cc.uly && offset == cc.offset && scanw == cc.scanw); - } - - /* end class ComputedComponents */ - } - - //UPGRADE_NOTE: The initialization of 'computed' was moved to method 'InitBlock'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'" - protected internal ComputedComponents computed; - - /// Copy the DataBlk geometry from source to target - /// DataBlk and assure that the target has an appropriate - /// data buffer. - /// - /// has its geometry set. - /// - /// used to get the new geometric parameters. - /// - 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; - } - - - /// Factory method for creating instances of this class. - /// -- source of image data - /// - /// -- provides colorspace info - /// - /// ColorSpaceMapper instance - /// - /// profile access exception - /// - public static BlkImgDataSrc createInstance(BlkImgDataSrc src, ColorSpace csMap) - { - - // Check parameters - csMap.pl.checkList(OPT_PREFIX, CSJ2K.j2k.util.ParameterList.toNameArray(pinfo)); - - // Perform ICCProfiling or ColorSpace tranfsormation. - if (csMap.Method == ColorSpace.MethodEnum.ICC_PROFILED) - { - return ICCProfiler.createInstance(src, csMap); - } - else - { - ColorSpace.CSEnum colorspace = csMap.getColorSpace(); - - if (colorspace == ColorSpace.CSEnum.sRGB) - { - return EnumeratedColorSpaceMapper.createInstance(src, csMap); - } - else if (colorspace == ColorSpace.CSEnum.GreyScale) - { - return EnumeratedColorSpaceMapper.createInstance(src, csMap); - } - else if (colorspace == ColorSpace.CSEnum.sYCC) - { - return SYccColorSpaceMapper.createInstance(src, csMap); - } + + /// This is the base class for all modules in the colorspace and icc + /// profiling steps of the decoding chain. It is responsible for the + /// allocation and iniitialization of all working storage. It provides + /// several utilities which are of generic use in preparing DataBlks + /// for use and provides default implementations for the getCompData + /// and getInternCompData methods. + /// + /// + /// + /// + /// 1.0 + /// + /// Bruce A. Kern + /// + public abstract class ColorSpaceMapper : ImgDataAdapter, BlkImgDataSrc + { + private void InitBlock() + { + computed = new ComputedComponents(this); + } + + /// Returns the parameters that are used in this class and implementing + /// classes. It returns a 2D String array. Each of the 1D arrays is for a + /// different option, and they have 3 elements. The first element is the + /// option name, the second one is the synopsis and the third one is a long + /// description of what the parameter is. The synopsis or description may + /// be 'null', in which case it is assumed that there is no synopsis or + /// description of the option, respectively. Null may be returned if no + /// options are supported. + /// + /// + /// the options name, their synopsis and their explanation, or null + /// if no options are supported. + /// + /// + public static System.String[][] ParameterInfo + { + get + { + return pinfo; + } + + } + + /// Arrange for the input DataBlk to receive an + /// appropriately sized and typed data buffer + /// + /// input DataBlk + /// + /// + /// + protected internal static DataBlk InternalBuffer + { + set + { + switch (value.DataType) + { + + + case DataBlk.TYPE_INT: + if (value.Data == null || ((int[])value.Data).Length < value.w * value.h) value.Data = new int[value.w * value.h]; + break; + + + case DataBlk.TYPE_FLOAT: + if (value.Data == null || ((float[])value.Data).Length < value.w * value.h) + { + value.Data = new float[value.w * value.h]; + } + break; + + + default: + throw new System.ArgumentException("Invalid output datablock" + " type"); + + } + } + + } + + /// The prefix for ICC Profiler options + public const char OPT_PREFIX = 'I'; + + /// Platform dependant end of line String. + //UPGRADE_NOTE: Final was removed from the declaration of 'eol '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + protected internal static readonly System.String eol = System.Environment.NewLine; + + // Temporary data buffers needed during profiling. + protected internal DataBlkInt[] inInt; // Integer input data. + + protected internal DataBlkFloat[] inFloat; // Floating point input data. + + protected internal DataBlkInt[] workInt; // Input data shifted to zero-offset + + protected internal DataBlkFloat[] workFloat; // Input data shifted to zero-offset. + + protected internal int[][] dataInt; // Points to input data. + + protected internal float[][] dataFloat; // Points to input data. + + protected internal float[][] workDataFloat; // References working data pixels. + + protected internal int[][] workDataInt; // References working data pixels. + + + /* input data parameters by component */ + + protected internal int[] shiftValueArray = null; + + protected internal int[] maxValueArray = null; + + protected internal int[] fixedPtBitsArray = null; + + /// The list of parameters that are accepted for ICC profiling. + //UPGRADE_NOTE: Final was removed from the declaration of 'pinfo'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + private static readonly System.String[][] pinfo = new System.String[][] + { + new System.String[] + { + "IcolorSpacedebug", null, + "Print debugging messages during colorspace mapping.", + "off" + } + }; + + /// Parameter Specs + protected internal ParameterList pl = null; + + /// ColorSpace info + protected internal ColorSpace csMap = null; + + /// Number of image components + protected internal int ncomps = 0; + + /// The image source. + protected internal BlkImgDataSrc src = null; + + /// The image source data per component. + protected internal DataBlk[] srcBlk = null; + + + //UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'ComputedComponents' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'" + protected internal class ComputedComponents + { + private void InitBlock(ColorSpaceMapper enclosingInstance) + { + this.enclosingInstance = enclosingInstance; + } + + private ColorSpaceMapper enclosingInstance; + + public ColorSpaceMapper Enclosing_Instance + { + get + { + return enclosingInstance; + } + + } + + //private int tIdx = - 1; + private int h = -1; + + private int w = -1; + + private int ulx = -1; + + private int uly = -1; + + private int offset = -1; + + private int scanw = -1; + + public ComputedComponents(ColorSpaceMapper enclosingInstance) + { + InitBlock(enclosingInstance); + clear(); + } + + public ComputedComponents(ColorSpaceMapper enclosingInstance, DataBlk db) + { + InitBlock(enclosingInstance); + set_Renamed(db); + } + + 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; + } + + public virtual void clear() + { + h = w = ulx = uly = offset = scanw = -1; + } + + public bool Equals(ComputedComponents cc) + { + return (h == cc.h && w == cc.w && ulx == cc.ulx && uly == cc.uly && offset == cc.offset + && scanw == cc.scanw); + } + + /* end class ComputedComponents */ + } + + //UPGRADE_NOTE: The initialization of 'computed' was moved to method 'InitBlock'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'" + protected internal ComputedComponents computed; + + /// Copy the DataBlk geometry from source to target + /// DataBlk and assure that the target has an appropriate + /// data buffer. + /// + /// has its geometry set. + /// + /// used to get the new geometric parameters. + /// + 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; + } + + + /// Factory method for creating instances of this class. + /// -- source of image data + /// + /// -- provides colorspace info + /// + /// ColorSpaceMapper instance + /// + /// profile access exception + /// + public static BlkImgDataSrc createInstance(BlkImgDataSrc src, ColorSpace csMap) + { + + // Check parameters + csMap.pl.checkList(OPT_PREFIX, CSJ2K.j2k.util.ParameterList.toNameArray(pinfo)); + + // Perform ICCProfiling or ColorSpace tranfsormation. + if (csMap.Method == ColorSpace.MethodEnum.ICC_PROFILED) + { + return ICCProfiler.createInstance(src, csMap); + } + else + { + ColorSpace.CSEnum colorspace = csMap.getColorSpace(); + + if (colorspace == ColorSpace.CSEnum.sRGB) + { + return EnumeratedColorSpaceMapper.createInstance(src, csMap); + } + else if (colorspace == ColorSpace.CSEnum.GreyScale) + { + return EnumeratedColorSpaceMapper.createInstance(src, csMap); + } + else if (colorspace == ColorSpace.CSEnum.sYCC) + { + return SYccColorSpaceMapper.createInstance(src, csMap); + } if (colorspace == ColorSpace.CSEnum.esRGB) { return EsRgbColorSpaceMapper.createInstance(src, csMap); @@ -268,185 +297,212 @@ namespace CSJ2K.Color { throw new ColorSpaceException("Bad color space specification in image"); } - } - } - - /// Ctor which creates an ICCProfile for the image and initializes - /// all data objects (input, working, and output). - /// - /// - /// -- Source of image data - /// - /// -- provides colorspace info - /// - /// - protected internal ColorSpaceMapper(BlkImgDataSrc src, ColorSpace csMap):base(src) - { - InitBlock(); - this.src = src; - this.csMap = csMap; - initialize(); - /* end ColorSpaceMapper ctor */ - } - - /// General utility used by ctors - private void initialize() - { - - this.pl = csMap.pl; - this.ncomps = src.NumComps; - - shiftValueArray = new int[ncomps]; - maxValueArray = new int[ncomps]; - fixedPtBitsArray = new int[ncomps]; - - srcBlk = new DataBlk[ncomps]; - inInt = new DataBlkInt[ncomps]; - inFloat = new DataBlkFloat[ncomps]; - workInt = new DataBlkInt[ncomps]; - workFloat = new DataBlkFloat[ncomps]; - dataInt = new int[ncomps][]; - dataFloat = new float[ncomps][]; - workDataInt = new int[ncomps][]; - workDataFloat = new float[ncomps][]; - dataInt = new int[ncomps][]; - dataFloat = new float[ncomps][]; - - - /* For each component, get a reference to the pixel data and + } + } + + /// Ctor which creates an ICCProfile for the image and initializes + /// all data objects (input, working, and output). + /// + /// + /// -- Source of image data + /// + /// -- provides colorspace info + /// + /// + protected internal ColorSpaceMapper(BlkImgDataSrc src, ColorSpace csMap) + : base(src) + { + InitBlock(); + this.src = src; + this.csMap = csMap; + initialize(); + /* end ColorSpaceMapper ctor */ + } + + /// General utility used by ctors + private void initialize() + { + + this.pl = csMap.pl; + this.ncomps = src.NumComps; + + shiftValueArray = new int[ncomps]; + maxValueArray = new int[ncomps]; + fixedPtBitsArray = new int[ncomps]; + + srcBlk = new DataBlk[ncomps]; + inInt = new DataBlkInt[ncomps]; + inFloat = new DataBlkFloat[ncomps]; + workInt = new DataBlkInt[ncomps]; + workFloat = new DataBlkFloat[ncomps]; + dataInt = new int[ncomps][]; + dataFloat = new float[ncomps][]; + workDataInt = new int[ncomps][]; + workDataFloat = new float[ncomps][]; + dataInt = new int[ncomps][]; + dataFloat = new float[ncomps][]; + + + /* For each component, get a reference to the pixel data and * set up working DataBlks for both integer and float output. */ - for (int i = 0; i < ncomps; ++i) - { - - shiftValueArray[i] = 1 << (src.getNomRangeBits(i) - 1); - maxValueArray[i] = (1 << src.getNomRangeBits(i)) - 1; - fixedPtBitsArray[i] = src.getFixedPoint(i); - - inInt[i] = new DataBlkInt(); - inFloat[i] = new DataBlkFloat(); - workInt[i] = new DataBlkInt(); - workInt[i].progressive = inInt[i].progressive; - workFloat[i] = new DataBlkFloat(); - workFloat[i].progressive = inFloat[i].progressive; - } - } - - /// Returns the number of bits, referred to as the "range bits", - /// corresponding to the nominal range of the data in the specified - /// component. If this number is b then for unsigned data the - /// nominal range is between 0 and 2^b-1, and for signed data it is between - /// -2^(b-1) and 2^(b-1)-1. For floating point data this value is not - /// applicable. - /// - /// - /// The index of the component. - /// - /// - /// The number of bits corresponding to the nominal range of the - /// data. Fro floating-point data this value is not applicable and the - /// return value is undefined. - /// - public virtual int getFixedPoint(int c) - { - return src.getFixedPoint(c); - } - - /// 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". - /// - ///

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. - /// - ///

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. - /// - ///

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. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// 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. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// - /// - /// - public virtual DataBlk getCompData(DataBlk out_Renamed, int c) - { - return src.getCompData(out_Renamed, c); - } - - /// 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. - /// - ///

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. - /// - ///

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. - /// - ///

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. - /// - ///

If the data array in blk is null, 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 blk 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 - /// blk after the method has returned. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// 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. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - public virtual DataBlk getInternCompData(DataBlk out_Renamed, int c) - { - return src.getInternCompData(out_Renamed, c); - } - - /* end class ColorSpaceMapper */ - } -} \ No newline at end of file + for (int i = 0; i < ncomps; ++i) + { + + shiftValueArray[i] = 1 << (src.getNomRangeBits(i) - 1); + maxValueArray[i] = (1 << src.getNomRangeBits(i)) - 1; + fixedPtBitsArray[i] = src.getFixedPoint(i); + + inInt[i] = new DataBlkInt(); + inFloat[i] = new DataBlkFloat(); + workInt[i] = new DataBlkInt(); + workInt[i].progressive = inInt[i].progressive; + workFloat[i] = new DataBlkFloat(); + workFloat[i].progressive = inFloat[i].progressive; + } + } + + /// Returns the number of bits, referred to as the "range bits", + /// corresponding to the nominal range of the data in the specified + /// component. If this number is b then for unsigned data the + /// nominal range is between 0 and 2^b-1, and for signed data it is between + /// -2^(b-1) and 2^(b-1)-1. For floating point data this value is not + /// applicable. + /// + /// + /// The index of the component. + /// + /// + /// The number of bits corresponding to the nominal range of the + /// data. Fro floating-point data this value is not applicable and the + /// return value is undefined. + /// + public virtual int getFixedPoint(int c) + { + return src.getFixedPoint(c); + } + + /// 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". + /// + ///

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. + /// + ///

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. + /// + ///

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. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// 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. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// + /// + /// + public virtual DataBlk getCompData(DataBlk out_Renamed, int c) + { + return src.getCompData(out_Renamed, c); + } + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + public void close() + { + // Do nothing. + } + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + public bool isOrigSigned(int c) + { + return false; + } + + /// 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. + /// + ///

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. + /// + ///

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. + /// + ///

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. + /// + ///

If the data array in blk is null, 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 blk 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 + /// blk after the method has returned. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// 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. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + public virtual DataBlk getInternCompData(DataBlk out_Renamed, int c) + { + return src.getInternCompData(out_Renamed, c); + } + + /* end class ColorSpaceMapper */ + } +} diff --git a/CSJ2K/Color/EnumeratedColorSpaceMapper.cs b/CSJ2K/Color/EnumeratedColorSpaceMapper.cs index d2739e41..c5163b6a 100644 --- a/CSJ2K/Color/EnumeratedColorSpaceMapper.cs +++ b/CSJ2K/Color/EnumeratedColorSpaceMapper.cs @@ -14,7 +14,7 @@ using DataBlkInt = CSJ2K.j2k.image.DataBlkInt; using DataBlkFloat = CSJ2K.j2k.image.DataBlkFloat; using ImgDataAdapter = CSJ2K.j2k.image.ImgDataAdapter; using FacilityManager = CSJ2K.j2k.util.FacilityManager; -using MsgLogger = CSJ2K.j2k.util.MsgLogger; + namespace CSJ2K.Color { diff --git a/CSJ2K/Color/EsRgbColorSpaceMapper.cs b/CSJ2K/Color/EsRgbColorSpaceMapper.cs index 8ba6a34f..2e412fc6 100644 --- a/CSJ2K/Color/EsRgbColorSpaceMapper.cs +++ b/CSJ2K/Color/EsRgbColorSpaceMapper.cs @@ -14,7 +14,7 @@ using DataBlkInt = CSJ2K.j2k.image.DataBlkInt; using DataBlkFloat = CSJ2K.j2k.image.DataBlkFloat; using ImgDataAdapter = CSJ2K.j2k.image.ImgDataAdapter; using FacilityManager = CSJ2K.j2k.util.FacilityManager; -using MsgLogger = CSJ2K.j2k.util.MsgLogger; + namespace CSJ2K.Color { diff --git a/CSJ2K/Color/SYccColorSpaceMapper.cs b/CSJ2K/Color/SYccColorSpaceMapper.cs index 18e26251..9a839695 100644 --- a/CSJ2K/Color/SYccColorSpaceMapper.cs +++ b/CSJ2K/Color/SYccColorSpaceMapper.cs @@ -14,7 +14,7 @@ using DataBlkInt = CSJ2K.j2k.image.DataBlkInt; using DataBlkFloat = CSJ2K.j2k.image.DataBlkFloat; using ImgDataAdapter = CSJ2K.j2k.image.ImgDataAdapter; using FacilityManager = CSJ2K.j2k.util.FacilityManager; -using MsgLogger = CSJ2K.j2k.util.MsgLogger; + namespace CSJ2K.Color { diff --git a/CSJ2K/Color/boxes/ChannelDefinitionBox.cs b/CSJ2K/Color/boxes/ChannelDefinitionBox.cs index 467ed977..46e0b7fc 100644 --- a/CSJ2K/Color/boxes/ChannelDefinitionBox.cs +++ b/CSJ2K/Color/boxes/ChannelDefinitionBox.cs @@ -7,6 +7,7 @@ /// *************************************************************************** /// using System; +using System.Collections.Generic; using ColorSpaceException = CSJ2K.Color.ColorSpaceException; using ICCProfile = CSJ2K.Icc.ICCProfile; using ParameterList = CSJ2K.j2k.util.ParameterList; @@ -37,7 +38,7 @@ namespace CSJ2K.Color.Boxes } private int ndefs; - private System.Collections.Hashtable definitions = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + private System.Collections.Generic.Dictionary definitions = new Dictionary(); /// Construct a ChannelDefinitionBox from an input image. /// RandomAccessIO jp2 image @@ -78,7 +79,7 @@ namespace CSJ2K.Color.Boxes /* Return the channel association. */ public int getCn(int asoc) { - System.Collections.IEnumerator keys = definitions.Keys.GetEnumerator(); + System.Collections.Generic.IEnumerator keys = definitions.Keys.GetEnumerator(); //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'" while (keys.MoveNext()) { @@ -111,7 +112,7 @@ namespace CSJ2K.Color.Boxes System.Text.StringBuilder rep = new System.Text.StringBuilder("[ChannelDefinitionBox ").Append(eol).Append(" "); rep.Append("ndefs= ").Append(System.Convert.ToString(ndefs)); - System.Collections.IEnumerator keys = definitions.Keys.GetEnumerator(); + System.Collections.Generic.IEnumerator keys = definitions.Keys.GetEnumerator(); //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'" while (keys.MoveNext()) { diff --git a/CSJ2K/Color/boxes/ComponentMappingBox.cs b/CSJ2K/Color/boxes/ComponentMappingBox.cs index 631f3fee..7fe695f8 100644 --- a/CSJ2K/Color/boxes/ComponentMappingBox.cs +++ b/CSJ2K/Color/boxes/ComponentMappingBox.cs @@ -7,6 +7,7 @@ /// *************************************************************************** /// using System; +using System.Collections.Generic; using ColorSpaceException = CSJ2K.Color.ColorSpaceException; using ICCProfile = CSJ2K.Icc.ICCProfile; using ParameterList = CSJ2K.j2k.util.ParameterList; @@ -37,7 +38,7 @@ namespace CSJ2K.Color.Boxes } private int nChannels; - private System.Collections.ArrayList map = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + private System.Collections.Generic.List map = new List(10); /// Construct a ComponentMappingBox from an input image. /// RandomAccessIO jp2 image diff --git a/CSJ2K/Color/boxes/JP2Box.cs b/CSJ2K/Color/boxes/JP2Box.cs index c2d18040..87a09a64 100644 --- a/CSJ2K/Color/boxes/JP2Box.cs +++ b/CSJ2K/Color/boxes/JP2Box.cs @@ -7,6 +7,7 @@ /// *************************************************************************** /// using System; +using System.Collections.Generic; using ColorSpaceException = CSJ2K.Color.ColorSpaceException; using FileFormatBoxes = CSJ2K.j2k.fileformat.FileFormatBoxes; using ICCProfile = CSJ2K.Icc.ICCProfile; @@ -48,18 +49,6 @@ namespace CSJ2K.Color.Boxes /// offset to start of data in box protected internal int dataStart; - public JP2Box() - { - try - { - throw new ColorSpaceException("JP2Box empty ctor called!!"); - } - catch (ColorSpaceException e) - { - SupportClass.WriteStackTrace(e, Console.Error); throw; - } - } - /// Construct a JP2Box from an input image. /// RandomAccessIO jp2 image /// @@ -93,12 +82,12 @@ namespace CSJ2K.Color.Boxes /// JP2 Box structure analysis help - [Serializable] - protected internal class BoxType:System.Collections.Hashtable + protected internal class BoxType:System.Collections.Generic.Dictionary { - private static System.Collections.Hashtable map = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); - private static void put(int type, System.String desc) + private static System.Collections.Generic.Dictionary map = new Dictionary(); + + private static void put(int type, System.String desc) { map[(System.Int32) type] = desc; } diff --git a/CSJ2K/Icc/ICCProfile.cs b/CSJ2K/Icc/ICCProfile.cs index 701371f7..44c640a8 100644 --- a/CSJ2K/Icc/ICCProfile.cs +++ b/CSJ2K/Icc/ICCProfile.cs @@ -1,4 +1,5 @@ -/// ************************************************************************** +/// +/// ************************************************************************** /// /// $Id: ICCProfile.java,v 1.1 2002/07/25 14:56:55 grosbois Exp $ /// @@ -6,952 +7,989 @@ /// $Date $ /// *************************************************************************** /// -using System; -using System.Text; -using ParameterList = CSJ2K.j2k.util.ParameterList; -using DecoderSpecs = CSJ2K.j2k.decoder.DecoderSpecs; -using BitstreamReaderAgent = CSJ2K.j2k.codestream.reader.BitstreamReaderAgent; -using ColorSpace = CSJ2K.Color.ColorSpace; -using ColorSpaceException = CSJ2K.Color.ColorSpaceException; -using ICCProfileHeader = CSJ2K.Icc.Types.ICCProfileHeader; -using ICCTag = CSJ2K.Icc.Tags.ICCTag; -using ICCTagTable = CSJ2K.Icc.Tags.ICCTagTable; -using ICCCurveType = CSJ2K.Icc.Tags.ICCCurveType; -using ICCXYZType = CSJ2K.Icc.Tags.ICCXYZType; -using XYZNumber = CSJ2K.Icc.Types.XYZNumber; -using ICCProfileVersion = CSJ2K.Icc.Types.ICCProfileVersion; -using ICCDateTime = CSJ2K.Icc.Types.ICCDateTime; -using FileFormatBoxes = CSJ2K.j2k.fileformat.FileFormatBoxes; -using RandomAccessIO = CSJ2K.j2k.io.RandomAccessIO; -using FacilityManager = CSJ2K.j2k.util.FacilityManager; -using MsgLogger = CSJ2K.j2k.util.MsgLogger; + namespace CSJ2K.Icc { - - /// This class models the ICCProfile file. This file is a binary file which is divided - /// into two parts, an ICCProfileHeader followed by an ICCTagTable. The header is a - /// straightforward list of descriptive parameters such as profile size, version, date and various - /// more esoteric parameters. The tag table is a structured list of more complexly aggragated data - /// describing things such as ICC curves, copyright information, descriptive text blocks, etc. - /// - /// Classes exist to model the header and tag table and their various constituent parts the developer - /// is refered to these for further information on the structure and contents of the header and tag table. - /// - /// - /// - /// - /// - /// - /// 1.0 - /// - /// Bruce A. Kern - /// - - public abstract class ICCProfile - { - private int ProfileSize - { - get - { - return header.dwProfileSize; - } - - set - { - header.dwProfileSize = value; - } - - } - private int CMMTypeSignature - { - get - { - return header.dwCMMTypeSignature; - } - - set - { - header.dwCMMTypeSignature = value; - } - - } - private int ProfileClass - { - get - { - return header.dwProfileClass; - } - - set - { - header.dwProfileClass = value; - } - - } - private int ColorSpaceType - { - get - { - return header.dwColorSpaceType; - } - - set - { - header.dwColorSpaceType = value; - } - - } - private int PCSType - { - get - { - return header.dwPCSType; - } - - set - { - header.dwPCSType = value; - } - - } - private int ProfileSignature - { - get - { - return header.dwProfileSignature; - } - - set - { - header.dwProfileSignature = value; - } - - } - private int PlatformSignature - { - get - { - return header.dwPlatformSignature; - } - - set - { - header.dwPlatformSignature = value; - } - - } - private int CMMFlags - { - get - { - return header.dwCMMFlags; - } - - set - { - header.dwCMMFlags = value; - } - - } - private int DeviceManufacturer - { - get - { - return header.dwDeviceManufacturer; - } - - set - { - header.dwDeviceManufacturer = value; - } - - } - private int DeviceModel - { - get - { - return header.dwDeviceModel; - } - - set - { - header.dwDeviceModel = value; - } - - } - private int DeviceAttributes1 - { - get - { - return header.dwDeviceAttributes1; - } - - set - { - header.dwDeviceAttributes1 = value; - } - - } - private int DeviceAttributesReserved - { - get - { - return header.dwDeviceAttributesReserved; - } - - set - { - header.dwDeviceAttributesReserved = value; - } - - } - private int RenderingIntent - { - get - { - return header.dwRenderingIntent; - } - - set - { - header.dwRenderingIntent = value; - } - - } - private int CreatorSig - { - get - { - return header.dwCreatorSig; - } - - set - { - header.dwCreatorSig = value; - } - - } - private ICCProfileVersion ProfileVersion - { - get - { - return header.profileVersion; - } - - set - { - header.profileVersion = value; - } - - } - private XYZNumber PCSIlluminant - { - set - { - header.PCSIlluminant = value; - } - - } - private ICCDateTime DateTime - { - set - { - header.dateTime = value; - } - - } - /// Access the profile header - /// ICCProfileHeader - /// - virtual public ICCProfileHeader Header - { - get - { - return header; - } - - } - /// Access the profile tag table - /// ICCTagTable - /// - virtual public ICCTagTable TagTable - { - get - { - return tags; - } - - } - - //UPGRADE_NOTE: Final was removed from the declaration of 'eol '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private static readonly System.String eol = System.Environment.NewLine; - - /// Gray index. - // Renamed for convenience: - public const int GRAY = 0; - /// RGB index. - public const int RED = 0; - /// RGB index. - public const int GREEN = 1; - /// RGB index. - public const int BLUE = 2; - - /// Size of native type - public const int boolean_size = 1; - /// Size of native type - public const int byte_size = 1; - /// Size of native type - public const int char_size = 2; - /// Size of native type - public const int short_size = 2; - /// Size of native type - public const int int_size = 4; - /// Size of native type - public const int float_size = 4; - /// Size of native type - public const int long_size = 8; - /// Size of native type - public const int double_size = 8; - - /* Bit twiddling constant for integral types. */ public const int BITS_PER_BYTE = 8; - /* Bit twiddling constant for integral types. */ public const int BITS_PER_SHORT = 16; - /* Bit twiddling constant for integral types. */ public const int BITS_PER_INT = 32; - /* Bit twiddling constant for integral types. */ public const int BITS_PER_LONG = 64; - /* Bit twiddling constant for integral types. */ public const int BYTES_PER_SHORT = 2; - /* Bit twiddling constant for integral types. */ public const int BYTES_PER_INT = 4; - /* Bit twiddling constant for integral types. */ public const int BYTES_PER_LONG = 8; - - /* JP2 Box structure analysis help */ - - [Serializable] - private class BoxType:System.Collections.Hashtable - { - - private static System.Collections.Hashtable map = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); - - public static void put(int type, System.String desc) - { - map[(System.Int32) type] = desc; - } - - public static System.String get_Renamed(int type) - { - return (System.String) map[(System.Int32) type]; - } - - public static System.String colorSpecMethod(int meth) - { - switch (meth) - { - - case 2: return "Restricted ICC Profile"; - - case 1: return "Enumerated Color Space"; - - default: return "Undefined Color Spec Method"; - - } - } - static BoxType() - { - { - put(CSJ2K.j2k.fileformat.FileFormatBoxes.BITS_PER_COMPONENT_BOX, "BITS_PER_COMPONENT_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.CAPTURE_RESOLUTION_BOX, "CAPTURE_RESOLUTION_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.CHANNEL_DEFINITION_BOX, "CHANNEL_DEFINITION_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.COLOUR_SPECIFICATION_BOX, "COLOUR_SPECIFICATION_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.COMPONENT_MAPPING_BOX, "COMPONENT_MAPPING_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.CONTIGUOUS_CODESTREAM_BOX, "CONTIGUOUS_CODESTREAM_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.DEFAULT_DISPLAY_RESOLUTION_BOX, "DEFAULT_DISPLAY_RESOLUTION_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.FILE_TYPE_BOX, "FILE_TYPE_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.IMAGE_HEADER_BOX, "IMAGE_HEADER_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.INTELLECTUAL_PROPERTY_BOX, "INTELLECTUAL_PROPERTY_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.JP2_HEADER_BOX, "JP2_HEADER_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.JP2_SIGNATURE_BOX, "JP2_SIGNATURE_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.PALETTE_BOX, "PALETTE_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.RESOLUTION_BOX, "RESOLUTION_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.URL_BOX, "URL_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.UUID_BOX, "UUID_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.UUID_INFO_BOX, "UUID_INFO_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.UUID_LIST_BOX, "UUID_LIST_BOX"); - put(CSJ2K.j2k.fileformat.FileFormatBoxes.XML_BOX, "XML_BOX"); - } - } - } - - - /// Creates an int from a 4 character String - /// string representation of an integer - /// - /// the integer which is denoted by the input String. - /// - public static int getIntFromString(System.String fourChar) - { - byte[] bytes = SupportClass.ToByteArray(fourChar); - return getInt(bytes, 0); - } - /// Create an XYZNumber from byte [] input - /// array containing the XYZNumber representation - /// - /// start of the rep in the array - /// - /// the created XYZNumber - /// - public static XYZNumber getXYZNumber(byte[] data, int offset) - { - int x, y, z; + using System; + using System.Collections.Generic; + using System.IO; + using System.Text; + + using ParameterList = CSJ2K.j2k.util.ParameterList; + using ColorSpace = CSJ2K.Color.ColorSpace; + using ICCProfileHeader = CSJ2K.Icc.Types.ICCProfileHeader; + using ICCTag = CSJ2K.Icc.Tags.ICCTag; + using ICCTagTable = CSJ2K.Icc.Tags.ICCTagTable; + using ICCCurveType = CSJ2K.Icc.Tags.ICCCurveType; + using ICCXYZType = CSJ2K.Icc.Tags.ICCXYZType; + using XYZNumber = CSJ2K.Icc.Types.XYZNumber; + using ICCProfileVersion = CSJ2K.Icc.Types.ICCProfileVersion; + using ICCDateTime = CSJ2K.Icc.Types.ICCDateTime; + using FacilityManager = CSJ2K.j2k.util.FacilityManager; + + + /// This class models the ICCProfile file. This file is a binary file which is divided + /// into two parts, an ICCProfileHeader followed by an ICCTagTable. The header is a + /// straightforward list of descriptive parameters such as profile size, version, date and various + /// more esoteric parameters. The tag table is a structured list of more complexly aggragated data + /// describing things such as ICC curves, copyright information, descriptive text blocks, etc. + /// + /// Classes exist to model the header and tag table and their various constituent parts the developer + /// is refered to these for further information on the structure and contents of the header and tag table. + /// + /// + /// + /// + /// + /// + /// 1.0 + /// + /// Bruce A. Kern + /// + + public abstract class ICCProfile + { + private int ProfileSize + { + get + { + return header.dwProfileSize; + } + + set + { + header.dwProfileSize = value; + } + + } + + private int CMMTypeSignature + { + get + { + return header.dwCMMTypeSignature; + } + + set + { + header.dwCMMTypeSignature = value; + } + + } + + private int ProfileClass + { + get + { + return header.dwProfileClass; + } + + set + { + header.dwProfileClass = value; + } + + } + + private int ColorSpaceType + { + get + { + return header.dwColorSpaceType; + } + + set + { + header.dwColorSpaceType = value; + } + + } + + private int PCSType + { + get + { + return header.dwPCSType; + } + + set + { + header.dwPCSType = value; + } + + } + + private int ProfileSignature + { + get + { + return header.dwProfileSignature; + } + + set + { + header.dwProfileSignature = value; + } + + } + + private int PlatformSignature + { + get + { + return header.dwPlatformSignature; + } + + set + { + header.dwPlatformSignature = value; + } + + } + + private int CMMFlags + { + get + { + return header.dwCMMFlags; + } + + set + { + header.dwCMMFlags = value; + } + + } + + private int DeviceManufacturer + { + get + { + return header.dwDeviceManufacturer; + } + + set + { + header.dwDeviceManufacturer = value; + } + + } + + private int DeviceModel + { + get + { + return header.dwDeviceModel; + } + + set + { + header.dwDeviceModel = value; + } + + } + + private int DeviceAttributes1 + { + get + { + return header.dwDeviceAttributes1; + } + + set + { + header.dwDeviceAttributes1 = value; + } + + } + + private int DeviceAttributesReserved + { + get + { + return header.dwDeviceAttributesReserved; + } + + set + { + header.dwDeviceAttributesReserved = value; + } + + } + + private int RenderingIntent + { + get + { + return header.dwRenderingIntent; + } + + set + { + header.dwRenderingIntent = value; + } + + } + + private int CreatorSig + { + get + { + return header.dwCreatorSig; + } + + set + { + header.dwCreatorSig = value; + } + + } + + private ICCProfileVersion ProfileVersion + { + get + { + return header.profileVersion; + } + + set + { + header.profileVersion = value; + } + + } + + private XYZNumber PCSIlluminant + { + set + { + header.PCSIlluminant = value; + } + + } + + private ICCDateTime DateTime + { + set + { + header.dateTime = value; + } + + } + + /// Access the profile header + /// ICCProfileHeader + /// + public virtual ICCProfileHeader Header + { + get + { + return header; + } + + } + + /// Access the profile tag table + /// ICCTagTable + /// + public virtual ICCTagTable TagTable + { + get + { + return tags; + } + + } + + private static readonly string eol = System.Environment.NewLine; + + /// Gray index. + // Renamed for convenience: + public const int GRAY = 0; + + /// RGB index. + public const int RED = 0; + + /// RGB index. + public const int GREEN = 1; + + /// RGB index. + public const int BLUE = 2; + + /// Size of native type + public const int boolean_size = 1; + + /// Size of native type + public const int byte_size = 1; + + /// Size of native type + public const int char_size = 2; + + /// Size of native type + public const int short_size = 2; + + /// Size of native type + public const int int_size = 4; + + /// Size of native type + public const int float_size = 4; + + /// Size of native type + public const int long_size = 8; + + /// Size of native type + public const int double_size = 8; + + /* Bit twiddling constant for integral types. */ + + public const int BITS_PER_BYTE = 8; + + /* Bit twiddling constant for integral types. */ + + public const int BITS_PER_SHORT = 16; + + /* Bit twiddling constant for integral types. */ + + public const int BITS_PER_INT = 32; + + /* Bit twiddling constant for integral types. */ + + public const int BITS_PER_LONG = 64; + + /* Bit twiddling constant for integral types. */ + + public const int BYTES_PER_SHORT = 2; + + /* Bit twiddling constant for integral types. */ + + public const int BYTES_PER_INT = 4; + + /* Bit twiddling constant for integral types. */ + + public const int BYTES_PER_LONG = 8; + + /* JP2 Box structure analysis help */ + + private class BoxType : System.Collections.Generic.Dictionary + { + + private static Dictionary map = + new Dictionary(); + + public static void put(int type, string desc) + { + map[type] = desc; + } + + public static string get_Renamed(int type) + { + return map[type]; + } + + public static string colorSpecMethod(int meth) + { + switch (meth) + { + + case 2: + return "Restricted ICC Profile"; + + case 1: + return "Enumerated Color Space"; + + default: + return "Undefined Color Spec Method"; + + } + } + + static BoxType() + { + { + put(CSJ2K.j2k.fileformat.FileFormatBoxes.BITS_PER_COMPONENT_BOX, "BITS_PER_COMPONENT_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.CAPTURE_RESOLUTION_BOX, "CAPTURE_RESOLUTION_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.CHANNEL_DEFINITION_BOX, "CHANNEL_DEFINITION_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.COLOUR_SPECIFICATION_BOX, "COLOUR_SPECIFICATION_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.COMPONENT_MAPPING_BOX, "COMPONENT_MAPPING_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.CONTIGUOUS_CODESTREAM_BOX, "CONTIGUOUS_CODESTREAM_BOX"); + put( + CSJ2K.j2k.fileformat.FileFormatBoxes.DEFAULT_DISPLAY_RESOLUTION_BOX, + "DEFAULT_DISPLAY_RESOLUTION_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.FILE_TYPE_BOX, "FILE_TYPE_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.IMAGE_HEADER_BOX, "IMAGE_HEADER_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.INTELLECTUAL_PROPERTY_BOX, "INTELLECTUAL_PROPERTY_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.JP2_HEADER_BOX, "JP2_HEADER_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.JP2_SIGNATURE_BOX, "JP2_SIGNATURE_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.PALETTE_BOX, "PALETTE_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.RESOLUTION_BOX, "RESOLUTION_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.URL_BOX, "URL_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.UUID_BOX, "UUID_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.UUID_INFO_BOX, "UUID_INFO_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.UUID_LIST_BOX, "UUID_LIST_BOX"); + put(CSJ2K.j2k.fileformat.FileFormatBoxes.XML_BOX, "XML_BOX"); + } + } + } + + + /// Creates an int from a 4 character String + /// string representation of an integer + /// + /// the integer which is denoted by the input String. + /// + public static int getIntFromString(string fourChar) + { + byte[] bytes = SupportClass.ToByteArray(fourChar); + return getInt(bytes, 0); + } + + /// Create an XYZNumber from byte [] input + /// array containing the XYZNumber representation + /// + /// start of the rep in the array + /// + /// the created XYZNumber + /// + public static XYZNumber getXYZNumber(byte[] data, int offset) + { + int x, y, z; x = ICCProfile.getInt(data, offset); y = ICCProfile.getInt(data, offset + int_size); z = ICCProfile.getInt(data, offset + 2 * int_size); - return new XYZNumber(x, y, z); - } - - /// Create an ICCProfileVersion from byte [] input - /// array containing the ICCProfileVersion representation - /// - /// start of the rep in the array - /// - /// the created ICCProfileVersion - /// - public static ICCProfileVersion getICCProfileVersion(byte[] data, int offset) - { - byte major = data[offset]; - byte minor = data[offset + byte_size]; - byte resv1 = data[offset + 2 * byte_size]; - byte resv2 = data[offset + 3 * byte_size]; - return new ICCProfileVersion(major, minor, resv1, resv2); - } - - /// Create an ICCDateTime from byte [] input - /// array containing the ICCProfileVersion representation - /// - /// start of the rep in the array - /// - /// the created ICCProfileVersion - /// - public static ICCDateTime getICCDateTime(byte[] data, int offset) - { + return new XYZNumber(x, y, z); + } + + /// Create an ICCProfileVersion from byte [] input + /// array containing the ICCProfileVersion representation + /// + /// start of the rep in the array + /// + /// the created ICCProfileVersion + /// + public static ICCProfileVersion getICCProfileVersion(byte[] data, int offset) + { + byte major = data[offset]; + byte minor = data[offset + byte_size]; + byte resv1 = data[offset + 2 * byte_size]; + byte resv2 = data[offset + 3 * byte_size]; + return new ICCProfileVersion(major, minor, resv1, resv2); + } + + /// Create an ICCDateTime from byte [] input + /// array containing the ICCProfileVersion representation + /// + /// start of the rep in the array + /// + /// the created ICCProfileVersion + /// + public static ICCDateTime getICCDateTime(byte[] data, int offset) + { short wYear = ICCProfile.getShort(data, offset); // Number of the actual year (i.e. 1994) short wMonth = ICCProfile.getShort(data, offset + ICCProfile.short_size); // Number of the month (1-12) short wDay = ICCProfile.getShort(data, offset + 2 * ICCProfile.short_size); // Number of the day short wHours = ICCProfile.getShort(data, offset + 3 * ICCProfile.short_size); // Number of hours (0-23) short wMinutes = ICCProfile.getShort(data, offset + 4 * ICCProfile.short_size); // Number of minutes (0-59) short wSeconds = ICCProfile.getShort(data, offset + 5 * ICCProfile.short_size); // Number of seconds (0-59) - return new ICCDateTime(wYear, wMonth, wDay, wHours, wMinutes, wSeconds); - } - - - /// Create a String from a byte []. Optionally swap adjacent byte - /// pairs. Intended to be used to create integer String representations - /// allowing for endian translations. - /// - /// data array - /// - /// start of data in array - /// - /// length of data in array - /// - /// swap adjacent bytes? - /// - /// String rep of data - /// - public static System.String getString(byte[] bfr, int offset, int length, bool swap) - { - - byte[] result = new byte[length]; - int incr = swap?- 1:1; - int start = swap?offset + length - 1:offset; - for (int i = 0, j = start; i < length; ++i) - { - result[i] = bfr[j]; - j += incr; - } - return new System.String(SupportClass.ToCharArray(result)); - } - - /// Create a short from a two byte [], with optional byte swapping. - /// data array - /// - /// start of data in array - /// - /// swap bytes? - /// - /// native type from representation. - /// - public static short getShort(byte[] bfr, int off, bool swap) - { - - int tmp0 = bfr[off] & 0xff; // Clear the sign extended bits in the int. - int tmp1 = bfr[off + 1] & 0xff; - - - return (short) (swap?(tmp1 << BITS_PER_BYTE | tmp0):(tmp0 << BITS_PER_BYTE | tmp1)); - } - - /// Create a short from a two byte []. - /// data array - /// - /// start of data in array - /// - /// native type from representation. - /// - public static short getShort(byte[] bfr, int off) - { - int tmp0 = bfr[off] & 0xff; // Clear the sign extended bits in the int. - int tmp1 = bfr[off + 1] & 0xff; - return (short) (tmp0 << BITS_PER_BYTE | tmp1); - } - - /// Separate bytes in an int into a byte array lsb to msb order. - /// integer to separate - /// - /// byte [] containing separated int. - /// - public static byte[] setInt(int d) - { - return setInt(d, new byte[BYTES_PER_INT]); - } - - /// Separate bytes in an int into a byte array lsb to msb order. - /// Return the result in the provided array - /// - /// integer to separate - /// - /// return output here. - /// - /// reference to output. - /// - public static byte[] setInt(int d, byte[] b) - { - if (b == null) - b = new byte[BYTES_PER_INT]; - for (int i = 0; i < BYTES_PER_INT; ++i) - { - b[i] = (byte) (d & 0x0ff); - d = d >> BITS_PER_BYTE; - } - return b; - } - - /// Separate bytes in a long into a byte array lsb to msb order. - /// long to separate - /// - /// byte [] containing separated int. - /// - public static byte[] setLong(long d) - { - return setLong(d, new byte[BYTES_PER_INT]); - } - - /// Separate bytes in a long into a byte array lsb to msb order. - /// Return the result in the provided array - /// - /// long to separate - /// - /// return output here. - /// - /// reference to output. - /// - public static byte[] setLong(long d, byte[] b) - { - if (b == null) - b = new byte[BYTES_PER_LONG]; - for (int i = 0; i < BYTES_PER_LONG; ++i) - { - b[i] = (byte) (d & 0x0ff); - d = d >> BITS_PER_BYTE; - } - return b; - } - - - /// Create an int from a byte [4], with optional byte swapping. - /// data array - /// - /// start of data in array - /// - /// swap bytes? - /// - /// native type from representation. - /// - public static int getInt(byte[] bfr, int off, bool swap) - { - - int tmp0 = getShort(bfr, off, swap) & 0xffff; // Clear the sign extended bits in the int. - int tmp1 = getShort(bfr, off + 2, swap) & 0xffff; - - return (int) (swap?(tmp1 << BITS_PER_SHORT | tmp0):(tmp0 << BITS_PER_SHORT | tmp1)); - } - - /// Create an int from a byte [4]. - /// data array - /// - /// start of data in array - /// - /// native type from representation. - /// - public static int getInt(byte[] bfr, int off) - { - - int tmp0 = getShort(bfr, off) & 0xffff; // Clear the sign extended bits in the int. - int tmp1 = getShort(bfr, off + 2) & 0xffff; - - return (int) (tmp0 << BITS_PER_SHORT | tmp1); - } - - /// Create an long from a byte [8]. - /// data array - /// - /// start of data in array - /// - /// native type from representation. - /// - public static long getLong(byte[] bfr, int off) - { - - long tmp0 = getInt(bfr, off) & unchecked((int) 0xffffffff); // Clear the sign extended bits in the int. - long tmp1 = getInt(bfr, off + 4) & unchecked((int) 0xffffffff); - - return (long) (tmp0 << BITS_PER_INT | tmp1); - } - - - /// signature - // Define the set of standard signature and type values - // Because of the endian issues and byte swapping, the profile codes must - // be stored in memory and be addressed by address. As such, only those - // codes required for Restricted ICC use are defined here - - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwProfileSignature '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwProfileSignature; - /// signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwProfileSigReverse '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwProfileSigReverse; - /// profile type - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwInputProfile '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwInputProfile; - /// tag type - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwDisplayProfile '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwDisplayProfile; - /// tag type - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwRGBData '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwRGBData; - /// tag type - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwGrayData '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwGrayData; - /// tag type - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwXYZData '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwXYZData; - /// input type - public const int kMonochromeInput = 0; - /// input type - public const int kThreeCompInput = 1; - - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwGrayTRCTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwGrayTRCTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwRedColorantTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwRedColorantTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwGreenColorantTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwGreenColorantTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwBlueColorantTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwBlueColorantTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwRedTRCTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwRedTRCTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwGreenTRCTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwGreenTRCTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwBlueTRCTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwBlueTRCTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwCopyrightTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwCopyrightTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwMediaWhiteTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwMediaWhiteTag; - /// tag signature - //UPGRADE_NOTE: Final was removed from the declaration of 'kdwProfileDescTag '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - public static readonly int kdwProfileDescTag; - - - private ICCProfileHeader header = null; - private ICCTagTable tags = null; - private byte[] profile = null; - - //private byte[] data = null; - private ParameterList pl = null; - - private ICCProfile() - { - throw new ICCProfileException("illegal to invoke empty constructor"); - } - - /// ParameterList constructor - /// provides colorspace information - /// - protected internal ICCProfile(ColorSpace csm) - { - this.pl = csm.pl; - profile = csm.ICCProfile; - initProfile(profile); - } - - /// Read the header and tags into memory and verify - /// that the correct type of profile is being used. for encoding. - /// - /// ICCProfile - /// - /// for bad signature and class and bad type - /// - private void initProfile(byte[] data) - { - header = new ICCProfileHeader(data); - tags = ICCTagTable.createInstance(data); - - - // Verify that the data pointed to by icc is indeed a valid profile - // and that it is possibly of one of the Restricted ICC types. The simplest way to check - // this is to verify that the profile signature is correct, that it is an input profile, - // and that the PCS used is XYX. - - // However, a common error in profiles will be to create Monitor profiles rather - // than input profiles. If this is the only error found, it's still useful to let this - // go through with an error written to stderr. - - if (ProfileClass == kdwDisplayProfile) - { - System.String message = "NOTE!! Technically, this profile is a Display profile, not an" + " Input Profile, and thus is not a valid Restricted ICC profile." + " However, it is quite possible that this profile is usable as" + " a Restricted ICC profile, so this code will ignore this state" + " and proceed with processing."; - - FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, message); - } - - if ((ProfileSignature != kdwProfileSignature) || ((ProfileClass != kdwInputProfile) && (ProfileClass != kdwDisplayProfile)) || (PCSType != kdwXYZData)) - { - throw new ICCProfileInvalidException(); - } - } - - - /// Provide a suitable string representation for the class - public override System.String ToString() - { - System.Text.StringBuilder rep = new System.Text.StringBuilder("[ICCProfile:"); - System.Text.StringBuilder body = new System.Text.StringBuilder(); - body.Append(eol).Append(header); - body.Append(eol).Append(eol).Append(tags); - rep.Append(ColorSpace.indent(" ", body)); - return rep.Append("]").ToString(); - } - - - /// Create a two character hex representation of a byte - /// byte to represent - /// - /// representation - /// - public static System.String toHexString(byte i) - { - System.String rep = (i >= 0 && i < 16?"0":"") + System.Convert.ToString((int) i, 16); - if (rep.Length > 2) - rep = rep.Substring(rep.Length - 2); - return rep; - } - - /// Create a 4 character hex representation of a short - /// short to represent - /// - /// representation - /// - public static System.String toHexString(short i) - { - System.String rep; - - if (i >= 0 && i < 0x10) - rep = "000" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x100) - rep = "00" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x1000) - rep = "0" + System.Convert.ToString((int) i, 16); - else - rep = "" + System.Convert.ToString((int) i, 16); - - if (rep.Length > 4) - rep = rep.Substring(rep.Length - 4); - return rep; - } - - - /// Create a 8 character hex representation of a int - /// int to represent - /// - /// representation - /// - public static System.String toHexString(int i) - { - System.String rep; - - if (i >= 0 && i < 0x10) - rep = "0000000" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x100) - rep = "000000" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x1000) - rep = "00000" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x10000) - rep = "0000" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x100000) - rep = "000" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x1000000) - rep = "00" + System.Convert.ToString((int) i, 16); - else if (i >= 0 && i < 0x10000000) - rep = "0" + System.Convert.ToString((int) i, 16); - else - rep = "" + System.Convert.ToString((int) i, 16); - - if (rep.Length > 8) - rep = rep.Substring(rep.Length - 8); - return rep; - } - - public static System.String ToString(byte[] data) - { - - int i, row, col, rem, rows, cols; - - System.Text.StringBuilder rep = new System.Text.StringBuilder(); - System.Text.StringBuilder rep0 = null; - System.Text.StringBuilder rep1 = null; - System.Text.StringBuilder rep2 = null; - - cols = 16; - rows = data.Length / cols; - rem = data.Length % cols; - - byte[] lbytes = new byte[8]; - for (row = 0, i = 0; row < rows; ++row) - { - rep1 = new System.Text.StringBuilder(); - rep2 = new System.Text.StringBuilder(); - - for (i = 0; i < 8; ++i) - lbytes[i] = 0; - byte[] tbytes = System.Text.ASCIIEncoding.ASCII.GetBytes(System.Convert.ToString(row * 16, 16)); - for (int t = 0, l = lbytes.Length - tbytes.Length; t < tbytes.Length; ++l, ++t) - lbytes[l] = tbytes[t]; - - rep0 = new System.Text.StringBuilder(new System.String(SupportClass.ToCharArray(lbytes))); - - for (col = 0; col < cols; ++col) - { - byte b = data[i++]; - rep1.Append(toHexString(b)).Append(i % 2 == 0?" ":""); - if ((System.Char.IsLetter((char) b) || ((char) b).CompareTo('$') == 0 || ((char) b).CompareTo('_') == 0)) - rep2.Append((char) b); - else - rep2.Append("."); - } - rep.Append(rep0).Append(" : ").Append(rep1).Append(": ").Append(rep2).Append(eol); - } - - rep1 = new System.Text.StringBuilder(); - rep2 = new System.Text.StringBuilder(); - - for (i = 0; i < 8; ++i) - lbytes[i] = 0; - byte[] tbytes2 = System.Text.ASCIIEncoding.ASCII.GetBytes(System.Convert.ToString(row * 16, 16)); - for (int t = 0, l = lbytes.Length - tbytes2.Length; t < tbytes2.Length; ++l, ++t) - lbytes[l] = tbytes2[t]; - - rep0 = new System.Text.StringBuilder(System.Text.ASCIIEncoding.ASCII.GetString(lbytes)); - - for (col = 0; col < rem; ++col) - { - byte b = data[i++]; - rep1.Append(toHexString(b)).Append(i % 2 == 0?" ":""); - if ((System.Char.IsLetter((char) b) || ((char) b).CompareTo('$') == 0 || ((char) b).CompareTo('_') == 0)) - rep2.Append((char) b); - else - rep2.Append("."); - } - for (col = rem; col < 16; ++col) - rep1.Append(" ").Append(col % 2 == 0?" ":""); - - rep.Append(rep0).Append(" : ").Append(rep1).Append(": ").Append(rep2).Append(eol); - - return rep.ToString(); - } - - /// Parse this ICCProfile into a RestrictedICCProfile - /// which is appropriate to the data in this profile. - /// Either a MonochromeInputRestrictedProfile or - /// MatrixBasedRestrictedProfile is returned - /// - /// RestrictedICCProfile - /// - /// no curve data - /// - public virtual RestrictedICCProfile parse() - { - - // The next step is to determine which Restricted ICC type is used by this profile. - // Unfortunately, the only way to do this is to look through the tag table for - // the tags required by the two types. - - // First look for the gray TRC tag. If the profile is indeed an input profile, and this - // tag exists, then the profile is a Monochrome Input profile - - ICCCurveType grayTag = (ICCCurveType) tags[(System.Int32) kdwGrayTRCTag]; - if (grayTag != null) - { - return RestrictedICCProfile.createInstance(grayTag); - } - - // If it wasn't a Monochrome Input profile, look for the Red Colorant tag. If that - // tag is found and the profile is indeed an input profile, then this profile is - // a Three-Component Matrix-Based Input profile - - ICCCurveType rTRCTag = (ICCCurveType) tags[(System.Int32) kdwRedTRCTag]; - - - if (rTRCTag != null) - { - ICCCurveType gTRCTag = (ICCCurveType) tags[(System.Int32) kdwGreenTRCTag]; - ICCCurveType bTRCTag = (ICCCurveType) tags[(System.Int32) kdwBlueTRCTag]; - ICCXYZType rColorantTag = (ICCXYZType) tags[(System.Int32) kdwRedColorantTag]; - ICCXYZType gColorantTag = (ICCXYZType) tags[(System.Int32) kdwGreenColorantTag]; - ICCXYZType bColorantTag = (ICCXYZType) tags[(System.Int32) kdwBlueColorantTag]; - return RestrictedICCProfile.createInstance(rTRCTag, gTRCTag, bTRCTag, rColorantTag, gColorantTag, bColorantTag); - } - - throw new ICCProfileInvalidException("curve data not found in profile"); - } - - /// Output this ICCProfile to a RandomAccessFile - /// output file - /// - //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public virtual void write(System.IO.FileStream os) - { - Header.write(os); - TagTable.write(os); - } - - - /* end class ICCProfile */ - static ICCProfile() - { - kdwProfileSignature = GetTagInt("acsp"); - kdwProfileSigReverse = GetTagInt("psca"); - kdwInputProfile = GetTagInt("scnr"); - kdwDisplayProfile = GetTagInt("mntr"); - kdwRGBData = GetTagInt("RGB "); - kdwGrayData = GetTagInt("GRAY"); - kdwXYZData = GetTagInt("XYZ "); + return new ICCDateTime(wYear, wMonth, wDay, wHours, wMinutes, wSeconds); + } - kdwGrayTRCTag = GetTagInt("kTRC"); + + /// Create a String from a byte []. Optionally swap adjacent byte + /// pairs. Intended to be used to create integer String representations + /// allowing for endian translations. + /// + /// data array + /// + /// start of data in array + /// + /// length of data in array + /// + /// swap adjacent bytes? + /// + /// String rep of data + /// + public static string getString(byte[] bfr, int offset, int length, bool swap) + { + + byte[] result = new byte[length]; + int incr = swap ? -1 : 1; + int start = swap ? offset + length - 1 : offset; + for (int i = 0, j = start; i < length; ++i) + { + result[i] = bfr[j]; + j += incr; + } + return new string(SupportClass.ToCharArray(result)); + } + + /// Create a short from a two byte [], with optional byte swapping. + /// data array + /// + /// start of data in array + /// + /// swap bytes? + /// + /// native type from representation. + /// + public static short getShort(byte[] bfr, int off, bool swap) + { + + int tmp0 = bfr[off] & 0xff; // Clear the sign extended bits in the int. + int tmp1 = bfr[off + 1] & 0xff; + + + return (short)(swap ? (tmp1 << BITS_PER_BYTE | tmp0) : (tmp0 << BITS_PER_BYTE | tmp1)); + } + + /// Create a short from a two byte []. + /// data array + /// + /// start of data in array + /// + /// native type from representation. + /// + public static short getShort(byte[] bfr, int off) + { + int tmp0 = bfr[off] & 0xff; // Clear the sign extended bits in the int. + int tmp1 = bfr[off + 1] & 0xff; + return (short)(tmp0 << BITS_PER_BYTE | tmp1); + } + + /// Separate bytes in an int into a byte array lsb to msb order. + /// integer to separate + /// + /// byte [] containing separated int. + /// + public static byte[] setInt(int d) + { + return setInt(d, new byte[BYTES_PER_INT]); + } + + /// Separate bytes in an int into a byte array lsb to msb order. + /// Return the result in the provided array + /// + /// integer to separate + /// + /// return output here. + /// + /// reference to output. + /// + public static byte[] setInt(int d, byte[] b) + { + if (b == null) b = new byte[BYTES_PER_INT]; + for (int i = 0; i < BYTES_PER_INT; ++i) + { + b[i] = (byte)(d & 0x0ff); + d = d >> BITS_PER_BYTE; + } + return b; + } + + /// Separate bytes in a long into a byte array lsb to msb order. + /// long to separate + /// + /// byte [] containing separated int. + /// + public static byte[] setLong(long d) + { + return setLong(d, new byte[BYTES_PER_INT]); + } + + /// Separate bytes in a long into a byte array lsb to msb order. + /// Return the result in the provided array + /// + /// long to separate + /// + /// return output here. + /// + /// reference to output. + /// + public static byte[] setLong(long d, byte[] b) + { + if (b == null) b = new byte[BYTES_PER_LONG]; + for (int i = 0; i < BYTES_PER_LONG; ++i) + { + b[i] = (byte)(d & 0x0ff); + d = d >> BITS_PER_BYTE; + } + return b; + } + + + /// Create an int from a byte [4], with optional byte swapping. + /// data array + /// + /// start of data in array + /// + /// swap bytes? + /// + /// native type from representation. + /// + public static int getInt(byte[] bfr, int off, bool swap) + { + + int tmp0 = getShort(bfr, off, swap) & 0xffff; // Clear the sign extended bits in the int. + int tmp1 = getShort(bfr, off + 2, swap) & 0xffff; + + return swap ? (tmp1 << BITS_PER_SHORT | tmp0) : (tmp0 << BITS_PER_SHORT | tmp1); + } + + /// Create an int from a byte [4]. + /// data array + /// + /// start of data in array + /// + /// native type from representation. + /// + public static int getInt(byte[] bfr, int off) + { + + int tmp0 = getShort(bfr, off) & 0xffff; // Clear the sign extended bits in the int. + int tmp1 = getShort(bfr, off + 2) & 0xffff; + + return tmp0 << BITS_PER_SHORT | tmp1; + } + + /// Create an long from a byte [8]. + /// data array + /// + /// start of data in array + /// + /// native type from representation. + /// + public static long getLong(byte[] bfr, int off) + { + + long tmp0 = getInt(bfr, off) & unchecked((int)0xffffffff); // Clear the sign extended bits in the int. + long tmp1 = getInt(bfr, off + 4) & unchecked((int)0xffffffff); + + return tmp0 << BITS_PER_INT | tmp1; + } + + + /// signature + // Define the set of standard signature and type values + // Because of the endian issues and byte swapping, the profile codes must + // be stored in memory and be addressed by address. As such, only those + // codes required for Restricted ICC use are defined here + + public static readonly int kdwProfileSignature; + + /// signature + public static readonly int kdwProfileSigReverse; + + /// profile type + public static readonly int kdwInputProfile; + + /// tag type + public static readonly int kdwDisplayProfile; + + /// tag type + public static readonly int kdwRGBData; + + /// tag type + public static readonly int kdwGrayData; + + /// tag type + public static readonly int kdwXYZData; + + /// input type + public const int kMonochromeInput = 0; + + /// input type + public const int kThreeCompInput = 1; + + /// tag signature + public static readonly int kdwGrayTRCTag; + + /// tag signature + public static readonly int kdwRedColorantTag; + + /// tag signature + public static readonly int kdwGreenColorantTag; + + /// tag signature + public static readonly int kdwBlueColorantTag; + + /// tag signature + public static readonly int kdwRedTRCTag; + + /// tag signature + public static readonly int kdwGreenTRCTag; + + /// tag signature + public static readonly int kdwBlueTRCTag; + + /// tag signature + public static readonly int kdwCopyrightTag; + + /// tag signature + public static readonly int kdwMediaWhiteTag; + + /// tag signature + public static readonly int kdwProfileDescTag; + + + private ICCProfileHeader header = null; + + private ICCTagTable tags = null; + + private byte[] profile = null; + + //private byte[] data = null; + private ParameterList pl = null; + + private ICCProfile() + { + throw new ICCProfileException("illegal to invoke empty constructor"); + } + + /// ParameterList constructor + /// provides colorspace information + /// + protected internal ICCProfile(ColorSpace csm) + { + this.pl = csm.pl; + profile = csm.ICCProfile; + initProfile(profile); + } + + /// Read the header and tags into memory and verify + /// that the correct type of profile is being used. for encoding. + /// + /// ICCProfile + /// + /// for bad signature and class and bad type + /// + private void initProfile(byte[] data) + { + header = new ICCProfileHeader(data); + tags = ICCTagTable.createInstance(data); + + + // Verify that the data pointed to by icc is indeed a valid profile + // and that it is possibly of one of the Restricted ICC types. The simplest way to check + // this is to verify that the profile signature is correct, that it is an input profile, + // and that the PCS used is XYX. + + // However, a common error in profiles will be to create Monitor profiles rather + // than input profiles. If this is the only error found, it's still useful to let this + // go through with an error written to stderr. + + if (ProfileClass == kdwDisplayProfile) + { + string message = "NOTE!! Technically, this profile is a Display profile, not an" + + " Input Profile, and thus is not a valid Restricted ICC profile." + + " However, it is quite possible that this profile is usable as" + + " a Restricted ICC profile, so this code will ignore this state" + + " and proceed with processing."; + + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, message); + } + + if ((ProfileSignature != kdwProfileSignature) + || ((ProfileClass != kdwInputProfile) && (ProfileClass != kdwDisplayProfile)) || (PCSType != kdwXYZData)) + { + throw new ICCProfileInvalidException(); + } + } + + + /// Provide a suitable string representation for the class + public override string ToString() + { + StringBuilder rep = new StringBuilder("[ICCProfile:"); + StringBuilder body = new StringBuilder(); + body.Append(eol).Append(header); + body.Append(eol).Append(eol).Append(tags); + rep.Append(ColorSpace.indent(" ", body)); + return rep.Append("]").ToString(); + } + + + /// Create a two character hex representation of a byte + /// byte to represent + /// + /// representation + /// + public static string toHexString(byte i) + { + string rep = (i >= 0 && i < 16 ? "0" : "") + System.Convert.ToString((int)i, 16); + if (rep.Length > 2) rep = rep.Substring(rep.Length - 2); + return rep; + } + + /// Create a 4 character hex representation of a short + /// short to represent + /// + /// representation + /// + public static string toHexString(short i) + { + string rep; + + if (i >= 0 && i < 0x10) rep = "000" + System.Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x100) rep = "00" + System.Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x1000) rep = "0" + System.Convert.ToString((int)i, 16); + else rep = "" + System.Convert.ToString((int)i, 16); + + if (rep.Length > 4) rep = rep.Substring(rep.Length - 4); + return rep; + } + + + /// Create a 8 character hex representation of a int + /// int to represent + /// + /// representation + /// + public static string toHexString(int i) + { + string rep; + + if (i >= 0 && i < 0x10) rep = "0000000" + Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x100) rep = "000000" + Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x1000) rep = "00000" + Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x10000) rep = "0000" + Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x100000) rep = "000" + Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x1000000) rep = "00" + Convert.ToString((int)i, 16); + else if (i >= 0 && i < 0x10000000) rep = "0" + Convert.ToString((int)i, 16); + else rep = "" + Convert.ToString((int)i, 16); + + if (rep.Length > 8) rep = rep.Substring(rep.Length - 8); + return rep; + } + + public static string ToString(byte[] data) + { + + int i, row, col, rem, rows, cols; + + StringBuilder rep = new StringBuilder(); + StringBuilder rep0 = null; + StringBuilder rep1 = null; + StringBuilder rep2 = null; + + cols = 16; + rows = data.Length / cols; + rem = data.Length % cols; + + byte[] lbytes = new byte[8]; + for (row = 0, i = 0; row < rows; ++row) + { + rep1 = new StringBuilder(); + rep2 = new StringBuilder(); + + for (i = 0; i < 8; ++i) lbytes[i] = 0; + byte[] tbytes = Encoding.UTF8.GetBytes(Convert.ToString(row * 16, 16)); + for (int t = 0, l = lbytes.Length - tbytes.Length; t < tbytes.Length; ++l, ++t) lbytes[l] = tbytes[t]; + + rep0 = new StringBuilder(new string(SupportClass.ToCharArray(lbytes))); + + for (col = 0; col < cols; ++col) + { + byte b = data[i++]; + rep1.Append(toHexString(b)).Append(i % 2 == 0 ? " " : ""); + if ((char.IsLetter((char)b) || ((char)b).CompareTo('$') == 0 || ((char)b).CompareTo('_') == 0)) rep2.Append((char)b); + else rep2.Append("."); + } + rep.Append(rep0).Append(" : ").Append(rep1).Append(": ").Append(rep2).Append(eol); + } + + rep1 = new System.Text.StringBuilder(); + rep2 = new System.Text.StringBuilder(); + + for (i = 0; i < 8; ++i) lbytes[i] = 0; + byte[] tbytes2 = System.Text.Encoding.UTF8.GetBytes(System.Convert.ToString(row * 16, 16)); + for (int t = 0, l = lbytes.Length - tbytes2.Length; t < tbytes2.Length; ++l, ++t) lbytes[l] = tbytes2[t]; + + rep0 = new StringBuilder(System.Text.Encoding.UTF8.GetString(lbytes, 0, lbytes.Length)); + + for (col = 0; col < rem; ++col) + { + byte b = data[i++]; + rep1.Append(toHexString(b)).Append(i % 2 == 0 ? " " : ""); + if ((char.IsLetter((char)b) || ((char)b).CompareTo('$') == 0 || ((char)b).CompareTo('_') == 0)) rep2.Append((char)b); + else rep2.Append("."); + } + for (col = rem; col < 16; ++col) rep1.Append(" ").Append(col % 2 == 0 ? " " : ""); + + rep.Append(rep0).Append(" : ").Append(rep1).Append(": ").Append(rep2).Append(eol); + + return rep.ToString(); + } + + /// Parse this ICCProfile into a RestrictedICCProfile + /// which is appropriate to the data in this profile. + /// Either a MonochromeInputRestrictedProfile or + /// MatrixBasedRestrictedProfile is returned + /// + /// RestrictedICCProfile + /// + /// no curve data + /// + public virtual RestrictedICCProfile parse() + { + // The next step is to determine which Restricted ICC type is used by this profile. + // Unfortunately, the only way to do this is to look through the tag table for + // the tags required by the two types. + + // First look for the gray TRC tag. If the profile is indeed an input profile, and this + // tag exists, then the profile is a Monochrome Input profile + ICCTag grayTag; + if (tags.TryGetValue(kdwGrayTRCTag, out grayTag)) + { + return RestrictedICCProfile.createInstance((ICCCurveType)grayTag); + } + + // If it wasn't a Monochrome Input profile, look for the Red Colorant tag. If that + // tag is found and the profile is indeed an input profile, then this profile is + // a Three-Component Matrix-Based Input profile + ICCCurveType rTRCTag = (ICCCurveType)tags[(System.Int32)kdwRedTRCTag]; + + + if (rTRCTag != null) + { + ICCCurveType gTRCTag = (ICCCurveType)tags[kdwGreenTRCTag]; + ICCCurveType bTRCTag = (ICCCurveType)tags[kdwBlueTRCTag]; + ICCXYZType rColorantTag = (ICCXYZType)tags[kdwRedColorantTag]; + ICCXYZType gColorantTag = (ICCXYZType)tags[kdwGreenColorantTag]; + ICCXYZType bColorantTag = (ICCXYZType)tags[kdwBlueColorantTag]; + return RestrictedICCProfile.createInstance( + rTRCTag, + gTRCTag, + bTRCTag, + rColorantTag, + gColorantTag, + bColorantTag); + } + + throw new ICCProfileInvalidException("curve data not found in profile"); + } + + /// Output this ICCProfile to a RandomAccessFile + /// output file + /// + public virtual void write(Stream os) + { + Header.write(os); + TagTable.write(os); + } + + + /* end class ICCProfile */ + + static ICCProfile() + { + kdwProfileSignature = GetTagInt("acsp"); + kdwProfileSigReverse = GetTagInt("psca"); + kdwInputProfile = GetTagInt("scnr"); + kdwDisplayProfile = GetTagInt("mntr"); + kdwRGBData = GetTagInt("RGB "); + kdwGrayData = GetTagInt("GRAY"); + kdwXYZData = GetTagInt("XYZ "); + + kdwGrayTRCTag = GetTagInt("kTRC"); kdwRedColorantTag = GetTagInt("rXYZ"); kdwGreenColorantTag = GetTagInt("gXYZ"); kdwBlueColorantTag = GetTagInt("bXYZ"); @@ -962,12 +1000,12 @@ namespace CSJ2K.Icc kdwMediaWhiteTag = GetTagInt("wtpt"); kdwProfileDescTag = GetTagInt("desc"); } - static int GetTagInt(string tag) + + private static int GetTagInt(string tag) { - byte[] tagBytes = ASCIIEncoding.ASCII.GetBytes(tag); + byte[] tagBytes = Encoding.UTF8.GetBytes(tag); Array.Reverse(tagBytes); return BitConverter.ToInt32(tagBytes, 0); } - - } -} \ No newline at end of file + } +} diff --git a/CSJ2K/Icc/ICCProfileException.cs b/CSJ2K/Icc/ICCProfileException.cs index 15c68ec6..5e4f67b9 100644 --- a/CSJ2K/Icc/ICCProfileException.cs +++ b/CSJ2K/Icc/ICCProfileException.cs @@ -20,7 +20,6 @@ namespace CSJ2K.Icc /// /// Bruce A. Kern /// - [Serializable] public class ICCProfileException:System.Exception { diff --git a/CSJ2K/Icc/ICCProfileInvalidException.cs b/CSJ2K/Icc/ICCProfileInvalidException.cs index 4b15a02a..6aa02812 100644 --- a/CSJ2K/Icc/ICCProfileInvalidException.cs +++ b/CSJ2K/Icc/ICCProfileInvalidException.cs @@ -21,7 +21,6 @@ namespace CSJ2K.Icc /// Bruce A. Kern /// - [Serializable] public class ICCProfileInvalidException:ICCProfileException { diff --git a/CSJ2K/Icc/ICCProfileNotFoundException.cs b/CSJ2K/Icc/ICCProfileNotFoundException.cs index 0b800b8c..a719fefd 100644 --- a/CSJ2K/Icc/ICCProfileNotFoundException.cs +++ b/CSJ2K/Icc/ICCProfileNotFoundException.cs @@ -21,7 +21,6 @@ namespace CSJ2K.Icc /// Bruce A. Kern /// - [Serializable] public class ICCProfileNotFoundException:ICCProfileException { diff --git a/CSJ2K/Icc/ICCProfiler.cs b/CSJ2K/Icc/ICCProfiler.cs index b1279ff2..fc1c69ef 100644 --- a/CSJ2K/Icc/ICCProfiler.cs +++ b/CSJ2K/Icc/ICCProfiler.cs @@ -373,7 +373,7 @@ namespace CSJ2K.Icc 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); + SupportClass.WriteStackTrace(e); } else { @@ -387,7 +387,7 @@ namespace CSJ2K.Icc 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); + SupportClass.WriteStackTrace(e); } else { diff --git a/CSJ2K/Icc/Lut/MatrixBasedTransformException.cs b/CSJ2K/Icc/Lut/MatrixBasedTransformException.cs index 7e20ef0d..b20f716c 100644 --- a/CSJ2K/Icc/Lut/MatrixBasedTransformException.cs +++ b/CSJ2K/Icc/Lut/MatrixBasedTransformException.cs @@ -20,7 +20,6 @@ namespace CSJ2K.Icc.Lut /// Bruce A. Kern /// - [Serializable] public class MatrixBasedTransformException:System.Exception { diff --git a/CSJ2K/Icc/Lut/MonochromeTransformException.cs b/CSJ2K/Icc/Lut/MonochromeTransformException.cs index febc4b7a..ab32ddaf 100644 --- a/CSJ2K/Icc/Lut/MonochromeTransformException.cs +++ b/CSJ2K/Icc/Lut/MonochromeTransformException.cs @@ -20,7 +20,6 @@ namespace CSJ2K.Icc.Lut /// Bruce A. Kern /// - [Serializable] public class MonochromeTransformException:System.Exception { diff --git a/CSJ2K/Icc/Tags/ICCTag.cs b/CSJ2K/Icc/Tags/ICCTag.cs index 40d96f54..615bac3a 100644 --- a/CSJ2K/Icc/Tags/ICCTag.cs +++ b/CSJ2K/Icc/Tags/ICCTag.cs @@ -209,10 +209,14 @@ namespace CSJ2K.Icc.Tags return new ICCSignatureType(signature, data, offset, count); else if (type == kdwViewType) return new ICCViewType(signature, data, offset, count); - else if (type == kdwDataType) - return new ICCDataType(signature, data, offset, count); - else - throw new System.ArgumentException("bad tag type: " + System.Text.ASCIIEncoding.ASCII.GetString(BitConverter.GetBytes(type)) + "(" + type + ")"); + else if (type == kdwDataType) + return new ICCDataType(signature, data, offset, count); + else + { + var bytes = BitConverter.GetBytes(type); + throw new System.ArgumentException("bad tag type: " + System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length) + + "(" + type + ")"); + } } @@ -269,7 +273,7 @@ namespace CSJ2K.Icc.Tags } static int GetTagInt(string tag) { - byte[] tagBytes=ASCIIEncoding.ASCII.GetBytes(tag); + byte[] tagBytes=Encoding.UTF8.GetBytes(tag); Array.Reverse(tagBytes); return BitConverter.ToInt32(tagBytes, 0); } diff --git a/CSJ2K/Icc/Tags/ICCTagTable.cs b/CSJ2K/Icc/Tags/ICCTagTable.cs index 77934631..7af2aedc 100644 --- a/CSJ2K/Icc/Tags/ICCTagTable.cs +++ b/CSJ2K/Icc/Tags/ICCTagTable.cs @@ -7,6 +7,7 @@ /// *************************************************************************** /// using System; +using System.IO; using ColorSpace = CSJ2K.Color.ColorSpace; using ICCProfile = CSJ2K.Icc.ICCProfile; using ICCProfileHeader = CSJ2K.Icc.Types.ICCProfileHeader; @@ -31,8 +32,7 @@ namespace CSJ2K.Icc.Tags /// /// Bruce A. Kern /// - [Serializable] - public class ICCTagTable:System.Collections.Hashtable + public class ICCTagTable:System.Collections.Generic.Dictionary { //UPGRADE_NOTE: Final was removed from the declaration of 'eol '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" private static readonly System.String eol = System.Environment.NewLine; @@ -44,7 +44,7 @@ namespace CSJ2K.Icc.Tags private static readonly int offTags; //UPGRADE_NOTE: Final was removed from the declaration of 'trios '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private System.Collections.ArrayList trios = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + private System.Collections.Generic.List trios = new System.Collections.Generic.List(10); private int tagCount; @@ -127,17 +127,14 @@ namespace CSJ2K.Icc.Tags } - System.Collections.IEnumerator Enum = trios.GetEnumerator(); + System.Collections.Generic.IEnumerator Enum = trios.GetEnumerator(); //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'" while (Enum.MoveNext()) { //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'" Triplet trio = (Triplet) Enum.Current; ICCTag tag = ICCTag.createInstance(trio.signature, data, trio.offset, trio.count); - System.Object tempObject; - tempObject = this[(System.Int32) tag.signature]; this[(System.Int32) tag.signature] = tag; - System.Object generatedAux2 = tempObject; } } @@ -148,7 +145,7 @@ namespace CSJ2K.Icc.Tags /// /// //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public virtual void write(System.IO.FileStream raf) + public virtual void write(System.IO.Stream raf) { int ntags = trios.Count; diff --git a/CSJ2K/Icc/Tags/ICCTextDescriptionType.cs b/CSJ2K/Icc/Tags/ICCTextDescriptionType.cs index 78543b12..c94de4fc 100644 --- a/CSJ2K/Icc/Tags/ICCTextDescriptionType.cs +++ b/CSJ2K/Icc/Tags/ICCTextDescriptionType.cs @@ -62,7 +62,7 @@ namespace CSJ2K.Icc.Tags /// Return the string rep of this tag. public override System.String ToString() { - return "[" + base.ToString() + " \"" + System.Text.ASCIIEncoding.ASCII.GetString(ascii) + "\"]"; + return "[" + base.ToString() + " \"" + System.Text.Encoding.UTF8.GetString(ascii, 0, ascii.Length) + "\"]"; } /* end class ICCTextDescriptionType */ diff --git a/CSJ2K/Icc/Tags/ICCTextType.cs b/CSJ2K/Icc/Tags/ICCTextType.cs index 4fcb7142..999b6d77 100644 --- a/CSJ2K/Icc/Tags/ICCTextType.cs +++ b/CSJ2K/Icc/Tags/ICCTextType.cs @@ -56,7 +56,7 @@ namespace CSJ2K.Icc.Tags /// Return the string rep of this tag. public override System.String ToString() { - return "[" + base.ToString() + " \"" + System.Text.ASCIIEncoding.ASCII.GetString(ascii, 0, ascii.Length) + "\"]"; + return "[" + base.ToString() + " \"" + System.Text.Encoding.UTF8.GetString(ascii, 0, ascii.Length) + "\"]"; } /* end class ICCTextType */ diff --git a/CSJ2K/Icc/Tags/ICCXYZType.cs b/CSJ2K/Icc/Tags/ICCXYZType.cs index 1491c3b9..c732ca83 100644 --- a/CSJ2K/Icc/Tags/ICCXYZType.cs +++ b/CSJ2K/Icc/Tags/ICCXYZType.cs @@ -75,7 +75,7 @@ namespace CSJ2K.Icc.Tags /// Write to a file. //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public virtual void write(System.IO.FileStream raf) + public virtual void write(System.IO.Stream raf) { byte[] xb = ICCProfile.setLong(x); byte[] yb = ICCProfile.setLong(y); diff --git a/CSJ2K/Icc/Types/ICCDateTime.cs b/CSJ2K/Icc/Types/ICCDateTime.cs index ae9884bd..ecb5ef18 100644 --- a/CSJ2K/Icc/Types/ICCDateTime.cs +++ b/CSJ2K/Icc/Types/ICCDateTime.cs @@ -51,7 +51,7 @@ namespace CSJ2K.Icc.Types /// Write an ICCDateTime to a file. //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public virtual void write(System.IO.FileStream raf) + public virtual void write(System.IO.Stream raf) { System.IO.BinaryWriter temp_BinaryWriter; temp_BinaryWriter = new System.IO.BinaryWriter(raf); diff --git a/CSJ2K/Icc/Types/ICCProfileHeader.cs b/CSJ2K/Icc/Types/ICCProfileHeader.cs index aaaaa4c0..34055639 100644 --- a/CSJ2K/Icc/Types/ICCProfileHeader.cs +++ b/CSJ2K/Icc/Types/ICCProfileHeader.cs @@ -40,10 +40,10 @@ namespace CSJ2K.Icc.Types * those codes required for Restricted ICC use are defined here. */ /// Profile header signature - private static int kdwProfileSignature = ICCProfile.getInt(System.Text.ASCIIEncoding.ASCII.GetBytes("acsp"), 0); + private static int kdwProfileSignature = ICCProfile.getInt(System.Text.Encoding.UTF8.GetBytes("acsp"), 0); /// Profile header signature - public static int kdwProfileSigReverse = ICCProfile.getInt(System.Text.ASCIIEncoding.ASCII.GetBytes("psca"),0); + public static int kdwProfileSigReverse = ICCProfile.getInt(System.Text.Encoding.UTF8.GetBytes("psca"),0); private const System.String kdwInputProfile = "scnr"; private const System.String kdwDisplayProfile = "mntr"; @@ -177,7 +177,7 @@ namespace CSJ2K.Icc.Types /// /// //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public virtual void write(System.IO.FileStream raf) + public virtual void write(System.IO.Stream raf) { raf.Seek(offProfileSize, System.IO.SeekOrigin.Begin); raf.WriteByte((System.Byte) dwProfileSize); diff --git a/CSJ2K/Icc/Types/ICCProfileVersion.cs b/CSJ2K/Icc/Types/ICCProfileVersion.cs index 5616e00f..c94290b7 100644 --- a/CSJ2K/Icc/Types/ICCProfileVersion.cs +++ b/CSJ2K/Icc/Types/ICCProfileVersion.cs @@ -48,7 +48,7 @@ namespace CSJ2K.Icc.Types /// Construct from file content. //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public virtual void write(System.IO.FileStream raf) + public virtual void write(System.IO.Stream raf) { raf.WriteByte(uMajor); raf.WriteByte(uMinor); raf.WriteByte(reserved1); raf.WriteByte(reserved2); } diff --git a/CSJ2K/Icc/Types/XYZNumber.cs b/CSJ2K/Icc/Types/XYZNumber.cs index ffcdbb71..6f505ab7 100644 --- a/CSJ2K/Icc/Types/XYZNumber.cs +++ b/CSJ2K/Icc/Types/XYZNumber.cs @@ -57,7 +57,7 @@ namespace CSJ2K.Icc.Types /// Write to a file //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public virtual void write(System.IO.FileStream raf) + public virtual void write(System.IO.Stream raf) { System.IO.BinaryWriter temp_BinaryWriter; temp_BinaryWriter = new System.IO.BinaryWriter(raf); diff --git a/CSJ2K/J2KEncoder.cs b/CSJ2K/J2KEncoder.cs index 6d86b9c3..614bf8e1 100644 --- a/CSJ2K/J2KEncoder.cs +++ b/CSJ2K/J2KEncoder.cs @@ -118,13 +118,13 @@ namespace CSJ2K for (int i = 0; i < parameters.Length; i++) { string[] param = parameters[i]; - pl.Set(param[0], param[3]); + pl.Add(param[0], param[3]); } // Custom parameters - pl.Set("Aptype", "layer"); - pl.Set("Qguard_bits", "1"); - pl.Set("Alayers", "sl"); + pl.Add("Aptype", "layer"); + pl.Add("Qguard_bits", "1"); + pl.Add("Alayers", "sl"); //pl.Set("lossless", "on"); } diff --git a/CSJ2K/J2kImage.cs b/CSJ2K/J2kImage.cs index 82e7fead..2514d403 100644 --- a/CSJ2K/J2kImage.cs +++ b/CSJ2K/J2kImage.cs @@ -1,55 +1,70 @@ -#region Using Statements -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; -using CSJ2K; -using CSJ2K.Color; -using CSJ2K.Icc; -using CSJ2K.j2k; -using CSJ2K.j2k.codestream; -using CSJ2K.j2k.codestream.reader; -using CSJ2K.j2k.decoder; -using CSJ2K.j2k.entropy.decoder; -using CSJ2K.j2k.fileformat.reader; -using CSJ2K.j2k.image; -using CSJ2K.j2k.image.invcomptransf; -using CSJ2K.j2k.io; -using CSJ2K.j2k.quantization.dequantizer; -using CSJ2K.j2k.roi; -using CSJ2K.j2k.util; -using CSJ2K.j2k.wavelet.synthesis; -#endregion +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +using System.Linq; namespace CSJ2K { + using System; + using System.Collections.Generic; + using System.IO; + using System.Text; + + using CSJ2K.Color; + using CSJ2K.Icc; + using CSJ2K.j2k.codestream; + using CSJ2K.j2k.codestream.reader; + using CSJ2K.j2k.codestream.writer; + using CSJ2K.j2k.decoder; + using CSJ2K.j2k.encoder; + using CSJ2K.j2k.entropy.decoder; + using CSJ2K.j2k.entropy.encoder; + using CSJ2K.j2k.fileformat.reader; + using CSJ2K.j2k.fileformat.writer; + using CSJ2K.j2k.image; + using CSJ2K.j2k.image.forwcomptransf; + using CSJ2K.j2k.image.input; + using CSJ2K.j2k.image.invcomptransf; + using CSJ2K.j2k.io; + using CSJ2K.j2k.quantization.dequantizer; + using CSJ2K.j2k.quantization.quantizer; + using CSJ2K.j2k.roi; + using CSJ2K.j2k.roi.encoder; + using CSJ2K.j2k.util; + using CSJ2K.j2k.wavelet.analysis; + using CSJ2K.j2k.wavelet.synthesis; + using CSJ2K.Util; + public class J2kImage { + #region Static Decoder Methods - public static Image FromFile(string filename) + + public static PortableImage FromFile(string filename, ParameterList parameters = null) { - Stream stream = new FileStream(filename, FileMode.Open, FileAccess.Read); - Image img = FromStream(stream); - stream.Close(); - return (img); + using (var stream = FileStreamFactory.New(filename, "r")) + { + return FromStream(stream, parameters); + } } - public static Image FromBytes(byte[] j2kdata) + public static PortableImage FromBytes(byte[] j2kdata, ParameterList parameters = null) { - return FromStream(new MemoryStream(j2kdata)); + using (var stream = new MemoryStream(j2kdata)) + { + return FromStream(stream, parameters); + } } - public static Image FromStream(Stream stream) + public static PortableImage FromStream(Stream stream, ParameterList parameters = null) { RandomAccessIO in_stream = new ISRandomAccessIO(stream); // Initialize default parameters - ParameterList defpl = GetDefaultParameterList(decoder_pinfo); + ParameterList defpl = GetDefaultDecoderParameterList(decoder_pinfo); // Create parameter list using defaults - ParameterList pl = new ParameterList(defpl); + ParameterList pl = parameters ?? new ParameterList(defpl); // **** File Format **** // If the codestream is wrapped in the jp2 fileformat, Read the @@ -75,7 +90,7 @@ namespace CSJ2K } catch (EndOfStreamException e) { - throw new ApplicationException("Codestream too short or bad header, unable to decode.", e); + throw new InvalidOperationException("Codestream too short or bad header, unable to decode.", e); } int nCompCod = hd.NumComps; @@ -93,17 +108,15 @@ namespace CSJ2K BitstreamReaderAgent breader; try { - breader = BitstreamReaderAgent. - createInstance(in_stream, hd, pl, decSpec, - false, hi); + breader = BitstreamReaderAgent.createInstance(in_stream, hd, pl, decSpec, false, hi); } catch (IOException e) { - throw new ApplicationException("Error while reading bit stream header or parsing packets.", e); + throw new InvalidOperationException("Error while reading bit stream header or parsing packets.", e); } catch (ArgumentException e) { - throw new ApplicationException("Cannot instantiate bit stream reader.", e); + throw new InvalidOperationException("Cannot instantiate bit stream reader.", e); } // **** Entropy decoder **** @@ -114,7 +127,7 @@ namespace CSJ2K } catch (ArgumentException e) { - throw new ApplicationException("Cannot instantiate entropy decoder.", e); + throw new InvalidOperationException("Cannot instantiate entropy decoder.", e); } // **** ROI de-scaler **** @@ -125,7 +138,7 @@ namespace CSJ2K } catch (ArgumentException e) { - throw new ApplicationException("Cannot instantiate roi de-scaler.", e); + throw new InvalidOperationException("Cannot instantiate roi de-scaler.", e); } // **** Dequantizer **** @@ -136,7 +149,7 @@ namespace CSJ2K } catch (ArgumentException e) { - throw new ApplicationException("Cannot instantiate dequantizer.", e); + throw new InvalidOperationException("Cannot instantiate dequantizer.", e); } // **** Inverse wavelet transform *** @@ -148,7 +161,7 @@ namespace CSJ2K } catch (ArgumentException e) { - throw new ApplicationException("Cannot instantiate inverse wavelet transform.", e); + throw new InvalidOperationException("Cannot instantiate inverse wavelet transform.", e); } int res = breader.ImgRes; @@ -174,15 +187,16 @@ namespace CSJ2K } catch (ArgumentException e) { - throw new ApplicationException("Could not instantiate ICC profiler.", e); + throw new InvalidOperationException("Could not instantiate ICC profiler.", e); } catch (ColorSpaceException e) { - throw new ApplicationException("Error processing ColorSpace information.", e); + throw new InvalidOperationException("Error processing ColorSpace information.", e); } } else - { // Skip colorspace mapping + { + // Skip colorspace mapping color = ictransf; } @@ -193,25 +207,15 @@ namespace CSJ2K { decodedImage = ictransf; } - int numComps = decodedImage.NumComps; - int bytesPerPixel = numComps; // Assuming 8-bit components + var numComps = decodedImage.NumComps; + var imgWidth = decodedImage.ImgWidth; // **** Copy to Bitmap **** - PixelFormat pixelFormat; - switch (numComps) - { - case 1: - pixelFormat = PixelFormat.Format24bppRgb; break; - case 3: - pixelFormat = PixelFormat.Format24bppRgb; break; - case 4: - case 5: - pixelFormat = PixelFormat.Format32bppArgb; break; - default: - throw new ApplicationException("Unsupported PixelFormat. " + numComps + " components."); - } - Bitmap dst = new Bitmap(decodedImage.ImgWidth, decodedImage.ImgHeight, pixelFormat); + var bitsUsed = new int[numComps]; + for (var j = 0; j < numComps; ++j) bitsUsed[j] = decodedImage.getNomRangeBits(numComps - 1 - j); + + var dst = new PortableImage(imgWidth, decodedImage.ImgHeight, numComps, bitsUsed); Coord numTiles = decodedImage.getNumTiles(null); @@ -227,13 +231,11 @@ namespace CSJ2K int height = decodedImage.getTileCompHeight(tIdx, 0); int width = decodedImage.getTileCompWidth(tIdx, 0); - int tOffx = decodedImage.getCompULX(0) - - (int)Math.Ceiling(decodedImage.ImgULX / - (double)decodedImage.getCompSubsX(0)); + int tOffx = decodedImage.getCompULX(0) + - (int)Math.Ceiling(decodedImage.ImgULX / (double)decodedImage.getCompSubsX(0)); - int tOffy = decodedImage.getCompULY(0) - - (int)Math.Ceiling(decodedImage.ImgULY / - (double)decodedImage.getCompSubsY(0)); + int tOffy = decodedImage.getCompULY(0) + - (int)Math.Ceiling(decodedImage.ImgULY / (double)decodedImage.getCompSubsY(0)); DataBlkInt[] db = new DataBlkInt[numComps]; int[] ls = new int[numComps]; @@ -259,8 +261,7 @@ namespace CSJ2K int[] k = new int[numComps]; for (int i = numComps - 1; i >= 0; i--) k[i] = db[i].offset + width - 1; - int outputBytesPerPixel = Math.Max(3, Math.Min(4, bytesPerPixel)); - byte[] rowvalues = new byte[width * outputBytesPerPixel]; + var rowvalues = new int[width * numComps]; for (int i = width - 1; i >= 0; i--) { @@ -270,371 +271,989 @@ namespace CSJ2K tmp[j] = (db[j].data_array[k[j]--] >> fb[j]) + ls[j]; tmp[j] = (tmp[j] < 0) ? 0 : ((tmp[j] > mv[j]) ? mv[j] : tmp[j]); - if (decodedImage.getNomRangeBits(j) != 8) - tmp[j] = (int)Math.Round(((double)tmp[j] / Math.Pow(2D, (double)decodedImage.getNomRangeBits(j))) * 255D); - } - int offset = i * outputBytesPerPixel; + var offset = i * numComps; switch (numComps) { case 1: - rowvalues[offset + 0] = (byte)tmp[0]; - rowvalues[offset + 1] = (byte)tmp[0]; - rowvalues[offset + 2] = (byte)tmp[0]; + rowvalues[offset + 0] = tmp[0]; break; case 3: - rowvalues[offset + 0] = (byte)tmp[2]; - rowvalues[offset + 1] = (byte)tmp[1]; - rowvalues[offset + 2] = (byte)tmp[0]; + rowvalues[offset + 0] = tmp[2]; + rowvalues[offset + 1] = tmp[1]; + rowvalues[offset + 2] = tmp[0]; break; case 4: - case 5: - rowvalues[offset + 0] = (byte)tmp[2]; - rowvalues[offset + 1] = (byte)tmp[1]; - rowvalues[offset + 2] = (byte)tmp[0]; - rowvalues[offset + 3] = (byte)tmp[3]; + rowvalues[offset + 0] = tmp[3]; + rowvalues[offset + 1] = tmp[2]; + rowvalues[offset + 2] = tmp[1]; + rowvalues[offset + 3] = tmp[0]; break; + default: + throw new InvalidOperationException($"Invalid number of components: {numComps}"); } } - BitmapData dstdata = dst.LockBits( - new System.Drawing.Rectangle(tOffx, tOffy + l, width, 1), - ImageLockMode.WriteOnly, pixelFormat); - - IntPtr ptr = dstdata.Scan0; - System.Runtime.InteropServices.Marshal.Copy(rowvalues, 0, ptr, rowvalues.Length); - dst.UnlockBits(dstdata); + dst.FillRow(tOffx, tOffy + l, imgWidth, rowvalues); } } } + return dst; } - public static List GetLayerBoundaries(Stream stream) - { - RandomAccessIO in_stream = new ISRandomAccessIO(stream); - - // Create parameter list using defaults - ParameterList pl = new ParameterList(GetDefaultParameterList(decoder_pinfo)); - - // **** File Format **** - // If the codestream is wrapped in the jp2 fileformat, Read the - // file format wrapper - FileFormatReader ff = new FileFormatReader(in_stream); - ff.readFileFormat(); - if (ff.JP2FFUsed) - { - in_stream.seek(ff.FirstCodeStreamPos); - } - - // +----------------------------+ - // | Instantiate decoding chain | - // +----------------------------+ - - // **** Header decoder **** - // Instantiate header decoder and read main header - HeaderInfo hi = new HeaderInfo(); - HeaderDecoder hd; - try - { - hd = new HeaderDecoder(in_stream, pl, hi); - } - catch (EndOfStreamException e) - { - throw new ArgumentException("Codestream too short or bad header, unable to decode.", e); - } - - int nCompCod = hd.NumComps; - int nTiles = hi.sizValue.NumTiles; - DecoderSpecs decSpec = hd.DecoderSpecs; - - // Get demixed bitdepths - int[] depth = new int[nCompCod]; - for (int i = 0; i < nCompCod; i++) - { - depth[i] = hd.getOriginalBitDepth(i); - } - - // **** Bit stream reader **** - BitstreamReaderAgent breader; - try - { - breader = BitstreamReaderAgent.createInstance(in_stream, hd, pl, decSpec, false, hi); - } - catch (IOException e) - { - throw new ArgumentException("Error while reading bit stream header or parsing packets.", e); - } - catch (ArgumentException e) - { - throw new ArgumentException("Cannot instantiate bit stream reader.", e); - } - - breader.setTile(0, 0); - - return ((FileBitstreamReaderAgent)breader).layerStarts; - } - #endregion #region Static Encoder Methods - public static void ToFile(Bitmap bitmap, string filename) + public static BlkImgDataSrc CreateEncodableSource(Stream stream) { - using (FileStream stream = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite)) - { - ToStream(bitmap, stream); - } + return CreateEncodableSource(new[] { stream }); } - public static byte[] ToArray(Bitmap bitmap) + + public static BlkImgDataSrc CreateEncodableSource(IEnumerable streams) { - using (MemoryStream stream = new MemoryStream()) + if (streams == null) { - ToStream(bitmap, stream); - return stream.ToArray(); + throw new ArgumentNullException("streams"); } + + var counter = 0; + var ncomp = 0; + var ppminput = false; + var imageReaders = new List(); + + foreach (var stream in streams) + { + ++counter; + var imgType = GetImageType(stream); + + switch (imgType) + { + case "P5": + imageReaders.Add(new ImgReaderPGM(stream)); + ncomp += 1; + break; + case "P6": + imageReaders.Add(new ImgReaderPPM(stream)); + ncomp += 3; + ppminput = true; + break; + case "PG": + imageReaders.Add(new ImgReaderPGX(stream)); + ncomp += 1; + break; + default: + throw new ArgumentOutOfRangeException("streams", "Invalid image type"); + } + } + + if (ppminput && counter > 1) + { + error("With PPM input format only 1 input file can be specified", 2); + return null; + } + + BlkImgDataSrc imgsrc; + + // **** ImgDataJoiner (if needed) **** + if (ppminput || ncomp == 1) + { + // Just one input + imgsrc = imageReaders[0]; + } + else + { + // More than one reader => join all readers into 1 + var imgcmpidxs = new int[ncomp]; + imgsrc = new ImgDataJoiner(imageReaders, imgcmpidxs); + } + + return imgsrc; } - public static void ToStream(Bitmap bitmap, Stream stream) + + public static byte[] ToBytes(object imageObject, ParameterList parameters = null) { - throw new NotImplementedException(); + var imgsrc = ImageFactory.ToPortableImageSource(imageObject); + return ToBytes(imgsrc, parameters); + } + + public static byte[] ToBytes(BlkImgDataSrc imgsrc, ParameterList parameters = null) + { + // Initialize default parameters + ParameterList defpl = GetDefaultEncoderParameterList(encoder_pinfo); + + // Create parameter list using defaults + ParameterList pl = parameters ?? new ParameterList(defpl); + + bool useFileFormat = false; + bool pphTile = false; + bool pphMain = false; + bool tempSop = false; + bool tempEph = false; + + // **** Get general parameters **** + + if (pl.getParameter("file_format").Equals("on")) + { + useFileFormat = true; + if (pl.getParameter("rate") != null && pl.getFloatParameter("rate") != defpl.getFloatParameter("rate")) + { + warning("Specified bit-rate applies only on the codestream but not on the whole file."); + } + } + + if (pl.getParameter("tiles") == null) + { + error("No tiles option specified", 2); + return null; + } + + if (pl.getParameter("pph_tile").Equals("on")) + { + pphTile = true; + + if (pl.getParameter("Psop").Equals("off")) + { + pl["Psop"] = "on"; + tempSop = true; + } + if (pl.getParameter("Peph").Equals("off")) + { + pl["Peph"] = "on"; + tempEph = true; + } + } + + if (pl.getParameter("pph_main").Equals("on")) + { + pphMain = true; + + if (pl.getParameter("Psop").Equals("off")) + { + pl["Psop"] = "on"; + tempSop = true; + } + if (pl.getParameter("Peph").Equals("off")) + { + pl["Peph"] = "on"; + tempEph = true; + } + } + + if (pphTile && pphMain) error("Can't have packed packet headers in both main and" + " tile headers", 2); + + if (pl.getBooleanParameter("lossless") && pl.getParameter("rate") != null + && pl.getFloatParameter("rate") != defpl.getFloatParameter("rate")) throw new ArgumentException("Cannot use '-rate' and " + "'-lossless' option at " + " the same time."); + + if (pl.getParameter("rate") == null) + { + error("Target bitrate not specified", 2); + return null; + } + float rate; + try + { + rate = pl.getFloatParameter("rate"); + if (rate == -1) + { + rate = float.MaxValue; + } + } + catch (FormatException e) + { + error("Invalid value in 'rate' option: " + pl.getParameter("rate"), 2); + return null; + } + int pktspertp; + try + { + pktspertp = pl.getIntParameter("tile_parts"); + if (pktspertp != 0) + { + if (pl.getParameter("Psop").Equals("off")) + { + pl["Psop"] = "on"; + tempSop = true; + } + if (pl.getParameter("Peph").Equals("off")) + { + pl["Peph"] = "on"; + tempEph = true; + } + } + } + catch (FormatException e) + { + error("Invalid value in 'tile_parts' option: " + pl.getParameter("tile_parts"), 2); + return null; + } + + // **** ImgReader **** + var ncomp = imgsrc.NumComps; + var ppminput = imgsrc.NumComps > 1; + + // **** Tiler **** + // get nominal tile dimensions + SupportClass.StreamTokenizerSupport stok = + new SupportClass.StreamTokenizerSupport(new StringReader(pl.getParameter("tiles"))); + stok.EOLIsSignificant(false); + + stok.NextToken(); + if (stok.ttype != SupportClass.StreamTokenizerSupport.TT_NUMBER) + { + error("An error occurred while parsing the tiles option: " + pl.getParameter("tiles"), 2); + return null; + } + var tw = (int)stok.nval; + stok.NextToken(); + if (stok.ttype != SupportClass.StreamTokenizerSupport.TT_NUMBER) + { + error("An error occurred while parsing the tiles option: " + pl.getParameter("tiles"), 2); + return null; + } + var th = (int)stok.nval; + + // Get image reference point + var refs = pl.getParameter("ref").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + int refx; + int refy; + try + { + refx = Int32.Parse(refs[0]); + refy = Int32.Parse(refs[1]); + } + catch (IndexOutOfRangeException e) + { + throw new ArgumentException("Error while parsing 'ref' " + "option"); + } + catch (FormatException e) + { + throw new ArgumentException("Invalid number type in " + "'ref' option"); + } + if (refx < 0 || refy < 0) + { + throw new ArgumentException("Invalid value in 'ref' " + "option "); + } + + // Get tiling reference point + var trefs = pl.getParameter("tref").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + int trefx; + int trefy; + try + { + trefx = Int32.Parse(trefs[0]); + trefy = Int32.Parse(trefs[1]); + } + catch (IndexOutOfRangeException e) + { + throw new ArgumentException("Error while parsing 'tref' " + "option"); + } + catch (FormatException e) + { + throw new ArgumentException("Invalid number type in " + "'tref' option"); + } + if (trefx < 0 || trefy < 0 || trefx > refx || trefy > refy) + { + throw new ArgumentException("Invalid value in 'tref' " + "option "); + } + + // Instantiate tiler + Tiler imgtiler; + try + { + imgtiler = new Tiler(imgsrc, refx, refy, trefx, trefy, tw, th); + } + catch (ArgumentException e) + { + error("Could not tile image" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2); + return null; + } + int ntiles = imgtiler.getNumTiles(); + + // **** Encoder specifications **** + var encSpec = new EncoderSpecs(ntiles, ncomp, imgsrc, pl); + + // **** Component transformation **** + if (ppminput && pl.getParameter("Mct") != null && pl.getParameter("Mct").Equals("off")) + { + FacilityManager.getMsgLogger() + .printmsg( + MsgLogger_Fields.WARNING, + "Input image is RGB and no color transform has " + + "been specified. Compression performance and " + + "image quality might be greatly degraded. Use " + + "the 'Mct' option to specify a color transform"); + } + ForwCompTransf fctransf; + try + { + fctransf = new ForwCompTransf(imgtiler, encSpec); + } + catch (ArgumentException e) + { + error( + "Could not instantiate forward component " + "transformation" + + ((e.Message != null) ? (":\n" + e.Message) : ""), + 2); + return null; + } + + // **** ImgDataConverter **** + var converter = new ImgDataConverter(fctransf); + + + // **** ForwardWT **** + ForwardWT dwt; + try + { + dwt = ForwardWT.createInstance(converter, pl, encSpec); + } + catch (ArgumentException e) + { + error("Could not instantiate wavelet transform" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2); + return null; + } + + // **** Quantizer **** + Quantizer quant; + try + { + quant = Quantizer.createInstance(dwt, encSpec); + } + catch (ArgumentException e) + { + error("Could not instantiate quantizer" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2); + return null; + } + + // **** ROIScaler **** + ROIScaler rois; + try + { + rois = ROIScaler.createInstance(quant, pl, encSpec); + } + catch (ArgumentException e) + { + error("Could not instantiate ROI scaler" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2); + return null; + } + + // **** EntropyCoder **** + EntropyCoder ecoder; + try + { + ecoder = EntropyCoder.createInstance( + rois, + pl, + encSpec.cblks, + encSpec.pss, + encSpec.bms, + encSpec.mqrs, + encSpec.rts, + encSpec.css, + encSpec.sss, + encSpec.lcs, + encSpec.tts); + } + catch (ArgumentException e) + { + error("Could not instantiate entropy coder" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2); + return null; + } + + // **** CodestreamWriter **** + using (var outStream = new MemoryStream()) + { + CodestreamWriter bwriter; + try + { + // Rely on rate allocator to limit amount of data + bwriter = new FileCodestreamWriter(outStream, Int32.MaxValue); + } + catch (IOException e) + { + error("Could not open output file" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2); + return null; + } + + // **** Rate allocator **** + PostCompRateAllocator ralloc; + try + { + ralloc = PostCompRateAllocator.createInstance(ecoder, pl, rate, bwriter, encSpec); + } + catch (ArgumentException e) + { + error("Could not instantiate rate allocator" + ((e.Message != null) ? (":\n" + e.Message) : ""), 2); + return null; + } + + // **** HeaderEncoder **** + var imsigned = Enumerable.Repeat(false, ncomp).ToArray(); // TODO Consider supporting signed components. + var headenc = new HeaderEncoder(imgsrc, imsigned, dwt, imgtiler, encSpec, rois, ralloc, pl); + ralloc.HeaderEncoder = headenc; + + // **** Write header to be able to estimate header overhead **** + headenc.encodeMainHeader(); + + // **** Initialize rate allocator, with proper header + // overhead. This will also encode all the data **** + ralloc.initialize(); + + // **** Write header (final) **** + headenc.reset(); + headenc.encodeMainHeader(); + + // Insert header into the codestream + bwriter.commitBitstreamHeader(headenc); + + // **** Now do the rate-allocation and write result **** + ralloc.runAndWrite(); + + // **** Done **** + bwriter.close(); + + // **** Calculate file length **** + int fileLength = bwriter.Length; + + // **** Tile-parts and packed packet headers **** + if (pktspertp > 0 || pphTile || pphMain) + { + try + { + CodestreamManipulator cm = new CodestreamManipulator( + outStream, + ntiles, + pktspertp, + pphMain, + pphTile, + tempSop, + tempEph); + fileLength += cm.doCodestreamManipulation(); + //String res=""; + if (pktspertp > 0) + { + FacilityManager.getMsgLogger() + .println( + "Created tile-parts " + "containing at most " + pktspertp + " packets per tile.", + 4, + 6); + } + if (pphTile) + { + FacilityManager.getMsgLogger().println("Moved packet headers " + "to tile headers", 4, 6); + } + if (pphMain) + { + FacilityManager.getMsgLogger().println("Moved packet headers " + "to main header", 4, 6); + } + } + catch (IOException e) + { + error( + "Error while creating tileparts or packed packet" + " headers" + + ((e.Message != null) ? (":\n" + e.Message) : ""), + 2); + return null; + } + } + + // **** File Format **** + if (useFileFormat) + { + try + { + int nc = imgsrc.NumComps; + int[] bpc = new int[nc]; + for (int comp = 0; comp < nc; comp++) + { + bpc[comp] = imgsrc.getNomRangeBits(comp); + } + + outStream.Seek(0, SeekOrigin.Begin); + var ffw = new FileFormatWriter( + outStream, + imgsrc.ImgHeight, + imgsrc.ImgWidth, + nc, + bpc, + fileLength); + fileLength += ffw.writeFileFormat(); + } + catch (IOException e) + { + throw new InvalidOperationException("Error while writing JP2 file format: " + e.Message); + } + } + + // **** Close image readers *** + imgsrc.close(); + + return outStream.ToArray(); + } } #endregion - #region Default Parameter Loader - public static ParameterList GetDefaultParameterList(string[][] pinfo) + #region Default Parameter Loaders + + public static ParameterList GetDefaultDecoderParameterList(string[][] pinfo) { ParameterList pl = new ParameterList(); string[][] str; str = BitstreamReaderAgent.ParameterInfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; str = EntropyDecoder.ParameterInfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; str = ROIDeScaler.ParameterInfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; str = Dequantizer.ParameterInfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; str = InvCompTransf.ParameterInfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; str = HeaderDecoder.ParameterInfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; str = ICCProfiler.ParameterInfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; - str = pinfo; - if (str != null) for (int i = str.Length - 1; i >= 0; i--) - pl.Set(str[i][0], str[i][3]); + str = pinfo ?? decoder_pinfo; + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; return pl; } + + public static ParameterList GetDefaultEncoderParameterList(string[][] pinfo) + { + ParameterList pl = new ParameterList(); + string[][] str; + + str = pinfo ?? encoder_pinfo; + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; + + str = ForwCompTransf.ParameterInfo; + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; + + str = AnWTFilter.ParameterInfo; + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; + + str = ForwardWT.ParameterInfo; + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; + + str = Quantizer.ParameterInfo; + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; + + str = ROIScaler.ParameterInfo; + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; + + str = EntropyCoder.ParameterInfo; + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; + + str = HeaderEncoder.ParameterInfo; + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; + + str = PostCompRateAllocator.ParameterInfo; + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; + + str = PktEncoder.ParameterInfo; + if (str != null) for (int i = str.Length - 1; i >= 0; i--) pl[str[i][0]] = str[i][3]; + + return pl; + } + #endregion #region Decoder Parameters - private static String[][] decoder_pinfo = { - new string[] { "u", "[on|off]", - "Prints usage information. "+ - "If specified all other arguments (except 'v') are ignored","off"}, - new string[] { "v", "[on|off]", - "Prints version and copyright information","off"}, - new string[] { "verbose", "[on|off]", - "Prints information about the decoded codestream","on"}, - new string[] { "pfile", "", - "Loads the arguments from the specified file. Arguments that are "+ - "specified on the command line override the ones from the file.\n"+ - "The arguments file is a simple text file with one argument per "+ - "line of the following form:\n" + - " =\n"+ - "If the argument is of boolean type (i.e. its presence turns a "+ - "feature on), then the 'on' value turns it on, while the 'off' "+ - "value turns it off. The argument name does not include the '-' "+ - "or '+' character. Long lines can be broken into several lines "+ - "by terminating them with '\\'. Lines starting with '#' are "+ - "considered as comments. This option is not recursive: any 'pfile' "+ - "argument appearing in the file is ignored.",null}, - new string[] { "res", "", - "The resolution level at which to reconstruct the image "+ - " (0 means the lowest available resolution whereas the maximum "+ - "resolution level corresponds to the original image resolution). "+ - "If the given index"+ - " is greater than the number of available resolution levels of the "+ - "compressed image, the image is reconstructed at its highest "+ - "resolution (among all tile-components). Note that this option"+ - " affects only the inverse wavelet transform and not the number "+ - " of bytes read by the codestream parser: this number of bytes "+ - "depends only on options '-nbytes' or '-rate'.", null}, - new string[] { "i", "", - "The file containing the JPEG 2000 compressed data. This can be "+ - "either a JPEG 2000 codestream or a JP2 file containing a "+ - "JPEG 2000 "+ - "codestream. In the latter case the first codestream in the file "+ - "will be decoded. If an URL is specified (e.g., http://...) "+ - "the data will be downloaded and cached in memory before decoding. "+ - "This is intended for easy use in applets, but it is not a very "+ - "efficient way of decoding network served data.", null}, - new string[] { "o", "", - "This is the name of the file to which the decompressed image "+ - "is written. If no output filename is given, the image is "+ - "displayed on the screen. "+ - "Output file format is PGX by default. If the extension"+ - " is '.pgm' then a PGM file is written as output, however this is "+ - "only permitted if the component bitdepth does not exceed 8. If "+ - "the extension is '.ppm' then a PPM file is written, however this "+ - "is only permitted if there are 3 components and none of them has "+ - "a bitdepth of more than 8. If there is more than 1 component, "+ - "suffices '-1', '-2', '-3', ... are added to the file name, just "+ - "before the extension, except for PPM files where all three "+ - "components are written to the same file.",null}, - new string[] { "rate","", - "Specifies the decoding rate in bits per pixel (bpp) where the "+ - "number of pixels is related to the image's original size (Note:"+ - " this number is not affected by the '-res' option). If it is equal"+ - "to -1, the whole codestream is decoded. "+ - "The codestream is either parsed (default) or truncated depending "+ - "the command line option '-parsing'. To specify the decoding "+ - "rate in bytes, use '-nbytes' options instead.","-1"}, - new string[] { "nbytes","", - "Specifies the decoding rate in bytes. "+ - "The codestream is either parsed (default) or truncated depending "+ - "the command line option '-parsing'. To specify the decoding "+ - "rate in bits per pixel, use '-rate' options instead.","-1"}, - new string[] { "parsing", null, - "Enable or not the parsing mode when decoding rate is specified "+ - "('-nbytes' or '-rate' options). If it is false, the codestream "+ - "is decoded as if it were truncated to the given rate. If it is "+ - "true, the decoder creates, truncates and decodes a virtual layer"+ - " progressive codestream with the same truncation points in each "+ - "code-block.","on"}, - new string[] { "ncb_quit","", - "Use the ncb and lbody quit conditions. If state information is "+ - "found for more code blocks than is indicated with this option, "+ - "the decoder "+ - "will decode using only information found before that point. "+ - "Using this otion implies that the 'rate' or 'nbyte' parameter "+ - "is used to indicate the lbody parameter which is the number of "+ - "packet body bytes the decoder will decode.","-1"}, - new string[] { "l_quit","", - "Specifies the maximum number of layers to decode for any code-"+ - "block","-1"}, - new string[] { "m_quit","", - "Specifies the maximum number of bit planes to decode for any code"+ - "-block","-1"}, - new string[] { "poc_quit",null, - "Specifies the whether the decoder should only decode code-blocks "+ - "included in the first progression order.","off"}, - new string[] { "one_tp",null, - "Specifies whether the decoder should only decode the first "+ - "tile part of each tile.","off"}, - new string[] { "comp_transf",null, - "Specifies whether the component transform indicated in the "+ - "codestream should be used.","on"}, - new string[] { "debug", null, - "Print debugging messages when an error is encountered.","off"}, - new string[] { "cdstr_info", null, - "Display information about the codestream. This information is: "+ - "\n- Marker segments value in main and tile-part headers,"+ - "\n- Tile-part length and position within the code-stream.", "off"}, - new string[] { "nocolorspace",null, - "Ignore any colorspace information in the image.","off"}, - new string[] { "colorspace_debug", null, - "Print debugging messages when an error is encountered in the"+ - " colorspace module.","off"} - }; + + private static String[][] decoder_pinfo = + { + new string[] + { + "u", "[on|off]", + "Prints usage information. " + + "If specified all other arguments (except 'v') are ignored", + "off" + }, + new string[] + { + "v", "[on|off]", "Prints version and copyright information", + "off" + }, + new string[] + { + "verbose", "[on|off]", + "Prints information about the decoded codestream", "on" + }, + new string[] + { + "pfile", "", + "Loads the arguments from the specified file. Arguments that are " + + "specified on the command line override the ones from the file.\n" + + "The arguments file is a simple text file with one argument per " + + "line of the following form:\n" + + " =\n" + + "If the argument is of boolean type (i.e. its presence turns a " + + "feature on), then the 'on' value turns it on, while the 'off' " + + "value turns it off. The argument name does not include the '-' " + + "or '+' character. Long lines can be broken into several lines " + + "by terminating them with '\\'. Lines starting with '#' are " + + "considered as comments. This option is not recursive: any 'pfile' " + + "argument appearing in the file is ignored.", + null + }, + new string[] + { + "res", "", + "The resolution level at which to reconstruct the image " + + " (0 means the lowest available resolution whereas the maximum " + + "resolution level corresponds to the original image resolution). " + + "If the given index" + + " is greater than the number of available resolution levels of the " + + "compressed image, the image is reconstructed at its highest " + + "resolution (among all tile-components). Note that this option" + + " affects only the inverse wavelet transform and not the number " + + " of bytes read by the codestream parser: this number of bytes " + + "depends only on options '-nbytes' or '-rate'.", + null + }, + new string[] + { + "i", "", + "The file containing the JPEG 2000 compressed data. This can be " + + "either a JPEG 2000 codestream or a JP2 file containing a " + + "JPEG 2000 " + + "codestream. In the latter case the first codestream in the file " + + "will be decoded. If an URL is specified (e.g., http://...) " + + "the data will be downloaded and cached in memory before decoding. " + + "This is intended for easy use in applets, but it is not a very " + + "efficient way of decoding network served data.", + null + }, + new string[] + { + "o", "", + "This is the name of the file to which the decompressed image " + + "is written. If no output filename is given, the image is " + + "displayed on the screen. " + + "Output file format is PGX by default. If the extension" + + " is '.pgm' then a PGM file is written as output, however this is " + + "only permitted if the component bitdepth does not exceed 8. If " + + "the extension is '.ppm' then a PPM file is written, however this " + + "is only permitted if there are 3 components and none of them has " + + "a bitdepth of more than 8. If there is more than 1 component, " + + "suffices '-1', '-2', '-3', ... are added to the file name, just " + + "before the extension, except for PPM files where all three " + + "components are written to the same file.", + null + }, + new string[] + { + "rate", "", + "Specifies the decoding rate in bits per pixel (bpp) where the " + + "number of pixels is related to the image's original size (Note:" + + " this number is not affected by the '-res' option). If it is equal" + + "to -1, the whole codestream is decoded. " + + "The codestream is either parsed (default) or truncated depending " + + "the command line option '-parsing'. To specify the decoding " + + "rate in bytes, use '-nbytes' options instead.", + "-1" + }, + new string[] + { + "nbytes", "", + "Specifies the decoding rate in bytes. " + + "The codestream is either parsed (default) or truncated depending " + + "the command line option '-parsing'. To specify the decoding " + + "rate in bits per pixel, use '-rate' options instead.", + "-1" + }, + new string[] + { + "parsing", null, + "Enable or not the parsing mode when decoding rate is specified " + + "('-nbytes' or '-rate' options). If it is false, the codestream " + + "is decoded as if it were truncated to the given rate. If it is " + + "true, the decoder creates, truncates and decodes a virtual layer" + + " progressive codestream with the same truncation points in each " + + "code-block.", + "on" + }, + new string[] + { + "ncb_quit", "", + "Use the ncb and lbody quit conditions. If state information is " + + "found for more code blocks than is indicated with this option, " + + "the decoder " + + "will decode using only information found before that point. " + + "Using this otion implies that the 'rate' or 'nbyte' parameter " + + "is used to indicate the lbody parameter which is the number of " + + "packet body bytes the decoder will decode.", + "-1" + }, + new string[] + { + "l_quit", "", + "Specifies the maximum number of layers to decode for any code-" + + "block", + "-1" + }, + new string[] + { + "m_quit", "", + "Specifies the maximum number of bit planes to decode for any code" + + "-block", + "-1" + }, + new string[] + { + "poc_quit", null, + "Specifies the whether the decoder should only decode code-blocks " + + "included in the first progression order.", + "off" + }, + new string[] + { + "one_tp", null, + "Specifies whether the decoder should only decode the first " + + "tile part of each tile.", + "off" + }, + new string[] + { + "comp_transf", null, + "Specifies whether the component transform indicated in the " + + "codestream should be used.", + "on" + }, + new string[] + { + "debug", null, + "Print debugging messages when an error is encountered.", + "off" + }, + new string[] + { + "cdstr_info", null, + "Display information about the codestream. This information is: " + + "\n- Marker segments value in main and tile-part headers," + + "\n- Tile-part length and position within the code-stream.", + "off" + }, + new string[] + { + "nocolorspace", null, + "Ignore any colorspace information in the image.", "off" + }, + new string[] + { + "colorspace_debug", null, + "Print debugging messages when an error is encountered in the" + + " colorspace module.", + "off" + } + }; + #endregion #region Encoder Parameters - private static String[][] encoder_pinfo = { - new string[] { "debug", null, - "Print debugging messages when an error is encountered.","off"}, - new string[] { "disable_jp2_extension", "[on|off]", - "JJ2000 automatically adds .jp2 extension when using 'file_format'"+ - "option. This option disables it when on.", "off"}, - new string[] { "file_format", "[on|off]", - "Puts the JPEG 2000 codestream in a JP2 file format wrapper.","off"}, - new string[] { "pph_tile", "[on|off]", - "Packs the packet headers in the tile headers.","off"}, - new string[] { "pph_main", "[on|off]", - "Packs the packet headers in the main header.","off"}, - new string[] { "pfile", "", - "Loads the arguments from the specified file. Arguments that are "+ - "specified on the command line override the ones from the file.\n"+ - "The arguments file is a simple text file with one argument per "+ - "line of the following form:\n" + - " =\n"+ - "If the argument is of boolean type (i.e. its presence turns a "+ - "feature on), then the 'on' value turns it on, while the 'off' "+ - "value turns it off. The argument name does not include the '-' "+ - "or '+' character. Long lines can be broken into several lines "+ - "by terminating them with '\'. Lines starting with '#' are "+ - "considered as comments. This option is not recursive: any 'pfile' "+ - "argument appearing in the file is ignored.",null}, - new string[] { "tile_parts", "", - "This option specifies the maximum number of packets to have in "+ - "one tile-part. 0 means include all packets in first tile-part "+ - "of each tile","0"}, - new string[] { "tiles", " ", - "This option specifies the maximum tile dimensions to use. "+ - "If both dimensions are 0 then no tiling is used.","0 0"}, - new string[] { "ref", " ", - "Sets the origin of the image in the canvas system. It sets the "+ - "coordinate of the top-left corner of the image reference grid, "+ - "with respect to the canvas origin","0 0"}, - new string[] { "tref", " ", - "Sets the origin of the tile partitioning on the reference grid, "+ - "with respect to the canvas origin. The value of 'x' ('y') "+ - "specified can not be larger than the 'x' one specified in the ref "+ - "option.","0 0"}, - new string[] { "rate", "", - "This is the output bitrate of the codestream in bits per pixel."+ - " When equal to -1, no image information (beside quantization "+ - "effects) is discarded during compression.\n"+ - "Note: In the case where '-file_format' option is used, the "+ - "resulting file may have a larger bitrate.","-1"}, - new string[] { "lossless", "[on|off]", - "Specifies a lossless compression for the encoder. This options"+ - " is equivalent to use reversible quantization ('-Qtype "+ - "reversible')"+ - " and 5x3 wavelet filters pair ('-Ffilters w5x3'). Note that "+ - "this option cannot be used with '-rate'. When this option is "+ - "off, the quantization type and the filters pair is defined by "+ - "'-Qtype' and '-Ffilters' respectively.","off"}, - new string[] { "i", " [, [, ... ]]", - "Mandatory argument. This option specifies the name of the input "+ - "image files. If several image files are provided, they have to be"+ - " separated by commas in the command line. Supported formats are "+ - "PGM (raw), PPM (raw) and PGX, "+ - "which is a simple extension of the PGM file format for single "+ - "component data supporting arbitrary bitdepths. If the extension "+ - "is '.pgm', PGM-raw file format is assumed, if the extension is "+ - "'.ppm', PPM-raw file format is assumed, otherwise PGX file "+ - "format is assumed. PGM and PPM files are assumed to be 8 bits "+ - "deep. A multi-component image can be specified by either "+ - "specifying several PPM and/or PGX files, or by specifying one "+ - "PPM file.",null}, - new string[] { "o", "", - "Mandatory argument. This option specifies the name of the output "+ - "file to which the codestream will be written.",null}, - new string[] { "verbose", null, - "Prints information about the obtained bit stream.","on"}, - new string[] { "v", "[on|off]", - "Prints version and copyright information.","off"}, - new string[] { "u", "[on|off]", - "Prints usage information. "+ - "If specified all other arguments (except 'v') are ignored","off"}, - }; + + private static String[][] encoder_pinfo = + { + new string[] + { + "debug", null, + "Print debugging messages when an error is encountered.", + "off" + }, + new string[] + { + "disable_jp2_extension", "[on|off]", + "JJ2000 automatically adds .jp2 extension when using 'file_format'" + + "option. This option disables it when on.", + "off" + }, + new string[] + { + "file_format", "[on|off]", + "Puts the JPEG 2000 codestream in a JP2 file format wrapper.", + "on" + }, + new string[] + { + "pph_tile", "[on|off]", + "Packs the packet headers in the tile headers.", "off" + }, + new string[] + { + "pph_main", "[on|off]", + "Packs the packet headers in the main header.", "off" + }, + new string[] + { + "pfile", "", + "Loads the arguments from the specified file. Arguments that are " + + "specified on the command line override the ones from the file.\n" + + "The arguments file is a simple text file with one argument per " + + "line of the following form:\n" + + " =\n" + + "If the argument is of boolean type (i.e. its presence turns a " + + "feature on), then the 'on' value turns it on, while the 'off' " + + "value turns it off. The argument name does not include the '-' " + + "or '+' character. Long lines can be broken into several lines " + + "by terminating them with '\'. Lines starting with '#' are " + + "considered as comments. This option is not recursive: any 'pfile' " + + "argument appearing in the file is ignored.", + null + }, + new string[] + { + "tile_parts", "", + "This option specifies the maximum number of packets to have in " + + "one tile-part. 0 means include all packets in first tile-part " + + "of each tile", + "0" + }, + new string[] + { + "tiles", " ", + "This option specifies the maximum tile dimensions to use. " + + "If both dimensions are 0 then no tiling is used.", + "0 0" + }, + new string[] + { + "ref", " ", + "Sets the origin of the image in the canvas system. It sets the " + + "coordinate of the top-left corner of the image reference grid, " + + "with respect to the canvas origin", + "0 0" + }, + new string[] + { + "tref", " ", + "Sets the origin of the tile partitioning on the reference grid, " + + "with respect to the canvas origin. The value of 'x' ('y') " + + "specified can not be larger than the 'x' one specified in the ref " + + "option.", + "0 0" + }, + new string[] + { + "rate", "", + "This is the output bitrate of the codestream in bits per pixel." + + " When equal to -1, no image information (beside quantization " + + "effects) is discarded during compression.\n" + + "Note: In the case where '-file_format' option is used, the " + + "resulting file may have a larger bitrate.", + "-1" + }, + new string[] + { + "lossless", "[on|off]", + "Specifies a lossless compression for the encoder. This options" + + " is equivalent to use reversible quantization ('-Qtype " + + "reversible')" + + " and 5x3 wavelet filters pair ('-Ffilters w5x3'). Note that " + + "this option cannot be used with '-rate'. When this option is " + + "off, the quantization type and the filters pair is defined by " + + "'-Qtype' and '-Ffilters' respectively.", + "off" + }, + new string[] + { + "i", " [, [, ... ]]", + "Mandatory argument. This option specifies the name of the input " + + "image files. If several image files are provided, they have to be" + + " separated by commas in the command line. Supported formats are " + + "PGM (raw), PPM (raw) and PGX, " + + "which is a simple extension of the PGM file format for single " + + "component data supporting arbitrary bitdepths. If the extension " + + "is '.pgm', PGM-raw file format is assumed, if the extension is " + + "'.ppm', PPM-raw file format is assumed, otherwise PGX file " + + "format is assumed. PGM and PPM files are assumed to be 8 bits " + + "deep. A multi-component image can be specified by either " + + "specifying several PPM and/or PGX files, or by specifying one " + + "PPM file.", + null + }, + new string[] + { + "o", "", + "Mandatory argument. This option specifies the name of the output " + + "file to which the codestream will be written.", + null + }, + new string[] + { + "verbose", null, + "Prints information about the obtained bit stream.", "on" + }, + new string[] + { + "v", "[on|off]", "Prints version and copyright information.", + "off" + }, + new string[] + { + "u", "[on|off]", + "Prints usage information. " + + "If specified all other arguments (except 'v') are ignored", + "off" + }, + }; + #endregion + + /** + * Prints the error message 'msg' to standard err, prepending "ERROR" to + * it, and sets the exitCode to 'code'. An exit code different than 0 + * indicates that there where problems. + * + * @param msg The error message + * + * @param code The exit code to set + * */ + + private static void error(String msg, int code) + { + //exitCode = code; + FacilityManager.getMsgLogger().printmsg(MsgLogger_Fields.ERROR, msg); + } + + /** + * Prints the warning message 'msg' to standard err, prepending "WARNING" + * to it. + * + * @param msg The error message + * */ + + private static void warning(String msg) + { + FacilityManager.getMsgLogger().printmsg(MsgLogger_Fields.WARNING, msg); + } + + private static string GetImageType(Stream inStream) + { + try + { + var bytes = new byte[2]; + inStream.Position = 0; + inStream.Read(bytes, 0, 2); + inStream.Position = 0; + var imgType = Encoding.UTF8.GetString(bytes, 0, 2); + return imgType; + } + catch + { + return null; + } + } } } diff --git a/CSJ2K/J2kSetup.cs b/CSJ2K/J2kSetup.cs new file mode 100644 index 00000000..416bc9f0 --- /dev/null +++ b/CSJ2K/J2kSetup.cs @@ -0,0 +1,128 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + + using CSJ2K.Util; + + /// + /// Setup helper methods for initializing library. + /// + internal static class J2kSetup + { + /// + /// Gets a single instance from the platform assembly implementing the type. + /// + /// (Abstract) type for which implementation is requested. + /// The single instance from the platform assembly implementing the type, + /// or null if no or more than one implementations are available. + /// It is implicitly assumed that implementation class has a public, parameter-less constructor. + internal static T GetSinglePlatformInstance() + { + try + { + var assembly = GetCurrentAssembly(); +#if NETFX_CORE || NETSTANDARD + var type = + assembly.DefinedTypes.Single( + t => (t.IsSubclassOf(typeof(T)) || typeof(T).GetTypeInfo().IsAssignableFrom(t)) && !t.IsAbstract) + .AsType(); +#else + var type = + assembly.GetTypes() + .Single(t => (t.IsSubclassOf(typeof(T)) || typeof(T).IsAssignableFrom(t)) && !t.IsAbstract); +#endif + var instance = (T)Activator.CreateInstance(type); + + return instance; + } + catch (Exception) + { + return default(T); + } + } + + /// + /// Gets the default classified instance from the platform assembly implementing the type. + /// + /// (Abstract) type for which implementation is requested. + /// The single instance from the platform assembly implementing the type that is classified as default, + /// or null if no or more than one default classified implementations are available. + /// It is implicitly assumed that all implementation classes has a public, parameter-less constructor. + internal static T GetDefaultPlatformInstance() where T : IDefaultable + { + try + { + var assembly = GetCurrentAssembly(); + var types = GetConcreteTypes(assembly); + + return GetDefaultOrSingleInstance(types); + } + catch (Exception) + { + return default(T); + } + } + + private static Assembly GetCurrentAssembly() + { +#if NETFX_CORE || NETSTANDARD + return typeof(J2kSetup).GetTypeInfo().Assembly; +#else + return typeof(J2kSetup).Assembly; +#endif + } + + private static IEnumerable GetConcreteTypes(Assembly assembly) + { +#if NETFX_CORE || NETSTANDARD + return assembly.DefinedTypes.Where( +#else + return assembly.GetTypes().Where( +#endif + t => + { + try + { +#if NETFX_CORE || NETSTANDARD + return (t.IsSubclassOf(typeof(T)) || typeof(T).GetTypeInfo().IsAssignableFrom(t)) + && !t.IsAbstract; +#else + return (t.IsSubclassOf(typeof(T)) || typeof(T).IsAssignableFrom(t)) && !t.IsAbstract; +#endif + } + catch + { + return false; + } +#if NETFX_CORE || NETSTANDARD + }).Select(t => t.AsType()); +#else + }); +#endif + } + + private static T GetDefaultOrSingleInstance(IEnumerable types) where T : IDefaultable + { + var instances = types.Select( + t => + { + try + { + return (T)Activator.CreateInstance(t); + } + catch + { + return default(T); + } + }).ToList(); + + return instances.Count > 1 ? instances.Single(instance => instance.IsDefault) : instances.SingleOrDefault(); + } + } +} diff --git a/CSJ2K/Util/BitmapImage.cs b/CSJ2K/Util/BitmapImage.cs new file mode 100644 index 00000000..88b76bbf --- /dev/null +++ b/CSJ2K/Util/BitmapImage.cs @@ -0,0 +1,40 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System.Drawing; + using System.Drawing.Imaging; + + internal class BitmapImage : ImageBase + { + #region CONSTRUCTORS + + internal BitmapImage(int width, int height, byte[] bytes) + : base(width, height, bytes) + { + } + + #endregion + + #region METHODS + + protected override object GetImageObject() + { + var bitmap = new Bitmap(Width, Height, PixelFormat.Format32bppArgb); + + var dstdata = bitmap.LockBits( + new Rectangle(0, 0, Width, Height), + ImageLockMode.ReadWrite, + bitmap.PixelFormat); + + var ptr = dstdata.Scan0; + System.Runtime.InteropServices.Marshal.Copy(Bytes, 0, ptr, Bytes.Length); + bitmap.UnlockBits(dstdata); + + return bitmap; + } + + #endregion + } +} diff --git a/CSJ2K/Util/BitmapImageCreator.cs b/CSJ2K/Util/BitmapImageCreator.cs new file mode 100644 index 00000000..0975b842 --- /dev/null +++ b/CSJ2K/Util/BitmapImageCreator.cs @@ -0,0 +1,47 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using CSJ2K.j2k.image; + + public class BitmapImageCreator : IImageCreator + { + #region FIELDS + + private static readonly IImageCreator Instance = new BitmapImageCreator(); + + #endregion + + #region PROPERTIES + + public bool IsDefault + { + get + { + return false; + } + } + + #endregion + + #region METHODS + + public static void Register() + { + ImageFactory.Register(Instance); + } + + public IImage Create(int width, int height, byte[] bytes) + { + return new BitmapImage(width, height, bytes); + } + + public BlkImgDataSrc ToPortableImageSource(object imageObject) + { + return BitmapImageSource.Create(imageObject); + } + + #endregion + } +} diff --git a/CSJ2K/Util/BitmapImageSource.cs b/CSJ2K/Util/BitmapImageSource.cs new file mode 100644 index 00000000..32b79511 --- /dev/null +++ b/CSJ2K/Util/BitmapImageSource.cs @@ -0,0 +1,110 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + using System.Drawing; + using System.Drawing.Imaging; + using System.Linq; + + using CSJ2K.j2k.image; + + internal class BitmapImageSource : PortableImageSource + { + #region CONSTRUCTORS + + private BitmapImageSource(Bitmap bitmap) + : base( + bitmap.Width, + bitmap.Height, + GetNumberOfComponents(bitmap.PixelFormat), + GetRangeBits(bitmap.PixelFormat), + GetSignedArray(bitmap.PixelFormat), + GetComponents(bitmap)) + { + } + + #endregion + + #region METHODS + + + internal static BlkImgDataSrc Create(object imageObject) + { + var bitmap = imageObject as Bitmap; + return bitmap == null ? null : new BitmapImageSource(bitmap); + } + + private static int GetNumberOfComponents(PixelFormat pixelFormat) + { + switch (pixelFormat) + { + case PixelFormat.Format16bppGrayScale: + case PixelFormat.Format1bppIndexed: + case PixelFormat.Format4bppIndexed: + case PixelFormat.Format8bppIndexed: + return 1; + case PixelFormat.Format24bppRgb: + case PixelFormat.Format32bppArgb: + case PixelFormat.Format32bppPArgb: + case PixelFormat.Format32bppRgb: + return 3; + default: + throw new ArgumentOutOfRangeException("pixelFormat"); + } + } + + private static int GetRangeBits(PixelFormat pixelFormat) + { + switch (pixelFormat) + { + case PixelFormat.Format16bppGrayScale: + return 16; + case PixelFormat.Format1bppIndexed: + return 1; + case PixelFormat.Format4bppIndexed: + return 4; + case PixelFormat.Format8bppIndexed: + case PixelFormat.Format24bppRgb: + case PixelFormat.Format32bppArgb: + case PixelFormat.Format32bppPArgb: + case PixelFormat.Format32bppRgb: + return 8; + default: + throw new ArgumentOutOfRangeException("pixelFormat"); + } + } + + private static bool[] GetSignedArray(PixelFormat pixelFormat) + { + return Enumerable.Repeat(false, GetNumberOfComponents(pixelFormat)).ToArray(); + } + + private static int[][] GetComponents(Bitmap bitmap) + { + var w = bitmap.Width; + var h = bitmap.Height; + var nc = GetNumberOfComponents(bitmap.PixelFormat); + + var comps = new int[nc][]; + for (var c = 0; c < nc; ++c) comps[c] = new int[w * h]; + + for (int y = 0, xy = 0; y < h; ++y) + { + for (var x = 0; x < w; ++x, ++xy) + { + var color = bitmap.GetPixel(x, y); + for (var c = 0; c < nc; ++c) + { + comps[c][xy] = c == 0 ? color.R : c == 1 ? color.G : color.B; + } + } + } + + return comps; + } + + #endregion + } +} diff --git a/CSJ2K/Util/DotnetFileInfo.cs b/CSJ2K/Util/DotnetFileInfo.cs new file mode 100644 index 00000000..e03d313b --- /dev/null +++ b/CSJ2K/Util/DotnetFileInfo.cs @@ -0,0 +1,71 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + using System.IO; + + internal class DotnetFileInfo : IFileInfo + { + #region FIELDS + + private readonly FileInfo _fileInfo; + + #endregion + + #region CONSTRUCTORS + + internal DotnetFileInfo(string fileName) + { + _fileInfo = new FileInfo(fileName); + } + + #endregion + + #region PROPERTIES + + public string Name + { + get + { + return _fileInfo.Name; + } + } + + public string FullName + { + get + { + return _fileInfo.FullName; + } + } + + public bool Exists + { + get + { + return _fileInfo.Exists; + } + } + + #endregion + + #region METHODS + + public bool Delete() + { + try + { + _fileInfo.Delete(); + return true; + } + catch (Exception) + { + return false; + } + } + + #endregion + } +} diff --git a/CSJ2K/Util/DotnetFileInfoCreator.cs b/CSJ2K/Util/DotnetFileInfoCreator.cs new file mode 100644 index 00000000..587351a4 --- /dev/null +++ b/CSJ2K/Util/DotnetFileInfoCreator.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + public class DotnetFileInfoCreator : IFileInfoCreator + { + #region FIELDS + + private static readonly IFileInfoCreator Instance = new DotnetFileInfoCreator(); + + #endregion + + #region METHODS + + public static void Register() + { + FileInfoFactory.Register(Instance); + } + + public IFileInfo Create(string fileName) + { + return new DotnetFileInfo(fileName); + } + + #endregion + } +} diff --git a/CSJ2K/Util/DotnetFileStreamCreator.cs b/CSJ2K/Util/DotnetFileStreamCreator.cs new file mode 100644 index 00000000..9cf559db --- /dev/null +++ b/CSJ2K/Util/DotnetFileStreamCreator.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + using System.IO; + + public class DotnetFileStreamCreator : IFileStreamCreator + { + #region FIELDS + + private static readonly IFileStreamCreator Instance = new DotnetFileStreamCreator(); + + #endregion + + #region METHODS + + public static void Register() + { + FileStreamFactory.Register(Instance); + } + + public Stream Create(string path, string mode) + { + if (mode.Equals("rw", StringComparison.OrdinalIgnoreCase)) return new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite); + if (mode.Equals("r", StringComparison.OrdinalIgnoreCase)) return new FileStream(path, FileMode.Open, FileAccess.Read); + throw new ArgumentException(String.Format("File mode: {0} not supported.", mode), "mode"); + } + + #endregion + } +} diff --git a/CSJ2K/Util/DotnetMsgLogger.cs b/CSJ2K/Util/DotnetMsgLogger.cs new file mode 100644 index 00000000..e5844542 --- /dev/null +++ b/CSJ2K/Util/DotnetMsgLogger.cs @@ -0,0 +1,36 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + + using CSJ2K.j2k.util; + + public class DotnetMsgLogger : StreamMsgLogger + { + #region FIELDS + + private static readonly IMsgLogger Instance = new DotnetMsgLogger(); + + #endregion + + #region CONSTRUCTORS + + public DotnetMsgLogger() + : base(Console.OpenStandardOutput(), Console.OpenStandardError(), 78) + { + } + + #endregion + + #region METHODS + + public static void Register() + { + FacilityManager.DefaultMsgLogger = Instance; + } + + #endregion + } +} diff --git a/CSJ2K/Util/EndianBinaryReader.cs b/CSJ2K/Util/EndianBinaryReader.cs index 79912cad..e41dad80 100644 --- a/CSJ2K/Util/EndianBinaryReader.cs +++ b/CSJ2K/Util/EndianBinaryReader.cs @@ -55,7 +55,7 @@ namespace CSJ2K.Util _bigEndian = bigEndian; } - public EndianBinaryReader(Stream input, bool bigEndian) : base(input, bigEndian ? Encoding.BigEndianUnicode : Encoding.ASCII) + public EndianBinaryReader(Stream input, bool bigEndian) : base(input, bigEndian ? Encoding.BigEndianUnicode : Encoding.UTF8) { _bigEndian = bigEndian; } @@ -344,6 +344,7 @@ namespace CSJ2K.Util // // System.IO.EndOfStreamException: // The end of the stream is reached. +#if DOTNET public override decimal ReadDecimal() { if (_bigEndian) @@ -361,6 +362,7 @@ namespace CSJ2K.Util } else return base.ReadDecimal(); } +#endif // // Summary: // Reads an 8-byte floating point value from the current stream and advances diff --git a/CSJ2K/Util/EndianBinaryWriter.cs b/CSJ2K/Util/EndianBinaryWriter.cs index 9390708f..c5b79c09 100644 --- a/CSJ2K/Util/EndianBinaryWriter.cs +++ b/CSJ2K/Util/EndianBinaryWriter.cs @@ -55,7 +55,7 @@ namespace CSJ2K.Util _bigEndian = bigEndian; } - public EndianBinaryWriter(Stream input, bool bigEndian) : base(input, bigEndian ? Encoding.BigEndianUnicode : Encoding.ASCII) + public EndianBinaryWriter(Stream input, bool bigEndian) : base(input, bigEndian ? Encoding.BigEndianUnicode : Encoding.UTF8) { _bigEndian = bigEndian; } @@ -212,6 +212,7 @@ namespace CSJ2K.Util // // System.IO.IOException: // An I/O error occurs. +#if DOTNET public override void Write(decimal value) { if (_bigEndian) @@ -234,6 +235,7 @@ namespace CSJ2K.Util } else base.Write(value); } +#endif // // Summary: // Writes an eight-byte floating-point value to the current stream and advances diff --git a/CSJ2K/Util/FileInfoFactory.cs b/CSJ2K/Util/FileInfoFactory.cs new file mode 100644 index 00000000..e6201dfa --- /dev/null +++ b/CSJ2K/Util/FileInfoFactory.cs @@ -0,0 +1,42 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + + public static class FileInfoFactory + { + #region FIELDS + + private static IFileInfoCreator _creator; + + #endregion + + #region CONSTRUCTORS + + static FileInfoFactory() + { + _creator = J2kSetup.GetSinglePlatformInstance(); + } + + #endregion + + #region METHODS + + public static void Register(IFileInfoCreator creator) + { + _creator = creator; + } + + internal static IFileInfo New(string fileName) + { + if (_creator == null) throw new InvalidOperationException("No file info creator is registered."); + if (fileName == null) throw new ArgumentNullException("fileName"); + + return _creator.Create(fileName); + } + + #endregion + } +} \ No newline at end of file diff --git a/CSJ2K/Util/FileStreamFactory.cs b/CSJ2K/Util/FileStreamFactory.cs new file mode 100644 index 00000000..89100358 --- /dev/null +++ b/CSJ2K/Util/FileStreamFactory.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + using System.IO; + + public class FileStreamFactory + { + #region FIELDS + + private static IFileStreamCreator _creator; + + #endregion + + #region CONSTRUCTORS + + static FileStreamFactory() + { + _creator = J2kSetup.GetSinglePlatformInstance(); + } + + #endregion + + #region METHODS + + public static void Register(IFileStreamCreator creator) + { + _creator = creator; + } + + internal static Stream New(string path, string mode) + { + if (_creator == null) throw new InvalidOperationException("No file stream creator is registered."); + if (path == null) throw new ArgumentNullException("path"); + if (mode == null) throw new ArgumentNullException("mode"); + + return _creator.Create(path, mode); + } + + #endregion + } +} diff --git a/CSJ2K/Util/IDefaultable.cs b/CSJ2K/Util/IDefaultable.cs new file mode 100644 index 00000000..eba1150d --- /dev/null +++ b/CSJ2K/Util/IDefaultable.cs @@ -0,0 +1,16 @@ +// Copyright (c) 2012-2016 fo-dicom contributors. +// Licensed under the Microsoft Public License (MS-PL). + +namespace CSJ2K.Util +{ + /// + /// Interface for default classification of manager types. + /// + public interface IDefaultable + { + /// + /// Gets whether or not this type is classified as a default manager. + /// + bool IsDefault { get; } + } +} \ No newline at end of file diff --git a/CSJ2K/Util/IFileInfo.cs b/CSJ2K/Util/IFileInfo.cs new file mode 100644 index 00000000..47c2a635 --- /dev/null +++ b/CSJ2K/Util/IFileInfo.cs @@ -0,0 +1,21 @@ +namespace CSJ2K.Util +{ + public interface IFileInfo + { + #region PROPERTIES + + string Name { get; } + + string FullName { get; } + + bool Exists { get; } + + #endregion + + #region METHODS + + bool Delete(); + + #endregion + } +} \ No newline at end of file diff --git a/CSJ2K/Util/IFileInfoCreator.cs b/CSJ2K/Util/IFileInfoCreator.cs new file mode 100644 index 00000000..9e993b07 --- /dev/null +++ b/CSJ2K/Util/IFileInfoCreator.cs @@ -0,0 +1,11 @@ +namespace CSJ2K.Util +{ + public interface IFileInfoCreator + { + #region METHODS + + IFileInfo Create(string fileName); + + #endregion + } +} \ No newline at end of file diff --git a/CSJ2K/Util/IFileStreamCreator.cs b/CSJ2K/Util/IFileStreamCreator.cs new file mode 100644 index 00000000..88f1da69 --- /dev/null +++ b/CSJ2K/Util/IFileStreamCreator.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System.IO; + + public interface IFileStreamCreator + { + Stream Create(string path, string mode); + } +} diff --git a/CSJ2K/Util/IImage.cs b/CSJ2K/Util/IImage.cs new file mode 100644 index 00000000..56001ccd --- /dev/null +++ b/CSJ2K/Util/IImage.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + public interface IImage + { + #region METHODS + + T As(); + + #endregion + } +} diff --git a/CSJ2K/Util/IImageCreator.cs b/CSJ2K/Util/IImageCreator.cs new file mode 100644 index 00000000..07e54788 --- /dev/null +++ b/CSJ2K/Util/IImageCreator.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using CSJ2K.j2k.image; + + public interface IImageCreator : IDefaultable + { + IImage Create(int width, int height, byte[] bytes); + + BlkImgDataSrc ToPortableImageSource(object imageObject); + } +} diff --git a/CSJ2K/Util/ImageBase.cs b/CSJ2K/Util/ImageBase.cs new file mode 100644 index 00000000..ed545cb8 --- /dev/null +++ b/CSJ2K/Util/ImageBase.cs @@ -0,0 +1,60 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + using System.Reflection; + + + public abstract class ImageBase : IImage + { + #region FIELDS + + protected const int SizeOfArgb = 4; + + #endregion + + #region CONSTRUCTORS + + protected ImageBase(int width, int height, byte[] bytes) + { + Width = width; + Height = height; + Bytes = bytes; + } + + #endregion + + #region PROPERTIES + + protected int Width { get; } + + protected int Height { get; } + + protected byte[] Bytes { get; } + + #endregion + + #region METHODS + + public virtual T As() + { +#if NETFX_CORE || NETSTANDARD + if (!typeof(TBase).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())) +#else + if (!typeof(TBase).IsAssignableFrom(typeof(T))) +#endif + { + throw new InvalidCastException( + $"Cannot cast to '{typeof(T).Name}'; type must be assignable from '{typeof(TBase).Name}'"); + } + + return (T)GetImageObject(); + } + + protected abstract object GetImageObject(); + + #endregion + } +} diff --git a/CSJ2K/Util/ImageFactory.cs b/CSJ2K/Util/ImageFactory.cs new file mode 100644 index 00000000..9dd5a214 --- /dev/null +++ b/CSJ2K/Util/ImageFactory.cs @@ -0,0 +1,51 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using CSJ2K.j2k.image; + + public static class ImageFactory + { + #region FIELDS + + private static IImageCreator _creator; + + #endregion + + #region CONSTRUCTORS + + static ImageFactory() + { + _creator = J2kSetup.GetDefaultPlatformInstance(); + } + + #endregion + + #region METHODS + + public static void Register(IImageCreator creator) + { + _creator = creator; + } + + internal static IImage New(int width, int height, byte[] bytes) + { + return _creator.Create(width, height, bytes); + } + + internal static BlkImgDataSrc ToPortableImageSource(object imageObject) + { + try + { + return _creator.ToPortableImageSource(imageObject); + } + catch + { + return null; + } + } + + #endregion + } +} diff --git a/CSJ2K/Util/PortableImage.cs b/CSJ2K/Util/PortableImage.cs new file mode 100644 index 00000000..91111022 --- /dev/null +++ b/CSJ2K/Util/PortableImage.cs @@ -0,0 +1,137 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +using System; +using System.Linq; + +namespace CSJ2K.Util +{ + public sealed class PortableImage : IImage + { + #region FIELDS + + private const int SizeOfArgb = 4; + + private readonly double[] _byteScaling; + + #endregion + + #region CONSTRUCTORS + + internal PortableImage(int width, int height, int numberOfComponents, int[] bitsUsed) + { + Width = width; + Height = height; + NumberOfComponents = numberOfComponents; + _byteScaling = bitsUsed.Select(b => 255.0 / (1 << b)).ToArray(); + + Data = new int[numberOfComponents * width * height]; + } + + #endregion + + #region PROPERTIES + + internal int Width { get; } + + internal int Height { get; } + + public int NumberOfComponents { get; } + + internal int[] Data { get; } + + #endregion + + #region METHODS + + public T As() + { + var image = ImageFactory.New(Width, Height, ToBytes(Width, Height, NumberOfComponents, _byteScaling, Data)); + return image.As(); + } + + public int[] GetComponent(int number) + { + if (number < 0 || number >= NumberOfComponents) + { + throw new ArgumentOutOfRangeException(nameof(number)); + } + + var length = Width * Height; + var component = new int[length]; + + for (int i = number, k = 0; k < length; i += NumberOfComponents, ++k) + { + component[k] = Data[i]; + } + + return component; + } + + internal void FillRow(int rowIndex, int lineIndex, int rowWidth, int[] rowValues) + { + Array.Copy( + rowValues, + 0, + Data, + NumberOfComponents * (rowIndex + lineIndex * rowWidth), + rowValues.Length); + } + + private static byte[] ToBytes(int width, int height, int numberOfComponents, double[] byteScaling, int[] data) + { + var count = numberOfComponents * width * height; + var bytes = new byte[SizeOfArgb * width * height]; + + switch (numberOfComponents) + { + case 1: + var scale = byteScaling[0]; + for (int i = 0, j = 0; i < count; ++i) + { + var b = (byte)(scale * data[i]); + bytes[j++] = b; + bytes[j++] = b; + bytes[j++] = b; + bytes[j++] = 0xff; + } + break; + case 3: + { + var scale0 = byteScaling[0]; + var scale1 = byteScaling[1]; + var scale2 = byteScaling[2]; + for (int i = 0, j = 0; i < count;) + { + bytes[j++] = (byte)(scale0 * data[i++]); + bytes[j++] = (byte)(scale1 * data[i++]); + bytes[j++] = (byte)(scale2 * data[i++]); + bytes[j++] = 0xff; + } + } + break; + case 4: + { + var scale0 = byteScaling[0]; + var scale1 = byteScaling[1]; + var scale2 = byteScaling[2]; + var scale3 = byteScaling[3]; + for (int i = 0, j = 0; i < count;) + { + bytes[j++] = (byte)(scale0 * data[i++]); + bytes[j++] = (byte)(scale1 * data[i++]); + bytes[j++] = (byte)(scale2 * data[i++]); + bytes[j++] = (byte)(scale3 * data[i++]); + } + } + break; + default: + throw new ArgumentOutOfRangeException(nameof(numberOfComponents), $"Invalid number of components: {numberOfComponents}"); + } + + return bytes; + } + + #endregion + } +} diff --git a/CSJ2K/Util/PortableImageSource.cs b/CSJ2K/Util/PortableImageSource.cs new file mode 100644 index 00000000..44e8d08b --- /dev/null +++ b/CSJ2K/Util/PortableImageSource.cs @@ -0,0 +1,283 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + + using CSJ2K.j2k; + using CSJ2K.j2k.image; + + public class PortableImageSource : BlkImgDataSrc + { + #region FIELDS + + private readonly int w; + + private readonly int h; + + private readonly int nc; + + private readonly int rb; + + private readonly bool[] sgnd; + + private readonly int[][] comps; + + #endregion + + #region CONSTRUCTORS + + public PortableImageSource(int w, int h, int nc, int rb, bool[] sgnd, int[][] comps) + { + this.w = w; + this.h = h; + this.nc = nc; + this.rb = rb; + this.sgnd = sgnd; + this.comps = comps; + } + + #endregion + + #region PROPERTIES + + public int TileWidth + { + get + { + return this.w; + } + } + + public int TileHeight + { + get + { + return this.h; + } + } + + public int NomTileWidth + { + get + { + return this.w; + } + } + + public int NomTileHeight { + get + { + return this.h; + } + } + + public int ImgWidth { + get + { + return this.w; + } + } + + public int ImgHeight { + get + { + return this.h; + } + } + + public int NumComps { + get + { + return this.nc; + } + } + + public int TileIdx { + get + { + return 0; + } + } + + public int TilePartULX { + get + { + return 0; + } + } + + public int TilePartULY { + get + { + return 0; + } + } + + public int ImgULX { + get + { + return 0; + } + } + + public int ImgULY { + get + { + return 0; + } + } + + #endregion + + #region METHODS + + public int getCompSubsX(int c) + { + return 1; + } + + public int getCompSubsY(int c) + { + return 1; + } + + public int getTileCompWidth(int t, int c) + { + if (t != 0) + { + throw new System.InvalidOperationException("Asking a tile-component width for a tile index" + " greater than 0 whereas there is only one tile"); + } + return this.w; + } + + public int getTileCompHeight(int t, int c) + { + if (t != 0) + { + throw new System.InvalidOperationException("Asking a tile-component width for a tile index" + " greater than 0 whereas there is only one tile"); + } + return this.h; + } + + public int getCompImgWidth(int c) + { + return this.w; + } + + public int getCompImgHeight(int c) + { + return this.h; + } + + public int getNomRangeBits(int c) + { + return this.rb; + } + + public void setTile(int x, int y) + { + if (x != 0 || y != 0) + { + throw new System.ArgumentException(); + } + } + + public void nextTile() + { + throw new NoNextElementException(); + } + + public Coord getTile(Coord co) + { + if (co != null) + { + co.x = 0; + co.y = 0; + return co; + } + + return new Coord(0, 0); + } + + public int getCompULX(int c) + { + return 0; + } + + public int getCompULY(int c) + { + return 0; + } + + public Coord getNumTiles(Coord co) + { + if (co != null) + { + co.x = 1; + co.y = 1; + return co; + } + + return new Coord(1, 1); + } + + public int getNumTiles() + { + return 1; + } + + public int getFixedPoint(int c) + { + return 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; + } + + public DataBlk getCompData(DataBlk blk, int c) + { + var newBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h); + return this.getInternCompData(newBlk, c); + } + + public void close() + { + // Do nothing. + } + + public bool isOrigSigned(int c) + { + if (c < 0 || c >= this.nc) + { + throw new ArgumentOutOfRangeException("c"); + } + + return this.sgnd[c]; + } + + #endregion + } +} diff --git a/CSJ2K/Util/StoreFileInfo.cs b/CSJ2K/Util/StoreFileInfo.cs new file mode 100644 index 00000000..877d0f8f --- /dev/null +++ b/CSJ2K/Util/StoreFileInfo.cs @@ -0,0 +1,67 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using Windows.Storage; + +namespace CSJ2K.Util +{ + internal class StoreFileInfo : IFileInfo + { + #region CONSTRUCTORS + + internal StoreFileInfo(string fileName) + { + FullName = fileName; + } + + #endregion + + #region PROPERTIES + + public string Name { get { return Path.GetFileName(FullName); } } + + public string FullName { get; private set; } + + public bool Exists + { + get + { + return Task.Run(async () => + { + try + { + var file = await StorageFile.GetFileFromPathAsync(FullName); + return file != null; + } + catch + { + return false; + } + }).Result; + } + } + + #endregion + + #region METHODS + + public bool Delete() + { + return Task.Run(async () => + { + try + { + var file = await StorageFile.GetFileFromPathAsync(FullName); + await file.DeleteAsync(); + return true; + } + catch + { + return false; + } + }).Result; + } + + #endregion + } +} diff --git a/CSJ2K/Util/StoreFileInfoCreator.cs b/CSJ2K/Util/StoreFileInfoCreator.cs new file mode 100644 index 00000000..bcbde6fa --- /dev/null +++ b/CSJ2K/Util/StoreFileInfoCreator.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + public class StoreFileInfoCreator : IFileInfoCreator + { + #region FIELDS + + private static readonly IFileInfoCreator Instance = new StoreFileInfoCreator(); + + #endregion + + #region METHODS + + public static void Register() + { + FileInfoFactory.Register(Instance); + } + + public IFileInfo Create(string name) + { + return new StoreFileInfo(name); + } + + #endregion + } +} diff --git a/CSJ2K/Util/StoreFileStream.cs b/CSJ2K/Util/StoreFileStream.cs new file mode 100644 index 00000000..18bd6063 --- /dev/null +++ b/CSJ2K/Util/StoreFileStream.cs @@ -0,0 +1,185 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using Windows.Storage; +using Windows.Storage.Streams; + +namespace CSJ2K.Util +{ + internal sealed class StoreFileStream : Stream + { + #region FIELDS + + private readonly IRandomAccessStream _stream; + private bool _disposed; + + #endregion + + #region CONSTRUCTORS + + internal StoreFileStream(string path, string mode) + { + try + { + _stream = Task.Run(async () => + { + StorageFile file; + if (mode.Equals("rw", StringComparison.OrdinalIgnoreCase)) + { + file = + await + StorageFile.CreateStreamedFileFromUriAsync(Path.GetFileName(path), new Uri(path), + null); + } + else if (mode.Equals("r", StringComparison.OrdinalIgnoreCase)) + { + file = await StorageFile.GetFileFromPathAsync(path); + } + else + { + throw new ArgumentOutOfRangeException("mode", "Only modes r and rw are supported."); + } + return await file.OpenAsync(FileAccessMode.ReadWrite); + }).Result; + _disposed = false; + Name = path; + } + catch + { + _stream = null; + _disposed = true; + Name = String.Empty; + } + } + + #endregion + + #region PROPERTIES + + public override bool CanRead + { + get { return true; } + } + + public override bool CanSeek + { + get { return true; } + } + + public override bool CanWrite + { + get { return true; } + } + + public override long Length + { + get + { + if (_disposed) throw new ObjectDisposedException("_stream"); + return (long)_stream.Size; + } + } + + public override long Position + { + get + { + if (_disposed) throw new ObjectDisposedException("_stream"); + return (long)_stream.Position; + } + set + { + if (_disposed) throw new ObjectDisposedException("_stream"); + _stream.Seek((ulong)value); + } + } + + internal string Name { get; private set; } + + #endregion + + #region METHODS + + public override void Flush() + { + if (_disposed) throw new ObjectDisposedException("_stream"); + Task.Run(async () => await _stream.FlushAsync()).Wait(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (_disposed) throw new ObjectDisposedException("_stream"); + return Task.Run(async () => + { + using (var reader = new DataReader(_stream)) + { + await reader.LoadAsync((uint)count); + var length = Math.Min(count, (int)reader.UnconsumedBufferLength); + var temp = new byte[length]; + reader.ReadBytes(temp); + Array.Copy(temp, 0, buffer, offset, length); + reader.DetachStream(); + return length; + } + }).Result; + } + + public override long Seek(long offset, SeekOrigin origin) + { + if (_disposed) throw new ObjectDisposedException("_stream"); + switch (origin) + { + case SeekOrigin.Begin: + _stream.Seek((ulong)offset); + break; + case SeekOrigin.Current: + _stream.Seek(_stream.Position + (ulong)offset); + break; + case SeekOrigin.End: + _stream.Seek(_stream.Size - (ulong)offset); + break; + default: + throw new ArgumentOutOfRangeException("offset"); + } + return (long)_stream.Position; + } + + public override void SetLength(long value) + { + if (_disposed) throw new ObjectDisposedException("_stream"); + _stream.Size = (ulong)value; + } + + public override void Write(byte[] buffer, int offset, int count) + { + if (_disposed) throw new ObjectDisposedException("_stream"); + Task.Run(async () => + { + using (var writer = new DataWriter(_stream)) + { + var temp = new byte[count]; + Array.Copy(buffer, offset, temp, 0, count); + writer.WriteBytes(temp); + await writer.StoreAsync(); + writer.DetachStream(); + } + }).Wait(); + } + + protected override void Dispose(bool disposing) + { + if (_disposed) return; + + if (disposing) + { + Flush(); + _stream.Dispose(); + } + _disposed = true; + + base.Dispose(disposing); + } + + #endregion + } +} \ No newline at end of file diff --git a/CSJ2K/Util/StoreFileStreamCreator.cs b/CSJ2K/Util/StoreFileStreamCreator.cs new file mode 100644 index 00000000..7b680563 --- /dev/null +++ b/CSJ2K/Util/StoreFileStreamCreator.cs @@ -0,0 +1,30 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System.IO; + + public class StoreFileStreamCreator : IFileStreamCreator + { + #region FIELDS + + private static readonly IFileStreamCreator Instance = new StoreFileStreamCreator(); + + #endregion + + #region METHODS + + public static void Register() + { + FileStreamFactory.Register(Instance); + } + + public Stream Create(string path, string mode) + { + return new StoreFileStream(path, mode); + } + + #endregion + } +} diff --git a/CSJ2K/Util/StoreMsgLogger.cs b/CSJ2K/Util/StoreMsgLogger.cs new file mode 100644 index 00000000..c02b7b00 --- /dev/null +++ b/CSJ2K/Util/StoreMsgLogger.cs @@ -0,0 +1,48 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + using System.IO; + + using CSJ2K.j2k.util; + + using Windows.Storage; + + public class StoreMsgLogger : StreamMsgLogger + { + #region FIELDS + + private static readonly IMsgLogger Instance = new StoreMsgLogger(); + + #endregion + + #region CONSTRUCTORS + + public StoreMsgLogger() + : base(GetLogFile("csj2k.out"), GetLogFile("csj2k.err"), 132) + { + } + + #endregion + + #region METHODS + + public static void Register() + { + FacilityManager.DefaultMsgLogger = Instance; + } + + private static Stream GetLogFile(string fileName) + { + var file = + ApplicationData.Current.LocalFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting) + .AsTask() + .Result; + return file.OpenStreamForWriteAsync().Result; + } + + #endregion + } +} diff --git a/CSJ2K/Util/SupportClass.cs b/CSJ2K/Util/SupportClass.cs index 611dc672..2c8bf6c9 100644 --- a/CSJ2K/Util/SupportClass.cs +++ b/CSJ2K/Util/SupportClass.cs @@ -10,8 +10,10 @@ // using System; +using CSJ2K.Util; +using CSJ2K.j2k.util; - /// +/// /// This interface should be implemented by any class whose instances are intended /// to be executed by a thread. /// @@ -54,7 +56,7 @@ internal class SupportClass /// The new array of bytes public static byte[] ToByteArray(System.String sourceString) { - return System.Text.UTF8Encoding.UTF8.GetBytes(sourceString); + return System.Text.Encoding.UTF8.GetBytes(sourceString); } /// @@ -75,15 +77,14 @@ internal class SupportClass } /*******************************/ + /// /// Writes the exception stack trace to the received stream /// /// Exception to obtain information from - /// Output sream used to write to - public static void WriteStackTrace(System.Exception throwable, System.IO.TextWriter stream) + public static void WriteStackTrace(Exception throwable) { - stream.Write(throwable.StackTrace); - stream.Flush(); + FacilityManager.getMsgLogger().printmsg(MsgLogger_Fields.ERROR, throwable.StackTrace); } /*******************************/ @@ -112,7 +113,7 @@ internal class SupportClass /// The new array of chars public static char[] ToCharArray(sbyte[] sByteArray) { - return System.Text.UTF8Encoding.UTF8.GetChars(ToByteArray(sByteArray)); + return System.Text.Encoding.UTF8.GetChars(ToByteArray(sByteArray)); } /// @@ -122,7 +123,7 @@ internal class SupportClass /// The new array of chars public static char[] ToCharArray(byte[] byteArray) { - return System.Text.UTF8Encoding.UTF8.GetChars(byteArray); + return System.Text.Encoding.UTF8.GetChars(byteArray); } /*******************************/ @@ -178,20 +179,9 @@ internal class SupportClass /// A relative or absolute path for the file to open /// Mode to open the file in /// The new System.IO.FileStream - public static System.IO.FileStream CreateRandomAccessFile(System.String fileName, System.String mode) + public static System.IO.Stream CreateRandomAccessFile(System.String fileName, System.String mode) { - System.IO.FileStream newFile = null; - - if (mode.CompareTo("rw") == 0) - // newFile = new System.IO.FileStream(fileName, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite); - //else if (mode.CompareTo("rw+") == 0) - newFile = new System.IO.FileStream(fileName, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite); - else if (mode.CompareTo("r") == 0) - newFile = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read); - else - throw new System.ArgumentException(); - - return newFile; + return FileStreamFactory.New(fileName, mode); } /// @@ -200,17 +190,17 @@ internal class SupportClass /// File infomation for the file to open /// Mode to open the file in /// The new System.IO.FileStream - public static System.IO.FileStream CreateRandomAccessFile(System.IO.FileInfo fileName, System.String mode) + public static System.IO.Stream CreateRandomAccessFile(IFileInfo fileName, System.String mode) { return CreateRandomAccessFile(fileName.FullName, mode); - } + } /// /// Writes the data to the specified file stream /// /// Data to write /// File to write to - public static void WriteBytes(System.String data,System.IO.FileStream fileStream) + public static void WriteBytes(System.String data,System.IO.Stream fileStream) { int index = 0; int length = data.Length; @@ -224,7 +214,7 @@ internal class SupportClass /// /// String of information to write /// File to write to - public static void WriteChars(System.String data,System.IO.FileStream fileStream) + public static void WriteChars(System.String data,System.IO.Stream fileStream) { WriteBytes(data, fileStream); } @@ -234,7 +224,7 @@ internal class SupportClass /// /// Data to write /// File to write to - public static void WriteRandomFile(sbyte[] sByteArray,System.IO.FileStream fileStream) + public static void WriteRandomFile(sbyte[] sByteArray,System.IO.Stream fileStream) { byte[] byteArray = ToByteArray(sByteArray); fileStream.Write(byteArray, 0, byteArray.Length); @@ -810,7 +800,7 @@ internal class SupportClass { s += (char) i; } - reader.Close(); + reader.Dispose(); this.inStringReader = new BackStringReader(s); this.init(); } @@ -831,7 +821,7 @@ internal class SupportClass /// Stream to be parsed. public StreamTokenizerSupport(System.IO.Stream stream) { - this.inStream = new BackInputStream(new System.IO.BufferedStream(stream), 2); + this.inStream = new BackInputStream(stream, 2); this.init(); } @@ -1711,249 +1701,6 @@ internal class SupportClass } } - - /*******************************/ - /// - /// Support class used to handle threads - /// - public class ThreadClass : IThreadRunnable - { - /// - /// The instance of System.Threading.Thread - /// - private System.Threading.Thread threadField; - - /// - /// Initializes a new instance of the ThreadClass class - /// - public ThreadClass() - { - threadField = new System.Threading.Thread(new System.Threading.ThreadStart(Run)); - } - - /// - /// Initializes a new instance of the Thread class. - /// - /// The name of the thread - public ThreadClass(System.String Name) - { - threadField = new System.Threading.Thread(new System.Threading.ThreadStart(Run)); - this.Name = Name; - } - - /// - /// Initializes a new instance of the Thread class. - /// - /// A ThreadStart delegate that references the methods to be invoked when this thread begins executing - public ThreadClass(System.Threading.ThreadStart Start) - { - threadField = new System.Threading.Thread(Start); - } - - /// - /// Initializes a new instance of the Thread class. - /// - /// A ThreadStart delegate that references the methods to be invoked when this thread begins executing - /// The name of the thread - public ThreadClass(System.Threading.ThreadStart Start, System.String Name) - { - threadField = new System.Threading.Thread(Start); - this.Name = Name; - } - - /// - /// This method has no functionality unless the method is overridden - /// - public virtual void Run() - { - } - - /// - /// Causes the operating system to change the state of the current thread instance to ThreadState.Running - /// - public virtual void Start() - { - threadField.Start(); - } - - /// - /// Interrupts a thread that is in the WaitSleepJoin thread state - /// - public virtual void Interrupt() - { - threadField.Interrupt(); - } - - /// - /// Gets the current thread instance - /// - public System.Threading.Thread Instance - { - get - { - return threadField; - } - set - { - threadField = value; - } - } - - /// - /// Gets or sets the name of the thread - /// - public System.String Name - { - get - { - return threadField.Name; - } - set - { - if (threadField.Name == null) - threadField.Name = value; - } - } - - /// - /// Gets or sets a value indicating the scheduling priority of a thread - /// - public System.Threading.ThreadPriority Priority - { - get - { - return threadField.Priority; - } - set - { - threadField.Priority = value; - } - } - - /// - /// Gets a value indicating the execution status of the current thread - /// - public bool IsAlive - { - get - { - return threadField.IsAlive; - } - } - - /// - /// Gets or sets a value indicating whether or not a thread is a background thread. - /// - public bool IsBackground - { - get - { - return threadField.IsBackground; - } - set - { - threadField.IsBackground = value; - } - } - - /// - /// Blocks the calling thread until a thread terminates - /// - public void Join() - { - threadField.Join(); - } - - /// - /// Blocks the calling thread until a thread terminates or the specified time elapses - /// - /// Time of wait in milliseconds - public void Join(long MiliSeconds) - { - lock(this) - { - threadField.Join(new System.TimeSpan(MiliSeconds * 10000)); - } - } - - /// - /// Blocks the calling thread until a thread terminates or the specified time elapses - /// - /// Time of wait in milliseconds - /// Time of wait in nanoseconds - public void Join(long MiliSeconds, int NanoSeconds) - { - lock(this) - { - threadField.Join(new System.TimeSpan(MiliSeconds * 10000 + NanoSeconds * 100)); - } - } - /* - /// - /// Resumes a thread that has been suspended - /// - public void Resume() - { - threadField.Resume(); - } - - /// - /// Raises a ThreadAbortException in the thread on which it is invoked, - /// to begin the process of terminating the thread. Calling this method - /// usually terminates the thread - /// - public void Abort() - { - threadField.Abort(); - } - - - /// - /// Raises a ThreadAbortException in the thread on which it is invoked, - /// to begin the process of terminating the thread while also providing - /// exception information about the thread termination. - /// Calling this method usually terminates the thread. - /// - /// An object that contains application-specific information, such as state, which can be used by the thread being aborted - public void Abort(System.Object stateInfo) - { - lock(this) - { - threadField.Abort(stateInfo); - } - } - - /// - /// Suspends the thread, if the thread is already suspended it has no effect - /// - public void Suspend() - { - threadField.Suspend(); - } - */ - - /// - /// Obtain a String that represents the current Object - /// - /// A String that represents the current Object - public override System.String ToString() - { - return "Thread[" + Name + "," + Priority.ToString() + "," + "" + "]"; - } - - /// - /// Gets the currently running thread - /// - /// The currently running thread - public static ThreadClass Current() - { - ThreadClass CurrentThread = new ThreadClass(); - CurrentThread.Instance = System.Threading.Thread.CurrentThread; - return CurrentThread; - } - } - - /*******************************/ /// /// SupportClass for the Stack class. @@ -1965,9 +1712,9 @@ internal class SupportClass /// /// The stack where the element at the top will be returned and removed. /// The element at the top of the stack. - public static System.Object Pop(System.Collections.ArrayList stack) + public static T Pop(System.Collections.Generic.List stack) { - System.Object obj = stack[stack.Count - 1]; + T obj = stack[stack.Count - 1]; stack.RemoveAt(stack.Count - 1); return obj; diff --git a/CSJ2K/Util/WriteableBitmapImage.cs b/CSJ2K/Util/WriteableBitmapImage.cs new file mode 100644 index 00000000..9b7e1a5d --- /dev/null +++ b/CSJ2K/Util/WriteableBitmapImage.cs @@ -0,0 +1,54 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ +#if NETFX_CORE + using System.Runtime.InteropServices.WindowsRuntime; + using Windows.UI.Xaml.Media; + using Windows.UI.Xaml.Media.Imaging; +#elif SILVERLIGHT + using System; + using System.Windows.Media; + using System.Windows.Media.Imaging; +#else + using System.Runtime.InteropServices; + using System.Windows; + using System.Windows.Media; + using System.Windows.Media.Imaging; +#endif + + internal class WriteableBitmapImage : ImageBase + { + #region CONSTRUCTORS + + internal WriteableBitmapImage(int width, int height, byte[] bytes) + : base(width, height, bytes) + { + } + + #endregion + + #region METHODS + + protected override object GetImageObject() + { +#if NETFX_CORE + var wbm = new WriteableBitmap(this.Width, this.Height); + this.Bytes.CopyTo(0, wbm.PixelBuffer, 0, this.Bytes.Length); +#elif SILVERLIGHT + var wbm = new WriteableBitmap(this.Width, this.Height); + Buffer.BlockCopy(this.Bytes, 0, wbm.Pixels, 0, this.Bytes.Length); +#else + var wbm = new WriteableBitmap(this.Width, this.Height, 96.0, 96.0, PixelFormats.Pbgra32, null); + wbm.Lock(); + Marshal.Copy(this.Bytes, 0, wbm.BackBuffer, this.Bytes.Length); + wbm.AddDirtyRect(new Int32Rect(0, 0, this.Width, this.Height)); + wbm.Unlock(); +#endif + return wbm; + } + + #endregion + } +} diff --git a/CSJ2K/Util/WriteableBitmapImageCreator.cs b/CSJ2K/Util/WriteableBitmapImageCreator.cs new file mode 100644 index 00000000..b5a9365b --- /dev/null +++ b/CSJ2K/Util/WriteableBitmapImageCreator.cs @@ -0,0 +1,53 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + + using CSJ2K.j2k.image; + + public class WriteableBitmapImageCreator : IImageCreator + { + #region FIELDS + + private static readonly IImageCreator Instance = new WriteableBitmapImageCreator(); + + #endregion + + #region PROPERTIES + + /// + /// Gets whether or not this type is classified as a default manager. + /// + public bool IsDefault + { + get + { + return true; + } + } + + #endregion + + #region METHODS + + public static void Register() + { + ImageFactory.Register(Instance); + } + + public IImage Create(int width, int height, byte[] bytes) + { + return new WriteableBitmapImage(width, height, bytes); + } + + public BlkImgDataSrc ToPortableImageSource(object imageObject) + { + throw new NotImplementedException(); + //return WriteableBitmapImageSource.Create(imageObject); + } + + #endregion + } +} diff --git a/CSJ2K/Util/WriteableBitmapImageSource.cs b/CSJ2K/Util/WriteableBitmapImageSource.cs new file mode 100644 index 00000000..1e50b8ec --- /dev/null +++ b/CSJ2K/Util/WriteableBitmapImageSource.cs @@ -0,0 +1,146 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +namespace CSJ2K.Util +{ + using System; + using System.Windows.Media; + using System.Windows.Media.Imaging; + + using CSJ2K.j2k.image; + using CSJ2K.j2k.image.input; + + internal class WriteableBitmapImageSource : ImgReader + { + #region FIELDS + + private readonly WriteableBitmap wbm; + + private readonly int rb; + + private readonly int redIdx; + + private readonly int greenIdx; + + private readonly int blueIdx; + + private readonly int pixelSize; + + private readonly bool isPremultiplied; + + #endregion + + #region CONSTRUCTORS + + private WriteableBitmapImageSource(WriteableBitmap wbm) + { + this.wbm = wbm; + this.w = wbm.PixelWidth; + this.h = wbm.PixelHeight; + this.nc = GetNumberOfComponents(wbm.Format); + this.rb = GetRangeBits(wbm.Format); + + this.DefineHelpers(wbm.Format); + } + + #endregion + + #region METHODS + + public override void close() + { + // Do nothing. + } + + public override bool isOrigSigned(int c) + { + if (c < 0 || c >= this.nc) + { + throw new ArgumentOutOfRangeException("c"); + } + + return false; + } + + public override int getFixedPoint(int c) + { + if (c < 0 || c >= this.nc) + { + throw new ArgumentOutOfRangeException("c"); + } + + return 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; + } + + 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); + } + + public override int getNomRangeBits(int c) + { + if (c < 0 || c >= this.nc) + { + throw new ArgumentOutOfRangeException("c"); + } + + return this.rb; + } + + public static ImgReader Create(object imageObject) + { + var wbm = imageObject as WriteableBitmap; + return wbm == null ? null : new WriteableBitmapImageSource(wbm); + } + + private void DefineHelpers(PixelFormat format) + { + throw new NotImplementedException(); + } + + private Array GetDataArray(int x0, int y0, int w, int h) + { + throw new NotImplementedException(); + } + + private static int GetNumberOfComponents(PixelFormat format) + { + if (format.Equals(PixelFormats.BlackWhite) || format.Equals(PixelFormats.Gray8)) + { + return 1; + } + + if (format.Equals(PixelFormats.Bgra32) || format.Equals(PixelFormats.Bgr24) + || format.Equals(PixelFormats.Bgr32) || format.Equals(PixelFormats.Pbgra32) + || format.Equals(PixelFormats.Rgb24)) + { + return 3; + } + + throw new ArgumentOutOfRangeException("format"); + } + + private static int GetRangeBits(PixelFormat format) + { + return format.BitsPerPixel; + } + + #endregion + } +} diff --git a/CSJ2K/j2k/IntegerSpec.cs b/CSJ2K/j2k/IntegerSpec.cs index 540e0ad8..853e759e 100644 --- a/CSJ2K/j2k/IntegerSpec.cs +++ b/CSJ2K/j2k/IntegerSpec.cs @@ -167,7 +167,7 @@ namespace CSJ2K.j2k { setDefault((System.Object) System.Int32.Parse(param)); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Non recognized value" + " for option -" + optName + ": " + param); } @@ -218,7 +218,7 @@ namespace CSJ2K.j2k { value_Renamed = System.Int32.Parse(word); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Non recognized value" + " for option -" + optName + ": " + word); } @@ -290,7 +290,7 @@ namespace CSJ2K.j2k { setDefault((System.Object) System.Int32.Parse(param)); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Non recognized value" + " for option -" + optName + ": " + param); } diff --git a/CSJ2K/j2k/JJ2KExceptionHandler.cs b/CSJ2K/j2k/JJ2KExceptionHandler.cs index 9d12c4d4..4df82828 100644 --- a/CSJ2K/j2k/JJ2KExceptionHandler.cs +++ b/CSJ2K/j2k/JJ2KExceptionHandler.cs @@ -44,6 +44,8 @@ * */ using System; +using CSJ2K.j2k.util; + namespace CSJ2K.j2k { @@ -82,13 +84,13 @@ namespace CSJ2K.j2k // including this method in the stack. //UPGRADE_ISSUE: Method 'java.lang.Throwable.fillInStackTrace' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangThrowablefillInStackTrace'" //e.fillInStackTrace(); - //SupportClass.WriteStackTrace(e, Console.Error); + SupportClass.WriteStackTrace(e); // Print an explicative message - System.Console.Error.WriteLine("The Thread is being terminated bacause an " + "Exception (shown above)\n" + "has been thrown and no special action was " + "defined for this Thread."); + FacilityManager.getMsgLogger().println("The Thread is being terminated bacause an " + "Exception (shown above)\n" + "has been thrown and no special action was " + "defined for this Thread.", 0, 0); // Stop the thread (do not use stop, since it's deprecated in // Java 1.2) - //UPGRADE_NOTE: Exception 'java.lang.ThreadDeath' was converted to 'System.ApplicationException' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - throw e; + //UPGRADE_NOTE: Exception 'java.lang.ThreadDeath' was converted to 'System.InvalidOperationException' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" + throw new System.InvalidOperationException(); } } } \ No newline at end of file diff --git a/CSJ2K/j2k/ModuleSpec.cs b/CSJ2K/j2k/ModuleSpec.cs index 8e8de139..7b1d7066 100644 --- a/CSJ2K/j2k/ModuleSpec.cs +++ b/CSJ2K/j2k/ModuleSpec.cs @@ -41,6 +41,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.image; namespace CSJ2K.j2k { @@ -62,7 +63,7 @@ namespace CSJ2K.j2k ///

/// ///
- public class ModuleSpec : System.ICloneable + public class ModuleSpec { virtual public ModuleSpec Copy { @@ -129,7 +130,7 @@ namespace CSJ2K.j2k /// 3 is accessible through the hash value "t16c3". Null if no /// tile-component specific value is defined ///
- protected internal System.Collections.Hashtable tileCompVal; + protected internal System.Collections.Generic.Dictionary tileCompVal; public virtual System.Object Clone() { @@ -139,9 +140,9 @@ namespace CSJ2K.j2k ms = (ModuleSpec) base.MemberwiseClone(); } //UPGRADE_NOTE: Exception 'java.lang.CloneNotSupportedException' was converted to 'System.Exception' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - catch (System.Exception) + catch (System.Exception e) { - throw new System.ApplicationException("Error when cloning ModuleSpec instance"); + throw new System.InvalidOperationException("Error when cloning ModuleSpec instance"); } // Create a copy of the specValType array ms.specValType = new byte[nTiles][]; @@ -168,16 +169,12 @@ namespace CSJ2K.j2k // Create a copy of tileCompVal if (tileCompVal != null) { - ms.tileCompVal = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); - System.String tmpKey; - System.Object tmpVal; + ms.tileCompVal = new Dictionary(); //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'" - for (System.Collections.IEnumerator e = tileCompVal.Keys.GetEnumerator(); e.MoveNext(); ) + for (System.Collections.Generic.IEnumerator e = tileCompVal.Keys.GetEnumerator(); e.MoveNext(); ) { //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'" - tmpKey = ((System.String) e.Current); - tmpVal = tileCompVal[tmpKey]; - ms.tileCompVal[tmpKey] = tmpVal; + ms.tileCompVal[e.Current] = tileCompVal[e.Current]; } } return ms; @@ -227,7 +224,7 @@ namespace CSJ2K.j2k // Rotate tileCompVal if (tileCompVal != null && tileCompVal.Count > 0) { - System.Collections.Hashtable tmptcv = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + System.Collections.Generic.Dictionary tmptcv = new Dictionary(); System.String tmpKey; System.Object tmpVal; int btIdx, atIdx; @@ -326,7 +323,7 @@ namespace CSJ2K.j2k { //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" System.String errMsg = "Option whose value is '" + value_Renamed + "' cannot be " + "specified for components as it is a 'tile only' specific " + "option"; - throw new System.ApplicationException(errMsg); + throw new System.InvalidOperationException(errMsg); } if (compDef == null) { @@ -360,7 +357,7 @@ namespace CSJ2K.j2k { if (specType == SPEC_TYPE_TILE) { - throw new System.ApplicationException("Illegal use of ModuleSpec class"); + throw new System.InvalidOperationException("Illegal use of ModuleSpec class"); } if (compDef == null || compDef[c] == null) { @@ -385,7 +382,7 @@ namespace CSJ2K.j2k { //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" System.String errMsg = "Option whose value is '" + value_Renamed + "' cannot be " + "specified for tiles as it is a 'component only' specific " + "option"; - throw new System.ApplicationException(errMsg); + throw new System.InvalidOperationException(errMsg); } if (tileDef == null) { @@ -418,7 +415,7 @@ namespace CSJ2K.j2k { if (specType == SPEC_TYPE_COMP) { - throw new System.ApplicationException("Illegal use of ModuleSpec class"); + throw new System.InvalidOperationException("Illegal use of ModuleSpec class"); } if (tileDef == null || tileDef[t] == null) { @@ -456,10 +453,10 @@ namespace CSJ2K.j2k errMsg += "tiles as it is a 'component only' specific option"; break; } - throw new System.ApplicationException(errMsg); + throw new System.InvalidOperationException(errMsg); } if (tileCompVal == null) - tileCompVal = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + tileCompVal = new Dictionary(); specValType[t][c] = SPEC_TILE_COMP; tileCompVal["t" + t + "c" + c] = value_Renamed; } @@ -487,7 +484,7 @@ namespace CSJ2K.j2k { if (specType != SPEC_TYPE_TILE_COMP) { - throw new System.ApplicationException("Illegal use of ModuleSpec class"); + throw new System.InvalidOperationException("Illegal use of ModuleSpec class"); } return getSpec(t, c); } diff --git a/CSJ2K/j2k/NoNextElementException.cs b/CSJ2K/j2k/NoNextElementException.cs index c907317b..57f76707 100644 --- a/CSJ2K/j2k/NoNextElementException.cs +++ b/CSJ2K/j2k/NoNextElementException.cs @@ -52,8 +52,7 @@ namespace CSJ2K.j2k /// there is no next element to return. /// /// - [Serializable] - public class NoNextElementException:System.SystemException + public class NoNextElementException:System.InvalidOperationException { /// Constructs a new NoNextElementException exception with no diff --git a/CSJ2K/j2k/codestream/CorruptedCodestreamException.cs b/CSJ2K/j2k/codestream/CorruptedCodestreamException.cs index b1bcbfaf..5f38c10f 100644 --- a/CSJ2K/j2k/codestream/CorruptedCodestreamException.cs +++ b/CSJ2K/j2k/codestream/CorruptedCodestreamException.cs @@ -51,7 +51,6 @@ namespace CSJ2K.j2k.codestream /// which is illegal. /// /// - [Serializable] public class CorruptedCodestreamException:System.IO.IOException { diff --git a/CSJ2K/j2k/codestream/HeaderInfo.cs b/CSJ2K/j2k/codestream/HeaderInfo.cs index eceb71a3..42f2df57 100644 --- a/CSJ2K/j2k/codestream/HeaderInfo.cs +++ b/CSJ2K/j2k/codestream/HeaderInfo.cs @@ -42,6 +42,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.wavelet; namespace CSJ2K.j2k.codestream { @@ -51,7 +52,7 @@ namespace CSJ2K.j2k.codestream /// in these headers. /// /// - public class HeaderInfo : FilterTypes, System.ICloneable + public class HeaderInfo : FilterTypes { /// Returns a new instance of SIZ virtual public SIZ NewSIZ @@ -155,7 +156,7 @@ namespace CSJ2K.j2k.codestream //UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'SIZ' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'" /// Internal class holding information found in the SIZ marker segment - public class SIZ : System.ICloneable + public class SIZ { public SIZ(HeaderInfo enclosingInstance) { @@ -242,9 +243,9 @@ namespace CSJ2K.j2k.codestream ms = (SIZ) this.Clone(); } //UPGRADE_NOTE: Exception 'java.lang.CloneNotSupportedException' was converted to 'System.Exception' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - catch (System.Exception) + catch (System.Exception e) { - throw new System.ApplicationException("Cannot clone SIZ marker segment"); + throw new System.InvalidOperationException("Cannot clone SIZ marker segment"); } return ms; } @@ -421,7 +422,7 @@ namespace CSJ2K.j2k.codestream //UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'COD' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'" /// Internal class holding information found in the COD marker segments - public class COD : System.ICloneable + public class COD { public COD(HeaderInfo enclosingInstance) { @@ -442,9 +443,9 @@ namespace CSJ2K.j2k.codestream ms = (COD) this.Clone(); } //UPGRADE_NOTE: Exception 'java.lang.CloneNotSupportedException' was converted to 'System.Exception' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - catch (System.Exception) + catch (System.Exception e) { - throw new System.ApplicationException("Cannot clone SIZ marker segment"); + throw new System.InvalidOperationException("Cannot clone SIZ marker segment"); } return ms; } @@ -1086,7 +1087,7 @@ namespace CSJ2K.j2k.codestream else if (rcom == 1) { str += (" Registration : General use (IS 8859-15:1999 " + "(Latin) values)\n"); - str += (" Text : " + System.Text.ASCIIEncoding.ASCII.GetString(ccom) + "\n"); + str += (" Text : " + System.Text.Encoding.UTF8.GetString(ccom, 0, ccom.Length) + "\n"); } else { @@ -1103,40 +1104,40 @@ namespace CSJ2K.j2k.codestream /// Reference to the SOT marker segments found in tile-part headers. The /// kwy is given by "t"+tileIdx"_tp"+tilepartIndex. /// - public System.Collections.Hashtable sotValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + public System.Collections.Generic.Dictionary sotValue = new Dictionary(); /// Reference to the COD marker segments found in main and first tile-part /// header. The key is either "main" or "t"+tileIdx. /// - public System.Collections.Hashtable codValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); - + public System.Collections.Generic.Dictionary codValue = new Dictionary(); + /// Reference to the COC marker segments found in main and first tile-part /// header. The key is either "main_c"+componentIndex or /// "t"+tileIdx+"_c"+component_index. /// - public System.Collections.Hashtable cocValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + public System.Collections.Generic.Dictionary cocValue = new Dictionary(); /// Reference to the RGN marker segments found in main and first tile-part /// header. The key is either "main_c"+componentIndex or /// "t"+tileIdx+"_c"+component_index. /// - public System.Collections.Hashtable rgnValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + public System.Collections.Generic.Dictionary rgnValue = new Dictionary(); /// Reference to the QCD marker segments found in main and first tile-part /// header. The key is either "main" or "t"+tileIdx. /// - public System.Collections.Hashtable qcdValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + public System.Collections.Generic.Dictionary qcdValue = new Dictionary(); /// Reference to the QCC marker segments found in main and first tile-part /// header. They key is either "main_c"+componentIndex or /// "t"+tileIdx+"_c"+component_index. /// - public System.Collections.Hashtable qccValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + public System.Collections.Generic.Dictionary qccValue = new Dictionary(); /// Reference to the POC marker segments found in main and first tile-part /// header. They key is either "main" or "t"+tileIdx. /// - public System.Collections.Hashtable pocValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + public System.Collections.Generic.Dictionary pocValue = new Dictionary(); /// Reference to the CRG marker segment found in main header public CRG crgValue; @@ -1144,7 +1145,7 @@ namespace CSJ2K.j2k.codestream /// Reference to the COM marker segments found in main and tile-part /// headers. The key is either "main_"+comIdx or "t"+tileIdx+"_"+comIdx. /// - public System.Collections.Hashtable comValue = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + public System.Collections.Generic.Dictionary comValue = new Dictionary(); /// Number of found COM marker segment private int ncom = 0; @@ -1339,9 +1340,9 @@ namespace CSJ2K.j2k.codestream nhi = (HeaderInfo) Clone(); } //UPGRADE_NOTE: Exception 'java.lang.CloneNotSupportedException' was converted to 'System.Exception' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - catch (System.Exception) + catch (System.Exception e) { - throw new System.ApplicationException("Cannot clone HeaderInfo instance"); + throw new System.InvalidOperationException("Cannot clone HeaderInfo instance"); } nhi.sizValue = sizValue.Copy; // COD diff --git a/CSJ2K/j2k/codestream/Markers.cs b/CSJ2K/j2k/codestream/Markers.cs index 536d2d9e..7a3a7bb2 100644 --- a/CSJ2K/j2k/codestream/Markers.cs +++ b/CSJ2K/j2k/codestream/Markers.cs @@ -151,9 +151,7 @@ namespace CSJ2K.j2k.codestream public const short CRG = unchecked((short)0xff63); /// Comment (COM): 0xFF64 public const short COM = unchecked((short)0xff64); - /// General use registration value (binary) (COM): 0x0000 - public const short RCOM_BINARY = 0; - /// General use registration value (latin) (COM): 0x0001 - public const short RCOM_LATIN = 1; + /// General use registration value (COM): 0x0001 + public const short RCOM_GEN_USE = unchecked((short)0x0001); } } \ No newline at end of file diff --git a/CSJ2K/j2k/codestream/reader/BitstreamReaderAgent.cs b/CSJ2K/j2k/codestream/reader/BitstreamReaderAgent.cs index a732fcbc..098b6f46 100644 --- a/CSJ2K/j2k/codestream/reader/BitstreamReaderAgent.cs +++ b/CSJ2K/j2k/codestream/reader/BitstreamReaderAgent.cs @@ -760,7 +760,7 @@ namespace CSJ2K.j2k.codestream.reader int tIdx = TileIdx; if (t != tIdx) { - throw new System.ApplicationException("Asking the tile-component width of a tile " + "different from the current one."); + throw new System.InvalidOperationException("Asking the tile-component width of a tile " + "different from the current one."); } int ntulx; int dl = mdl[c] - rl; @@ -795,7 +795,7 @@ namespace CSJ2K.j2k.codestream.reader int tIdx = TileIdx; if (t != tIdx) { - throw new System.ApplicationException("Asking the tile-component width of a tile " + "different from the current one."); + throw new System.InvalidOperationException("Asking the tile-component width of a tile " + "different from the current one."); } int ntuly; int dl = mdl[c] - rl; // Revert level indexation (0 is hi-res) @@ -1232,7 +1232,7 @@ namespace CSJ2K.j2k.codestream.reader break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } if (sb.ulcx - acb0x < 0 || sb.ulcy - acb0y < 0) diff --git a/CSJ2K/j2k/codestream/reader/FileBitstreamReaderAgent.cs b/CSJ2K/j2k/codestream/reader/FileBitstreamReaderAgent.cs index 9309377c..d1a7cb47 100644 --- a/CSJ2K/j2k/codestream/reader/FileBitstreamReaderAgent.cs +++ b/CSJ2K/j2k/codestream/reader/FileBitstreamReaderAgent.cs @@ -41,6 +41,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.quantization.dequantizer; using CSJ2K.j2k.wavelet.synthesis; using CSJ2K.j2k.entropy.decoder; @@ -113,7 +114,7 @@ namespace CSJ2K.j2k.codestream.reader { if (firstPackOff == null || firstPackOff[t] == null) { - throw new System.ApplicationException("Tile " + t + " not found in input codestream."); + throw new System.InvalidOperationException("Tile " + t + " not found in input codestream."); } return firstPackOff[t].Length; } @@ -160,10 +161,7 @@ namespace CSJ2K.j2k.codestream.reader private int[][] tilePartHeadLen; /// Length of each packet head found in the tile - private System.Collections.ArrayList pktHL; - - /// Layer starting positions - public System.Collections.Generic.List layerStarts; + private System.Collections.Generic.List pktHL; /// True if truncation mode is used. False if parsing mode private bool isTruncMode; @@ -243,6 +241,7 @@ namespace CSJ2K.j2k.codestream.reader this.pl = pl; this.printInfo = cdstrInfo; this.hi = hi; + System.String strInfo = "Codestream elements information in bytes " + "(offset, total length, header length):\n\n"; // Check whether quit conditiosn used usePOCQuit = pl.getBooleanParameter("poc_quit"); @@ -258,26 +257,26 @@ namespace CSJ2K.j2k.codestream.reader trate = System.Single.MaxValue; } } - catch (System.FormatException) + catch (System.FormatException e) { - throw new System.ApplicationException("Invalid value in 'rate' option: " + pl.getParameter("rate")); + throw new System.InvalidOperationException("Invalid value in 'rate' option: " + pl.getParameter("rate")); } - catch (System.ArgumentException) + catch (System.ArgumentException e) { - throw new System.ApplicationException("'rate' option is missing"); + throw new System.InvalidOperationException("'rate' option is missing"); } try { tnbytes = pl.getIntParameter("nbytes"); } - catch (System.FormatException) + catch (System.FormatException e) { - throw new System.ApplicationException("Invalid value in 'nbytes' option: " + pl.getParameter("nbytes")); + throw new System.InvalidOperationException("Invalid value in 'nbytes' option: " + pl.getParameter("nbytes")); } - catch (System.ArgumentException) + catch (System.ArgumentException e) { - throw new System.ApplicationException("'nbytes' option is missing"); + throw new System.InvalidOperationException("'nbytes' option is missing"); } // Check that '-rate' and '-nbytes' are not used at the same time @@ -299,7 +298,7 @@ namespace CSJ2K.j2k.codestream.reader { //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'" tnbytes = (int) (trate * hd.MaxCompImgWidth * hd.MaxCompImgHeight) / 8; - if (tnbytes <= 0) tnbytes = int.MaxValue; + if (tnbytes < 0) tnbytes = int.MaxValue; } isTruncMode = !pl.getBooleanParameter("parsing"); @@ -309,30 +308,30 @@ namespace CSJ2K.j2k.codestream.reader { ncbQuit = pl.getIntParameter("ncb_quit"); } - catch (System.FormatException) + catch (System.FormatException e) { - throw new System.ApplicationException("Invalid value in 'ncb_quit' option: " + pl.getParameter("ncb_quit")); + throw new System.InvalidOperationException("Invalid value in 'ncb_quit' option: " + pl.getParameter("ncb_quit")); } - catch (System.ArgumentException) + catch (System.ArgumentException e) { - throw new System.ApplicationException("'ncb_quit' option is missing"); + throw new System.InvalidOperationException("'ncb_quit' option is missing"); } if (ncbQuit != - 1 && !isTruncMode) { - throw new System.ApplicationException("Cannot use -parsing and -ncb_quit condition at " + "the same time."); + throw new System.InvalidOperationException("Cannot use -parsing and -ncb_quit condition at " + "the same time."); } try { lQuit = pl.getIntParameter("l_quit"); } - catch (System.FormatException) + catch (System.FormatException e) { - throw new System.ApplicationException("Invalid value in 'l_quit' option: " + pl.getParameter("l_quit")); + throw new System.InvalidOperationException("Invalid value in 'l_quit' option: " + pl.getParameter("l_quit")); } - catch (System.ArgumentException) + catch (System.ArgumentException e) { - throw new System.ApplicationException("'l_quit' option is missing"); + throw new System.InvalidOperationException("'l_quit' option is missing"); } // initializations @@ -370,10 +369,12 @@ namespace CSJ2K.j2k.codestream.reader anbytes = 0; } + strInfo += ("Main header length : " + cdstreamStart + ", " + mainHeadLen + ", " + mainHeadLen + "\n"); + // If cannot even read the first tile-part if (anbytes > tnbytes) { - throw new System.ApplicationException("Requested bitrate is too small."); + throw new System.InvalidOperationException("Requested bitrate is too small."); } // Read all tile-part headers from all tiles. @@ -435,6 +436,8 @@ namespace CSJ2K.j2k.codestream.reader firstPackOff[t][tp] = pos; tilePartHeadLen[t][tp] = (pos - tilePartStart); + strInfo += ("Tile-part " + tp + " of tile " + t + " : " + tilePartStart + ", " + tilePartLen[t][tp] + ", " + tilePartHeadLen[t][tp] + "\n"); + // Update length counters totTileLen[t] += tilePartLen[t][tp]; totTileHeadLen[t] += tilePartHeadLen[t][tp]; @@ -492,10 +495,11 @@ namespace CSJ2K.j2k.codestream.reader } } } - catch (System.IO.EndOfStreamException) + catch (System.IO.EndOfStreamException e) { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Codestream truncated in tile " + t); @@ -528,7 +532,7 @@ namespace CSJ2K.j2k.codestream.reader throw new System.ArgumentException("Specified negative " + "resolution level " + "index: " + targetRes); } } - catch (System.FormatException) + catch (System.FormatException f) { throw new System.ArgumentException("Invalid resolution level " + "index ('-res' option) " + pl.getParameter("res")); } @@ -567,7 +571,7 @@ namespace CSJ2K.j2k.codestream.reader throw new System.ArgumentException("Specified negative " + "resolution level index: " + targetRes); } } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Invalid resolution level " + "index ('-res' option) " + pl.getParameter("res")); } @@ -583,6 +587,7 @@ namespace CSJ2K.j2k.codestream.reader if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } // Check presence of EOC marker is decoding rate not reached or if @@ -591,16 +596,12 @@ namespace CSJ2K.j2k.codestream.reader { try { - short eocCheck = 0; - if (in_Renamed.Pos + sizeof(short) <= in_Renamed.length()) - eocCheck = in_Renamed.readShort(); - - if (!rateReached && !isPsotEqualsZero && eocCheck != CSJ2K.j2k.codestream.Markers.EOC) + if (!rateReached && !isPsotEqualsZero && in_Renamed.readShort() != CSJ2K.j2k.codestream.Markers.EOC) { FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "EOC marker not found. " + "Codestream is corrupted."); } } - catch (System.IO.EndOfStreamException) + catch (System.IO.EndOfStreamException e) { FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "EOC marker is missing"); } @@ -648,7 +649,7 @@ namespace CSJ2K.j2k.codestream.reader // error if (anbytes > stopOff) { - throw new System.ApplicationException("Requested bitrate is too small for parsing"); + throw new System.InvalidOperationException("Requested bitrate is too small for parsing"); } // Calculate bitrate for each tile @@ -710,7 +711,7 @@ namespace CSJ2K.j2k.codestream.reader isPsotEqualsZero = (psot != 0)?false:true; if (psot < 0) { - throw new NotImplementedException("Tile length larger " + "than maximum supported"); + throw new NotImplementedException("Tile length larger " + "than maximum supported"); } // TPsot int tilePart = in_Renamed.read(); @@ -927,6 +928,7 @@ namespace CSJ2K.j2k.codestream.reader int numLayers = ((System.Int32) decSpec.nls.getTileDef(t)); int nPrec = 1; int hlen, plen; + System.String strInfo = "Tile " + TileIdx + " (tile-part:" + curTilePart + "): offset, length, header length\n"; ; bool pph = false; if (((System.Boolean) decSpec.pphs.getTileDef(t))) { @@ -934,9 +936,6 @@ namespace CSJ2K.j2k.codestream.reader } for (int l = minlys; l < lye; l++) { - // store the layer starting position - layerStarts.Add(in_Renamed.Pos); - // loop on layers for (int r = ress; r < rese; r++) { @@ -985,6 +984,7 @@ namespace CSJ2K.j2k.codestream.reader { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -998,6 +998,7 @@ namespace CSJ2K.j2k.codestream.reader { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1009,11 +1010,13 @@ namespace CSJ2K.j2k.codestream.reader // Reads packet's body status = pktDec.readPktBody(l, r, c, p, cbI[c][r], nBytes); plen = in_Renamed.Pos - start; + strInfo += (" Pkt l=" + l + ",r=" + r + ",c=" + c + ",p=" + p + ": " + start + ", " + plen + ", " + hlen + "\n"); if (status) { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1024,6 +1027,7 @@ namespace CSJ2K.j2k.codestream.reader if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return false; // Decoding rate was not reached } @@ -1079,6 +1083,7 @@ namespace CSJ2K.j2k.codestream.reader } } + System.String strInfo = "Tile " + TileIdx + " (tile-part:" + curTilePart + "): offset, length, header length\n"; ; int numLayers = ((System.Int32) decSpec.nls.getTileDef(t)); bool pph = false; if (((System.Boolean) decSpec.pphs.getTileDef(t))) @@ -1139,6 +1144,7 @@ namespace CSJ2K.j2k.codestream.reader { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1152,6 +1158,7 @@ namespace CSJ2K.j2k.codestream.reader { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } // Output rate of EOF reached return true; @@ -1164,11 +1171,13 @@ namespace CSJ2K.j2k.codestream.reader // Reads packet's body status = pktDec.readPktBody(l, r, c, p, cbI[c][r], nBytes); plen = in_Renamed.Pos - start; + strInfo += (" Pkt l=" + l + ",r=" + r + ",c=" + c + ",p=" + p + ": " + start + ", " + plen + ", " + hlen + "\n"); if (status) { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } // Output rate or EOF reached return true; @@ -1180,6 +1189,7 @@ namespace CSJ2K.j2k.codestream.reader if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return false; // Decoding rate was not reached } @@ -1298,7 +1308,7 @@ namespace CSJ2K.j2k.codestream.reader if (nPrec == 0) { - throw new System.ApplicationException("Image cannot have no precinct"); + throw new System.InvalidOperationException("Image cannot have no precinct"); } int pyend = (maxy - miny) / gcd_y + 1; @@ -1309,6 +1319,7 @@ namespace CSJ2K.j2k.codestream.reader bool status = false; int lastByte = firstPackOff[t][curTilePart] + tilePartLen[t][curTilePart] - 1 - tilePartHeadLen[t][curTilePart]; int numLayers = ((System.Int32) decSpec.nls.getTileDef(t)); + System.String strInfo = "Tile " + TileIdx + " (tile-part:" + curTilePart + "): offset, length, header length\n"; ; bool pph = false; if (((System.Boolean) decSpec.pphs.getTileDef(t))) { @@ -1375,6 +1386,7 @@ namespace CSJ2K.j2k.codestream.reader { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1388,6 +1400,7 @@ namespace CSJ2K.j2k.codestream.reader { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1399,11 +1412,13 @@ namespace CSJ2K.j2k.codestream.reader // Reads packet's body status = pktDec.readPktBody(l, r, c, nextPrec[c][r], cbI[c][r], nBytes); plen = in_Renamed.Pos - start; + strInfo += (" Pkt l=" + l + ",r=" + r + ",c=" + c + ",p=" + nextPrec[c][r] + ": " + start + ", " + plen + ", " + hlen + "\n"); if (status) { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1432,6 +1447,7 @@ namespace CSJ2K.j2k.codestream.reader if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return false; // Decoding rate was not reached } @@ -1548,7 +1564,7 @@ namespace CSJ2K.j2k.codestream.reader if (nPrec == 0) { - throw new System.ApplicationException("Image cannot have no precinct"); + throw new System.InvalidOperationException("Image cannot have no precinct"); } int pyend = (maxy - miny) / gcd_y + 1; @@ -1558,6 +1574,7 @@ namespace CSJ2K.j2k.codestream.reader bool status = false; int lastByte = firstPackOff[t][curTilePart] + tilePartLen[t][curTilePart] - 1 - tilePartHeadLen[t][curTilePart]; int numLayers = ((System.Int32) decSpec.nls.getTileDef(t)); + System.String strInfo = "Tile " + TileIdx + " (tile-part:" + curTilePart + "): offset, length, header length\n"; ; bool pph = false; if (((System.Boolean) decSpec.pphs.getTileDef(t))) { @@ -1625,6 +1642,7 @@ namespace CSJ2K.j2k.codestream.reader { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1638,6 +1656,7 @@ namespace CSJ2K.j2k.codestream.reader { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1649,11 +1668,13 @@ namespace CSJ2K.j2k.codestream.reader // Reads packet's body status = pktDec.readPktBody(l, r, c, nextPrec[c][r], cbI[c][r], nBytes); plen = in_Renamed.Pos - start; + strInfo += (" Pkt l=" + l + ",r=" + r + ",c=" + c + ",p=" + nextPrec[c][r] + ": " + start + ", " + plen + ", " + hlen + "\n"); if (status) { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1682,6 +1703,7 @@ namespace CSJ2K.j2k.codestream.reader if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return false; // Decoding rate was not reached } @@ -1798,7 +1820,7 @@ namespace CSJ2K.j2k.codestream.reader if (nPrec == 0) { - throw new System.ApplicationException("Image cannot have no precinct"); + throw new System.InvalidOperationException("Image cannot have no precinct"); } int pyend = (maxy - miny) / gcd_y + 1; @@ -1808,6 +1830,7 @@ namespace CSJ2K.j2k.codestream.reader bool status = false; int lastByte = firstPackOff[t][curTilePart] + tilePartLen[t][curTilePart] - 1 - tilePartHeadLen[t][curTilePart]; int numLayers = ((System.Int32) decSpec.nls.getTileDef(t)); + System.String strInfo = "Tile " + TileIdx + " (tile-part:" + curTilePart + "): offset, length, header length\n"; ; bool pph = false; if (((System.Boolean) decSpec.pphs.getTileDef(t))) { @@ -1877,6 +1900,7 @@ namespace CSJ2K.j2k.codestream.reader { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1890,6 +1914,7 @@ namespace CSJ2K.j2k.codestream.reader { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1901,11 +1926,13 @@ namespace CSJ2K.j2k.codestream.reader // Reads packet's body status = pktDec.readPktBody(l, r, c, nextPrec[c][r], cbI[c][r], nBytes); plen = in_Renamed.Pos - start; + strInfo += (" Pkt l=" + l + ",r=" + r + ",c=" + c + ",p=" + nextPrec[c][r] + ": " + start + ", " + plen + ", " + hlen + "\n"); if (status) { if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return true; } @@ -1934,6 +1961,7 @@ namespace CSJ2K.j2k.codestream.reader if (printInfo) { + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo); } return false; // Decoding rate was not reached } @@ -1956,8 +1984,7 @@ namespace CSJ2K.j2k.codestream.reader /// private void readTilePkts(int t) { - pktHL = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); - layerStarts = new System.Collections.Generic.List(5); + pktHL = new List(10); // Number of layers int nl = ((System.Int32) decSpec.nls.getTileDef(t)); @@ -2030,7 +2057,7 @@ namespace CSJ2K.j2k.codestream.reader } in_Renamed.seek(firstPackOff[t][0]); } - catch (System.IO.EndOfStreamException) + catch (System.IO.EndOfStreamException e) { FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Codestream truncated in tile " + t); return ; @@ -2365,8 +2392,8 @@ namespace CSJ2K.j2k.codestream.reader } catch (System.IO.IOException e) { - SupportClass.WriteStackTrace(e, Console.Error); - throw new System.ApplicationException("IO Error when reading tile " + x + " x " + y); + SupportClass.WriteStackTrace(e); + throw new System.InvalidOperationException("IO Error when reading tile " + x + " x " + y); } } @@ -2482,7 +2509,7 @@ namespace CSJ2K.j2k.codestream.reader int maxdl = getSynSubbandTree(t, c).resLvl; if (r > targetRes + maxdl - decSpec.dls.Min) { - throw new System.ApplicationException("JJ2000 error: requesting a code-block " + "disallowed by the '-res' option."); + throw new System.InvalidOperationException("JJ2000 error: requesting a code-block " + "disallowed by the '-res' option."); } // Check validity of all the arguments @@ -2495,11 +2522,11 @@ namespace CSJ2K.j2k.codestream.reader throw new System.ArgumentException(); } } - catch (System.IndexOutOfRangeException) + catch (System.IndexOutOfRangeException e) { throw new System.ArgumentException("Code-block (t:" + t + ", c:" + c + ", r:" + r + ", s:" + s + ", " + m + "x" + (+ n) + ") not found in codestream"); } - catch (System.NullReferenceException) + catch (System.NullReferenceException e) { throw new System.ArgumentException("Code-block (t:" + t + ", c:" + c + ", r:" + r + ", s:" + s + ", " + m + "x" + n + ") not found in bit stream"); } @@ -2727,4 +2754,4 @@ namespace CSJ2K.j2k.codestream.reader return ccb; } } -} +} \ No newline at end of file diff --git a/CSJ2K/j2k/codestream/reader/HeaderDecoder.cs b/CSJ2K/j2k/codestream/reader/HeaderDecoder.cs index fb12a38d..db019851 100644 --- a/CSJ2K/j2k/codestream/reader/HeaderDecoder.cs +++ b/CSJ2K/j2k/codestream/reader/HeaderDecoder.cs @@ -41,6 +41,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.quantization.dequantizer; using CSJ2K.j2k.wavelet.synthesis; using CSJ2K.j2k.entropy.decoder; @@ -451,7 +452,7 @@ namespace CSJ2K.j2k.codestream.reader //private static readonly int TILE_RESET = ~ (PLM_FOUND | SIZ_FOUND | RGN_FOUND); /// HashTable used to store temporary marker segment byte buffers - private System.Collections.Hashtable ht = null; + private System.Collections.Generic.Dictionary ht = null; /// The number of components in the image private int nComp; @@ -472,7 +473,7 @@ namespace CSJ2K.j2k.codestream.reader public int mainHeadOff; /// Vector containing info as to which tile each tilepart belong - private System.Collections.ArrayList tileOfTileParts; + private System.Collections.Generic.List tileOfTileParts; /// Array containing the Nppm and Ippm fields of the PPM marker segments private byte[][] pPMMarkerData; @@ -667,7 +668,7 @@ namespace CSJ2K.j2k.codestream.reader kid = filtIdx[0] = ehs.ReadByte(); if (kid >= (1 << 7)) { - throw new NotImplementedException("Custom filters not supported"); + throw new NotImplementedException("Custom filters not supported"); } // Return filter based on ID switch (kid) @@ -736,7 +737,7 @@ namespace CSJ2K.j2k.codestream.reader ms.rsiz = ehs.ReadUInt16(); if (ms.rsiz > 2) { - throw new System.ApplicationException("Codestream capabiities not JPEG 2000 - Part I" + " compliant"); + throw new System.InvalidOperationException("Codestream capabiities not JPEG 2000 - Part I" + " compliant"); } // Read image size @@ -865,18 +866,19 @@ namespace CSJ2K.j2k.codestream.reader ms.rcom = ehs.ReadUInt16(); switch (ms.rcom) { - case CSJ2K.j2k.codestream.Markers.RCOM_BINARY: - case CSJ2K.j2k.codestream.Markers.RCOM_LATIN: + + case CSJ2K.j2k.codestream.Markers.RCOM_GEN_USE: ms.ccom = new byte[ms.lcom - 4]; for (int i = 0; i < ms.lcom - 4; i++) { ms.ccom[i] = ehs.ReadByte(); } break; - default: + + default: // --- Unknown or unsupported markers --- // (skip them and see if we can get way with it) - FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "COM marker registered as " + ms.rcom + " unknown, ignoring (this might crash the " + "decoder or decode a quality degraded or even " + "useless image)"); + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "COM marker registered as 0x" + System.Convert.ToString(ms.rcom, 16) + " unknown, ignoring (this might crash the " + "decoder or decode a quality degraded or even " + "useless image)"); System.IO.BinaryReader temp_BinaryReader; System.Int64 temp_Int64; temp_BinaryReader = ehs; @@ -1596,9 +1598,9 @@ namespace CSJ2K.j2k.codestream.reader hvfilters[1] = vfilters; // Get precinct partition sizes - System.Collections.ArrayList[] v = new System.Collections.ArrayList[2]; - v[0] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); - v[1] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + System.Collections.Generic.List[] v = new System.Collections.Generic.List[2]; + v[0] = new List(10); + v[1] = new List(10); int val = CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE; if (!precinctPartitionIsUsed) { @@ -1774,9 +1776,9 @@ namespace CSJ2K.j2k.codestream.reader hvfilters[1] = vfilters; // Get precinct partition sizes - System.Collections.ArrayList[] v = new System.Collections.ArrayList[2]; - v[0] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); - v[1] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + System.Collections.Generic.List[] v = new System.Collections.Generic.List[2]; + v[0] = new List(10); + v[1] = new List(10); int val = CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE; if (!precinctPartitionIsUsed) { @@ -2186,7 +2188,7 @@ namespace CSJ2K.j2k.codestream.reader if (pPMMarkerData == null) { pPMMarkerData = new byte[nPPMMarkSeg][]; - tileOfTileParts = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + tileOfTileParts = new List(10); decSpec.pphs.setDefault((System.Object) true); } @@ -2292,7 +2294,7 @@ namespace CSJ2K.j2k.codestream.reader System.String htKey = ""; // Name used as a key for the hash-table if (ht == null) { - ht = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + ht = new Dictionary(); } switch (marker) @@ -2458,7 +2460,7 @@ namespace CSJ2K.j2k.codestream.reader System.String htKey = ""; // Name used as a hash-table key if (ht == null) { - ht = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); + ht = new Dictionary(); } switch (marker) @@ -2594,7 +2596,6 @@ namespace CSJ2K.j2k.codestream.reader { bais = new System.IO.MemoryStream((byte[])ht["SIZ"]); readSIZ(new CSJ2K.Util.EndianBinaryReader(bais, true)); - bais.Dispose(); } // COM marker segments @@ -2604,7 +2605,6 @@ namespace CSJ2K.j2k.codestream.reader { bais = new System.IO.MemoryStream((byte[])ht["COM" + i]); readCOM(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, i); - bais.Dispose(); } } @@ -2613,7 +2613,6 @@ namespace CSJ2K.j2k.codestream.reader { bais = new System.IO.MemoryStream((byte[])ht["CRG"]); readCRG(new CSJ2K.Util.EndianBinaryReader(bais, true)); - bais.Dispose(); } // COD marker segment @@ -2621,7 +2620,6 @@ namespace CSJ2K.j2k.codestream.reader { bais = new System.IO.MemoryStream((byte[])ht["COD"]); readCOD(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); - bais.Dispose(); } // COC marker segments @@ -2631,7 +2629,6 @@ namespace CSJ2K.j2k.codestream.reader { bais = new System.IO.MemoryStream((byte[])ht["COC" + i]); readCOC(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); - bais.Dispose(); } } @@ -2642,7 +2639,6 @@ namespace CSJ2K.j2k.codestream.reader { bais = new System.IO.MemoryStream((byte[])ht["RGN" + i]); readRGN(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); - bais.Dispose(); } } @@ -2651,7 +2647,6 @@ namespace CSJ2K.j2k.codestream.reader { bais = new System.IO.MemoryStream((byte[])ht["QCD"]); readQCD(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); - bais.Dispose(); } // QCC marker segments @@ -2661,7 +2656,6 @@ namespace CSJ2K.j2k.codestream.reader { bais = new System.IO.MemoryStream((byte[])ht["QCC" + i]); readQCC(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); - bais.Dispose(); } } @@ -2670,7 +2664,6 @@ namespace CSJ2K.j2k.codestream.reader { bais = new System.IO.MemoryStream((byte[])ht["POC"]); readPOC(new CSJ2K.Util.EndianBinaryReader(bais, true), true, 0, 0); - bais.Dispose(); } // PPM marker segments @@ -2680,7 +2673,6 @@ namespace CSJ2K.j2k.codestream.reader { bais = new System.IO.MemoryStream((byte[])ht["PPM" + i]); readPPM(new CSJ2K.Util.EndianBinaryReader(bais)); - bais.Dispose(); } } diff --git a/CSJ2K/j2k/codestream/reader/PktDecoder.cs b/CSJ2K/j2k/codestream/reader/PktDecoder.cs index ac4390d5..1fbfca2c 100644 --- a/CSJ2K/j2k/codestream/reader/PktDecoder.cs +++ b/CSJ2K/j2k/codestream/reader/PktDecoder.cs @@ -42,6 +42,7 @@ /// /// using System; +using System.Collections.Generic; using CSJ2K.j2k.wavelet.synthesis; using CSJ2K.j2k.codestream; using CSJ2K.j2k.entropy; @@ -168,7 +169,7 @@ namespace CSJ2K.j2k.codestream.reader /// List of code-blocks found in last read packet head (one list /// per subband) /// - private System.Collections.ArrayList[] cblks; + private System.Collections.Generic.List[] cblks; /// Number of codeblocks encountered. used for ncb quit condition private int ncb; @@ -991,10 +992,10 @@ namespace CSJ2K.j2k.codestream.reader if (bin.readBit() == 0) { // No code-block is included - cblks = new System.Collections.ArrayList[maxs + 1]; + cblks = new List[maxs + 1]; for (int s = mins; s < maxs; s++) { - cblks[s] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + cblks[s] = new List(10); } pktIdx++; @@ -1027,14 +1028,14 @@ namespace CSJ2K.j2k.codestream.reader // Loop on each subband in this resolution level if (cblks == null || cblks.Length < maxs + 1) { - cblks = new System.Collections.ArrayList[maxs + 1]; + cblks = new List[maxs + 1]; } for (int s = mins; s < maxs; s++) { if (cblks[s] == null) { - cblks[s] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + cblks[s] = new List(10); } else { @@ -1310,7 +1311,7 @@ namespace CSJ2K.j2k.codestream.reader } } } - catch (System.IO.EndOfStreamException) + catch (System.IO.EndOfStreamException e) { // Remove found information in this code-block if (l == 0) @@ -1420,7 +1421,7 @@ namespace CSJ2K.j2k.codestream.reader { ehs.seek(curOff); } - catch (System.IO.EndOfStreamException) + catch (System.IO.EndOfStreamException e) { if (l == 0) { @@ -1433,13 +1434,7 @@ namespace CSJ2K.j2k.codestream.reader ccb.ntp[l] = 0; ccb.pktIdx[l] = - 1; } - - // JH: If we try and seek past the end of the stream just stop the decoding - curOff = ehs.length() - 1; - ehs.seek(curOff); - stopRead = true; - return true; - //throw new System.IO.EndOfStreamException(); + throw new System.IO.EndOfStreamException(); } // If truncation mode @@ -1601,7 +1596,7 @@ namespace CSJ2K.j2k.codestream.reader val |= sopArray[1]; if (val != CSJ2K.j2k.codestream.Markers.SOP) { - throw new System.ApplicationException("Corrupted Bitstream: Could not parse SOP " + "marker !"); + throw new System.InvalidOperationException("Corrupted Bitstream: Could not parse SOP " + "marker !"); } // Check if length is correct @@ -1610,7 +1605,7 @@ namespace CSJ2K.j2k.codestream.reader val |= (sopArray[3] & 0xff); if (val != 4) { - throw new System.ApplicationException("Corrupted Bitstream: Corrupted SOP marker !"); + throw new System.InvalidOperationException("Corrupted Bitstream: Corrupted SOP marker !"); } // Check if sequence number if ok @@ -1620,13 +1615,13 @@ namespace CSJ2K.j2k.codestream.reader if (!pph && val != pktIdx) { - throw new System.ApplicationException("Corrupted Bitstream: SOP marker out of " + "sequence !"); + throw new System.InvalidOperationException("Corrupted Bitstream: SOP marker out of " + "sequence !"); } if (pph && val != pktIdx - 1) { // if packed packet headers are used, packet header was read // before SOP marker segment - throw new System.ApplicationException("Corrupted Bitstream: SOP marker out of " + "sequence !"); + throw new System.InvalidOperationException("Corrupted Bitstream: SOP marker out of " + "sequence !"); } return false; } @@ -1658,7 +1653,7 @@ namespace CSJ2K.j2k.codestream.reader val |= ephArray[1]; if (val != CSJ2K.j2k.codestream.Markers.EPH) { - throw new System.ApplicationException("Corrupted Bitstream: Could not parse EPH " + "marker ! "); + throw new System.InvalidOperationException("Corrupted Bitstream: Could not parse EPH " + "marker ! "); } } diff --git a/CSJ2K/j2k/codestream/writer/FileCodestreamWriter.cs b/CSJ2K/j2k/codestream/writer/FileCodestreamWriter.cs index 5e29491a..3d581cf1 100644 --- a/CSJ2K/j2k/codestream/writer/FileCodestreamWriter.cs +++ b/CSJ2K/j2k/codestream/writer/FileCodestreamWriter.cs @@ -41,6 +41,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; using CSJ2K.j2k.codestream; namespace CSJ2K.j2k.codestream.writer { @@ -147,7 +148,8 @@ namespace CSJ2K.j2k.codestream.writer /// Length of last packets containing no ROI information private int lenLastNoROI = 0; - + +#if DOTNET /// Opens the file 'file' for writing the codestream. The magic number is /// written to the bit stream. Normally, the header encoder must be empty /// (i.e. no data has been written to it yet). A BufferedOutputStream is @@ -166,41 +168,15 @@ namespace CSJ2K.j2k.codestream.writer /// for writing or while writing the magic number. /// /// - public FileCodestreamWriter(System.IO.FileInfo file, int mb):base(mb) + public FileCodestreamWriter(System.IO.FileInfo file, int mb) + : base(mb) { //UPGRADE_TODO: Constructor 'java.io.FileOutputStream.FileOutputStream' was converted to 'System.IO.FileStream.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioFileOutputStreamFileOutputStream_javaioFile'" out_Renamed = new System.IO.BufferedStream(new System.IO.FileStream(file.FullName, System.IO.FileMode.Create), DEF_BUF_LEN); initSOP_EPHArrays(); - } - - /// Opens the file named 'fname' for writing the bit stream, using the 'he' - /// header encoder. The magic number is written to the bit - /// stream. Normally, the header encoder must be empty (i.e. no data has - /// been written to it yet). A BufferedOutputStream is used on top of the - /// file to increase throughput, the length of the buffer is DEF_BUF_LEN. - /// - /// - /// The name of file where to write the bit stream - /// - /// - /// The maximum number of bytes that can be written to the bit - /// stream. - /// - /// - /// The encoder's specifications - /// - /// - /// If an error occurs while trying to open the file - /// for writing or while writing the magic number. - /// - /// - public FileCodestreamWriter(System.String fname, int mb):base(mb) - { - //UPGRADE_TODO: Constructor 'java.io.FileOutputStream.FileOutputStream' was converted to 'System.IO.FileStream.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioFileOutputStreamFileOutputStream_javalangString'" - out_Renamed = new System.IO.BufferedStream(new System.IO.FileStream(fname, System.IO.FileMode.Create), DEF_BUF_LEN); - initSOP_EPHArrays(); - } - + } +#endif + /// Uses the output stream 'os' for writing the bit stream, using the 'he' /// header encoder. The magic number is written to the bit /// stream. Normally, the header encoder must be empty (i.e. no data has @@ -395,7 +371,7 @@ namespace CSJ2K.j2k.codestream.writer return len; } - /// Writes the EOC marker and closes the underlying stream. + /// Writes the EOC marker. /// /// /// If an error occurs while closing the underlying @@ -411,8 +387,6 @@ namespace CSJ2K.j2k.codestream.writer out_Renamed.WriteByte((byte) (CSJ2K.j2k.codestream.Markers.EOC & 0x00FF)); ndata += 2; // Add two to length of codestream for EOC marker - - out_Renamed.Close(); } /// Writes the header data in the codestream and actualize ndata with the diff --git a/CSJ2K/j2k/codestream/writer/HeaderEncoder.cs b/CSJ2K/j2k/codestream/writer/HeaderEncoder.cs index a27231e9..6bccb1ee 100644 --- a/CSJ2K/j2k/codestream/writer/HeaderEncoder.cs +++ b/CSJ2K/j2k/codestream/writer/HeaderEncoder.cs @@ -666,14 +666,14 @@ namespace CSJ2K.j2k.codestream.writer { // Write the precinct size for each resolution level + 1 // (resolution 0) if precinct partition is used. - System.Collections.ArrayList[] v = null; + System.Collections.Generic.List[] v = null; if (mh) { - v = (System.Collections.ArrayList[]) encSpec.pss.getDefault(); + v = (System.Collections.Generic.List[])encSpec.pss.getDefault(); } else { - v = (System.Collections.ArrayList[]) encSpec.pss.getTileDef(tileIdx); + v = (System.Collections.Generic.List[])encSpec.pss.getTileDef(tileIdx); } for (int r = mrl; r >= 0; r--) { @@ -903,14 +903,14 @@ namespace CSJ2K.j2k.codestream.writer { // Write the precinct size for each resolution level + 1 // (resolution 0) if precinct partition is used. - System.Collections.ArrayList[] v = null; + System.Collections.Generic.List[] v = null; if (mh) { - v = (System.Collections.ArrayList[]) encSpec.pss.getCompDef(compIdx); + v = (System.Collections.Generic.List[])encSpec.pss.getCompDef(compIdx); } else { - v = (System.Collections.ArrayList[]) encSpec.pss.getTileCompVal(tileIdx, compIdx); + v = (System.Collections.Generic.List[])encSpec.pss.getTileCompVal(tileIdx, compIdx); } for (int r = mrl; r >= 0; r--) { @@ -983,7 +983,7 @@ namespace CSJ2K.j2k.codestream.writer } if (notFound) { - throw new System.ApplicationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in main QCD marker segment. " + "You have found a JJ2000 bug."); + throw new System.InvalidOperationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in main QCD marker segment. " + "You have found a JJ2000 bug."); } SubbandAn sb, csb, sbRoot = dwt.getAnSubbandTree(tcIdx[0], tcIdx[1]); defimgn = dwt.getNomRangeBits(tcIdx[1]); @@ -1029,7 +1029,7 @@ namespace CSJ2K.j2k.codestream.writer break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } @@ -1104,7 +1104,7 @@ namespace CSJ2K.j2k.codestream.writer break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } } @@ -1160,7 +1160,7 @@ namespace CSJ2K.j2k.codestream.writer } if (notFound) { - throw new System.ApplicationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in main QCC (c=" + compIdx + ") marker segment. " + "You have found a JJ2000 bug."); + throw new System.InvalidOperationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in main QCC (c=" + compIdx + ") marker segment. " + "You have found a JJ2000 bug."); } sbRoot = dwt.getAnSubbandTree(tIdx, compIdx); @@ -1223,7 +1223,7 @@ namespace CSJ2K.j2k.codestream.writer break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } @@ -1309,7 +1309,7 @@ namespace CSJ2K.j2k.codestream.writer break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } } @@ -1354,7 +1354,7 @@ namespace CSJ2K.j2k.codestream.writer } if (notFound) { - throw new System.ApplicationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in tile QCD (t=" + tIdx + ") marker segment. " + "You have found a JJ2000 bug."); + throw new System.InvalidOperationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in tile QCD (t=" + tIdx + ") marker segment. " + "You have found a JJ2000 bug."); } sbRoot = dwt.getAnSubbandTree(tIdx, compIdx); @@ -1405,7 +1405,7 @@ namespace CSJ2K.j2k.codestream.writer break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } @@ -1480,7 +1480,7 @@ namespace CSJ2K.j2k.codestream.writer break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } } @@ -1576,7 +1576,7 @@ namespace CSJ2K.j2k.codestream.writer break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } @@ -1662,7 +1662,7 @@ namespace CSJ2K.j2k.codestream.writer break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } } @@ -1845,7 +1845,7 @@ namespace CSJ2K.j2k.codestream.writer // Rcom hbuf.Write((System.Int16) 1); // General use (IS 8859-15:1999(Latin) values) - byte[] chars = System.Text.ASCIIEncoding.ASCII.GetBytes(str); + byte[] chars = System.Text.Encoding.UTF8.GetBytes(str); for (int i = 0; i < chars.Length; i++) { hbuf.Write((byte) chars[i]); @@ -1871,7 +1871,7 @@ namespace CSJ2K.j2k.codestream.writer hbuf.Write((System.Int16) 1); // General use (IS 8859-15:1999(Latin) // values) - byte[] chars = System.Text.ASCIIEncoding.ASCII.GetBytes(str); + byte[] chars = System.Text.Encoding.UTF8.GetBytes(str); for (int i = 0; i < chars.Length; i++) { hbuf.Write((byte) chars[i]); diff --git a/CSJ2K/j2k/codestream/writer/PktEncoder.cs b/CSJ2K/j2k/codestream/writer/PktEncoder.cs index 3861977e..b6827f10 100644 --- a/CSJ2K/j2k/codestream/writer/PktEncoder.cs +++ b/CSJ2K/j2k/codestream/writer/PktEncoder.cs @@ -1287,7 +1287,7 @@ namespace CSJ2K.j2k.codestream.writer // Must never happen if (hbuf.Length == 0) { - throw new System.ApplicationException("You have found a bug in PktEncoder, method:" + " encodePacket"); + throw new System.InvalidOperationException("You have found a bug in PktEncoder, method:" + " encodePacket"); } return hbuf; diff --git a/CSJ2K/j2k/decoder/DecoderSpecs.cs b/CSJ2K/j2k/decoder/DecoderSpecs.cs index 707cb183..b8f191ba 100644 --- a/CSJ2K/j2k/decoder/DecoderSpecs.cs +++ b/CSJ2K/j2k/decoder/DecoderSpecs.cs @@ -62,7 +62,7 @@ namespace CSJ2K.j2k.decoder /// /// /// - public class DecoderSpecs : System.ICloneable + public class DecoderSpecs { /// Returns a copy of the current object. /// @@ -77,9 +77,9 @@ namespace CSJ2K.j2k.decoder decSpec2 = (DecoderSpecs) this.Clone(); } //UPGRADE_NOTE: Exception 'java.lang.CloneNotSupportedException' was converted to 'System.Exception' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - catch (System.Exception) + catch (System.Exception e) { - throw new System.ApplicationException("Cannot clone the DecoderSpecs instance"); + throw new System.InvalidOperationException("Cannot clone the DecoderSpecs instance"); } // Quantization decSpec2.qts = (QuantTypeSpec) qts.Copy; diff --git a/CSJ2K/j2k/entropy/CBlkSizeSpec.cs b/CSJ2K/j2k/entropy/CBlkSizeSpec.cs index fd2cd3e2..a4c32840 100644 --- a/CSJ2K/j2k/entropy/CBlkSizeSpec.cs +++ b/CSJ2K/j2k/entropy/CBlkSizeSpec.cs @@ -208,7 +208,7 @@ namespace CSJ2K.j2k.entropy throw new System.ArgumentException(errMsg); } } - catch (System.FormatException) + catch (System.FormatException e) { errMsg = "'" + optName + "' option : the code-block's " + "width could not be parsed."; throw new System.ArgumentException(errMsg); @@ -218,7 +218,7 @@ namespace CSJ2K.j2k.entropy { word = stk.NextToken(); } - catch (System.ArgumentOutOfRangeException) + catch (System.ArgumentOutOfRangeException e) { errMsg = "'" + optName + "' option : could not parse the " + "code-block's height"; throw new System.ArgumentException(errMsg); @@ -255,7 +255,7 @@ namespace CSJ2K.j2k.entropy throw new System.ArgumentException(errMsg); } } - catch (System.FormatException) + catch (System.FormatException e) { errMsg = "'" + optName + "' option : the code-block's height " + "could not be parsed."; throw new System.ArgumentException(errMsg); diff --git a/CSJ2K/j2k/entropy/PrecinctSizeSpec.cs b/CSJ2K/j2k/entropy/PrecinctSizeSpec.cs index 4ecfe182..01202e0d 100644 --- a/CSJ2K/j2k/entropy/PrecinctSizeSpec.cs +++ b/CSJ2K/j2k/entropy/PrecinctSizeSpec.cs @@ -41,6 +41,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.codestream; using CSJ2K.j2k.wavelet; using CSJ2K.j2k.image; @@ -137,10 +138,10 @@ namespace CSJ2K.j2k.entropy // Set precinct sizes to default i.e. 2^15 = // Markers.PRECINCT_PARTITION_DEF_SIZE - System.Collections.ArrayList[] tmpv = new System.Collections.ArrayList[2]; - tmpv[0] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); // ppx + System.Collections.Generic.List[] tmpv = new List[2]; + tmpv[0] = new List(10); // ppx tmpv[0].Add((System.Int32) CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE); - tmpv[1] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); // ppy + tmpv[1] = new List(10); // ppy tmpv[1].Add((System.Int32) CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE); setDefault(tmpv); @@ -167,7 +168,7 @@ namespace CSJ2K.j2k.entropy while ((stk.HasMoreTokens() || wasReadingPrecinctSize) && !endOfParamList) { - System.Collections.ArrayList[] v = new System.Collections.ArrayList[2]; // v[0] : ppx, v[1] : ppy + System.Collections.Generic.List[] v = new List[2]; // v[0] : ppx, v[1] : ppy // We do not read the next token if we were reading a precinct's // size argument as we have already read the next token into word. @@ -216,8 +217,8 @@ namespace CSJ2K.j2k.entropy } // Initialises Vector objects - v[0] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); // ppx - v[1] = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); // ppy + v[0] = new List(10); // ppx + v[1] = new List(10); // ppy while (true) { @@ -233,7 +234,7 @@ namespace CSJ2K.j2k.entropy { word = stk.NextToken(); } - catch (System.ArgumentOutOfRangeException) + catch (System.ArgumentOutOfRangeException e) { errMsg = "'" + optName + "' option : could not " + "parse the precinct's width"; throw new System.ArgumentException(errMsg); @@ -246,7 +247,7 @@ namespace CSJ2K.j2k.entropy throw new System.ArgumentException(errMsg); } } - catch (System.FormatException) + catch (System.FormatException e) { errMsg = "'" + optName + "' option : the argument '" + word + "' could not be parsed."; throw new System.ArgumentException(errMsg); @@ -393,7 +394,7 @@ namespace CSJ2K.j2k.entropy public virtual int getPPX(int t, int c, int rl) { int mrl, idx; - System.Collections.ArrayList[] v = null; + System.Collections.Generic.List[] v = null; bool tileSpecified = (t != - 1?true:false); bool compSpecified = (c != - 1?true:false); @@ -403,22 +404,22 @@ namespace CSJ2K.j2k.entropy if (tileSpecified && compSpecified) { mrl = ((System.Int32) dls.getTileCompVal(t, c)); - v = (System.Collections.ArrayList[]) getTileCompVal(t, c); + v = (System.Collections.Generic.List[])getTileCompVal(t, c); } else if (tileSpecified && !compSpecified) { mrl = ((System.Int32) dls.getTileDef(t)); - v = (System.Collections.ArrayList[]) getTileDef(t); + v = (System.Collections.Generic.List[])getTileDef(t); } else if (!tileSpecified && compSpecified) { mrl = ((System.Int32) dls.getCompDef(c)); - v = (System.Collections.ArrayList[]) getCompDef(c); + v = (System.Collections.Generic.List[])getCompDef(c); } else { mrl = ((System.Int32) dls.getDefault()); - v = (System.Collections.ArrayList[]) getDefault(); + v = (System.Collections.Generic.List[])getDefault(); } idx = mrl - rl; if (v[0].Count > idx) @@ -455,7 +456,7 @@ namespace CSJ2K.j2k.entropy public virtual int getPPY(int t, int c, int rl) { int mrl, idx; - System.Collections.ArrayList[] v = null; + System.Collections.Generic.List[] v = null; bool tileSpecified = (t != - 1?true:false); bool compSpecified = (c != - 1?true:false); @@ -465,22 +466,22 @@ namespace CSJ2K.j2k.entropy if (tileSpecified && compSpecified) { mrl = ((System.Int32) dls.getTileCompVal(t, c)); - v = (System.Collections.ArrayList[]) getTileCompVal(t, c); + v = (System.Collections.Generic.List[]) getTileCompVal(t, c); } else if (tileSpecified && !compSpecified) { mrl = ((System.Int32) dls.getTileDef(t)); - v = (System.Collections.ArrayList[]) getTileDef(t); + v = (System.Collections.Generic.List[]) getTileDef(t); } else if (!tileSpecified && compSpecified) { mrl = ((System.Int32) dls.getCompDef(c)); - v = (System.Collections.ArrayList[]) getCompDef(c); + v = (System.Collections.Generic.List[]) getCompDef(c); } else { mrl = ((System.Int32) dls.getDefault()); - v = (System.Collections.ArrayList[]) getDefault(); + v = (System.Collections.Generic.List[]) getDefault(); } idx = mrl - rl; if (v[1].Count > idx) diff --git a/CSJ2K/j2k/entropy/Progression.cs b/CSJ2K/j2k/entropy/Progression.cs index 1853a1cd..45d0c265 100644 --- a/CSJ2K/j2k/entropy/Progression.cs +++ b/CSJ2K/j2k/entropy/Progression.cs @@ -142,7 +142,7 @@ namespace CSJ2K.j2k.entropy break; default: - throw new System.ApplicationException("Unknown progression type"); + throw new System.InvalidOperationException("Unknown progression type"); } str += ("comp.: " + cs + "-" + ce + ", "); diff --git a/CSJ2K/j2k/entropy/ProgressionSpec.cs b/CSJ2K/j2k/entropy/ProgressionSpec.cs index b6bb4368..72436765 100644 --- a/CSJ2K/j2k/entropy/ProgressionSpec.cs +++ b/CSJ2K/j2k/entropy/ProgressionSpec.cs @@ -40,6 +40,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.codestream; using CSJ2K.j2k.wavelet; using CSJ2K.j2k.image; @@ -78,7 +79,7 @@ namespace CSJ2K.j2k.entropy { if (type != ModuleSpec.SPEC_TYPE_TILE) { - throw new System.ApplicationException("Illegal use of class ProgressionSpec !"); + throw new System.InvalidOperationException("Illegal use of class ProgressionSpec !"); } } @@ -146,7 +147,7 @@ namespace CSJ2K.j2k.entropy // resolution level, 1= index of first component, 2=index of first // layer not included, 3= index of first resolution level not // included, 4= index of first component not included - System.Collections.ArrayList progression = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + System.Collections.Generic.List progression = new List(10); int tmp = 0; Progression curProg = null; @@ -200,7 +201,7 @@ namespace CSJ2K.j2k.entropy { tmp = (System.Int32.Parse(word)); } - catch (System.FormatException) + catch (System.FormatException e) { // Progression has missing parameters throw new System.ArgumentException("Progression " + "order" + " specification " + "has missing " + "parameters: " + param); @@ -263,7 +264,7 @@ namespace CSJ2K.j2k.entropy } else { - throw new System.ApplicationException("Error in usage of 'Aptype' " + "option: " + param); + throw new System.InvalidOperationException("Error in usage of 'Aptype' " + "option: " + param); } } diff --git a/CSJ2K/j2k/entropy/decoder/StdEntropyDecoder.cs b/CSJ2K/j2k/entropy/decoder/StdEntropyDecoder.cs index 86db191d..5ce7ad37 100644 --- a/CSJ2K/j2k/entropy/decoder/StdEntropyDecoder.cs +++ b/CSJ2K/j2k/entropy/decoder/StdEntropyDecoder.cs @@ -681,7 +681,7 @@ namespace CSJ2K.j2k.entropy.decoder break; default: - throw new System.ApplicationException("JJ2000 internal error"); + throw new System.InvalidOperationException("JJ2000 internal error"); } diff --git a/CSJ2K/j2k/entropy/encoder/EBCOTRateAllocator.cs b/CSJ2K/j2k/entropy/encoder/EBCOTRateAllocator.cs index e29cd506..43e36498 100644 --- a/CSJ2K/j2k/entropy/encoder/EBCOTRateAllocator.cs +++ b/CSJ2K/j2k/entropy/encoder/EBCOTRateAllocator.cs @@ -670,7 +670,7 @@ namespace CSJ2K.j2k.entropy.encoder } if (nValidProg == 0) { - throw new System.ApplicationException("Unable to initialize rate allocator: No " + "default progression type has been defined."); + throw new System.InvalidOperationException("Unable to initialize rate allocator: No " + "default progression type has been defined."); } // Tile specific values @@ -689,7 +689,7 @@ namespace CSJ2K.j2k.entropy.encoder } if (nValidProg == 0) { - throw new System.ApplicationException("Unable to initialize rate allocator:" + " No default progression type has been " + "defined for tile " + t); + throw new System.InvalidOperationException("Unable to initialize rate allocator:" + " No default progression type has been " + "defined for tile " + t); } } } // End loop on tiles @@ -731,15 +731,12 @@ namespace CSJ2K.j2k.entropy.encoder SubbandAn root, sb; int cblkToEncode = 0; - int nEncCblk = 0; - ProgressWatch pw = FacilityManager.ProgressWatch; //Get all coded code-blocks Goto first tile src.setTile(0, 0); for (t = 0; t < numTiles; t++) { //loop on tiles - nEncCblk = 0; cblkToEncode = 0; for (c = 0; c < numComps; c++) { @@ -766,10 +763,6 @@ namespace CSJ2K.j2k.entropy.encoder } } } - if (pw != null) - { - pw.initProgressWatch(0, cblkToEncode, "Encoding tile " + t + "..."); - } for (c = 0; c < numComps; c++) { @@ -781,13 +774,7 @@ namespace CSJ2K.j2k.entropy.encoder #if DO_TIMING stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; #endif - - if (pw != null) - { - nEncCblk++; - pw.updateProgressWatch(nEncCblk, null); - } - + subb = ccb.sb; //Get the coded code-block resolution level index @@ -827,11 +814,6 @@ namespace CSJ2K.j2k.entropy.encoder } } - if (pw != null) - { - pw.terminateProgressWatch(); - } - //Goto next tile if (t < numTiles - 1) //not at last tile @@ -1015,7 +997,7 @@ namespace CSJ2K.j2k.entropy.encoder break; default: - throw new System.ApplicationException("Unsupported bit stream progression type"); + throw new System.InvalidOperationException("Unsupported bit stream progression type"); } // switch on progression @@ -1363,7 +1345,7 @@ namespace CSJ2K.j2k.entropy.encoder if (nPrec == 0) { - throw new System.ApplicationException("Image cannot have no precinct"); + throw new System.InvalidOperationException("Image cannot have no precinct"); } int pyend = (maxy - miny) / gcd_y + 1; @@ -1456,7 +1438,7 @@ namespace CSJ2K.j2k.entropy.encoder continue; if (nextPrec[c][r] < numPrec[t][c][r].x * numPrec[t][c][r].y - 1) { - throw new System.ApplicationException("JJ2000 bug: One precinct at least has " + "not been written for resolution level " + r + " of component " + c + " in tile " + t + "."); + throw new System.InvalidOperationException("JJ2000 bug: One precinct at least has " + "not been written for resolution level " + r + " of component " + c + " in tile " + t + "."); } } } @@ -1580,7 +1562,7 @@ namespace CSJ2K.j2k.entropy.encoder if (nPrec == 0) { - throw new System.ApplicationException("Image cannot have no precinct"); + throw new System.InvalidOperationException("Image cannot have no precinct"); } int pyend = (maxy - miny) / gcd_y + 1; @@ -1676,7 +1658,7 @@ namespace CSJ2K.j2k.entropy.encoder continue; if (nextPrec[c][r] < numPrec[t][c][r].x * numPrec[t][c][r].y - 1) { - throw new System.ApplicationException("JJ2000 bug: One precinct at least has " + "not been written for resolution level " + r + " of component " + c + " in tile " + t + "."); + throw new System.InvalidOperationException("JJ2000 bug: One precinct at least has " + "not been written for resolution level " + r + " of component " + c + " in tile " + t + "."); } } } @@ -1800,7 +1782,7 @@ namespace CSJ2K.j2k.entropy.encoder if (nPrec == 0) { - throw new System.ApplicationException("Image cannot have no precinct"); + throw new System.InvalidOperationException("Image cannot have no precinct"); } int pyend = (maxy - miny) / gcd_y + 1; @@ -1893,7 +1875,7 @@ namespace CSJ2K.j2k.entropy.encoder continue; if (nextPrec[c][r] < numPrec[t][c][r].x * numPrec[t][c][r].y - 1) { - throw new System.ApplicationException("JJ2000 bug: One precinct at least has " + "not been written for resolution level " + r + " of component " + c + " in tile " + t + "."); + throw new System.InvalidOperationException("JJ2000 bug: One precinct at least has " + "not been written for resolution level " + r + " of component " + c + " in tile " + t + "."); } } } diff --git a/CSJ2K/j2k/entropy/encoder/MQCoder.cs b/CSJ2K/j2k/entropy/encoder/MQCoder.cs index 520d87ce..63319c9e 100644 --- a/CSJ2K/j2k/entropy/encoder/MQCoder.cs +++ b/CSJ2K/j2k/entropy/encoder/MQCoder.cs @@ -295,7 +295,7 @@ namespace CSJ2K.j2k.entropy.encoder return nrOfWrittenBytes; default: - throw new System.ApplicationException("Illegal length calculation type code"); + throw new System.InvalidOperationException("Illegal length calculation type code"); } } @@ -1285,7 +1285,7 @@ namespace CSJ2K.j2k.entropy.encoder break; default: - throw new System.ApplicationException("Illegal termination type code"); + throw new System.InvalidOperationException("Illegal termination type code"); } diff --git a/CSJ2K/j2k/entropy/encoder/PostCompRateAllocator.cs b/CSJ2K/j2k/entropy/encoder/PostCompRateAllocator.cs index 51813164..6713af7c 100644 --- a/CSJ2K/j2k/entropy/encoder/PostCompRateAllocator.cs +++ b/CSJ2K/j2k/entropy/encoder/PostCompRateAllocator.cs @@ -262,9 +262,9 @@ namespace CSJ2K.j2k.entropy.encoder { stok.NextToken(); } - catch (System.IO.IOException) + catch (System.IO.IOException e) { - throw new System.ApplicationException("An IOException has ocurred where it " + "should never occur"); + throw new System.InvalidOperationException("An IOException has ocurred where it " + "should never occur"); } ratepending = false; islayer = false; @@ -327,9 +327,9 @@ namespace CSJ2K.j2k.entropy.encoder { stok.NextToken(); } - catch (System.IO.IOException) + catch (System.IO.IOException e) { - throw new System.ApplicationException("An IOException has ocurred where it " + "should never occur"); + throw new System.InvalidOperationException("An IOException has ocurred where it " + "should never occur"); } if (stok.ttype != SupportClass.StreamTokenizerSupport.TT_EOF) { @@ -345,9 +345,9 @@ namespace CSJ2K.j2k.entropy.encoder { stok.NextToken(); } - catch (System.IO.IOException) + catch (System.IO.IOException e) { - throw new System.ApplicationException("An IOException has ocurred where it " + "should never occur"); + throw new System.InvalidOperationException("An IOException has ocurred where it " + "should never occur"); } } if (islayer) diff --git a/CSJ2K/j2k/entropy/encoder/StdEntropyCoder.cs b/CSJ2K/j2k/entropy/encoder/StdEntropyCoder.cs index f396aaf6..f566bdca 100644 --- a/CSJ2K/j2k/entropy/encoder/StdEntropyCoder.cs +++ b/CSJ2K/j2k/entropy/encoder/StdEntropyCoder.cs @@ -40,17 +40,14 @@ * * Copyright (c) 1999/2000 JJ2000 Partners. * */ -using System; +#define DO_TIMING + using CSJ2K.j2k.quantization.quantizer; using CSJ2K.j2k.wavelet.analysis; -using CSJ2K.j2k.codestream; using CSJ2K.j2k.wavelet; -using CSJ2K.j2k.encoder; -using CSJ2K.j2k.entropy; using CSJ2K.j2k.image; using CSJ2K.j2k.util; -using CSJ2K.j2k.io; -using CSJ2K.j2k; + namespace CSJ2K.j2k.entropy.encoder { @@ -113,53 +110,14 @@ namespace CSJ2K.j2k.entropy.encoder /// public class StdEntropyCoder:EntropyCoder { - - /// Whether to collect timing information or not: false. Used as a compile - /// time directive. - /// - private const bool DO_TIMING = false; - +#if DO_TIMING /// The cumulative wall time for the entropy coding engine, for each /// component. In the single-threaded implementation it is the total time, /// in the multi-threaded implementation it is the time spent managing the /// compressor threads only. /// - //private long[] time; - - /// The Java system property name for the number of threads to use: - /// jj2000.j2k.entropy.encoder.StdEntropyCoder.nthreads - /// - public const System.String THREADS_PROP_NAME = "jj2000.j2k.entropy.encoder.StdEntropyCoder.nthreads"; - - /// The default value for the property in THREADS_PROP_NAME: 0 - public const System.String DEF_THREADS_NUM = "0"; - - /// The increase in priority for the compressor threads, currently 3. The - /// compressor threads will have a priority of THREADS_PRIORITY_INC more - /// than the priority of the thread calling this class constructor. Used - /// only in the multi-threaded implementation. - /// - public const int THREADS_PRIORITY_INC = 0; - - /// The pool of threads, for the threaded implementation. It is null, if - /// non threaded implementation is used - /// - private ThreadPool tPool; - - /// The queue of idle compressors. Used in multithreaded - /// implementation only - /// - private System.Collections.ArrayList idleComps; - - /// The queue of completed compressors, for each component. Used - /// in multithreaded implementation only. - /// - private System.Collections.ArrayList[] completedComps; - - /// The number of busy compressors, for each component. Used in - /// multithreaded implementation only. - /// - private int[] nBusyComps; + private long[] time; +#endif /// A flag indicating for each component if all the code-blocks of the * /// current tile have been returned. Used in multithreaded implementation @@ -555,8 +513,6 @@ namespace CSJ2K.j2k.entropy.encoder /// table is indexed with one less bit. /// private const int MSE_LKP_BITS = 7; - - private const int MSE_LKP_BITS_M1 = 6; /// The number of fractional bits used to store data in the 'fm' and 'fs' /// lookup tables. @@ -567,7 +523,7 @@ namespace CSJ2K.j2k.entropy.encoder /// (SC) primative, for lossy coding (i.e. normal). /// //UPGRADE_NOTE: Final was removed from the declaration of 'FS_LOSSY '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private static readonly int[] FS_LOSSY = new int[1 << MSE_LKP_BITS_M1]; + private static readonly int[] FS_LOSSY = new int[1 << (MSE_LKP_BITS - 1)]; /// Distortion estimation lookup table for bits coded using the /// magnitude-refinement (MR) primative, for lossy coding (i.e. normal) @@ -581,7 +537,7 @@ namespace CSJ2K.j2k.entropy.encoder /// distortion after the last bit-plane is coded is strictly 0. /// //UPGRADE_NOTE: Final was removed from the declaration of 'FS_LOSSLESS '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private static readonly int[] FS_LOSSLESS = new int[1 << MSE_LKP_BITS_M1]; + private static readonly int[] FS_LOSSLESS = new int[1 << (MSE_LKP_BITS - 1)]; /// Distortion estimation lookup table for bits coded using the /// magnitude-refinement (MR) primative, for lossless coding and last @@ -631,120 +587,6 @@ namespace CSJ2K.j2k.entropy.encoder /// private bool[][] precinctPartition; - //UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'Compressor' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'" - /// Class that takes care of running the 'compressCodeBlock()' method with - /// thread local arguments. Used only in multithreaded implementation. - /// - /// - private class Compressor : IThreadRunnable - { - private void InitBlock(StdEntropyCoder enclosingInstance) - { - this.enclosingInstance = enclosingInstance; - } - private StdEntropyCoder enclosingInstance; - /// Returns the index of this compressor. - /// - /// - /// The index of this compressor. - /// - /// - virtual public int Idx - { - get - { - return idx; - } - - } - public StdEntropyCoder Enclosing_Instance - { - get - { - return enclosingInstance; - } - - } - /// The index of this compressor. Used to access thread local - /// variables - /// - //UPGRADE_NOTE: Final was removed from the declaration of 'idx '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private int idx; - - /// The object where to store the compressed code-block - // Should be private, but some buggy JDK 1.1 compilers complain - internal CBlkRateDistStats ccb; - - /// The component on which to compress - // Should be private, but some buggy JDK 1.1 compilers complain - internal int c; - - /// The options bitmask to use in compression - // Should be private, but some buggy JDK 1.1 compilers complain - internal int options; - - /// The reversible flag to use in compression - // Should be private, but some buggy JDK 1.1 compilers complain - internal bool rev; - - /// The length calculation type to use in compression - // Should be private, but some buggy JDK 1.1 compilers complain - internal int lcType; - - /// The MQ termination type to use in compression - // Should be private, but some buggy JDK 1.1 compilers complain - internal int tType; - - /// The cumulative wall time for this compressor, for each - /// component. - /// - //private long[] time; - - /// Creates a new compressor object with the given index. - /// - /// - /// The index of this compressor. - /// - /// - internal Compressor(StdEntropyCoder enclosingInstance, int idx) - { - InitBlock(enclosingInstance); - this.idx = idx; -#if DO_TIMING - time = new long[Enclosing_Instance.src.NumComps]; -#endif - } - - /// Calls the 'compressCodeBlock()' method with thread local - /// arguments. Once completed it adds itself to the 'completedComps[c]' - /// stack, where 'c' is the component for which this compressor is - /// running. This last step occurs even if exceptions are thrown by the - /// 'compressCodeBlock()' method. - /// - /// - public virtual void Run() - { - // Start the code-block compression - try - { -#if DO_TIMING - long stime = 0L; - stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; -#endif - CSJ2K.j2k.entropy.encoder.StdEntropyCoder.compressCodeBlock(c, ccb, Enclosing_Instance.srcblkT[idx], Enclosing_Instance.mqT[idx], Enclosing_Instance.boutT[idx], Enclosing_Instance.outT[idx], Enclosing_Instance.stateT[idx], Enclosing_Instance.distbufT[idx], Enclosing_Instance.ratebufT[idx], Enclosing_Instance.istermbufT[idx], Enclosing_Instance.symbufT[idx], Enclosing_Instance.ctxtbufT[idx], options, rev, lcType, tType); -#if DO_TIMING - time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime; -#endif - } - finally - { - // Join the queue of completed compression, even if exceptions - // occurred. - Enclosing_Instance.completedComps[c].Add(this); - } - } - } - /// Instantiates a new entropy coder engine, with the specified source of /// data, nominal block width and height. /// @@ -798,29 +640,12 @@ namespace CSJ2K.j2k.entropy.encoder this.tts = tts; int maxCBlkWidth, maxCBlkHeight; int i; // Counter - int nt; // The number of threads int tsl; // Size for thread structures // Get the biggest width/height for the code-blocks maxCBlkWidth = cblks.MaxCBlkWidth; maxCBlkHeight = cblks.MaxCBlkHeight; - nt = Environment.ProcessorCount; - /* - // Get the number of threads to use, or default to one - try - { - //UPGRADE_ISSUE: Method 'java.lang.System.getProperty' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangSystem'" - nt = System.Int32.Parse(System_Renamed.getProperty(THREADS_PROP_NAME, DEF_THREADS_NUM)); - if (nt < 0) - throw new System.FormatException(); - } - catch (System.FormatException e) - { - throw new System.ArgumentException("Invalid number of threads " + "for " + "entropy coding in property " + THREADS_PROP_NAME); - } - */ - // If we do timing create necessary structures #if DO_TIMING time = new long[src.NumComps]; @@ -828,35 +653,10 @@ namespace CSJ2K.j2k.entropy.encoder //UPGRADE_ISSUE: Method 'java.lang.System.runFinalizersOnExit' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangSystem'" // CONVERSION PROBLEM? //System_Renamed.runFinalizersOnExit(true); -#endif - // If using multithreaded implementation get necessasry objects - if (nt > 0) - { - FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, "Using multithreaded entropy coder " + "with " + nt + " compressor threads."); - tsl = nt; - tPool = new ThreadPool(nt, (System.Int32) SupportClass.ThreadClass.Current().Priority + THREADS_PRIORITY_INC, "StdEntropyCoder"); - idleComps = new System.Collections.ArrayList(); - completedComps = new System.Collections.ArrayList[src.NumComps]; - nBusyComps = new int[src.NumComps]; - finishedTileComponent = new bool[src.NumComps]; - for (i = src.NumComps - 1; i >= 0; i--) - { - completedComps[i] = new System.Collections.ArrayList(); - } - for (i = 0; i < nt; i++) - { - idleComps.Add(new StdEntropyCoder.Compressor(this, i)); - } - } - else - { - tsl = 1; - tPool = null; - idleComps = null; - completedComps = null; - nBusyComps = null; - finishedTileComponent = null; - } +#endif + + tsl = 1; + finishedTileComponent = null; // Allocate data structures outT = new ByteOutputBuffer[tsl]; @@ -934,57 +734,17 @@ namespace CSJ2K.j2k.entropy.encoder int c; System.Text.StringBuilder sb; - if (tPool == null) + // Single threaded implementation + sb = new System.Text.StringBuilder("StdEntropyCoder compression wall " + "clock time:"); + for (c = 0; c < time.Length; c++) { - // Single threaded implementation - sb = new System.Text.StringBuilder("StdEntropyCoder compression wall " + "clock time:"); - for (c = 0; c < time.Length; c++) - { - sb.Append("\n component "); - sb.Append(c); - sb.Append(": "); - sb.Append(time[c]); - sb.Append(" ms"); - } - FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, sb.ToString()); + sb.Append("\n component "); + sb.Append(c); + sb.Append(": "); + sb.Append(time[c]); + sb.Append(" ms"); } - else - { - // Multithreaded implementation - Compressor compr; - MsgLogger msglog = FacilityManager.getMsgLogger(); - - sb = new System.Text.StringBuilder("StdEntropyCoder manager thread " + "wall clock time:"); - for (c = 0; c < time.Length; c++) - { - sb.Append("\n component "); - sb.Append(c); - sb.Append(": "); - sb.Append(time[c]); - sb.Append(" ms"); - } - System.Collections.IEnumerator Enum = idleComps.GetEnumerator(); - sb.Append("\nStdEntropyCoder compressor threads wall clock " + "time:"); - //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'" - while (Enum.MoveNext()) - { - //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'" - compr = (Compressor)(Enum.Current); - for (c = 0; c < time.Length; c++) - { - sb.Append("\n compressor "); - sb.Append(compr.Idx); - sb.Append(", component "); - sb.Append(c); - sb.Append(": "); - sb.Append(compr.getTiming(c)); - sb.Append(" ms"); - } - } - FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, sb.ToString()); - } - - //UPGRADE_NOTE: Call to 'super.finalize()' was removed. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1124'" + FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, sb.ToString()); } #endif @@ -1061,143 +821,38 @@ namespace CSJ2K.j2k.entropy.encoder #if DO_TIMING long stime = 0L; // Start time for timed sections #endif - if (tPool == null) - { - // Use single threaded implementation - // Get code-block data from source - srcblkT[0] = src.getNextInternCodeBlock(c, srcblkT[0]); + // Use single threaded implementation + // Get code-block data from source + srcblkT[0] = src.getNextInternCodeBlock(c, srcblkT[0]); #if DO_TIMING - stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; + stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; #endif - if (srcblkT[0] == null) - { - // We got all code-blocks - return null; - } - // Initialize thread local variables - if ((opts[tIdx][c] & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && boutT[0] == null) - { - boutT[0] = new BitToByteOutput(outT[0]); - } - // Initialize output code-block - if (ccb == null) - { - ccb = new CBlkRateDistStats(); - } - // Compress code-block - compressCodeBlock(c, ccb, srcblkT[0], mqT[0], boutT[0], outT[0], stateT[0], distbufT[0], ratebufT[0], istermbufT[0], symbufT[0], ctxtbufT[0], opts[tIdx][c], isReversible(tIdx, c), lenCalc[tIdx][c], tType[tIdx][c]); + if (srcblkT[0] == null) + { + // We got all code-blocks + return null; + } + // Initialize thread local variables + if ((opts[tIdx][c] & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && boutT[0] == null) + { + boutT[0] = new BitToByteOutput(outT[0]); + } + // Initialize output code-block + if (ccb == null) + { + ccb = new CBlkRateDistStats(); + } + // Compress code-block + compressCodeBlock(c, ccb, srcblkT[0], mqT[0], boutT[0], outT[0], stateT[0], distbufT[0], ratebufT[0], istermbufT[0], symbufT[0], ctxtbufT[0], opts[tIdx][c], isReversible(tIdx, c), lenCalc[tIdx][c], tType[tIdx][c]); #if DO_TIMING - time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime; + time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime; #endif - // Return result - return ccb; - } - else - { - // Use multiple threaded implementation - int cIdx; // Compressor idx - Compressor compr; // Compressor - -#if DO_TIMING - stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; -#endif - // Give data to all free compressors, using the current component - while (!finishedTileComponent[c] && !(idleComps.Count == 0)) - { - // Get an idle compressor - compr = (Compressor) SupportClass.StackSupport.Pop(idleComps); - cIdx = compr.Idx; - // Get data for the compressor and wake it up -#if DO_TIMING - time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime; -#endif - srcblkT[cIdx] = src.getNextInternCodeBlock(c, srcblkT[cIdx]); -#if DO_TIMING - stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; -#endif - if (srcblkT[cIdx] != null) - { - // Initialize thread local variables - if ((opts[tIdx][c] & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_BYPASS) != 0 && boutT[cIdx] == null) - { - boutT[cIdx] = new BitToByteOutput(outT[cIdx]); - } - // Initialize output code-block and compressor thread - if (ccb == null) - ccb = new CBlkRateDistStats(); - compr.ccb = ccb; - compr.c = c; - compr.options = opts[tIdx][c]; - compr.rev = isReversible(tIdx, c); - compr.lcType = lenCalc[tIdx][c]; - compr.tType = tType[tIdx][c]; - nBusyComps[c]++; - ccb = null; - // Send compressor to execution in thread pool - tPool.runTarget(compr, completedComps[c]); - } - else - { - // We finished with all the code-blocks in the current - // tile component - idleComps.Add(compr); - finishedTileComponent[c] = true; - } - } - // If there are threads for this component which result has not - // been returned yet, get it - if (nBusyComps[c] > 0) - { - lock (completedComps[c]) - { - // If no compressor is done, wait until one is - if ((completedComps[c].Count == 0)) - { - try - { -#if DO_TIMING - time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime; -#endif - System.Threading.Monitor.Wait(completedComps[c]); -#if DO_TIMING - stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; -#endif - } - catch (System.Threading.ThreadInterruptedException) - { - } - } - // Remove the thread from the completed queue and put it - // on the idle queue - compr = (Compressor) SupportClass.StackSupport.Pop(completedComps[c]); - cIdx = compr.Idx; - nBusyComps[c]--; - idleComps.Add(compr); - // Check targets error condition - tPool.checkTargetErrors(); - // Get the result of compression and return that. -#if DO_TIMING - time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime; -#endif - return compr.ccb; - } - } - else - { - // Check targets error condition - tPool.checkTargetErrors(); - // Printing timing info if necessary -#if DO_TIMING - time[c] += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime; -#endif - // Nothing is running => no more code-blocks - return null; - } - } + // Return result + return ccb; } /// Changes the current tile, given the new indexes. An @@ -1381,7 +1036,7 @@ namespace CSJ2K.j2k.entropy.encoder break; default: - throw new System.ApplicationException("JJ2000 internal error"); + throw new System.InvalidOperationException("JJ2000 internal error"); } @@ -1641,7 +1296,7 @@ namespace CSJ2K.j2k.entropy.encoder dist = 0; // We use the MSE_LKP_BITS-1 bits below the bit just coded for // distortion estimation. - shift = bp - MSE_LKP_BITS_M1; + shift = bp - (MSE_LKP_BITS - 1); upshift = (shift >= 0)?0:- shift; downshift = (shift <= 0)?0:shift; causal = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL) != 0; @@ -1722,7 +1377,7 @@ namespace CSJ2K.j2k.entropy.encoder } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -1771,7 +1426,7 @@ namespace CSJ2K.j2k.entropy.encoder } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -1827,7 +1482,7 @@ namespace CSJ2K.j2k.entropy.encoder } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -1876,7 +1531,7 @@ namespace CSJ2K.j2k.entropy.encoder } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -2008,7 +1663,7 @@ namespace CSJ2K.j2k.entropy.encoder dist = 0; // We use the MSE_LKP_BITS-1 bits below the bit just coded for // distortion estimation. - shift = bp - MSE_LKP_BITS_M1; + shift = bp - (MSE_LKP_BITS - 1); upshift = (shift >= 0)?0:- shift; downshift = (shift <= 0)?0:shift; causal = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL) != 0; @@ -2090,7 +1745,7 @@ namespace CSJ2K.j2k.entropy.encoder } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -2140,7 +1795,7 @@ namespace CSJ2K.j2k.entropy.encoder } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -2196,7 +1851,7 @@ namespace CSJ2K.j2k.entropy.encoder } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -2245,7 +1900,7 @@ namespace CSJ2K.j2k.entropy.encoder } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } else { @@ -2361,7 +2016,7 @@ namespace CSJ2K.j2k.entropy.encoder dist = 0; // We use the bit just coded plus MSE_LKP_BITS-1 bits below the bit // just coded for distortion estimation. - shift = bp - MSE_LKP_BITS_M1; + shift = bp - (MSE_LKP_BITS - 1); upshift = (shift >= 0)?0:- shift; downshift = (shift <= 0)?0:shift; @@ -2580,7 +2235,7 @@ namespace CSJ2K.j2k.entropy.encoder dist = 0; // We use the bit just coded plus MSE_LKP_BITS-1 bits below the bit // just coded for distortion estimation. - shift = bp - MSE_LKP_BITS_M1; + shift = bp - (MSE_LKP_BITS - 1); upshift = (shift >= 0)?0:- shift; downshift = (shift <= 0)?0:shift; @@ -2790,7 +2445,7 @@ namespace CSJ2K.j2k.entropy.encoder dist = 0; // We use the MSE_LKP_BITS-1 bits below the bit just coded for // distortion estimation. - shift = bp - MSE_LKP_BITS_M1; + shift = bp - (MSE_LKP_BITS - 1); upshift = (shift >= 0)?0:- shift; downshift = (shift <= 0)?0:shift; causal = (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_VERT_STR_CAUSAL) != 0; @@ -2861,7 +2516,7 @@ namespace CSJ2K.j2k.entropy.encoder // Code sign of sample that became significant // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; // Apply sign coding sym = SupportClass.URShift(data[k], 31); if ((rlclen & 0x01) == 0) @@ -3021,7 +2676,7 @@ namespace CSJ2K.j2k.entropy.encoder } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } } if (sheight < 2) @@ -3067,7 +2722,7 @@ namespace CSJ2K.j2k.entropy.encoder } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } } } @@ -3125,7 +2780,7 @@ top_half_brk: ; } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } } if (sheight < 4) @@ -3171,7 +2826,7 @@ top_half_brk: ; } // Update distortion normval = (data[k] >> downshift) << upshift; - dist += fs[normval & ((1 << MSE_LKP_BITS_M1) - 1)]; + dist += fs[normval & ((1 << (MSE_LKP_BITS - 1)) - 1)]; } } } @@ -3699,10 +3354,10 @@ top_half_brk: ; // Initialize the distortion estimation lookup tables // fs tables - for (i = 0; i < (1 << MSE_LKP_BITS_M1); i++) + for (i = 0; i < (1 << (MSE_LKP_BITS - 1)); i++) { // In fs we index by val-1, since val is really: 1 <= val < 2 - val = (double) i / (1 << MSE_LKP_BITS_M1) + 1.0; + val = (double) i / (1 << (MSE_LKP_BITS - 1)) + 1.0; deltaMSE = val * val; //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'" FS_LOSSLESS[i] = (int) System.Math.Floor(deltaMSE * ((double) (1 << MSE_LKP_FRAC_BITS)) + 0.5); @@ -3715,11 +3370,11 @@ top_half_brk: ; // fm tables for (i = 0; i < (1 << MSE_LKP_BITS); i++) { - val = (double) i / (1 << MSE_LKP_BITS_M1); + val = (double) i / (1 << (MSE_LKP_BITS - 1)); deltaMSE = (val - 1.0) * (val - 1.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'" FM_LOSSLESS[i] = (int) System.Math.Floor(deltaMSE * ((double) (1 << MSE_LKP_FRAC_BITS)) + 0.5); - val -= ((i < (1 << MSE_LKP_BITS_M1))?0.5:1.5); + val -= ((i < (1 << (MSE_LKP_BITS - 1)))?0.5:1.5); deltaMSE -= val * val; //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'" FM_LOSSY[i] = (int) System.Math.Floor(deltaMSE * ((double) (1 << MSE_LKP_FRAC_BITS)) + 0.5); diff --git a/CSJ2K/j2k/fileformat/reader/FileFormatReader.cs b/CSJ2K/j2k/fileformat/reader/FileFormatReader.cs index 4fc488cf..620bd91f 100644 --- a/CSJ2K/j2k/fileformat/reader/FileFormatReader.cs +++ b/CSJ2K/j2k/fileformat/reader/FileFormatReader.cs @@ -41,6 +41,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.codestream; using CSJ2K.j2k.fileformat; using CSJ2K.j2k.util; @@ -113,10 +114,10 @@ namespace CSJ2K.j2k.fileformat.reader private RandomAccessIO in_Renamed; /// The positions of the codestreams in the fileformat - private System.Collections.ArrayList codeStreamPos; + private System.Collections.Generic.List codeStreamPos; /// The lengths of the codestreams in the fileformat - private System.Collections.ArrayList codeStreamLength; + private System.Collections.Generic.List codeStreamLength; /// Flag indicating whether or not the JP2 file format is used public bool JP2FFUsed; @@ -174,7 +175,7 @@ namespace CSJ2K.j2k.fileformat.reader marker = (short) in_Renamed.readShort(); if (marker != CSJ2K.j2k.codestream.Markers.SOC) //Standard syntax marker found - throw new System.ApplicationException("File is neither valid JP2 file nor " + "valid JPEG 2000 codestream"); + throw new System.InvalidOperationException("File is neither valid JP2 file nor " + "valid JPEG 2000 codestream"); JP2FFUsed = false; in_Renamed.seek(0); return ; @@ -187,7 +188,7 @@ namespace CSJ2K.j2k.fileformat.reader if (!readFileTypeBox()) { // Not a valid JP2 file or codestream - throw new System.ApplicationException("Invalid JP2 file: File Type box missing"); + throw new System.InvalidOperationException("Invalid JP2 file: File Type box missing"); } // Read all remaining boxes @@ -218,14 +219,14 @@ namespace CSJ2K.j2k.fileformat.reader case CSJ2K.j2k.fileformat.FileFormatBoxes.CONTIGUOUS_CODESTREAM_BOX: if (!jp2HeaderBoxFound) { - throw new System.ApplicationException("Invalid JP2 file: JP2Header box not " + "found before Contiguous codestream " + "box "); + throw new System.InvalidOperationException("Invalid JP2 file: JP2Header box not " + "found before Contiguous codestream " + "box "); } readContiguousCodeStreamBox(pos, length, longLength); break; case CSJ2K.j2k.fileformat.FileFormatBoxes.JP2_HEADER_BOX: if (jp2HeaderBoxFound) - throw new System.ApplicationException("Invalid JP2 file: Multiple " + "JP2Header boxes found"); + throw new System.InvalidOperationException("Invalid JP2 file: Multiple " + "JP2Header boxes found"); readJP2HeaderBox(pos, length, longLength); jp2HeaderBoxFound = true; break; @@ -259,15 +260,15 @@ namespace CSJ2K.j2k.fileformat.reader in_Renamed.seek(pos + length); } } - catch (System.IO.EndOfStreamException) + catch (System.IO.EndOfStreamException e) { - throw new System.ApplicationException("EOF reached before finding Contiguous " + "Codestream Box"); + throw new System.InvalidOperationException("EOF reached before finding Contiguous " + "Codestream Box"); } if (codeStreamPos.Count == 0) { // Not a valid JP2 file or codestream - throw new System.ApplicationException("Invalid JP2 file: Contiguous codestream box " + "missing"); + throw new System.InvalidOperationException("Invalid JP2 file: Contiguous codestream box " + "missing"); } return ; @@ -300,7 +301,7 @@ namespace CSJ2K.j2k.fileformat.reader if (length == 0) { // This can not be last box - throw new System.ApplicationException("Zero-length of Profile Box"); + throw new System.InvalidOperationException("Zero-length of Profile Box"); } // Check that this is a File Type box (TBox) @@ -367,7 +368,7 @@ namespace CSJ2K.j2k.fileformat.reader if (length == 0) { // This can not be last box - throw new System.ApplicationException("Zero-length of JP2Header Box"); + throw new System.InvalidOperationException("Zero-length of JP2Header Box"); } // Here the JP2Header data (DBox) would be read if we were to use it @@ -405,12 +406,12 @@ namespace CSJ2K.j2k.fileformat.reader int ccpos = in_Renamed.Pos; if (codeStreamPos == null) - codeStreamPos = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + codeStreamPos = new List(10); codeStreamPos.Add((System.Int32) ccpos); // Add new codestream length to length vector if (codeStreamLength == null) - codeStreamLength = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + codeStreamLength = new List(10); codeStreamLength.Add((System.Int32) length); return true; diff --git a/CSJ2K/j2k/fileformat/writer/FileFormatWriter.cs b/CSJ2K/j2k/fileformat/writer/FileFormatWriter.cs index 21d48d79..283daa37 100644 --- a/CSJ2K/j2k/fileformat/writer/FileFormatWriter.cs +++ b/CSJ2K/j2k/fileformat/writer/FileFormatWriter.cs @@ -46,7 +46,8 @@ using CSJ2K.j2k.fileformat; using CSJ2K.j2k.io; namespace CSJ2K.j2k.fileformat.writer { - + using System.IO; + /// This class writes the file format wrapper that may or may not exist around /// a valid JPEG 2000 codestream. This class writes the simple possible legal /// fileformat @@ -61,28 +62,28 @@ namespace CSJ2K.j2k.fileformat.writer /// The file from which to read the codestream and write file private BEBufferedRandomAccessFile fi; - /// The name of the file from which to read the codestream and to write + /// The stream from which to read the codestream and to write /// the JP2 file /// - private System.String filename; + private Stream stream; /// Image height - private int height; + private readonly int height; /// Image width - private int width; + private readonly int width; /// Number of components - private int nc; + private readonly int nc; /// Bits per component - private int[] bpc; + private readonly int[] bpc; /// Flag indicating whether number of bits per component varies - private bool bpcVaries; + private readonly bool bpcVaries; /// Length of codestream - private int clength; + private readonly int clength; /// Length of Colour Specification Box private const int CSB_LENGTH = 15; @@ -102,7 +103,7 @@ namespace CSJ2K.j2k.fileformat.writer /// information necessary about a codestream to generate a legal JP2 file /// /// - /// The name of the file that is to be made a JP2 file + /// The stream that is to be made a JP2 file /// /// /// The height of the image @@ -120,13 +121,13 @@ namespace CSJ2K.j2k.fileformat.writer /// Length of codestream /// /// - public FileFormatWriter(System.String filename, int height, int width, int nc, int[] bpc, int clength) + public FileFormatWriter(Stream stream, int height, int width, int nc, int[] bpc, int clength) { this.height = height; this.width = width; this.nc = nc; this.bpc = bpc; - this.filename = filename; + this.stream = stream; this.clength = clength; bpcVaries = false; @@ -157,7 +158,7 @@ namespace CSJ2K.j2k.fileformat.writer try { // Read and buffer the codestream - fi = new BEBufferedRandomAccessFile(filename, "rw+"); + fi = new BEBufferedRandomAccessFile(stream, false); codestream = new byte[clength]; fi.readFully(codestream, 0, clength); @@ -180,7 +181,7 @@ namespace CSJ2K.j2k.fileformat.writer } catch (System.Exception e) { - throw new System.ApplicationException("Error while writing JP2 file format(2): " + e.Message + "\n" + e.StackTrace); + throw new System.InvalidOperationException("Error while writing JP2 file format(2): " + e.Message + "\n" + e.StackTrace); } if (bpcVaries) return 12 + FTB_LENGTH + 8 + IHB_LENGTH + CSB_LENGTH + BPC_LENGTH + nc + 8; diff --git a/CSJ2K/j2k/image/BlkImgDataSrc.cs b/CSJ2K/j2k/image/BlkImgDataSrc.cs index 353249fe..09ea0b22 100644 --- a/CSJ2K/j2k/image/BlkImgDataSrc.cs +++ b/CSJ2K/j2k/image/BlkImgDataSrc.cs @@ -41,139 +41,160 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; + namespace CSJ2K.j2k.image { - - /// This interface defines the methods to transfer image data in blocks, - /// without following any particular order (random access). This interface does - /// not define the methods to access the image characteristics, such as width, - /// height, number of components, tiles, etc., or to change the current - /// tile. That is provided by other interfaces such as ImgData. - /// - ///

This interface has the notion of a current tile. All data, coordinates - /// and dimensions are always relative to the current tile. If there is only - /// one tile then it is equivalent as having no tiles. - /// - ///

A block of requested data may never cross tile boundaries. This should - /// be enforced by the implementing class, or the source of image data. - /// - ///

This interface defines the methods that can be used to retrieve image - /// data. Implementing classes need not buffer all the image data, they can ask - /// their source to load the data they need. - /// - ///

- /// - /// - /// - public interface BlkImgDataSrc:ImgData - { - - /// Returns the position of the fixed point in the specified component, or - /// equivalently the number of fractional bits. 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. - /// - /// - /// The index of the component. - /// - /// - /// The position of the fixed-point, which is the same as the - /// number of fractional bits. For floating-point data 0 is returned. - /// - /// - int getFixedPoint(int c); - - /// 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. - /// - ///

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. - /// - ///

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. - /// - ///

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. - /// - ///

If the data array in blk is null, 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 blk 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 - /// blk after the method has returned. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// 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. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - DataBlk getInternCompData(DataBlk blk, int c); - - /// 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". - /// - ///

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. - /// - ///

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. - /// - ///

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. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// 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. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// - /// - /// - DataBlk getCompData(DataBlk blk, int c); - } -} \ No newline at end of file + + /// This interface defines the methods to transfer image data in blocks, + /// without following any particular order (random access). This interface does + /// not define the methods to access the image characteristics, such as width, + /// height, number of components, tiles, etc., or to change the current + /// tile. That is provided by other interfaces such as ImgData. + /// + ///

This interface has the notion of a current tile. All data, coordinates + /// and dimensions are always relative to the current tile. If there is only + /// one tile then it is equivalent as having no tiles. + /// + ///

A block of requested data may never cross tile boundaries. This should + /// be enforced by the implementing class, or the source of image data. + /// + ///

This interface defines the methods that can be used to retrieve image + /// data. Implementing classes need not buffer all the image data, they can ask + /// their source to load the data they need. + /// + ///

+ /// + /// + /// + public interface BlkImgDataSrc : ImgData + { + + /// Returns the position of the fixed point in the specified component, or + /// equivalently the number of fractional bits. 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. + /// + /// + /// The index of the component. + /// + /// + /// The position of the fixed-point, which is the same as the + /// number of fractional bits. For floating-point data 0 is returned. + /// + /// + int getFixedPoint(int c); + + /// 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. + /// + ///

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. + /// + ///

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. + /// + ///

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. + /// + ///

If the data array in blk is null, 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 blk 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 + /// blk after the method has returned. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// 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. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + DataBlk getInternCompData(DataBlk blk, int c); + + /// 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". + /// + ///

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. + /// + ///

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. + /// + ///

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. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// 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. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// + /// + /// + DataBlk getCompData(DataBlk blk, int c); + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + void close(); + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + bool isOrigSigned(int c); + } +} diff --git a/CSJ2K/j2k/image/ImgDataConverter.cs b/CSJ2K/j2k/image/ImgDataConverter.cs index 96c8a590..037ea5e4 100644 --- a/CSJ2K/j2k/image/ImgDataConverter.cs +++ b/CSJ2K/j2k/image/ImgDataConverter.cs @@ -44,380 +44,417 @@ using System; using CSJ2K.j2k.image; using CSJ2K.j2k; + namespace CSJ2K.j2k.image { - - /// 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. - /// - /// - public class ImgDataConverter:ImgDataAdapter, BlkImgDataSrc - { - - /// 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 - /// - private DataBlk srcBlk = new DataBlkInt(); - - /// The source of image data - private BlkImgDataSrc src; - - /// The number of fraction bits in the casted ints - private int fp; - - /// Constructs a new ImgDataConverter object that operates on the specified - /// source of image data. - /// - /// - /// The source from where to get the data to be transformed - /// - /// - /// The number of fraction bits in the casted ints - /// - /// - /// - /// - /// - public ImgDataConverter(BlkImgDataSrc imgSrc, int fp):base(imgSrc) - { - src = imgSrc; - this.fp = fp; - } - - /// Constructs a new ImgDataConverter object that operates on the specified - /// source of image data. - /// - /// - /// The source from where to get the data to be transformed - /// - /// - /// - /// - /// - public ImgDataConverter(BlkImgDataSrc imgSrc):base(imgSrc) - { - src = imgSrc; - fp = 0; - } - - /// 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. - /// - /// - /// The index of the component. - /// - /// - /// The position of the fixed-point, which is the same as the - /// number of fractional bits. - /// - /// - public virtual int getFixedPoint(int c) - { - return fp; - } - - /// 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". - /// - ///

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. - /// - ///

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. - /// - ///

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. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// 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. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// - /// - /// - public virtual DataBlk getCompData(DataBlk blk, int c) - { - return getData(blk, c, false); - } - - /// 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. - /// - ///

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. - /// - ///

If source data and expected data (blk) are using the same type, - /// block returned without any modification. If not appropriate cast is - /// used. - /// - ///

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. - /// - ///

If the data array in blk is null, 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 blk 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 - /// blk after the method has returned. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// 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. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - public DataBlk getInternCompData(DataBlk blk, int c) - { - return getData(blk, c, true); - } - - /// Implements the 'getInternCompData()' and the 'getCompData()' - /// methods. The 'intern' flag signals which of the two methods should run - /// as. - /// - /// - /// The data block to get. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// If true behave as 'getInternCompData(). Otherwise behave - /// as 'getCompData()' - /// - /// - /// The requested data block - /// - /// - /// - /// - /// - /// - /// - /// - 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; - } - } -} \ No newline at end of file + + /// 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. + /// + /// + public class ImgDataConverter : ImgDataAdapter, BlkImgDataSrc + { + + /// 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 + /// + private DataBlk srcBlk = new DataBlkInt(); + + /// The source of image data + private BlkImgDataSrc src; + + /// The number of fraction bits in the casted ints + private int fp; + + /// Constructs a new ImgDataConverter object that operates on the specified + /// source of image data. + /// + /// + /// The source from where to get the data to be transformed + /// + /// + /// The number of fraction bits in the casted ints + /// + /// + /// + /// + /// + public ImgDataConverter(BlkImgDataSrc imgSrc, int fp) + : base(imgSrc) + { + src = imgSrc; + this.fp = fp; + } + + /// Constructs a new ImgDataConverter object that operates on the specified + /// source of image data. + /// + /// + /// The source from where to get the data to be transformed + /// + /// + /// + /// + /// + public ImgDataConverter(BlkImgDataSrc imgSrc) + : base(imgSrc) + { + src = imgSrc; + fp = 0; + } + + /// 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. + /// + /// + /// The index of the component. + /// + /// + /// The position of the fixed-point, which is the same as the + /// number of fractional bits. + /// + /// + public virtual int getFixedPoint(int c) + { + return fp; + } + + /// 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". + /// + ///

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. + /// + ///

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. + /// + ///

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. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// 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. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// + /// + /// + public virtual DataBlk getCompData(DataBlk blk, int c) + { + return getData(blk, c, false); + } + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + public void close() + { + // Do nothing. + } + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + public bool isOrigSigned(int c) + { + return false; + } + + /// 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. + /// + ///

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. + /// + ///

If source data and expected data (blk) are using the same type, + /// block returned without any modification. If not appropriate cast is + /// used. + /// + ///

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. + /// + ///

If the data array in blk is null, 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 blk 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 + /// blk after the method has returned. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// 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. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + public DataBlk getInternCompData(DataBlk blk, int c) + { + return getData(blk, c, true); + } + + /// Implements the 'getInternCompData()' and the 'getCompData()' + /// methods. The 'intern' flag signals which of the two methods should run + /// as. + /// + /// + /// The data block to get. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// If true behave as 'getInternCompData(). Otherwise behave + /// as 'getCompData()' + /// + /// + /// The requested data block + /// + /// + /// + /// + /// + /// + /// + /// + 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; + } + } +} diff --git a/CSJ2K/j2k/image/ImgDataJoiner.cs b/CSJ2K/j2k/image/ImgDataJoiner.cs index df781548..4266caca 100644 --- a/CSJ2K/j2k/image/ImgDataJoiner.cs +++ b/CSJ2K/j2k/image/ImgDataJoiner.cs @@ -40,687 +40,718 @@ * * Copyright (c) 1999/2000 JJ2000 Partners. * */ -using System; -using CSJ2K.j2k; + namespace CSJ2K.j2k.image { - - /// This class implements the ImgData interface and allows to obtain data from - /// different sources. Here, one source is represented by an ImgData and a - /// component index. The typical use of this class is when the encoder needs - /// different components (Red, Green, Blue, alpha, ...) from different input - /// files (i.e. from different ImgReader objects). - /// - ///

All input ImgData must not be tiled (i.e. must have only 1 tile) and the - /// image origin must be the canvas origin. The different inputs can have - /// different dimensions though (this will lead to different subsampling - /// factors for each component).

- /// - ///

The input ImgData and component index list must be defined when - /// constructing this class and can not be modified later.

- /// - ///
- /// - /// - /// - /// - /// - public class ImgDataJoiner : BlkImgDataSrc - { - /// Returns the overall width of the current tile in pixels. This is the - /// tile's width without accounting for any component subsampling. - /// - /// - /// The total current tile's width in pixels. - /// - /// - virtual public int TileWidth - { - get - { - return w; - } - - } - /// Returns the overall height of the current tile in pixels. This is the - /// tile's height without accounting for any component subsampling. - /// - /// - /// The total current tile's height in pixels. - /// - /// - virtual public int TileHeight - { - get - { - return h; - } - - } - /// Returns the nominal tiles width - virtual public int NomTileWidth - { - get - { - return w; - } - - } - /// Returns the nominal tiles height - virtual public int NomTileHeight - { - get - { - return h; - } - - } - /// Returns the overall width of the image in pixels. This is the image's - /// width without accounting for any component subsampling or tiling. - /// - /// - /// The total image's width in pixels. - /// - /// - virtual public int ImgWidth - { - get - { - return w; - } - - } - /// Returns the overall height of the image in pixels. This is the image's - /// height without accounting for any component subsampling or tiling. - /// - /// - /// The total image's height in pixels. - /// - /// - virtual public int ImgHeight - { - get - { - return h; - } - - } - /// Returns the number of components in the image. - /// - /// - /// The number of components in the image. - /// - /// - virtual public int NumComps - { - get - { - return nc; - } - - } - /// Returns the index of the current tile, relative to a standard scan-line - /// order. This default implementations assumes no tiling, so 0 is always - /// returned. - /// - /// - /// The current tile's index (starts at 0). - /// - /// - virtual public int TileIdx - { - get - { - return 0; - } - - } - /// Returns the horizontal tile partition offset in the reference grid - virtual public int TilePartULX - { - get - { - return 0; - } - - } - /// Returns the vertical tile partition offset in the reference grid - virtual public int TilePartULY - { - get - { - return 0; - } - - } - /// Returns the horizontal coordinate of the image origin, the top-left - /// corner, in the canvas system, on the reference grid. - /// - /// - /// The horizontal coordinate of the image origin in the canvas - /// system, on the reference grid. - /// - /// - virtual public int ImgULX - { - get - { - return 0; - } - - } - /// Returns the vertical coordinate of the image origin, the top-left - /// corner, in the canvas system, on the reference grid. - /// - /// - /// The vertical coordinate of the image origin in the canvas - /// system, on the reference grid. - /// - /// - virtual public int ImgULY - { - get - { - return 0; - } - - } - - /// The width of the image - private int w; - - /// The height of the image - private int h; - - /// The number of components in the image - private int nc; - - /// The list of input ImgData - private BlkImgDataSrc[] imageData; - - /// The component index associated with each ImgData - private int[] compIdx; - - /// The subsampling factor along the horizontal direction, for every - /// component - /// - private int[] subsX; - - /// The subsampling factor along the vertical direction, for every - /// component - /// - private int[] subsY; - - /// Class constructor. Each input BlkImgDataSrc and its component index - /// must appear in the order wanted for the output components.
- /// - /// Example: Reading R,G,B components from 3 PGM files.
- /// - /// BlkImgDataSrc[] idList =
- /// {
- /// new ImgReaderPGM(new BEBufferedRandomAccessFile("R.pgm", "r")),
- /// new ImgReaderPGM(new BEBufferedRandomAccessFile("G.pgm", "r")),
- /// new ImgReaderPGM(new BEBufferedRandomAccessFile("B.pgm", "r"))
- /// };
- /// int[] compIdx = {0,0,0};
- /// ImgDataJoiner idj = new ImgDataJoiner(idList, compIdx); - ///
- /// - ///

Of course, the 2 arrays must have the same length (This length is - /// the number of output components). The image width and height are - /// definded to be the maximum values of all the input ImgData. - /// - ///

- /// The list of input BlkImgDataSrc in an array. - /// - /// - /// The component index associated with each ImgData. - /// - /// - public ImgDataJoiner(BlkImgDataSrc[] imD, int[] cIdx) - { - int i; - int maxW, maxH; - - // Initializes - imageData = imD; - compIdx = cIdx; - if (imageData.Length != compIdx.Length) - throw new System.ArgumentException("imD and cIdx must have the" + " same length"); - - nc = imD.Length; - - subsX = new int[nc]; - subsY = new int[nc]; - - // Check that no source is tiled and that the image origin is at the - // canvas origin. - for (i = 0; i < nc; i++) - { - if (imD[i].getNumTiles() != 1 || imD[i].getCompULX(cIdx[i]) != 0 || imD[i].getCompULY(cIdx[i]) != 0) - { - throw new System.ArgumentException("All input components must, " + "not use tiles and must " + "have " + "the origin at the canvas " + "origin"); - } - } - - // Guess component subsampling factors based on the fact that the - // ceil() operation relates the reference grid size to the component's - // size, through the subsampling factor. - - // Mhhh, difficult problem. For now just assume that one of the - // subsampling factors is always 1 and that the component width is - // always larger than its subsampling factor, which covers most of the - // cases. We check the correctness of the solution once found to chek - // out hypothesis. - - // Look for max width and height. - maxW = 0; - maxH = 0; - for (i = 0; i < nc; i++) - { - if (imD[i].getCompImgWidth(cIdx[i]) > maxW) - maxW = imD[i].getCompImgWidth(cIdx[i]); - if (imD[i].getCompImgHeight(cIdx[i]) > maxH) - maxH = imD[i].getCompImgHeight(cIdx[i]); - } - // Set the image width and height as the maximum ones - w = maxW; - h = maxH; - - // Now get the sumsampling factors and check the subsampling factors, - // just to see if above hypothesis were correct. - for (i = 0; i < nc; i++) - { - // This calculation only holds if the subsampling factor is less - // than the component width - subsX[i] = (maxW + imD[i].getCompImgWidth(cIdx[i]) - 1) / imD[i].getCompImgWidth(cIdx[i]); - subsY[i] = (maxH + imD[i].getCompImgHeight(cIdx[i]) - 1) / imD[i].getCompImgHeight(cIdx[i]); - if ((maxW + subsX[i] - 1) / subsX[i] != imD[i].getCompImgWidth(cIdx[i]) || (maxH + subsY[i] - 1) / subsY[i] != imD[i].getCompImgHeight(cIdx[i])) - { - throw new System.ApplicationException("Can not compute component subsampling " + "factors: strange subsampling."); - } - } - } - - /// Returns the component subsampling factor in the horizontal direction, - /// for the specified component. This is, approximately, the ratio of - /// dimensions between the reference grid and the component itself, see the - /// 'ImgData' interface desription for details. - /// - /// - /// The index of the component (between 0 and N-1) - /// - /// - /// The horizontal subsampling factor of component 'c' - /// - /// - /// - /// - /// - public virtual int getCompSubsX(int c) - { - return subsX[c]; - } - - /// Returns the component subsampling factor in the vertical direction, for - /// the specified component. This is, approximately, the ratio of - /// dimensions between the reference grid and the component itself, see the - /// 'ImgData' interface desription for details. - /// - /// - /// The index of the component (between 0 and N-1) - /// - /// - /// The vertical subsampling factor of component 'c' - /// - /// - /// - /// - /// - public virtual int getCompSubsY(int c) - { - return subsY[c]; - } - - - /// Returns the width in pixels of the specified tile-component - /// - /// - /// Tile index - /// - /// - /// The index of the component, from 0 to N-1. - /// - /// - /// The width in pixels of component c in tilet. - /// - /// - public virtual int getTileCompWidth(int t, int c) - { - return imageData[c].getTileCompWidth(t, compIdx[c]); - } - - /// Returns the height in pixels of the specified tile-component. - /// - /// - /// The tile index. - /// - /// - /// The index of the component, from 0 to N-1. - /// - /// - /// The height in pixels of component c in the current - /// tile. - /// - /// - public virtual int getTileCompHeight(int t, int c) - { - return imageData[c].getTileCompHeight(t, compIdx[c]); - } - - /// Returns the width in pixels of the specified component in the overall - /// image. - /// - /// - /// The index of the component, from 0 to N-1. - /// - /// - /// The width in pixels of component c in the overall - /// image. - /// - /// - public virtual int getCompImgWidth(int c) - { - return imageData[c].getCompImgWidth(compIdx[c]); - } - - /// Returns the height in pixels of the specified component in the - /// overall image. - /// - /// - /// The index of the component, from 0 to N-1. - /// - /// - /// The height in pixels of component n in the overall - /// image. - /// - /// - /// - /// - public virtual int getCompImgHeight(int n) - { - return imageData[n].getCompImgHeight(compIdx[n]); - } - - /// Returns the number of bits, referred to as the "range bits", - /// corresponding to the nominal range of the data in the specified - /// component. If this number is b then for unsigned data the - /// nominal range is between 0 and 2^b-1, and for signed data it is between - /// -2^(b-1) and 2^(b-1)-1. For floating point data this value is not - /// applicable. - /// - /// - /// The index of the component. - /// - /// - /// The number of bits corresponding to the nominal range of the - /// data. Fro floating-point data this value is not applicable and the - /// return value is undefined. - /// - /// - public virtual int getNomRangeBits(int c) - { - return imageData[c].getNomRangeBits(compIdx[c]); - } - - /// 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. - /// - /// - /// The index of the component. - /// - /// - /// The position of the fixed-point, which is the same as the - /// number of fractional bits. For floating-point data 0 is returned. - /// - /// - public virtual int getFixedPoint(int c) - { - return imageData[c].getFixedPoint(compIdx[c]); - } - - /// 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. - /// - ///

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. - /// - ///

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. - /// - ///

If the data array in blk is null, 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 blk 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 - /// blk after the method has returned. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// 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. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - public virtual DataBlk getInternCompData(DataBlk blk, int c) - { - return imageData[c].getInternCompData(blk, compIdx[c]); - } - - /// 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". - /// - ///

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. - /// - ///

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. - /// - ///

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. - /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" data. - /// - ///

- /// 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. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - public virtual DataBlk getCompData(DataBlk blk, int c) - { - return imageData[c].getCompData(blk, compIdx[c]); - } - - /// Changes the current tile, given the new coordinates. An - /// IllegalArgumentException is thrown if the coordinates do not correspond - /// to a valid tile. - /// - /// - /// The horizontal coordinate of the tile. - /// - /// - /// The vertical coordinate of the new tile. - /// - /// - public virtual void setTile(int x, int y) - { - if (x != 0 || y != 0) - { - throw new System.ArgumentException(); - } - } - - /// Advances to the next tile, in standard scan-line order (by rows then - /// columns). A NoNextElementException is thrown if the current tile is the - /// last one (i.e. there is no next tile). This default implementation - /// assumes no tiling, so NoNextElementException() is always thrown. - /// - /// - public virtual void nextTile() - { - throw new NoNextElementException(); - } - - /// Returns the coordinates of the current tile. This default - /// implementation assumes no-tiling, so (0,0) is returned. - /// - /// - /// If not null this object is used to return the information. If - /// null a new one is created and returned. - /// - /// - /// The current tile's coordinates. - /// - /// - public virtual Coord getTile(Coord co) - { - if (co != null) - { - co.x = 0; - co.y = 0; - return co; - } - else - { - return new Coord(0, 0); - } - } - - /// Returns the horizontal coordinate of the upper-left corner of the - /// specified component in the current tile. - /// - /// - /// The component index. - /// - /// - public virtual int getCompULX(int c) - { - return 0; - } - - /// Returns the vertical coordinate of the upper-left corner of the - /// specified component in the current tile. - /// - /// - /// The component index. - /// - /// - public virtual int getCompULY(int c) - { - return 0; - } - - /// Returns the number of tiles in the horizontal and vertical - /// directions. This default implementation assumes no tiling, so (1,1) is - /// always returned. - /// - /// - /// If not null this object is used to return the information. If - /// null a new one is created and returned. - /// - /// - /// The number of tiles in the horizontal (Coord.x) and vertical - /// (Coord.y) directions. - /// - /// - public virtual Coord getNumTiles(Coord co) - { - if (co != null) - { - co.x = 1; - co.y = 1; - return co; - } - else - { - return new Coord(1, 1); - } - } - - /// Returns the total number of tiles in the image. This default - /// implementation assumes no tiling, so 1 is always returned. - /// - /// - /// The total number of tiles in the image. - /// - /// - public virtual int getNumTiles() - { - return 1; - } - - /// Returns a string of information about the object, more than 1 line - /// long. The information string includes information from the several - /// input ImgData (their toString() method are called one after the other). - /// - /// - /// A string of information about the object. - /// - /// - public override System.String ToString() - { - System.String string_Renamed = "ImgDataJoiner: WxH = " + w + "x" + h; - for (int i = 0; i < nc; i++) - { - //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" - string_Renamed += ("\n- Component " + i + " " + imageData[i]); - } - return string_Renamed; - } - } -} \ No newline at end of file + using System.Collections.Generic; + + using CSJ2K.j2k.image.input; + + /// This class implements the ImgData interface and allows to obtain data from + /// different sources. Here, one source is represented by an ImgData and a + /// component index. The typical use of this class is when the encoder needs + /// different components (Red, Green, Blue, alpha, ...) from different input + /// files (i.e. from different ImgReader objects). + /// + ///

All input ImgData must not be tiled (i.e. must have only 1 tile) and the + /// image origin must be the canvas origin. The different inputs can have + /// different dimensions though (this will lead to different subsampling + /// factors for each component).

+ /// + ///

The input ImgData and component index list must be defined when + /// constructing this class and can not be modified later.

+ /// + ///
+ /// + /// + /// + /// + /// + public class ImgDataJoiner : BlkImgDataSrc + { + /// Returns the overall width of the current tile in pixels. This is the + /// tile's width without accounting for any component subsampling. + /// + /// + /// The total current tile's width in pixels. + /// + /// + virtual public int TileWidth + { + get + { + return w; + } + + } + /// Returns the overall height of the current tile in pixels. This is the + /// tile's height without accounting for any component subsampling. + /// + /// + /// The total current tile's height in pixels. + /// + /// + virtual public int TileHeight + { + get + { + return h; + } + + } + /// Returns the nominal tiles width + virtual public int NomTileWidth + { + get + { + return w; + } + + } + /// Returns the nominal tiles height + virtual public int NomTileHeight + { + get + { + return h; + } + + } + /// Returns the overall width of the image in pixels. This is the image's + /// width without accounting for any component subsampling or tiling. + /// + /// + /// The total image's width in pixels. + /// + /// + virtual public int ImgWidth + { + get + { + return w; + } + + } + /// Returns the overall height of the image in pixels. This is the image's + /// height without accounting for any component subsampling or tiling. + /// + /// + /// The total image's height in pixels. + /// + /// + virtual public int ImgHeight + { + get + { + return h; + } + + } + /// Returns the number of components in the image. + /// + /// + /// The number of components in the image. + /// + /// + virtual public int NumComps + { + get + { + return nc; + } + + } + /// Returns the index of the current tile, relative to a standard scan-line + /// order. This default implementations assumes no tiling, so 0 is always + /// returned. + /// + /// + /// The current tile's index (starts at 0). + /// + /// + virtual public int TileIdx + { + get + { + return 0; + } + + } + /// Returns the horizontal tile partition offset in the reference grid + virtual public int TilePartULX + { + get + { + return 0; + } + + } + /// Returns the vertical tile partition offset in the reference grid + virtual public int TilePartULY + { + get + { + return 0; + } + + } + /// Returns the horizontal coordinate of the image origin, the top-left + /// corner, in the canvas system, on the reference grid. + /// + /// + /// The horizontal coordinate of the image origin in the canvas + /// system, on the reference grid. + /// + /// + virtual public int ImgULX + { + get + { + return 0; + } + + } + /// Returns the vertical coordinate of the image origin, the top-left + /// corner, in the canvas system, on the reference grid. + /// + /// + /// The vertical coordinate of the image origin in the canvas + /// system, on the reference grid. + /// + /// + virtual public int ImgULY + { + get + { + return 0; + } + + } + + /// The width of the image + private readonly int w; + + /// The height of the image + private readonly int h; + + /// The number of components in the image + private readonly int nc; + + /// The list of input ImgData + private readonly IList imageData; + + /// The component index associated with each ImgData + private readonly IList compIdx; + + /// The subsampling factor along the horizontal direction, for every + /// component + /// + private readonly int[] subsX; + + /// The subsampling factor along the vertical direction, for every + /// component + /// + private readonly int[] subsY; + + /// Class constructor. Each input BlkImgDataSrc and its component index + /// must appear in the order wanted for the output components.
+ /// + /// Example: Reading R,G,B components from 3 PGM files.
+ /// + /// BlkImgDataSrc[] idList =
+ /// {
+ /// new ImgReaderPGM(new BEBufferedRandomAccessFile("R.pgm", "r")),
+ /// new ImgReaderPGM(new BEBufferedRandomAccessFile("G.pgm", "r")),
+ /// new ImgReaderPGM(new BEBufferedRandomAccessFile("B.pgm", "r"))
+ /// };
+ /// int[] compIdx = {0,0,0};
+ /// ImgDataJoiner idj = new ImgDataJoiner(idList, compIdx); + ///
+ /// + ///

Of course, the 2 arrays must have the same length (This length is + /// the number of output components). The image width and height are + /// definded to be the maximum values of all the input ImgData. + /// + ///

+ /// The list of input BlkImgDataSrc in an array. + /// + /// + /// The component index associated with each ImgData. + /// + /// + public ImgDataJoiner(IList imD, IList cIdx) + { + int i; + int maxW, maxH; + + // Initializes + imageData = imD; + compIdx = cIdx; + if (imageData.Count != compIdx.Count) + throw new System.ArgumentException("imD and cIdx must have the" + " same length"); + + nc = imD.Count; + + subsX = new int[nc]; + subsY = new int[nc]; + + // Check that no source is tiled and that the image origin is at the + // canvas origin. + for (i = 0; i < nc; i++) + { + if (imD[i].getNumTiles() != 1 || imD[i].getCompULX(cIdx[i]) != 0 || imD[i].getCompULY(cIdx[i]) != 0) + { + throw new System.ArgumentException("All input components must, " + "not use tiles and must " + "have " + "the origin at the canvas " + "origin"); + } + } + + // Guess component subsampling factors based on the fact that the + // ceil() operation relates the reference grid size to the component's + // size, through the subsampling factor. + + // Mhhh, difficult problem. For now just assume that one of the + // subsampling factors is always 1 and that the component width is + // always larger than its subsampling factor, which covers most of the + // cases. We check the correctness of the solution once found to chek + // out hypothesis. + + // Look for max width and height. + maxW = 0; + maxH = 0; + for (i = 0; i < nc; i++) + { + if (imD[i].getCompImgWidth(cIdx[i]) > maxW) + maxW = imD[i].getCompImgWidth(cIdx[i]); + if (imD[i].getCompImgHeight(cIdx[i]) > maxH) + maxH = imD[i].getCompImgHeight(cIdx[i]); + } + // Set the image width and height as the maximum ones + w = maxW; + h = maxH; + + // Now get the sumsampling factors and check the subsampling factors, + // just to see if above hypothesis were correct. + for (i = 0; i < nc; i++) + { + // This calculation only holds if the subsampling factor is less + // than the component width + subsX[i] = (maxW + imD[i].getCompImgWidth(cIdx[i]) - 1) / imD[i].getCompImgWidth(cIdx[i]); + subsY[i] = (maxH + imD[i].getCompImgHeight(cIdx[i]) - 1) / imD[i].getCompImgHeight(cIdx[i]); + if ((maxW + subsX[i] - 1) / subsX[i] != imD[i].getCompImgWidth(cIdx[i]) || (maxH + subsY[i] - 1) / subsY[i] != imD[i].getCompImgHeight(cIdx[i])) + { + throw new System.InvalidOperationException("Can not compute component subsampling " + "factors: strange subsampling."); + } + } + } + + /// Returns the component subsampling factor in the horizontal direction, + /// for the specified component. This is, approximately, the ratio of + /// dimensions between the reference grid and the component itself, see the + /// 'ImgData' interface desription for details. + /// + /// + /// The index of the component (between 0 and N-1) + /// + /// + /// The horizontal subsampling factor of component 'c' + /// + /// + /// + /// + /// + public virtual int getCompSubsX(int c) + { + return subsX[c]; + } + + /// Returns the component subsampling factor in the vertical direction, for + /// the specified component. This is, approximately, the ratio of + /// dimensions between the reference grid and the component itself, see the + /// 'ImgData' interface desription for details. + /// + /// + /// The index of the component (between 0 and N-1) + /// + /// + /// The vertical subsampling factor of component 'c' + /// + /// + /// + /// + /// + public virtual int getCompSubsY(int c) + { + return subsY[c]; + } + + + /// Returns the width in pixels of the specified tile-component + /// + /// + /// Tile index + /// + /// + /// The index of the component, from 0 to N-1. + /// + /// + /// The width in pixels of component c in tilet. + /// + /// + public virtual int getTileCompWidth(int t, int c) + { + return imageData[c].getTileCompWidth(t, compIdx[c]); + } + + /// Returns the height in pixels of the specified tile-component. + /// + /// + /// The tile index. + /// + /// + /// The index of the component, from 0 to N-1. + /// + /// + /// The height in pixels of component c in the current + /// tile. + /// + /// + public virtual int getTileCompHeight(int t, int c) + { + return imageData[c].getTileCompHeight(t, compIdx[c]); + } + + /// Returns the width in pixels of the specified component in the overall + /// image. + /// + /// + /// The index of the component, from 0 to N-1. + /// + /// + /// The width in pixels of component c in the overall + /// image. + /// + /// + public virtual int getCompImgWidth(int c) + { + return imageData[c].getCompImgWidth(compIdx[c]); + } + + /// Returns the height in pixels of the specified component in the + /// overall image. + /// + /// + /// The index of the component, from 0 to N-1. + /// + /// + /// The height in pixels of component n in the overall + /// image. + /// + /// + /// + /// + public virtual int getCompImgHeight(int n) + { + return imageData[n].getCompImgHeight(compIdx[n]); + } + + /// Returns the number of bits, referred to as the "range bits", + /// corresponding to the nominal range of the data in the specified + /// component. If this number is b then for unsigned data the + /// nominal range is between 0 and 2^b-1, and for signed data it is between + /// -2^(b-1) and 2^(b-1)-1. For floating point data this value is not + /// applicable. + /// + /// + /// The index of the component. + /// + /// + /// The number of bits corresponding to the nominal range of the + /// data. Fro floating-point data this value is not applicable and the + /// return value is undefined. + /// + /// + public virtual int getNomRangeBits(int c) + { + return imageData[c].getNomRangeBits(compIdx[c]); + } + + /// 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. + /// + /// + /// The index of the component. + /// + /// + /// The position of the fixed-point, which is the same as the + /// number of fractional bits. For floating-point data 0 is returned. + /// + /// + public virtual int getFixedPoint(int c) + { + return imageData[c].getFixedPoint(compIdx[c]); + } + + /// 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. + /// + ///

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. + /// + ///

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. + /// + ///

If the data array in blk is null, 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 blk 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 + /// blk after the method has returned. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// 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. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + public virtual DataBlk getInternCompData(DataBlk blk, int c) + { + return imageData[c].getInternCompData(blk, compIdx[c]); + } + + /// 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". + /// + ///

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. + /// + ///

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. + /// + ///

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. + /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" data. + /// + ///

+ /// 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. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + public virtual DataBlk getCompData(DataBlk blk, int c) + { + return imageData[c].getCompData(blk, compIdx[c]); + } + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + public void close() + { + foreach (var reader in imageData) + { + reader.close(); + } + } + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + public bool isOrigSigned(int c) + { + return false; + } + + /// Changes the current tile, given the new coordinates. An + /// IllegalArgumentException is thrown if the coordinates do not correspond + /// to a valid tile. + /// + /// + /// The horizontal coordinate of the tile. + /// + /// + /// The vertical coordinate of the new tile. + /// + /// + public virtual void setTile(int x, int y) + { + if (x != 0 || y != 0) + { + throw new System.ArgumentException(); + } + } + + /// Advances to the next tile, in standard scan-line order (by rows then + /// columns). A NoNextElementException is thrown if the current tile is the + /// last one (i.e. there is no next tile). This default implementation + /// assumes no tiling, so NoNextElementException() is always thrown. + /// + /// + public virtual void nextTile() + { + throw new NoNextElementException(); + } + + /// Returns the coordinates of the current tile. This default + /// implementation assumes no-tiling, so (0,0) is returned. + /// + /// + /// If not null this object is used to return the information. If + /// null a new one is created and returned. + /// + /// + /// The current tile's coordinates. + /// + /// + public virtual Coord getTile(Coord co) + { + if (co != null) + { + co.x = 0; + co.y = 0; + return co; + } + else + { + return new Coord(0, 0); + } + } + + /// Returns the horizontal coordinate of the upper-left corner of the + /// specified component in the current tile. + /// + /// + /// The component index. + /// + /// + public virtual int getCompULX(int c) + { + return 0; + } + + /// Returns the vertical coordinate of the upper-left corner of the + /// specified component in the current tile. + /// + /// + /// The component index. + /// + /// + public virtual int getCompULY(int c) + { + return 0; + } + + /// Returns the number of tiles in the horizontal and vertical + /// directions. This default implementation assumes no tiling, so (1,1) is + /// always returned. + /// + /// + /// If not null this object is used to return the information. If + /// null a new one is created and returned. + /// + /// + /// The number of tiles in the horizontal (Coord.x) and vertical + /// (Coord.y) directions. + /// + /// + public virtual Coord getNumTiles(Coord co) + { + if (co != null) + { + co.x = 1; + co.y = 1; + return co; + } + else + { + return new Coord(1, 1); + } + } + + /// Returns the total number of tiles in the image. This default + /// implementation assumes no tiling, so 1 is always returned. + /// + /// + /// The total number of tiles in the image. + /// + /// + public virtual int getNumTiles() + { + return 1; + } + + /// Returns a string of information about the object, more than 1 line + /// long. The information string includes information from the several + /// input ImgData (their toString() method are called one after the other). + /// + /// + /// A string of information about the object. + /// + /// + public override System.String ToString() + { + System.String string_Renamed = "ImgDataJoiner: WxH = " + w + "x" + h; + for (int i = 0; i < nc; i++) + { + //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" + string_Renamed += ("\n- Component " + i + " " + imageData[i]); + } + return string_Renamed; + } + } +} diff --git a/CSJ2K/j2k/image/Tiler.cs b/CSJ2K/j2k/image/Tiler.cs index ec8ed229..0c0845c0 100644 --- a/CSJ2K/j2k/image/Tiler.cs +++ b/CSJ2K/j2k/image/Tiler.cs @@ -44,707 +44,747 @@ using System; using CSJ2K.j2k.util; using CSJ2K.j2k; + namespace CSJ2K.j2k.image { - - /// This class places an image in the canvas coordinate system, tiles it, if so - /// specified, and performs the coordinate conversions transparently. The - /// source must be a 'BlkImgDataSrc' which is not tiled and has a the image - /// origin at the canvas origin (i.e. it is not "canvased"), or an exception is - /// thrown by the constructor. A tiled and "canvased" output is given through - /// the 'BlkImgDataSrc' interface. See the 'ImgData' interface for a - /// description of the canvas and tiling. - /// - ///

All tiles produced are rectangular, non-overlapping and their union - /// covers all the image. However, the tiling may not be uniform, depending on - /// the nominal tile size, tiling origin, component subsampling and other - /// factors. Therefore it might not be assumed that all tiles are of the same - /// width and height.

- /// - ///

The nominal dimension of the tiles is the maximal one, in the reference - /// grid. All the components of the image have the same number of tiles.

- /// - ///
- /// - /// - /// - /// - /// - public class Tiler:ImgDataAdapter, BlkImgDataSrc - { - /// Returns the overall width of the current tile in pixels. This is the - /// tile's width without accounting for any component subsampling. - /// - /// - /// The total current tile width in pixels. - /// - /// - override public int TileWidth - { - get - { - return tileW; - } - - } - /// Returns the overall height of the current tile in pixels. This is the - /// tile's width without accounting for any component subsampling. - /// - /// - /// The total current tile height in pixels. - /// - /// - override public int TileHeight - { - get - { - return tileH; - } - - } - /// Returns the index of the current tile, relative to a standard scan-line - /// order. - /// - /// - /// The current tile's index (starts at 0). - /// - /// - override public int TileIdx - { - get - { - return ty * ntX + tx; - } - - } - /// Returns the horizontal tile partition offset in the reference grid - override public int TilePartULX - { - get - { - return xt0siz; - } - - } - /// Returns the vertical tile partition offset in the reference grid - override public int TilePartULY - { - get - { - return yt0siz; - } - - } - /// Returns the horizontal coordinate of the image origin, the top-left - /// corner, in the canvas system, on the reference grid. - /// - /// - /// The horizontal coordinate of the image origin in the canvas - /// system, on the reference grid. - /// - /// - override public int ImgULX - { - get - { - return x0siz; - } - - } - /// Returns the vertical coordinate of the image origin, the top-left - /// corner, in the canvas system, on the reference grid. - /// - /// - /// The vertical coordinate of the image origin in the canvas - /// system, on the reference grid. - /// - /// - override public int ImgULY - { - get - { - return y0siz; - } - - } - /// Returns the nominal width of the tiles in the reference grid. - /// - /// - /// The nominal tile width, in the reference grid. - /// - /// - override public int NomTileWidth - { - get - { - return xtsiz; - } - - } - /// Returns the nominal width of the tiles in the reference grid. - /// - /// - /// The nominal tile width, in the reference grid. - /// - /// - override public int NomTileHeight - { - get - { - return ytsiz; - } - - } - - /// The source of image data - private BlkImgDataSrc src = null; - - /// Horizontal coordinate of the upper left hand reference grid point. - private int x0siz; - - /// Vertical coordinate of the upper left hand reference grid point. - private int y0siz; - - /// The horizontal coordinate of the tiling origin in the canvas system, - /// on the reference grid. - /// - private int xt0siz; - - /// The vertical coordinate of the tiling origin in the canvas system, on - /// the reference grid. - /// - private int yt0siz; - - /// The nominal width of the tiles, on the reference grid. If 0 then there - /// is no tiling in that direction. - /// - private int xtsiz; - - /// The nominal height of the tiles, on the reference grid. If 0 then - /// there is no tiling in that direction. - /// - private int ytsiz; - - /// The number of tiles in the horizontal direction. - private int ntX; - - /// The number of tiles in the vertical direction. - private int ntY; - - /// The component width in the current active tile, for each component - private int[] compW = null; - - /// The component height in the current active tile, for each component - private int[] compH = null; - - /// The horizontal coordinates of the upper-left corner of the components - /// in the current tile - /// - private int[] tcx0 = null; - - /// The vertical coordinates of the upper-left corner of the components in - /// the current tile. - /// - private int[] tcy0 = null; - - /// The horizontal index of the current tile - private int tx; - - /// The vertical index of the current tile - private int ty; - - /// The width of the current tile, on the reference grid. - private int tileW; - - /// The height of the current tile, on the reference grid. - private int tileH; - - /// Constructs a new tiler with the specified 'BlkImgDataSrc' source, - /// image origin, tiling origin and nominal tile size. - /// - /// - /// The 'BlkImgDataSrc' source from where to get the image - /// data. It must not be tiled and the image origin must be at '(0,0)' on - /// its canvas. - /// - /// - /// The horizontal coordinate of the image origin in the canvas - /// system, on the reference grid (i.e. the image's top-left corner in the - /// reference grid). - /// - /// - /// The vertical coordinate of the image origin in the canvas - /// system, on the reference grid (i.e. the image's top-left corner in the - /// reference grid). - /// - /// - /// The horizontal tiling origin, in the canvas system, on the - /// reference grid. It must satisfy 'px<=ax'. - /// - /// - /// The vertical tiling origin, in the canvas system, on the - /// reference grid. It must satisfy 'py<=ay'. - /// - /// - /// The nominal tile width, on the reference grid. If 0 then - /// there is no tiling in that direction. - /// - /// - /// The nominal tile height, on the reference grid. If 0 then - /// there is no tiling in that direction. - /// - /// - /// If src is tiled or "canvased", or - /// if the arguments do not satisfy the specified constraints. - /// - /// - public Tiler(BlkImgDataSrc src, int ax, int ay, int px, int py, int nw, int nh):base(src) - { - - // Initialize - this.src = src; - this.x0siz = ax; - this.y0siz = ay; - this.xt0siz = px; - this.yt0siz = py; - this.xtsiz = nw; - this.ytsiz = nh; - - // Verify that input is not tiled - if (src.getNumTiles() != 1) - { - throw new System.ArgumentException("Source is tiled"); - } - // Verify that source is not "canvased" - if (src.ImgULX != 0 || src.ImgULY != 0) - { - throw new System.ArgumentException("Source is \"canvased\""); - } - // Verify that arguments satisfy trivial requirements - if (x0siz < 0 || y0siz < 0 || xt0siz < 0 || yt0siz < 0 || xtsiz < 0 || ytsiz < 0 || xt0siz > x0siz || yt0siz > y0siz) - { - throw new System.ArgumentException("Invalid image origin, " + "tiling origin or nominal " + "tile size"); - } - - // If no tiling has been specified, creates a unique tile with maximum - // dimension. - if (xtsiz == 0) - xtsiz = x0siz + src.ImgWidth - xt0siz; - if (ytsiz == 0) - ytsiz = y0siz + src.ImgHeight - yt0siz; - - // Automatically adjusts xt0siz,yt0siz so that tile (0,0) always - // overlaps with the image. - if (x0siz - xt0siz >= xtsiz) - { - xt0siz += ((x0siz - xt0siz) / xtsiz) * xtsiz; - } - if (y0siz - yt0siz >= ytsiz) - { - yt0siz += ((y0siz - yt0siz) / ytsiz) * ytsiz; - } - if (x0siz - xt0siz >= xtsiz || y0siz - yt0siz >= ytsiz) - { - FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, "Automatically adjusted tiling " + "origin to equivalent one (" + xt0siz + "," + yt0siz + ") so that " + "first tile overlaps the image"); - } - - // Calculate the number of tiles - //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'" - ntX = (int) System.Math.Ceiling((x0siz + src.ImgWidth) / (double) xtsiz); - //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'" - ntY = (int) System.Math.Ceiling((y0siz + src.ImgHeight) / (double) ytsiz); - } - - /// Returns the width in pixels of the specified tile-component. - /// - /// - /// Tile index - /// - /// - /// The index of the component, from 0 to N-1. - /// - /// - /// The width of specified tile-component. - /// - /// - public override int getTileCompWidth(int t, int c) - { - if (t != TileIdx) - { - throw new System.ApplicationException("Asking the width of a tile-component which is " + "not in the current tile (call setTile() or " + "nextTile() methods before)."); - } - return compW[c]; - } - - /// Returns the height in pixels of the specified tile-component. - /// - /// - /// The tile index. - /// - /// - /// The index of the component, from 0 to N-1. - /// - /// - /// The height of specified tile-component. - /// - /// - public override int getTileCompHeight(int t, int c) - { - if (t != TileIdx) - { - throw new System.ApplicationException("Asking the width of a tile-component which is " + "not in the current tile (call setTile() or " + "nextTile() methods before)."); - } - return compH[c]; - } - - /// 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. - /// - /// - /// The index of the component. - /// - /// - /// The position of the fixed-point, which is the same as the - /// number of fractional bits. For floating-point data 0 is returned. - /// - /// - public virtual int getFixedPoint(int c) - { - return src.getFixedPoint(c); - } - - /// 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. - /// - ///

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.

- /// - ///

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.

- /// - ///

If the data array in blk is null, 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 blk 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 - /// blk after the method has returned.

- /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" - /// data.

- /// - ///
- /// 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. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - public DataBlk getInternCompData(DataBlk blk, int c) - { - // Check that block is inside tile - if (blk.ulx < 0 || blk.uly < 0 || blk.w > compW[c] || blk.h > compH[c]) - { - throw new System.ArgumentException("Block is outside the tile"); - } - // Translate to the sources coordinates - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - int incx = (int) System.Math.Ceiling(x0siz / (double) src.getCompSubsX(c)); - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - int incy = (int) System.Math.Ceiling(y0siz / (double) src.getCompSubsY(c)); - blk.ulx -= incx; - blk.uly -= incy; - blk = src.getInternCompData(blk, c); - // Translate back to the tiled coordinates - blk.ulx += incx; - blk.uly += incy; - return blk; - } - - /// 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". - /// - ///

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.

- /// - ///

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.

- /// - ///

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.

- /// - ///

The returned data may have its 'progressive' attribute set. In this - /// case the returned data is only an approximation of the "final" - /// data.

- /// - ///
- /// 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. - /// - /// - /// The index of the component from which to get the data. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - public DataBlk getCompData(DataBlk blk, int c) - { - // Check that block is inside tile - if (blk.ulx < 0 || blk.uly < 0 || blk.w > compW[c] || blk.h > compH[c]) - { - throw new System.ArgumentException("Block is outside the tile"); - } - // Translate to the source's coordinates - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - int incx = (int) System.Math.Ceiling(x0siz / (double) src.getCompSubsX(c)); - //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" - int incy = (int) System.Math.Ceiling(y0siz / (double) src.getCompSubsY(c)); - blk.ulx -= incx; - blk.uly -= incy; - blk = src.getCompData(blk, c); - // Translate back to the tiled coordinates - blk.ulx += incx; - blk.uly += incy; - return blk; - } - - /// Changes the current tile, given the new tile indexes. An - /// IllegalArgumentException is thrown if the coordinates do not correspond - /// to a valid tile. - /// - /// - /// The horizontal index of the tile. - /// - /// - /// The vertical index of the new tile. - /// - /// - public override void setTile(int x, int y) - { - // Check tile indexes - if (x < 0 || y < 0 || x >= ntX || y >= ntY) - { - throw new System.ArgumentException("Tile's indexes out of bounds"); - } - - // Set new current tile - tx = x; - ty = y; - // Calculate tile origins - int tx0 = (x != 0)?xt0siz + x * xtsiz:x0siz; - int ty0 = (y != 0)?yt0siz + y * ytsiz:y0siz; - int tx1 = (x != ntX - 1)?(xt0siz + (x + 1) * xtsiz):(x0siz + src.ImgWidth); - int ty1 = (y != ntY - 1)?(yt0siz + (y + 1) * ytsiz):(y0siz + src.ImgHeight); - // Set general variables - tileW = tx1 - tx0; - tileH = ty1 - ty0; - // Set component specific variables - int nc = src.NumComps; - if (compW == null) - compW = new int[nc]; - if (compH == null) - compH = new int[nc]; - if (tcx0 == null) - tcx0 = new int[nc]; - if (tcy0 == null) - tcy0 = new int[nc]; - for (int i = 0; i < nc; i++) - { - //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'" - tcx0[i] = (int) System.Math.Ceiling(tx0 / (double) src.getCompSubsX(i)); - //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'" - tcy0[i] = (int) System.Math.Ceiling(ty0 / (double) src.getCompSubsY(i)); - //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'" - compW[i] = (int) System.Math.Ceiling(tx1 / (double) src.getCompSubsX(i)) - tcx0[i]; - //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'" - compH[i] = (int) System.Math.Ceiling(ty1 / (double) src.getCompSubsY(i)) - tcy0[i]; - } - } - - /// Advances to the next tile, in standard scan-line order (by rows then - /// columns). An NoNextElementException is thrown if the current tile is - /// the last one (i.e. there is no next tile). - /// - /// - public override void nextTile() - { - if (tx == ntX - 1 && ty == ntY - 1) - { - // Already at last tile - throw new NoNextElementException(); - } - else if (tx < ntX - 1) - { - // If not at end of current tile line - setTile(tx + 1, ty); - } - else - { - // First tile at next line - setTile(0, ty + 1); - } - } - - /// Returns the horizontal and vertical indexes of the current tile. - /// - /// - /// If not null this object is used to return the - /// information. If null a new one is created and returned. - /// - /// - /// The current tile's horizontal and vertical indexes.. - /// - /// - public override Coord getTile(Coord co) - { - if (co != null) - { - co.x = tx; - co.y = ty; - return co; - } - else - { - return new Coord(tx, ty); - } - } - - /// Returns the horizontal coordinate of the upper-left corner of the - /// specified component in the current tile. - /// - /// - /// The component index. - /// - /// - public override int getCompULX(int c) - { - return tcx0[c]; - } - - /// Returns the vertical coordinate of the upper-left corner of the - /// specified component in the current tile. - /// - /// - /// The component index. - /// - /// - public override int getCompULY(int c) - { - return tcy0[c]; - } - - /// Returns the number of tiles in the horizontal and vertical directions. - /// - /// - /// If not null this object is used to return the information. If - /// null a new one is created and returned. - /// - /// - /// The number of tiles in the horizontal (Coord.x) and vertical - /// (Coord.y) directions. - /// - /// - public override Coord getNumTiles(Coord co) - { - if (co != null) - { - co.x = ntX; - co.y = ntY; - return co; - } - else - { - return new Coord(ntX, ntY); - } - } - - /// Returns the total number of tiles in the image. - /// - /// - /// The total number of tiles in the image. - /// - /// - public override int getNumTiles() - { - return ntX * ntY; - } - - /// Returns the tiling origin, referred to as '(xt0siz,yt0siz)' in the - /// codestream header (SIZ marker segment). - /// - /// - /// If not null this object is used to return the information. If - /// null a new one is created and returned. - /// - /// - /// The coordinate of the tiling origin, in the canvas system, on - /// the reference grid. - /// - /// - /// - /// - /// - public Coord getTilingOrigin(Coord co) - { - if (co != null) - { - co.x = xt0siz; - co.y = yt0siz; - return co; - } - else - { - return new Coord(xt0siz, yt0siz); - } - } - - /// Returns a String object representing Tiler's informations - /// - /// - /// Tiler's infos in a string - /// - /// - public override System.String ToString() - { - //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" - return "Tiler: source= " + src + "\n" + getNumTiles() + " tile(s), nominal width=" + xtsiz + ", nominal height=" + ytsiz; - } - } -} \ No newline at end of file + + /// This class places an image in the canvas coordinate system, tiles it, if so + /// specified, and performs the coordinate conversions transparently. The + /// source must be a 'BlkImgDataSrc' which is not tiled and has a the image + /// origin at the canvas origin (i.e. it is not "canvased"), or an exception is + /// thrown by the constructor. A tiled and "canvased" output is given through + /// the 'BlkImgDataSrc' interface. See the 'ImgData' interface for a + /// description of the canvas and tiling. + /// + ///

All tiles produced are rectangular, non-overlapping and their union + /// covers all the image. However, the tiling may not be uniform, depending on + /// the nominal tile size, tiling origin, component subsampling and other + /// factors. Therefore it might not be assumed that all tiles are of the same + /// width and height.

+ /// + ///

The nominal dimension of the tiles is the maximal one, in the reference + /// grid. All the components of the image have the same number of tiles.

+ /// + ///
+ /// + /// + /// + /// + /// + public class Tiler : ImgDataAdapter, BlkImgDataSrc + { + /// Returns the overall width of the current tile in pixels. This is the + /// tile's width without accounting for any component subsampling. + /// + /// + /// The total current tile width in pixels. + /// + /// + public override int TileWidth + { + get + { + return tileW; + } + + } + + /// Returns the overall height of the current tile in pixels. This is the + /// tile's width without accounting for any component subsampling. + /// + /// + /// The total current tile height in pixels. + /// + /// + public override int TileHeight + { + get + { + return tileH; + } + + } + + /// Returns the index of the current tile, relative to a standard scan-line + /// order. + /// + /// + /// The current tile's index (starts at 0). + /// + /// + public override int TileIdx + { + get + { + return ty * ntX + tx; + } + + } + + /// Returns the horizontal tile partition offset in the reference grid + public override int TilePartULX + { + get + { + return xt0siz; + } + + } + + /// Returns the vertical tile partition offset in the reference grid + public override int TilePartULY + { + get + { + return yt0siz; + } + + } + + /// Returns the horizontal coordinate of the image origin, the top-left + /// corner, in the canvas system, on the reference grid. + /// + /// + /// The horizontal coordinate of the image origin in the canvas + /// system, on the reference grid. + /// + /// + public override int ImgULX + { + get + { + return x0siz; + } + + } + + /// Returns the vertical coordinate of the image origin, the top-left + /// corner, in the canvas system, on the reference grid. + /// + /// + /// The vertical coordinate of the image origin in the canvas + /// system, on the reference grid. + /// + /// + public override int ImgULY + { + get + { + return y0siz; + } + + } + + /// Returns the nominal width of the tiles in the reference grid. + /// + /// + /// The nominal tile width, in the reference grid. + /// + /// + public override int NomTileWidth + { + get + { + return xtsiz; + } + + } + + /// Returns the nominal width of the tiles in the reference grid. + /// + /// + /// The nominal tile width, in the reference grid. + /// + /// + public override int NomTileHeight + { + get + { + return ytsiz; + } + + } + + /// The source of image data + private BlkImgDataSrc src = null; + + /// Horizontal coordinate of the upper left hand reference grid point. + private int x0siz; + + /// Vertical coordinate of the upper left hand reference grid point. + private int y0siz; + + /// The horizontal coordinate of the tiling origin in the canvas system, + /// on the reference grid. + /// + private int xt0siz; + + /// The vertical coordinate of the tiling origin in the canvas system, on + /// the reference grid. + /// + private int yt0siz; + + /// The nominal width of the tiles, on the reference grid. If 0 then there + /// is no tiling in that direction. + /// + private int xtsiz; + + /// The nominal height of the tiles, on the reference grid. If 0 then + /// there is no tiling in that direction. + /// + private int ytsiz; + + /// The number of tiles in the horizontal direction. + private int ntX; + + /// The number of tiles in the vertical direction. + private int ntY; + + /// The component width in the current active tile, for each component + private int[] compW = null; + + /// The component height in the current active tile, for each component + private int[] compH = null; + + /// The horizontal coordinates of the upper-left corner of the components + /// in the current tile + /// + private int[] tcx0 = null; + + /// The vertical coordinates of the upper-left corner of the components in + /// the current tile. + /// + private int[] tcy0 = null; + + /// The horizontal index of the current tile + private int tx; + + /// The vertical index of the current tile + private int ty; + + /// The width of the current tile, on the reference grid. + private int tileW; + + /// The height of the current tile, on the reference grid. + private int tileH; + + /// Constructs a new tiler with the specified 'BlkImgDataSrc' source, + /// image origin, tiling origin and nominal tile size. + /// + /// + /// The 'BlkImgDataSrc' source from where to get the image + /// data. It must not be tiled and the image origin must be at '(0,0)' on + /// its canvas. + /// + /// + /// The horizontal coordinate of the image origin in the canvas + /// system, on the reference grid (i.e. the image's top-left corner in the + /// reference grid). + /// + /// + /// The vertical coordinate of the image origin in the canvas + /// system, on the reference grid (i.e. the image's top-left corner in the + /// reference grid). + /// + /// + /// The horizontal tiling origin, in the canvas system, on the + /// reference grid. It must satisfy 'px<=ax'. + /// + /// + /// The vertical tiling origin, in the canvas system, on the + /// reference grid. It must satisfy 'py<=ay'. + /// + /// + /// The nominal tile width, on the reference grid. If 0 then + /// there is no tiling in that direction. + /// + /// + /// The nominal tile height, on the reference grid. If 0 then + /// there is no tiling in that direction. + /// + /// + /// If src is tiled or "canvased", or + /// if the arguments do not satisfy the specified constraints. + /// + /// + public Tiler(BlkImgDataSrc src, int ax, int ay, int px, int py, int nw, int nh) + : base(src) + { + + // Initialize + this.src = src; + this.x0siz = ax; + this.y0siz = ay; + this.xt0siz = px; + this.yt0siz = py; + this.xtsiz = nw; + this.ytsiz = nh; + + // Verify that input is not tiled + if (src.getNumTiles() != 1) + { + throw new System.ArgumentException("Source is tiled"); + } + // Verify that source is not "canvased" + if (src.ImgULX != 0 || src.ImgULY != 0) + { + throw new System.ArgumentException("Source is \"canvased\""); + } + // Verify that arguments satisfy trivial requirements + if (x0siz < 0 || y0siz < 0 || xt0siz < 0 || yt0siz < 0 || xtsiz < 0 || ytsiz < 0 || xt0siz > x0siz + || yt0siz > y0siz) + { + throw new System.ArgumentException("Invalid image origin, " + "tiling origin or nominal " + "tile size"); + } + + // If no tiling has been specified, creates a unique tile with maximum + // dimension. + if (xtsiz == 0) xtsiz = x0siz + src.ImgWidth - xt0siz; + if (ytsiz == 0) ytsiz = y0siz + src.ImgHeight - yt0siz; + + // Automatically adjusts xt0siz,yt0siz so that tile (0,0) always + // overlaps with the image. + if (x0siz - xt0siz >= xtsiz) + { + xt0siz += ((x0siz - xt0siz) / xtsiz) * xtsiz; + } + if (y0siz - yt0siz >= ytsiz) + { + yt0siz += ((y0siz - yt0siz) / ytsiz) * ytsiz; + } + if (x0siz - xt0siz >= xtsiz || y0siz - yt0siz >= ytsiz) + { + FacilityManager.getMsgLogger() + .printmsg( + CSJ2K.j2k.util.MsgLogger_Fields.INFO, + "Automatically adjusted tiling " + "origin to equivalent one (" + xt0siz + "," + yt0siz + + ") so that " + "first tile overlaps the image"); + } + + // Calculate the number of tiles + //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'" + ntX = (int)System.Math.Ceiling((x0siz + src.ImgWidth) / (double)xtsiz); + //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'" + ntY = (int)System.Math.Ceiling((y0siz + src.ImgHeight) / (double)ytsiz); + } + + /// Returns the width in pixels of the specified tile-component. + /// + /// + /// Tile index + /// + /// + /// The index of the component, from 0 to N-1. + /// + /// + /// The width of specified tile-component. + /// + /// + public override int getTileCompWidth(int t, int c) + { + if (t != TileIdx) + { + throw new System.InvalidOperationException( + "Asking the width of a tile-component which is " + "not in the current tile (call setTile() or " + + "nextTile() methods before)."); + } + return compW[c]; + } + + /// Returns the height in pixels of the specified tile-component. + /// + /// + /// The tile index. + /// + /// + /// The index of the component, from 0 to N-1. + /// + /// + /// The height of specified tile-component. + /// + /// + public override int getTileCompHeight(int t, int c) + { + if (t != TileIdx) + { + throw new System.InvalidOperationException( + "Asking the width of a tile-component which is " + "not in the current tile (call setTile() or " + + "nextTile() methods before)."); + } + return compH[c]; + } + + /// 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. + /// + /// + /// The index of the component. + /// + /// + /// The position of the fixed-point, which is the same as the + /// number of fractional bits. For floating-point data 0 is returned. + /// + /// + public virtual int getFixedPoint(int c) + { + return src.getFixedPoint(c); + } + + /// 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. + /// + ///

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.

+ /// + ///

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.

+ /// + ///

If the data array in blk is null, 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 blk 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 + /// blk after the method has returned.

+ /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" + /// data.

+ /// + ///
+ /// 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. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + public DataBlk getInternCompData(DataBlk blk, int c) + { + // Check that block is inside tile + if (blk.ulx < 0 || blk.uly < 0 || blk.w > compW[c] || blk.h > compH[c]) + { + throw new System.ArgumentException("Block is outside the tile"); + } + // Translate to the sources coordinates + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + int incx = (int)System.Math.Ceiling(x0siz / (double)src.getCompSubsX(c)); + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + int incy = (int)System.Math.Ceiling(y0siz / (double)src.getCompSubsY(c)); + blk.ulx -= incx; + blk.uly -= incy; + blk = src.getInternCompData(blk, c); + // Translate back to the tiled coordinates + blk.ulx += incx; + blk.uly += incy; + return blk; + } + + /// 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". + /// + ///

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.

+ /// + ///

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.

+ /// + ///

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.

+ /// + ///

The returned data may have its 'progressive' attribute set. In this + /// case the returned data is only an approximation of the "final" + /// data.

+ /// + ///
+ /// 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. + /// + /// + /// The index of the component from which to get the data. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + public DataBlk getCompData(DataBlk blk, int c) + { + // Check that block is inside tile + if (blk.ulx < 0 || blk.uly < 0 || blk.w > compW[c] || blk.h > compH[c]) + { + throw new System.ArgumentException("Block is outside the tile"); + } + // Translate to the source's coordinates + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + int incx = (int)System.Math.Ceiling(x0siz / (double)src.getCompSubsX(c)); + //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" + int incy = (int)System.Math.Ceiling(y0siz / (double)src.getCompSubsY(c)); + blk.ulx -= incx; + blk.uly -= incy; + blk = src.getCompData(blk, c); + // Translate back to the tiled coordinates + blk.ulx += incx; + blk.uly += incy; + return blk; + } + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + public void close() + { + // Do nothing. + } + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + public bool isOrigSigned(int c) + { + return false; + } + + /// Changes the current tile, given the new tile indexes. An + /// IllegalArgumentException is thrown if the coordinates do not correspond + /// to a valid tile. + /// + /// + /// The horizontal index of the tile. + /// + /// + /// The vertical index of the new tile. + /// + /// + public override void setTile(int x, int y) + { + // Check tile indexes + if (x < 0 || y < 0 || x >= ntX || y >= ntY) + { + throw new System.ArgumentException("Tile's indexes out of bounds"); + } + + // Set new current tile + tx = x; + ty = y; + // Calculate tile origins + int tx0 = (x != 0) ? xt0siz + x * xtsiz : x0siz; + int ty0 = (y != 0) ? yt0siz + y * ytsiz : y0siz; + int tx1 = (x != ntX - 1) ? (xt0siz + (x + 1) * xtsiz) : (x0siz + src.ImgWidth); + int ty1 = (y != ntY - 1) ? (yt0siz + (y + 1) * ytsiz) : (y0siz + src.ImgHeight); + // Set general variables + tileW = tx1 - tx0; + tileH = ty1 - ty0; + // Set component specific variables + int nc = src.NumComps; + if (compW == null) compW = new int[nc]; + if (compH == null) compH = new int[nc]; + if (tcx0 == null) tcx0 = new int[nc]; + if (tcy0 == null) tcy0 = new int[nc]; + for (int i = 0; i < nc; i++) + { + //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'" + tcx0[i] = (int)System.Math.Ceiling(tx0 / (double)src.getCompSubsX(i)); + //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'" + tcy0[i] = (int)System.Math.Ceiling(ty0 / (double)src.getCompSubsY(i)); + //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'" + compW[i] = (int)System.Math.Ceiling(tx1 / (double)src.getCompSubsX(i)) - tcx0[i]; + //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'" + compH[i] = (int)System.Math.Ceiling(ty1 / (double)src.getCompSubsY(i)) - tcy0[i]; + } + } + + /// Advances to the next tile, in standard scan-line order (by rows then + /// columns). An NoNextElementException is thrown if the current tile is + /// the last one (i.e. there is no next tile). + /// + /// + public override void nextTile() + { + if (tx == ntX - 1 && ty == ntY - 1) + { + // Already at last tile + throw new NoNextElementException(); + } + else if (tx < ntX - 1) + { + // If not at end of current tile line + setTile(tx + 1, ty); + } + else + { + // First tile at next line + setTile(0, ty + 1); + } + } + + /// Returns the horizontal and vertical indexes of the current tile. + /// + /// + /// If not null this object is used to return the + /// information. If null a new one is created and returned. + /// + /// + /// The current tile's horizontal and vertical indexes.. + /// + /// + public override Coord getTile(Coord co) + { + if (co != null) + { + co.x = tx; + co.y = ty; + return co; + } + else + { + return new Coord(tx, ty); + } + } + + /// Returns the horizontal coordinate of the upper-left corner of the + /// specified component in the current tile. + /// + /// + /// The component index. + /// + /// + public override int getCompULX(int c) + { + return tcx0[c]; + } + + /// Returns the vertical coordinate of the upper-left corner of the + /// specified component in the current tile. + /// + /// + /// The component index. + /// + /// + public override int getCompULY(int c) + { + return tcy0[c]; + } + + /// Returns the number of tiles in the horizontal and vertical directions. + /// + /// + /// If not null this object is used to return the information. If + /// null a new one is created and returned. + /// + /// + /// The number of tiles in the horizontal (Coord.x) and vertical + /// (Coord.y) directions. + /// + /// + public override Coord getNumTiles(Coord co) + { + if (co != null) + { + co.x = ntX; + co.y = ntY; + return co; + } + else + { + return new Coord(ntX, ntY); + } + } + + /// Returns the total number of tiles in the image. + /// + /// + /// The total number of tiles in the image. + /// + /// + public override int getNumTiles() + { + return ntX * ntY; + } + + /// Returns the tiling origin, referred to as '(xt0siz,yt0siz)' in the + /// codestream header (SIZ marker segment). + /// + /// + /// If not null this object is used to return the information. If + /// null a new one is created and returned. + /// + /// + /// The coordinate of the tiling origin, in the canvas system, on + /// the reference grid. + /// + /// + /// + /// + /// + public Coord getTilingOrigin(Coord co) + { + if (co != null) + { + co.x = xt0siz; + co.y = yt0siz; + return co; + } + else + { + return new Coord(xt0siz, yt0siz); + } + } + + /// Returns a String object representing Tiler's informations + /// + /// + /// Tiler's infos in a string + /// + /// + public override System.String ToString() + { + //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" + return "Tiler: source= " + src + "\n" + getNumTiles() + " tile(s), nominal width=" + xtsiz + + ", nominal height=" + ytsiz; + } + } +} diff --git a/CSJ2K/j2k/image/forwcomptransf/ForwCompTransf.cs b/CSJ2K/j2k/image/forwcomptransf/ForwCompTransf.cs index 00af357f..c52a540d 100644 --- a/CSJ2K/j2k/image/forwcomptransf/ForwCompTransf.cs +++ b/CSJ2K/j2k/image/forwcomptransf/ForwCompTransf.cs @@ -441,8 +441,34 @@ namespace CSJ2K.j2k.image.forwcomptransf return getInternCompData(blk, c); } } - - /// Apply the component transformation associated with the current tile. If + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + public void close() + { + // Do nothing. + } + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + public bool isOrigSigned(int c) + { + return false; + } + + /// 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). /// diff --git a/CSJ2K/j2k/image/input/ImgReader.cs b/CSJ2K/j2k/image/input/ImgReader.cs index 7de37453..aecb5110 100644 --- a/CSJ2K/j2k/image/input/ImgReader.cs +++ b/CSJ2K/j2k/image/input/ImgReader.cs @@ -308,7 +308,7 @@ namespace CSJ2K.j2k.image.input { if (t != 0) { - throw new System.ApplicationException("Asking a tile-component width for a tile index" + " greater than 0 whereas there is only one tile"); + throw new System.InvalidOperationException("Asking a tile-component width for a tile index" + " greater than 0 whereas there is only one tile"); } return w; } @@ -333,7 +333,7 @@ namespace CSJ2K.j2k.image.input { if (t != 0) { - throw new System.ApplicationException("Asking a tile-component width for a tile index" + " greater than 0 whereas there is only one tile"); + throw new System.InvalidOperationException("Asking a tile-component width for a tile index" + " greater than 0 whereas there is only one tile"); } return h; } @@ -502,9 +502,9 @@ namespace CSJ2K.j2k.image.input /// /// public abstract bool isOrigSigned(int c); - public abstract int getFixedPoint(int param1); - public abstract CSJ2K.j2k.image.DataBlk getInternCompData(CSJ2K.j2k.image.DataBlk param1, int param2); - public abstract int getNomRangeBits(int param1); - public abstract CSJ2K.j2k.image.DataBlk getCompData(CSJ2K.j2k.image.DataBlk param1, int param2); + public abstract int getFixedPoint(int c); + public abstract DataBlk getInternCompData(DataBlk blk, int c); + public abstract int getNomRangeBits(int c); + public abstract DataBlk getCompData(DataBlk blk, int c); } } \ No newline at end of file diff --git a/CSJ2K/j2k/image/input/ImgReaderPGM.cs b/CSJ2K/j2k/image/input/ImgReaderPGM.cs index 3540030d..f72a7fce 100644 --- a/CSJ2K/j2k/image/input/ImgReaderPGM.cs +++ b/CSJ2K/j2k/image/input/ImgReaderPGM.cs @@ -39,6 +39,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; using CSJ2K.j2k.image; using CSJ2K.j2k; namespace CSJ2K.j2k.image.input @@ -66,7 +67,7 @@ namespace CSJ2K.j2k.image.input /// Where to read the data from //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private System.IO.FileStream in_Renamed; + private System.IO.Stream in_Renamed; /// The offset of the raw pixel data in the PGM file private int offset; @@ -83,7 +84,7 @@ namespace CSJ2K.j2k.image.input /// filters). This avoid allocating new DataBlk at each time /// private DataBlkInt intBlk; - + /// Creates a new PGM file reader from the specified file. /// /// @@ -93,9 +94,10 @@ namespace CSJ2K.j2k.image.input /// If an error occurs while opening the file. /// /// - public ImgReaderPGM(System.IO.FileInfo file):this(SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(file, "r")) + public ImgReaderPGM(IFileInfo file) + : this(SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(file, "r")) { - } + } /// Creates a new PGM file reader from the specified file name. /// @@ -123,7 +125,7 @@ namespace CSJ2K.j2k.image.input /// /// //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - public ImgReaderPGM(System.IO.FileStream in_Renamed) + public ImgReaderPGM(System.IO.Stream in_Renamed) { this.in_Renamed = in_Renamed; @@ -149,7 +151,7 @@ namespace CSJ2K.j2k.image.input /// public override void close() { - in_Renamed.Close(); + in_Renamed.Dispose(); in_Renamed = null; } diff --git a/CSJ2K/j2k/image/input/ImgReaderPGX.cs b/CSJ2K/j2k/image/input/ImgReaderPGX.cs index 0ccfee87..496a72cd 100644 --- a/CSJ2K/j2k/image/input/ImgReaderPGX.cs +++ b/CSJ2K/j2k/image/input/ImgReaderPGX.cs @@ -42,6 +42,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; using CSJ2K.j2k.image; using CSJ2K.j2k.io; using CSJ2K.j2k; @@ -109,7 +110,7 @@ namespace CSJ2K.j2k.image.input /// The RandomAccessIO where to get datas from //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private System.IO.FileStream in_Renamed; + private System.IO.Stream in_Renamed; /// The bit-depth of the input file (must be between 1 and 31) private int bitDepth; @@ -145,36 +146,25 @@ namespace CSJ2K.j2k.image.input /// If an I/O error occurs. /// /// - public ImgReaderPGX(System.IO.FileInfo in_Renamed) + public ImgReaderPGX(System.IO.Stream in_Renamed) { System.String header; - // Check if specified file exists - bool tmpBool; - if (System.IO.File.Exists(in_Renamed.FullName)) - tmpBool = true; - else - tmpBool = System.IO.Directory.Exists(in_Renamed.FullName); - if (!tmpBool) - { - throw new System.ArgumentException("PGX file " + in_Renamed.Name + " does not exist"); - } - //Opens the given file - this.in_Renamed = SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(in_Renamed, "r"); + this.in_Renamed = in_Renamed; try { System.IO.StreamReader in_reader = new System.IO.StreamReader(this.in_Renamed); //UPGRADE_ISSUE: Method 'java.io.RandomAccessFile.readLine' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javaioRandomAccessFilereadLine'" header = in_reader.ReadLine(); } - catch (System.IO.IOException) + catch (System.IO.IOException e) { - throw new System.IO.IOException(in_Renamed.Name + " is not a PGX file"); + throw new System.IO.IOException("Not a PGX file"); } if (header == null) { - throw new System.IO.IOException(in_Renamed.Name + " is an empty file"); + throw new System.IO.IOException("Empty file"); } offset = (header.Length + 1); @@ -186,7 +176,7 @@ namespace CSJ2K.j2k.image.input // Magic Number if (!(st.NextToken()).Equals("PG")) - throw new System.IO.IOException(in_Renamed.Name + " is not a PGX file"); + throw new System.IO.IOException("Not a PGX file"); // Endianess System.String tmp = st.NextToken(); @@ -195,7 +185,7 @@ namespace CSJ2K.j2k.image.input else if (tmp.Equals("ML")) byteOrder = CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN; else - throw new System.IO.IOException(in_Renamed.Name + " is not a PGX file"); + throw new System.IO.IOException("Not a PGX file"); // Unsigned/signed if present in the header if (nTokens == 6) @@ -206,7 +196,7 @@ namespace CSJ2K.j2k.image.input else if (tmp.Equals("-")) isSigned = true; else - throw new System.IO.IOException(in_Renamed.Name + " is not a PGX file"); + throw new System.IO.IOException("Not a PGX file"); } // bit-depth, width, height @@ -215,19 +205,19 @@ namespace CSJ2K.j2k.image.input bitDepth = (System.Int32.Parse(st.NextToken())); // bitDepth must be between 1 and 31 if ((bitDepth <= 0) || (bitDepth > 31)) - throw new System.IO.IOException(in_Renamed.Name + " is not a valid PGX file"); + throw new System.IO.IOException("Not a PGX file"); w = (System.Int32.Parse(st.NextToken())); h = (System.Int32.Parse(st.NextToken())); } - catch (System.FormatException) + catch (System.FormatException e) { - throw new System.IO.IOException(in_Renamed.Name + " is not a PGX file"); + throw new System.IO.IOException("Not a PGX file"); } } - catch (System.ArgumentOutOfRangeException) + catch (System.ArgumentOutOfRangeException e) { - throw new System.IO.IOException(in_Renamed.Name + " is not a PGX file"); + throw new System.IO.IOException("Not a PGX file"); } // Number of component @@ -242,14 +232,27 @@ namespace CSJ2K.j2k.image.input else packBytes = 4; } - + + /// Creates a new PGX file reader from the specified File object. + /// + /// + /// The input file as File object. + /// + /// + /// If an I/O error occurs. + /// + /// + public ImgReaderPGX(IFileInfo in_Renamed) : this(SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(in_Renamed, "r")) + { + } + /// Creates a new PGX file reader from the specified file name. /// /// /// The input file name. /// /// - public ImgReaderPGX(System.String inName):this(new System.IO.FileInfo(inName)) + public ImgReaderPGX(System.String inName):this(FileInfoFactory.New(inName)) { } @@ -262,7 +265,7 @@ namespace CSJ2K.j2k.image.input /// public override void close() { - in_Renamed.Close(); + in_Renamed.Dispose(); in_Renamed = null; buf = null; } @@ -459,7 +462,7 @@ namespace CSJ2K.j2k.image.input break; default: - throw new System.ApplicationException("Internal JJ2000 bug"); + throw new System.InvalidOperationException("Internal JJ2000 bug"); } } @@ -490,7 +493,7 @@ namespace CSJ2K.j2k.image.input break; default: - throw new System.ApplicationException("Internal JJ2000 bug"); + throw new System.InvalidOperationException("Internal JJ2000 bug"); } } @@ -526,7 +529,7 @@ namespace CSJ2K.j2k.image.input break; default: - throw new System.ApplicationException("Internal JJ2000 bug"); + throw new System.InvalidOperationException("Internal JJ2000 bug"); } } @@ -556,7 +559,7 @@ namespace CSJ2K.j2k.image.input break; default: - throw new System.ApplicationException("Internal JJ2000 bug"); + throw new System.InvalidOperationException("Internal JJ2000 bug"); } } diff --git a/CSJ2K/j2k/image/input/ImgReaderPPM.cs b/CSJ2K/j2k/image/input/ImgReaderPPM.cs index 97fdf37c..24986d19 100644 --- a/CSJ2K/j2k/image/input/ImgReaderPPM.cs +++ b/CSJ2K/j2k/image/input/ImgReaderPPM.cs @@ -39,6 +39,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; using CSJ2K.j2k.image; using CSJ2K.j2k.io; using CSJ2K.j2k; @@ -71,7 +72,7 @@ namespace CSJ2K.j2k.image.input /// Where to read the data from //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private System.IO.FileStream in_Renamed; + private System.IO.Stream in_Renamed; /// The offset of the raw pixel data in the PPM file private int offset; @@ -94,7 +95,7 @@ namespace CSJ2K.j2k.image.input /// filters). This avoid allocating new DataBlk at each time /// private DataBlkInt intBlk; - + /// Creates a new PPM file reader from the specified file. /// /// @@ -104,9 +105,10 @@ namespace CSJ2K.j2k.image.input /// If an error occurs while opening the file. /// /// - public ImgReaderPPM(System.IO.FileInfo file):this(SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(file, "r")) + public ImgReaderPPM(IFileInfo file) + : this(SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(file, "r")) { - } + } /// Creates a new PPM file reader from the specified file name. /// @@ -134,7 +136,7 @@ namespace CSJ2K.j2k.image.input /// /// //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private ImgReaderPPM(System.IO.FileStream in_Renamed) + public ImgReaderPPM(System.IO.Stream in_Renamed) { this.in_Renamed = in_Renamed; @@ -159,7 +161,7 @@ namespace CSJ2K.j2k.image.input /// public override void close() { - in_Renamed.Close(); + in_Renamed.Dispose(); in_Renamed = null; // Free memory barr[0] = null; diff --git a/CSJ2K/j2k/image/invcomptransf/InvCompTransf.cs b/CSJ2K/j2k/image/invcomptransf/InvCompTransf.cs index dd88510a..4402a7ad 100644 --- a/CSJ2K/j2k/image/invcomptransf/InvCompTransf.cs +++ b/CSJ2K/j2k/image/invcomptransf/InvCompTransf.cs @@ -46,766 +46,805 @@ using CSJ2K.j2k.decoder; using CSJ2K.j2k.image; using CSJ2K.j2k.util; using CSJ2K.j2k; + namespace CSJ2K.j2k.image.invcomptransf { - - /// This class apply inverse component transformations to the tiles depending - /// on specification read from the codestream header. These transformations can - /// be used to improve compression efficiency but are not related to colour - /// transforms used to map colour values for display purposes. JPEG 2000 part I - /// defines 2 component transformations: RCT (Reversible Component - /// Transformation) and ICT (Irreversible Component Transformation). - /// - /// - /// - /// - /// - public class InvCompTransf:ImgDataAdapter, BlkImgDataSrc - { - /// Returns the parameters that are used in this class and implementing - /// classes. It returns a 2D String array. Each of the 1D arrays is for a - /// different option, and they have 4 elements. The first element is the - /// option name, the second one is the synopsis, the third one is a long - /// description of what the parameter is and the fourth is its default - /// value. The synopsis or description may be 'null', in which case it is - /// assumed that there is no synopsis or description of the option, - /// respectively. Null may be returned if no options are supported. - /// - /// - /// the options name, their synopsis and their explanation, - /// or null if no options are supported. - /// - /// - public static System.String[][] ParameterInfo - { - get - { - return pinfo; - } - - } - /// Returns true if this transform is reversible in current - /// tile. Reversible component transformations are those which operation - /// can be completely reversed without any loss of information (not even - /// due to rounding). - /// - /// - /// Reversibility of component transformation in current - /// tile - /// - /// - virtual public bool Reversible - { - get - { - switch (transfType) - { - - case NONE: - case INV_RCT: - return true; - - case INV_ICT: - return false; - - default: - throw new System.ArgumentException("Non JPEG 2000 part I" + " component transformation"); - - } - } - - } - - /// Identifier for no component transformation. Value is 0. - public const int NONE = 0; - - /// The prefix for inverse component transformation options: 'M' - public const char OPT_PREFIX = 'M'; - - /// The list of parameters that is accepted by the inverse - /// component transformation module. They start with 'M'. - /// - //UPGRADE_NOTE: Final was removed from the declaration of 'pinfo'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private static readonly System.String[][] pinfo = null; - - /// Identifier for the Inverse Reversible Component Transformation - /// (INV_RCT). Value is 1. - /// - public const int INV_RCT = 1; - - /// Identifier for the Inverse Irreversible Component - /// Transformation (INV_ICT). Value is 2 - /// - public const int INV_ICT = 2; - - /// The source of image data - private BlkImgDataSrc src; - - /// The component transformations specifications - private CompTransfSpec cts; - - /// The wavelet filter specifications - private SynWTFilterSpec wfs; - - /// The type of the current component transformation JPEG 2000 - /// part I only support NONE, FORW_RCT and FORW_ICT types - /// - private int transfType = NONE; - - /// Buffer for each component of output data - private int[][] outdata = new int[3][]; - - /// Block used to request component 0 - private DataBlk block0; - - /// Block used to request component 1 - private DataBlk block1; - - /// Block used to request component 2 - private DataBlk block2; - - /// Data block used only to store coordinates and progressiveness - /// of the buffered blocks - /// - private DataBlkInt dbi = new DataBlkInt(); - - /// The bit-depths of un-transformed components - private int[] utdepth; - - /// Flag indicating whether the decoder should skip the component - /// transform - /// - private bool noCompTransf = false; - - /// Constructs a new ForwCompTransf object that operates on the - /// specified source of image data. - /// - /// - /// The source from where to get the data to be - /// transformed - /// - /// - /// The decoder specifications - /// - /// - /// The bit depth of the un-transformed components - /// - /// - /// The command line optinons of the decoder - /// - /// - /// - /// - /// - public InvCompTransf(BlkImgDataSrc imgSrc, DecoderSpecs decSpec, int[] utdepth, ParameterList pl):base(imgSrc) - { - this.cts = decSpec.cts; - this.wfs = decSpec.wfs; - src = imgSrc; - this.utdepth = utdepth; - noCompTransf = !(pl.getBooleanParameter("comp_transf")); - } - - /// Returns a string with a descriptive text of which inverse component - /// transformation is used. This can be either "Inverse RCT" or "Inverse - /// ICT" or "No component transformation" depending on the current tile. - /// - /// - /// A descriptive string - /// - /// - public override System.String ToString() - { - switch (transfType) - { - - case INV_RCT: - return "Inverse RCT"; - - case INV_ICT: - return "Inverse ICT"; - - case NONE: - return "No component transformation"; - - default: - throw new System.ArgumentException("Non JPEG 2000 part I" + " component transformation"); - - } - } - - /// 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. - /// - ///

This default implementation assumes that the number of fractional - /// bits is not modified by the component mixer. - /// - ///

- /// The index of the component. - /// - /// - /// The value of the fixed point position of the source since the - /// color transform does not affect it. - /// - /// - public virtual int getFixedPoint(int c) - { - return src.getFixedPoint(c); - } - - /// Calculates the bitdepths of the transformed components, given the - /// bitdepth of the un-transformed components and the component - /// tranformation type. - /// - /// - /// The bitdepth of each un-transformed component - /// - /// - /// The type ID of the inverse component tranformation - /// - /// - /// If not null the results are stored in this - /// array, otherwise a new array is allocated and returned. - /// - /// - /// The bitdepth of each transformed component. - /// - /// - public static int[] calcMixedBitDepths(int[] utdepth, int ttype, int[] tdepth) - { - - if (utdepth.Length < 3 && ttype != NONE) - { - throw new System.ArgumentException(); - } - - if (tdepth == null) - { - tdepth = new int[utdepth.Length]; - } - - switch (ttype) - { - - case NONE: - Array.Copy(utdepth, 0, tdepth, 0, utdepth.Length); - break; - - case INV_RCT: - if (utdepth.Length > 3) - { - Array.Copy(utdepth, 3, tdepth, 3, utdepth.Length - 3); - } - // The formulas are: - // tdepth[0] = ceil(log2(2^(utdepth[0])+2^utdepth[1]+ - // 2^(utdepth[2])))-2+1 - // tdepth[1] = ceil(log2(2^(utdepth[0])+2^(utdepth[1])-1))+1 - // tdepth[2] = ceil(log2(2^(utdepth[1])+2^(utdepth[2])-1))+1 - // The MathUtil.log2(x) function calculates floor(log2(x)), so we - // use 'MathUtil.log2(2*x-1)+1', which calculates ceil(log2(x)) - // for any x>=1, x integer. - tdepth[0] = MathUtil.log2((1 << utdepth[0]) + (2 << utdepth[1]) + (1 << utdepth[2]) - 1) - 2 + 1; - tdepth[1] = MathUtil.log2((1 << utdepth[2]) + (1 << utdepth[1]) - 1) + 1; - tdepth[2] = MathUtil.log2((1 << utdepth[0]) + (1 << utdepth[1]) - 1) + 1; - break; - - case INV_ICT: - if (utdepth.Length > 3) - { - Array.Copy(utdepth, 3, tdepth, 3, utdepth.Length - 3); - } - // The MathUtil.log2(x) function calculates floor(log2(x)), so we - // use 'MathUtil.log2(2*x-1)+1', which calculates ceil(log2(x)) - // for any x>=1, x integer. - //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'" - tdepth[0] = MathUtil.log2((int) System.Math.Floor((1 << utdepth[0]) * 0.299072 + (1 << utdepth[1]) * 0.586914 + (1 << utdepth[2]) * 0.114014) - 1) + 1; - //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'" - tdepth[1] = MathUtil.log2((int) System.Math.Floor((1 << utdepth[0]) * 0.168701 + (1 << utdepth[1]) * 0.331299 + (1 << utdepth[2]) * 0.5) - 1) + 1; - //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'" - tdepth[2] = MathUtil.log2((int) System.Math.Floor((1 << utdepth[0]) * 0.5 + (1 << utdepth[1]) * 0.418701 + (1 << utdepth[2]) * 0.081299) - 1) + 1; - break; - } - - return tdepth; - } - - /// Returns the number of bits, referred to as the "range bits", - /// corresponding to the nominal range of the data in the specified - /// component. If this number is b then for unsigned data the - /// nominal range is between 0 and 2^b-1, and for signed data it is between - /// -2^(b-1) and 2^(b-1)-1. - /// - /// - /// The index of the component. - /// - /// - /// The bitdepth of un-transformed component 'c'. - /// - /// - public override int getNomRangeBits(int c) - { - return utdepth[c]; - } - - /// Apply inverse component transformation associated with the current - /// tile. If no component transformation has been requested by the user, - /// data are not modified. - /// - ///

This method calls the getInternCompData() method, but respects the - /// definitions of the getCompData() method defined in the BlkImgDataSrc - /// interface. - /// - ///

- /// Determines the rectangular area to return, and the - /// data is returned in this object. - /// - /// - /// Index of the output component. - /// - /// - /// The requested DataBlk - /// - /// - /// - /// - /// - 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 || noCompTransf) - { - return src.getCompData(blk, c); - } - else - { - // We can use getInternCompData (since data is a copy anyways) - return getInternCompData(blk, c); - } - } - - /// 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). - /// - /// - /// - /// - /// - /// - /// - /// - /// Determines the rectangular area to return. - /// - /// - /// Index of the output component. - /// - /// - /// The requested DataBlk - /// - /// - 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"); - - } - } - - /// Apply inverse component transformation to obtain requested component - /// from specified block of data. Whatever the type of requested DataBlk, - /// it always returns a DataBlkInt. - /// - /// - /// Determine the rectangular area to return - /// - /// - /// The index of the requested component - /// - /// - /// Data of requested component - /// - /// - private DataBlk invRCT(DataBlk blk, int c) - { - // If the component number is three or greater, return original data - if (c >= 3 && c < NumComps) - { - // Requesting a component whose index is greater than 3 - return src.getInternCompData(blk, c); - } - // If asking a component for the first time for this block, - // do transform for the 3 components - else if ((outdata[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, k0, k1, k2, mink, i; - int w = blk.w; //width of output block - int h = blk.h; //height of ouput block - - //Reference to output block data array - outdata[c] = (int[]) blk.Data; - - //Create data array of blk if necessary - if (outdata[c] == null || outdata[c].Length != h * w) - { - outdata[c] = new int[h * w]; - blk.Data = outdata[c]; - } - - outdata[(c + 1) % 3] = new int[outdata[c].Length]; - outdata[(c + 2) % 3] = new int[outdata[c].Length]; - - if (block0 == null || block0.DataType != DataBlk.TYPE_INT) - block0 = new DataBlkInt(); - if (block1 == null || block1.DataType != DataBlk.TYPE_INT) - block1 = new DataBlkInt(); - if (block2 == null || block2.DataType != DataBlk.TYPE_INT) - 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; - - int[] data0, data1, data2; // input data arrays - - // 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); - 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; - - // set attributes of the DataBlk used for buffering - dbi.progressive = blk.progressive; - dbi.ulx = blk.ulx; - dbi.uly = blk.uly; - dbi.w = blk.w; - dbi.h = blk.h; - - // 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; - - for (i = h - 1; i >= 0; i--) - { - for (mink = k - w; k > mink; k--, k0--, k1--, k2--) - { - outdata[1][k] = (data0[k0] - ((data1[k1] + data2[k2]) >> 2)); - outdata[0][k] = data2[k2] + outdata[1][k]; - outdata[2][k] = data1[k1] + outdata[1][k]; - } - // Jump to beggining of previous line in input - k0 -= (block0.scanw - w); - k1 -= (block1.scanw - w); - k2 -= (block2.scanw - w); - } - outdata[c] = null; - } - else if ((c >= 0) && (c < 3)) - { - //Asking for the 2nd or 3rd block component - blk.Data = outdata[c]; - blk.progressive = dbi.progressive; - blk.offset = (blk.uly - dbi.uly) * dbi.w + blk.ulx - dbi.ulx; - blk.scanw = dbi.w; - outdata[c] = null; - } - else - { - // Requesting a non valid component index - throw new System.ArgumentException(); - } - return blk; - } - - /// Apply inverse irreversible component transformation to obtain requested - /// component from specified block of data. Whatever the type of requested - /// DataBlk, it always returns a DataBlkFloat. - /// - /// - /// Determine the rectangular area to return - /// - /// - /// The index of the requested component - /// - /// - /// Data of requested component - /// - /// - private DataBlk invICT(DataBlk blk, int c) - { - if (c >= 3 && c < NumComps) - { - // Requesting a component whose index is greater than 3 + + /// This class apply inverse component transformations to the tiles depending + /// on specification read from the codestream header. These transformations can + /// be used to improve compression efficiency but are not related to colour + /// transforms used to map colour values for display purposes. JPEG 2000 part I + /// defines 2 component transformations: RCT (Reversible Component + /// Transformation) and ICT (Irreversible Component Transformation). + /// + /// + /// + /// + /// + public class InvCompTransf : ImgDataAdapter, BlkImgDataSrc + { + /// Returns the parameters that are used in this class and implementing + /// classes. It returns a 2D String array. Each of the 1D arrays is for a + /// different option, and they have 4 elements. The first element is the + /// option name, the second one is the synopsis, the third one is a long + /// description of what the parameter is and the fourth is its default + /// value. The synopsis or description may be 'null', in which case it is + /// assumed that there is no synopsis or description of the option, + /// respectively. Null may be returned if no options are supported. + /// + /// + /// the options name, their synopsis and their explanation, + /// or null if no options are supported. + /// + /// + public static System.String[][] ParameterInfo + { + get + { + return pinfo; + } + + } + + /// Returns true if this transform is reversible in current + /// tile. Reversible component transformations are those which operation + /// can be completely reversed without any loss of information (not even + /// due to rounding). + /// + /// + /// Reversibility of component transformation in current + /// tile + /// + /// + public virtual bool Reversible + { + get + { + switch (transfType) + { + + case NONE: + case INV_RCT: + return true; + + case INV_ICT: + return false; + + default: + throw new System.ArgumentException("Non JPEG 2000 part I" + " component transformation"); + + } + } + + } + + /// Identifier for no component transformation. Value is 0. + public const int NONE = 0; + + /// The prefix for inverse component transformation options: 'M' + public const char OPT_PREFIX = 'M'; + + /// The list of parameters that is accepted by the inverse + /// component transformation module. They start with 'M'. + /// + //UPGRADE_NOTE: Final was removed from the declaration of 'pinfo'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + private static readonly System.String[][] pinfo = null; + + /// Identifier for the Inverse Reversible Component Transformation + /// (INV_RCT). Value is 1. + /// + public const int INV_RCT = 1; + + /// Identifier for the Inverse Irreversible Component + /// Transformation (INV_ICT). Value is 2 + /// + public const int INV_ICT = 2; + + /// The source of image data + private BlkImgDataSrc src; + + /// The component transformations specifications + private CompTransfSpec cts; + + /// The wavelet filter specifications + private SynWTFilterSpec wfs; + + /// The type of the current component transformation JPEG 2000 + /// part I only support NONE, FORW_RCT and FORW_ICT types + /// + private int transfType = NONE; + + /// Buffer for each component of output data + private int[][] outdata = new int[3][]; + + /// Block used to request component 0 + private DataBlk block0; + + /// Block used to request component 1 + private DataBlk block1; + + /// Block used to request component 2 + private DataBlk block2; + + /// Data block used only to store coordinates and progressiveness + /// of the buffered blocks + /// + private DataBlkInt dbi = new DataBlkInt(); + + /// The bit-depths of un-transformed components + private int[] utdepth; + + /// Flag indicating whether the decoder should skip the component + /// transform + /// + private bool noCompTransf = false; + + /// Constructs a new ForwCompTransf object that operates on the + /// specified source of image data. + /// + /// + /// The source from where to get the data to be + /// transformed + /// + /// + /// The decoder specifications + /// + /// + /// The bit depth of the un-transformed components + /// + /// + /// The command line optinons of the decoder + /// + /// + /// + /// + /// + public InvCompTransf(BlkImgDataSrc imgSrc, DecoderSpecs decSpec, int[] utdepth, ParameterList pl) + : base(imgSrc) + { + this.cts = decSpec.cts; + this.wfs = decSpec.wfs; + src = imgSrc; + this.utdepth = utdepth; + noCompTransf = !(pl.getBooleanParameter("comp_transf")); + } + + /// Returns a string with a descriptive text of which inverse component + /// transformation is used. This can be either "Inverse RCT" or "Inverse + /// ICT" or "No component transformation" depending on the current tile. + /// + /// + /// A descriptive string + /// + /// + public override System.String ToString() + { + switch (transfType) + { + + case INV_RCT: + return "Inverse RCT"; + + case INV_ICT: + return "Inverse ICT"; + + case NONE: + return "No component transformation"; + + default: + throw new System.ArgumentException("Non JPEG 2000 part I" + " component transformation"); + + } + } + + /// 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. + /// + ///

This default implementation assumes that the number of fractional + /// bits is not modified by the component mixer. + /// + ///

+ /// The index of the component. + /// + /// + /// The value of the fixed point position of the source since the + /// color transform does not affect it. + /// + /// + public virtual int getFixedPoint(int c) + { + return src.getFixedPoint(c); + } + + /// Calculates the bitdepths of the transformed components, given the + /// bitdepth of the un-transformed components and the component + /// tranformation type. + /// + /// + /// The bitdepth of each un-transformed component + /// + /// + /// The type ID of the inverse component tranformation + /// + /// + /// If not null the results are stored in this + /// array, otherwise a new array is allocated and returned. + /// + /// + /// The bitdepth of each transformed component. + /// + /// + public static int[] calcMixedBitDepths(int[] utdepth, int ttype, int[] tdepth) + { + + if (utdepth.Length < 3 && ttype != NONE) + { + throw new System.ArgumentException(); + } + + if (tdepth == null) + { + tdepth = new int[utdepth.Length]; + } + + switch (ttype) + { + + case NONE: + Array.Copy(utdepth, 0, tdepth, 0, utdepth.Length); + break; + + case INV_RCT: + if (utdepth.Length > 3) + { + Array.Copy(utdepth, 3, tdepth, 3, utdepth.Length - 3); + } + // The formulas are: + // tdepth[0] = ceil(log2(2^(utdepth[0])+2^utdepth[1]+ + // 2^(utdepth[2])))-2+1 + // tdepth[1] = ceil(log2(2^(utdepth[0])+2^(utdepth[1])-1))+1 + // tdepth[2] = ceil(log2(2^(utdepth[1])+2^(utdepth[2])-1))+1 + // The MathUtil.log2(x) function calculates floor(log2(x)), so we + // use 'MathUtil.log2(2*x-1)+1', which calculates ceil(log2(x)) + // for any x>=1, x integer. + tdepth[0] = MathUtil.log2((1 << utdepth[0]) + (2 << utdepth[1]) + (1 << utdepth[2]) - 1) - 2 + 1; + tdepth[1] = MathUtil.log2((1 << utdepth[2]) + (1 << utdepth[1]) - 1) + 1; + tdepth[2] = MathUtil.log2((1 << utdepth[0]) + (1 << utdepth[1]) - 1) + 1; + break; + + case INV_ICT: + if (utdepth.Length > 3) + { + Array.Copy(utdepth, 3, tdepth, 3, utdepth.Length - 3); + } + // The MathUtil.log2(x) function calculates floor(log2(x)), so we + // use 'MathUtil.log2(2*x-1)+1', which calculates ceil(log2(x)) + // for any x>=1, x integer. + //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'" + tdepth[0] = + MathUtil.log2( + (int) + System.Math.Floor( + (1 << utdepth[0]) * 0.299072 + (1 << utdepth[1]) * 0.586914 + + (1 << utdepth[2]) * 0.114014) - 1) + 1; + //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'" + tdepth[1] = + MathUtil.log2( + (int) + System.Math.Floor( + (1 << utdepth[0]) * 0.168701 + (1 << utdepth[1]) * 0.331299 + (1 << utdepth[2]) * 0.5) + - 1) + 1; + //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'" + tdepth[2] = + MathUtil.log2( + (int) + System.Math.Floor( + (1 << utdepth[0]) * 0.5 + (1 << utdepth[1]) * 0.418701 + (1 << utdepth[2]) * 0.081299) + - 1) + 1; + break; + } + + return tdepth; + } + + /// Returns the number of bits, referred to as the "range bits", + /// corresponding to the nominal range of the data in the specified + /// component. If this number is b then for unsigned data the + /// nominal range is between 0 and 2^b-1, and for signed data it is between + /// -2^(b-1) and 2^(b-1)-1. + /// + /// + /// The index of the component. + /// + /// + /// The bitdepth of un-transformed component 'c'. + /// + /// + public override int getNomRangeBits(int c) + { + return utdepth[c]; + } + + /// Apply inverse component transformation associated with the current + /// tile. If no component transformation has been requested by the user, + /// data are not modified. + /// + ///

This method calls the getInternCompData() method, but respects the + /// definitions of the getCompData() method defined in the BlkImgDataSrc + /// interface. + /// + ///

+ /// Determines the rectangular area to return, and the + /// data is returned in this object. + /// + /// + /// Index of the output component. + /// + /// + /// The requested DataBlk + /// + /// + /// + /// + /// + 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 || noCompTransf) + { + return src.getCompData(blk, c); + } + else + { + // We can use getInternCompData (since data is a copy anyways) + return getInternCompData(blk, c); + } + } + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + public void close() + { + // Do nothing. + } + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + public bool isOrigSigned(int c) + { + return false; + } + + /// 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). + /// + /// + /// + /// + /// + /// + /// + /// + /// Determines the rectangular area to return. + /// + /// + /// Index of the output component. + /// + /// + /// The requested DataBlk + /// + /// + 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"); + + } + } + + /// Apply inverse component transformation to obtain requested component + /// from specified block of data. Whatever the type of requested DataBlk, + /// it always returns a DataBlkInt. + /// + /// + /// Determine the rectangular area to return + /// + /// + /// The index of the requested component + /// + /// + /// Data of requested component + /// + /// + private DataBlk invRCT(DataBlk blk, int c) + { + // If the component number is three or greater, return original data + if (c >= 3 && c < NumComps) + { + // Requesting a component whose index is greater than 3 + return src.getInternCompData(blk, c); + } + // If asking a component for the first time for this block, + // do transform for the 3 components + else if ((outdata[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, k0, k1, k2, mink, i; + int w = blk.w; //width of output block + int h = blk.h; //height of ouput block + + //Reference to output block data array + outdata[c] = (int[])blk.Data; + + //Create data array of blk if necessary + if (outdata[c] == null || outdata[c].Length != h * w) + { + outdata[c] = new int[h * w]; + blk.Data = outdata[c]; + } + + outdata[(c + 1) % 3] = new int[outdata[c].Length]; + outdata[(c + 2) % 3] = new int[outdata[c].Length]; + + if (block0 == null || block0.DataType != DataBlk.TYPE_INT) block0 = new DataBlkInt(); + if (block1 == null || block1.DataType != DataBlk.TYPE_INT) block1 = new DataBlkInt(); + if (block2 == null || block2.DataType != DataBlk.TYPE_INT) 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; + + int[] data0, data1, data2; // input data arrays + + // 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); + 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; + + // set attributes of the DataBlk used for buffering + dbi.progressive = blk.progressive; + dbi.ulx = blk.ulx; + dbi.uly = blk.uly; + dbi.w = blk.w; + dbi.h = blk.h; + + // 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; + + for (i = h - 1; i >= 0; i--) + { + for (mink = k - w; k > mink; k--, k0--, k1--, k2--) + { + outdata[1][k] = (data0[k0] - ((data1[k1] + data2[k2]) >> 2)); + outdata[0][k] = data2[k2] + outdata[1][k]; + outdata[2][k] = data1[k1] + outdata[1][k]; + } + // Jump to beggining of previous line in input + k0 -= (block0.scanw - w); + k1 -= (block1.scanw - w); + k2 -= (block2.scanw - w); + } + outdata[c] = null; + } + else if ((c >= 0) && (c < 3)) + { + //Asking for the 2nd or 3rd block component + blk.Data = outdata[c]; + blk.progressive = dbi.progressive; + blk.offset = (blk.uly - dbi.uly) * dbi.w + blk.ulx - dbi.ulx; + blk.scanw = dbi.w; + outdata[c] = null; + } + else + { + // Requesting a non valid component index + throw new System.ArgumentException(); + } + return blk; + } + + /// Apply inverse irreversible component transformation to obtain requested + /// component from specified block of data. Whatever the type of requested + /// DataBlk, it always returns a DataBlkFloat. + /// + /// + /// Determine the rectangular area to return + /// + /// + /// The index of the requested component + /// + /// + /// Data of requested component + /// + /// + private DataBlk invICT(DataBlk blk, int c) + { + if (c >= 3 && c < NumComps) + { + // Requesting a component whose index is greater than 3 int k, k0, mink, i; // k1, k2 removed - int w = blk.w; //width of output block - int h = blk.h; //height of ouput block - - int[] out_data; // array of output data - - //Reference to output block data array - out_data = (int[]) blk.Data; - - //Create data array of blk if necessary - if (out_data == null) - { - out_data = new int[h * w]; - blk.Data = out_data; - } - - // Variables - DataBlkFloat indb = new DataBlkFloat(blk.ulx, blk.uly, w, h); - float[] indata; // input data array - - // Get the input data - // (returned block may be larger than requested one) - src.getInternCompData(indb, c); - indata = (float[]) indb.Data; - - // Copy the data converting from int to int - 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'" - out_data[k] = (int) (indata[k0]); - } - // Jump to beggining of previous line in input - k0 -= (indb.scanw - w); - } - - // Set the progressivity and offset - blk.progressive = indb.progressive; - blk.offset = 0; - blk.scanw = w; - } - // If asking a component for the first time for this block, - // do transform for the 3 components - else if ((outdata[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, k0, k1, k2, mink, i; - int w = blk.w; //width of output block - int h = blk.h; //height of ouput block - - //Reference to output block data array - outdata[c] = (int[]) blk.Data; - - //Create data array of blk if necessary - if (outdata[c] == null || outdata[c].Length != w * h) - { - outdata[c] = new int[h * w]; - blk.Data = outdata[c]; - } - - outdata[(c + 1) % 3] = new int[outdata[c].Length]; - outdata[(c + 2) % 3] = new int[outdata[c].Length]; - - if (block0 == null || block0.DataType != DataBlk.TYPE_FLOAT) - block0 = new DataBlkFloat(); - if (block2 == null || block2.DataType != DataBlk.TYPE_FLOAT) - block2 = new DataBlkFloat(); - if (block1 == null || block1.DataType != DataBlk.TYPE_FLOAT) - block1 = new DataBlkFloat(); - block0.w = block2.w = block1.w = blk.w; - block0.h = block2.h = block1.h = blk.h; - block0.ulx = block2.ulx = block1.ulx = blk.ulx; - block0.uly = block2.uly = block1.uly = blk.uly; - - float[] data0, data1, data2; // input data arrays - - // Fill in buffer blocks (to be read only) - // Returned blocks may have different size and position - block0 = (DataBlkFloat) src.getInternCompData(block0, 0); - data0 = (float[]) block0.Data; - block2 = (DataBlkFloat) src.getInternCompData(block2, 1); - data2 = (float[]) block2.Data; - block1 = (DataBlkFloat) src.getInternCompData(block1, 2); - data1 = (float[]) block1.Data; - - // Set the progressiveness of the output data - blk.progressive = block0.progressive || block1.progressive || block2.progressive; - blk.offset = 0; - blk.scanw = w; - - // set attributes of the DataBlk used for buffering - dbi.progressive = blk.progressive; - dbi.ulx = blk.ulx; - dbi.uly = blk.uly; - dbi.w = blk.w; - dbi.h = blk.h; - - //Perform conversion - - // Initialize general indexes - k = w * h - 1; - k0 = block0.offset + (h - 1) * block0.scanw + w - 1; - k2 = block2.offset + (h - 1) * block2.scanw + w - 1; - k1 = block1.offset + (h - 1) * block1.scanw + w - 1; - - for (i = h - 1; i >= 0; i--) - { - for (mink = k - w; k > mink; k--, k0--, k2--, k1--) - { - //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[0][k] = (int) (data0[k0] + 1.402f * data1[k1] + 0.5f); - //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[1][k] = (int) (data0[k0] - 0.34413f * data2[k2] - 0.71414f * data1[k1] + 0.5f); - //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[2][k] = (int) (data0[k0] + 1.772f * data2[k2] + 0.5f); - } - // Jump to beggining of previous line in input - k0 -= (block0.scanw - w); - k2 -= (block2.scanw - w); - k1 -= (block1.scanw - w); - } - outdata[c] = null; - } - else if ((c >= 0) && (c <= 3)) - { - //Asking for the 2nd or 3rd block component - blk.Data = outdata[c]; - blk.progressive = dbi.progressive; - blk.offset = (blk.uly - dbi.uly) * dbi.w + blk.ulx - dbi.ulx; - blk.scanw = dbi.w; - outdata[c] = null; - } - else - { - // Requesting a non valid component index - throw new System.ArgumentException(); - } - return blk; - } - - /// Changes the current tile, given the new indexes. An - /// IllegalArgumentException is thrown if the indexes do not - /// correspond to a valid tile. - /// - ///

This default implementation changes the tile in the source - /// and re-initializes properly component transformation variables.. - /// - ///

- /// The horizontal index of the tile. - /// - /// - /// The vertical index of the new tile. - /// - /// - /// - public override void setTile(int x, int y) - { - src.setTile(x, y); - tIdx = TileIdx; // index of the current tile - - // initializations - if (((System.Int32) cts.getTileDef(tIdx)) == NONE) - transfType = NONE; - else - { - int nc = src.NumComps > 3?3:src.NumComps; - int rev = 0; - for (int c = 0; c < nc; c++) - { - rev += (wfs.isReversible(tIdx, c)?1:0); - } - if (rev == 3) - { - // All WT are reversible - transfType = INV_RCT; - } - else if (rev == 0) - { - // All WT irreversible - transfType = INV_ICT; - } - else - { - // Error - throw new System.ArgumentException("Wavelet transformation and " + "component transformation" + " not coherent in tile" + tIdx); - } - } - } - - /// Advances to the next tile, in standard scan-line order (by rows - /// then columns). An NoNextElementException is thrown if the - /// current tile is the last one (i.e. there is no next tile). - /// - ///

This default implementation just advances to the next tile - /// in the source and re-initializes properly component - /// transformation variables. - /// - /// - ///

- public override void nextTile() - { - src.nextTile(); - tIdx = TileIdx; // index of the current tile - - // initializations - if (((System.Int32) cts.getTileDef(tIdx)) == NONE) - transfType = NONE; - else - { - int nc = src.NumComps > 3?3:src.NumComps; - int rev = 0; - for (int c = 0; c < nc; c++) - { - rev += (wfs.isReversible(tIdx, c)?1:0); - } - if (rev == 3) - { - // All WT are reversible - transfType = INV_RCT; - } - else if (rev == 0) - { - // All WT irreversible - transfType = INV_ICT; - } - else - { - // Error - throw new System.ArgumentException("Wavelet transformation and " + "component transformation" + " not coherent in tile" + tIdx); - } - } - } - } -} \ No newline at end of file + int w = blk.w; //width of output block + int h = blk.h; //height of ouput block + + int[] out_data; // array of output data + + //Reference to output block data array + out_data = (int[])blk.Data; + + //Create data array of blk if necessary + if (out_data == null) + { + out_data = new int[h * w]; + blk.Data = out_data; + } + + // Variables + DataBlkFloat indb = new DataBlkFloat(blk.ulx, blk.uly, w, h); + float[] indata; // input data array + + // Get the input data + // (returned block may be larger than requested one) + src.getInternCompData(indb, c); + indata = (float[])indb.Data; + + // Copy the data converting from int to int + 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'" + out_data[k] = (int)(indata[k0]); + } + // Jump to beggining of previous line in input + k0 -= (indb.scanw - w); + } + + // Set the progressivity and offset + blk.progressive = indb.progressive; + blk.offset = 0; + blk.scanw = w; + } + // If asking a component for the first time for this block, + // do transform for the 3 components + else if ((outdata[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, k0, k1, k2, mink, i; + int w = blk.w; //width of output block + int h = blk.h; //height of ouput block + + //Reference to output block data array + outdata[c] = (int[])blk.Data; + + //Create data array of blk if necessary + if (outdata[c] == null || outdata[c].Length != w * h) + { + outdata[c] = new int[h * w]; + blk.Data = outdata[c]; + } + + outdata[(c + 1) % 3] = new int[outdata[c].Length]; + outdata[(c + 2) % 3] = new int[outdata[c].Length]; + + if (block0 == null || block0.DataType != DataBlk.TYPE_FLOAT) block0 = new DataBlkFloat(); + if (block2 == null || block2.DataType != DataBlk.TYPE_FLOAT) block2 = new DataBlkFloat(); + if (block1 == null || block1.DataType != DataBlk.TYPE_FLOAT) block1 = new DataBlkFloat(); + block0.w = block2.w = block1.w = blk.w; + block0.h = block2.h = block1.h = blk.h; + block0.ulx = block2.ulx = block1.ulx = blk.ulx; + block0.uly = block2.uly = block1.uly = blk.uly; + + float[] data0, data1, data2; // input data arrays + + // Fill in buffer blocks (to be read only) + // Returned blocks may have different size and position + block0 = (DataBlkFloat)src.getInternCompData(block0, 0); + data0 = (float[])block0.Data; + block2 = (DataBlkFloat)src.getInternCompData(block2, 1); + data2 = (float[])block2.Data; + block1 = (DataBlkFloat)src.getInternCompData(block1, 2); + data1 = (float[])block1.Data; + + // Set the progressiveness of the output data + blk.progressive = block0.progressive || block1.progressive || block2.progressive; + blk.offset = 0; + blk.scanw = w; + + // set attributes of the DataBlk used for buffering + dbi.progressive = blk.progressive; + dbi.ulx = blk.ulx; + dbi.uly = blk.uly; + dbi.w = blk.w; + dbi.h = blk.h; + + //Perform conversion + + // Initialize general indexes + k = w * h - 1; + k0 = block0.offset + (h - 1) * block0.scanw + w - 1; + k2 = block2.offset + (h - 1) * block2.scanw + w - 1; + k1 = block1.offset + (h - 1) * block1.scanw + w - 1; + + for (i = h - 1; i >= 0; i--) + { + for (mink = k - w; k > mink; k--, k0--, k2--, k1--) + { + //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[0][k] = (int)(data0[k0] + 1.402f * data1[k1] + 0.5f); + //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[1][k] = (int)(data0[k0] - 0.34413f * data2[k2] - 0.71414f * data1[k1] + 0.5f); + //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[2][k] = (int)(data0[k0] + 1.772f * data2[k2] + 0.5f); + } + // Jump to beggining of previous line in input + k0 -= (block0.scanw - w); + k2 -= (block2.scanw - w); + k1 -= (block1.scanw - w); + } + outdata[c] = null; + } + else if ((c >= 0) && (c <= 3)) + { + //Asking for the 2nd or 3rd block component + blk.Data = outdata[c]; + blk.progressive = dbi.progressive; + blk.offset = (blk.uly - dbi.uly) * dbi.w + blk.ulx - dbi.ulx; + blk.scanw = dbi.w; + outdata[c] = null; + } + else + { + // Requesting a non valid component index + throw new System.ArgumentException(); + } + return blk; + } + + /// Changes the current tile, given the new indexes. An + /// IllegalArgumentException is thrown if the indexes do not + /// correspond to a valid tile. + /// + ///

This default implementation changes the tile in the source + /// and re-initializes properly component transformation variables.. + /// + ///

+ /// The horizontal index of the tile. + /// + /// + /// The vertical index of the new tile. + /// + /// + /// + public override void setTile(int x, int y) + { + src.setTile(x, y); + tIdx = TileIdx; // index of the current tile + + // initializations + if (((System.Int32)cts.getTileDef(tIdx)) == NONE) transfType = NONE; + else + { + int nc = src.NumComps > 3 ? 3 : src.NumComps; + int rev = 0; + for (int c = 0; c < nc; c++) + { + rev += (wfs.isReversible(tIdx, c) ? 1 : 0); + } + if (rev == 3) + { + // All WT are reversible + transfType = INV_RCT; + } + else if (rev == 0) + { + // All WT irreversible + transfType = INV_ICT; + } + else + { + // Error + throw new System.ArgumentException( + "Wavelet transformation and " + "component transformation" + " not coherent in tile" + tIdx); + } + } + } + + /// Advances to the next tile, in standard scan-line order (by rows + /// then columns). An NoNextElementException is thrown if the + /// current tile is the last one (i.e. there is no next tile). + /// + ///

This default implementation just advances to the next tile + /// in the source and re-initializes properly component + /// transformation variables. + /// + /// + ///

+ public override void nextTile() + { + src.nextTile(); + tIdx = TileIdx; // index of the current tile + + // initializations + if (((System.Int32)cts.getTileDef(tIdx)) == NONE) transfType = NONE; + else + { + int nc = src.NumComps > 3 ? 3 : src.NumComps; + int rev = 0; + for (int c = 0; c < nc; c++) + { + rev += (wfs.isReversible(tIdx, c) ? 1 : 0); + } + if (rev == 3) + { + // All WT are reversible + transfType = INV_RCT; + } + else if (rev == 0) + { + // All WT irreversible + transfType = INV_ICT; + } + else + { + // Error + throw new System.ArgumentException( + "Wavelet transformation and " + "component transformation" + " not coherent in tile" + tIdx); + } + } + } + } +} diff --git a/CSJ2K/j2k/image/output/ImgWriterPGM.cs b/CSJ2K/j2k/image/output/ImgWriterPGM.cs index 121a1e62..043705e5 100644 --- a/CSJ2K/j2k/image/output/ImgWriterPGM.cs +++ b/CSJ2K/j2k/image/output/ImgWriterPGM.cs @@ -42,6 +42,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; using CSJ2K.j2k.image; using CSJ2K.j2k.util; namespace CSJ2K.j2k.image.output @@ -73,7 +74,7 @@ namespace CSJ2K.j2k.image.output /// Where to write the data //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private System.IO.FileStream out_Renamed; + private System.IO.Stream out_Renamed; /// The index of the component from where to get the data private int c; @@ -111,7 +112,7 @@ namespace CSJ2K.j2k.image.output /// The index of the component from where to get the data. /// /// - public ImgWriterPGM(System.IO.FileInfo out_Renamed, BlkImgDataSrc imgSrc, int c) + public ImgWriterPGM(IFileInfo out_Renamed, BlkImgDataSrc imgSrc, int c) { // Check that imgSrc is of the correct type // Check that the component index is valid @@ -127,25 +128,7 @@ namespace CSJ2K.j2k.image.output } // Initialize - bool tmpBool; - if (System.IO.File.Exists(out_Renamed.FullName)) - tmpBool = true; - else - tmpBool = System.IO.Directory.Exists(out_Renamed.FullName); - bool tmpBool2; - if (System.IO.File.Exists(out_Renamed.FullName)) - { - System.IO.File.Delete(out_Renamed.FullName); - tmpBool2 = true; - } - else if (System.IO.Directory.Exists(out_Renamed.FullName)) - { - System.IO.Directory.Delete(out_Renamed.FullName); - tmpBool2 = true; - } - else - tmpBool2 = false; - if (tmpBool && !tmpBool2) + if (out_Renamed.Exists && !out_Renamed.Delete()) { throw new System.IO.IOException("Could not reset file"); } @@ -177,7 +160,7 @@ namespace CSJ2K.j2k.image.output /// The index of the component from where to get the data. /// /// - public ImgWriterPGM(System.String fname, BlkImgDataSrc imgSrc, int c):this(new System.IO.FileInfo(fname), imgSrc, c) + public ImgWriterPGM(System.String fname, BlkImgDataSrc imgSrc, int c):this(FileInfoFactory.New(fname), imgSrc, c) { } @@ -204,7 +187,7 @@ namespace CSJ2K.j2k.image.output out_Renamed.WriteByte((System.Byte) 0); } } - out_Renamed.Close(); + out_Renamed.Dispose(); src = null; out_Renamed = null; db = null; @@ -375,7 +358,7 @@ namespace CSJ2K.j2k.image.output offset = 3; // Write width in ASCII val = System.Convert.ToString(w); - byteVals = System.Text.ASCIIEncoding.ASCII.GetBytes(val); + byteVals = System.Text.Encoding.UTF8.GetBytes(val); for (i = 0; i < byteVals.Length; i++) { out_Renamed.WriteByte((byte) byteVals[i]); @@ -385,7 +368,7 @@ namespace CSJ2K.j2k.image.output offset++; // Write height in ASCII val = System.Convert.ToString(h); - byteVals = System.Text.ASCIIEncoding.ASCII.GetBytes(val); + byteVals = System.Text.Encoding.UTF8.GetBytes(val); for (i = 0; i < byteVals.Length; i++) { out_Renamed.WriteByte((byte) byteVals[i]); diff --git a/CSJ2K/j2k/image/output/ImgWriterPGX.cs b/CSJ2K/j2k/image/output/ImgWriterPGX.cs index ceb4ad18..01563ee5 100644 --- a/CSJ2K/j2k/image/output/ImgWriterPGX.cs +++ b/CSJ2K/j2k/image/output/ImgWriterPGX.cs @@ -42,6 +42,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; using CSJ2K.j2k.image; using CSJ2K.j2k.util; namespace CSJ2K.j2k.image.output @@ -115,7 +116,7 @@ namespace CSJ2K.j2k.image.output /// Where to write the data //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private System.IO.FileStream out_Renamed; + private System.IO.Stream out_Renamed; /// The offset of the raw pixel data in the PGX file private int offset; @@ -170,29 +171,11 @@ namespace CSJ2K.j2k.image.output /// /// /// - public ImgWriterPGX(System.IO.FileInfo out_Renamed, BlkImgDataSrc imgSrc, int c, bool isSigned) + public ImgWriterPGX(IFileInfo out_Renamed, BlkImgDataSrc imgSrc, int c, bool isSigned) { //Initialize this.c = c; - bool tmpBool; - if (System.IO.File.Exists(out_Renamed.FullName)) - tmpBool = true; - else - tmpBool = System.IO.Directory.Exists(out_Renamed.FullName); - bool tmpBool2; - if (System.IO.File.Exists(out_Renamed.FullName)) - { - System.IO.File.Delete(out_Renamed.FullName); - tmpBool2 = true; - } - else if (System.IO.Directory.Exists(out_Renamed.FullName)) - { - System.IO.Directory.Delete(out_Renamed.FullName); - tmpBool2 = true; - } - else - tmpBool2 = false; - if (tmpBool && !tmpBool2) + if (out_Renamed.Exists && !out_Renamed.Delete()) { throw new System.IO.IOException("Could not reset file"); } @@ -225,7 +208,7 @@ namespace CSJ2K.j2k.image.output // Writes PGX header System.String tmpString = "PG " + "ML " + ((this.isSigned)?"- ":"+ ") + bitDepth + " " + w + " " + h + "\n"; // component height - byte[] tmpByte = System.Text.ASCIIEncoding.ASCII.GetBytes(tmpString); + byte[] tmpByte = System.Text.Encoding.UTF8.GetBytes(tmpString); for (int i = 0; i < tmpByte.Length; i++) { this.out_Renamed.WriteByte((byte) tmpByte[i]); @@ -267,7 +250,7 @@ namespace CSJ2K.j2k.image.output /// /// /// - public ImgWriterPGX(System.String fname, BlkImgDataSrc imgSrc, int c, bool isSigned):this(new System.IO.FileInfo(fname), imgSrc, c, isSigned) + public ImgWriterPGX(System.String fname, BlkImgDataSrc imgSrc, int c, bool isSigned):this(FileInfoFactory.New(fname), imgSrc, c, isSigned) { } @@ -294,7 +277,7 @@ namespace CSJ2K.j2k.image.output out_Renamed.WriteByte((System.Byte) 0); } } - out_Renamed.Close(); + out_Renamed.Dispose(); src = null; out_Renamed = null; db = null; diff --git a/CSJ2K/j2k/image/output/ImgWriterPPM.cs b/CSJ2K/j2k/image/output/ImgWriterPPM.cs index f4c24bc2..cb27655c 100644 --- a/CSJ2K/j2k/image/output/ImgWriterPPM.cs +++ b/CSJ2K/j2k/image/output/ImgWriterPPM.cs @@ -42,6 +42,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; using CSJ2K.j2k.image; using CSJ2K.j2k.util; using CSJ2K.j2k.io; @@ -81,7 +82,7 @@ namespace CSJ2K.j2k.image.output /// Where to write the data //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private System.IO.FileStream out_Renamed; + private System.IO.Stream out_Renamed; /// The array of indexes of the components from where to get the data private int[] cps = new int[3]; @@ -132,7 +133,7 @@ namespace CSJ2K.j2k.image.output /// /// /// - public ImgWriterPPM(System.IO.FileInfo out_Renamed, BlkImgDataSrc imgSrc, int n1, int n2, int n3) + public ImgWriterPPM(IFileInfo out_Renamed, BlkImgDataSrc imgSrc, int n1, int n2, int n3) { // Check that imgSrc is of the correct type // Check that the component index is valid @@ -152,25 +153,7 @@ namespace CSJ2K.j2k.image.output h = imgSrc.ImgHeight; // Continue initialization - bool tmpBool; - if (System.IO.File.Exists(out_Renamed.FullName)) - tmpBool = true; - else - tmpBool = System.IO.Directory.Exists(out_Renamed.FullName); - bool tmpBool2; - if (System.IO.File.Exists(out_Renamed.FullName)) - { - System.IO.File.Delete(out_Renamed.FullName); - tmpBool2 = true; - } - else if (System.IO.Directory.Exists(out_Renamed.FullName)) - { - System.IO.Directory.Delete(out_Renamed.FullName); - tmpBool2 = true; - } - else - tmpBool2 = false; - if (tmpBool && !tmpBool2) + if (out_Renamed.Exists && !out_Renamed.Delete()) { throw new System.IO.IOException("Could not reset file"); } @@ -218,7 +201,7 @@ namespace CSJ2K.j2k.image.output /// /// /// - public ImgWriterPPM(System.String fname, BlkImgDataSrc imgSrc, int n1, int n2, int n3):this(new System.IO.FileInfo(fname), imgSrc, n1, n2, n3) + public ImgWriterPPM(System.String fname, BlkImgDataSrc imgSrc, int n1, int n2, int n3):this(FileInfoFactory.New(fname), imgSrc, n1, n2, n3) { } @@ -245,7 +228,7 @@ namespace CSJ2K.j2k.image.output out_Renamed.WriteByte((System.Byte) 0); } } - out_Renamed.Close(); + out_Renamed.Dispose(); src = null; out_Renamed = null; db = null; @@ -424,7 +407,7 @@ namespace CSJ2K.j2k.image.output offset = 3; // Write width in ASCII val = System.Convert.ToString(w); - byteVals = System.Text.ASCIIEncoding.ASCII.GetBytes(val); + byteVals = System.Text.Encoding.UTF8.GetBytes(val); for (i = 0; i < byteVals.Length; i++) { out_Renamed.WriteByte((byte) byteVals[i]); @@ -434,7 +417,7 @@ namespace CSJ2K.j2k.image.output offset++; // Write height in ASCII val = System.Convert.ToString(h); - byteVals = System.Text.ASCIIEncoding.ASCII.GetBytes(val); + byteVals = System.Text.Encoding.UTF8.GetBytes(val); for (i = 0; i < byteVals.Length; i++) { out_Renamed.WriteByte((byte) byteVals[i]); diff --git a/CSJ2K/j2k/io/BEBufferedRandomAccessFile.cs b/CSJ2K/j2k/io/BEBufferedRandomAccessFile.cs index f55500e7..37a152d6 100644 --- a/CSJ2K/j2k/io/BEBufferedRandomAccessFile.cs +++ b/CSJ2K/j2k/io/BEBufferedRandomAccessFile.cs @@ -41,9 +41,12 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using CSJ2K.Util; + namespace CSJ2K.j2k.io { - + using System.IO; + /// This class defines a Buffered Random Access File, where all I/O is /// considered to be big-endian. It extends the /// BufferedRandomAccessFile class. @@ -60,51 +63,33 @@ namespace CSJ2K.j2k.io /// public class BEBufferedRandomAccessFile:BufferedRandomAccessFile, RandomAccessIO, EndianType { - /// Constructor. Always needs a size for the buffer. /// /// - /// The file associated with the buffer - /// - /// - /// "r" for read, "rw" or "rw+" for read and write mode ("rw+" - /// opens the file for update whereas "rw" removes it - /// before. So the 2 modes are different only if the file - /// already exists). - /// - /// - /// The number of bytes to buffer - /// - /// + /// The stream associated with the buffer + /// Indicates whether file is read-only or not. + /// The number of bytes to buffer /// If an I/O error ocurred. /// /// - public BEBufferedRandomAccessFile(System.IO.FileInfo file, System.String mode, int bufferSize):base(file, mode, bufferSize) + public BEBufferedRandomAccessFile(Stream stream, bool isReadOnly, int bufferSize) + : base(stream, isReadOnly, bufferSize) { byte_Ordering = CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN; } - + /// Constructor. Uses the default value for the byte-buffer size (512 /// bytes). - /// /// - /// The file associated with the buffer - /// - /// - /// "r" for read, "rw" or "rw+" for read and write mode ("rw+" - /// opens the file for update whereas "rw" removes it - /// before. So the 2 modes are different only if the file - /// already exists). - /// - /// - /// If an I/O error ocurred. - /// - /// - public BEBufferedRandomAccessFile(System.IO.FileInfo file, System.String mode):base(file, mode) + /// The stream associated with the buffer + /// Indicates whether file is read-only or not. + /// If an I/O error ocurred. + public BEBufferedRandomAccessFile(Stream stream, bool isReadOnly) + : base(stream, isReadOnly) { byte_Ordering = CSJ2K.j2k.io.EndianType_Fields.BIG_ENDIAN; } - + /// Constructor. Always needs a size for the buffer. /// /// @@ -226,35 +211,35 @@ namespace CSJ2K.j2k.io /// public override void writeFloat(float v) { - // CONVERSION PROBLEM? OPTIMIZE!!! - //byte[] floatbytes = BitConverter.GetBytes(v); - //for (int i = floatbytes.Length-1; i >= 0 ; i--) write(floatbytes[i]); + // CONVERSION PROBLEM? OPTIMIZE!!! + //byte[] floatbytes = BitConverter.GetBytes(v); + //for (int i = floatbytes.Length-1; i >= 0 ; i--) write(floatbytes[i]); //UPGRADE_ISSUE: Method 'java.lang.Float.floatToIntBits' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangFloatfloatToIntBits_float'" - //int intV = Float.floatToIntBits(v); - int intV = BitConverter.ToInt32(BitConverter.GetBytes(v), 0); + //int intV = Float.floatToIntBits(v); + int intV = BitConverter.ToInt32(BitConverter.GetBytes(v), 0); write(SupportClass.URShift(intV, 24)); write(SupportClass.URShift(intV, 16)); write(SupportClass.URShift(intV, 8)); write(intV); } - /// Writes the IEEE double value v (i.e., 64 bits) to the - /// output. Prior to writing, the output should be realigned at the byte - /// level. - /// - /// - /// The value to write to the output - /// - /// - /// If an I/O error ocurred. - /// - /// - public override void writeDouble(double v) + /// Writes the IEEE double value v (i.e., 64 bits) to the + /// output. Prior to writing, the output should be realigned at the byte + /// level. + /// + /// + /// The value to write to the output + /// + /// + /// If an I/O error ocurred. + /// + /// + public override void writeDouble(double v) { - //byte[] doublebytes = BitConverter.GetBytes(v); - //for (int i = doublebytes.Length-1; i >= 0 ; i--) write(doublebytes[i]); - + //byte[] doublebytes = BitConverter.GetBytes(v); + //for (int i = doublebytes.Length-1; i >= 0 ; i--) write(doublebytes[i]); + //UPGRADE_ISSUE: Method 'java.lang.Double.doubleToLongBits' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangDoubledoubleToLongBits_double'" //long longV = Double.doubleToLongBits(v); long longV = BitConverter.ToInt64(BitConverter.GetBytes(v), 0); @@ -266,24 +251,24 @@ namespace CSJ2K.j2k.io write((int) (SupportClass.URShift(longV, 16))); write((int) (SupportClass.URShift(longV, 8))); write((int) (longV)); - + } - /// Reads a signed short (i.e. 16 bit) from the input. Prior to reading, - /// the input should be realigned at the byte level. - /// - /// - /// The next byte-aligned signed short (16 bit) from the input. - /// - /// - /// If the end-of file was reached before - /// getting all the necessary data. - /// - /// - /// If an I/O error ocurred. - /// - /// - public override short readShort() + /// Reads a signed short (i.e. 16 bit) from the input. Prior to reading, + /// the input should be realigned at the byte level. + /// + /// + /// The next byte-aligned signed short (16 bit) from the input. + /// + /// + /// If the end-of file was reached before + /// getting all the necessary data. + /// + /// + /// If an I/O error ocurred. + /// + /// + public override short readShort() { return (short) ((read() << 8) | (read())); } @@ -366,9 +351,9 @@ namespace CSJ2K.j2k.io /// public override long readLong() { - //byte[] longbytes = new byte[8]; - //for (int i = longbytes.Length-1; i >= 0; i--) longbytes[i] = read(); - //return BitConverter.ToInt64(longbytes, 0); + //byte[] longbytes = new byte[8]; + //for (int i = longbytes.Length-1; i >= 0; i--) longbytes[i] = read(); + //return BitConverter.ToInt64(longbytes, 0); return ((long)(((ulong) read() << 56) | ((ulong) read() << 48) | ((ulong) read() << 40) | ((ulong) read() << 32) | ((ulong) read() << 24) | ((ulong) read() << 16) | ((ulong) read() << 8) | ((ulong) read()))); } @@ -389,14 +374,14 @@ namespace CSJ2K.j2k.io /// public override float readFloat() { - // CONVERSION PROBLEM? OPTIMIZE!!! - //byte[] floatbytes = new byte[4]; - //for (int i = floatbytes.Length-1; i >= 0 ; i--) floatbytes[i] = (byte)read(); - //return BitConverter.ToSingle(floatbytes, 0); + // CONVERSION PROBLEM? OPTIMIZE!!! + //byte[] floatbytes = new byte[4]; + //for (int i = floatbytes.Length-1; i >= 0 ; i--) floatbytes[i] = (byte)read(); + //return BitConverter.ToSingle(floatbytes, 0); //UPGRADE_ISSUE: Method 'java.lang.Float.intBitsToFloat' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangFloatintBitsToFloat_int'" - //return Float.intBitsToFloat((read() << 24) | (read() << 16) | (read() << 8) | (read())); - return BitConverter.ToSingle(BitConverter.GetBytes((read() << 24) | (read() << 16) | (read() << 8) | (read())), 0); + //return Float.intBitsToFloat((read() << 24) | (read() << 16) | (read() << 8) | (read())); + return BitConverter.ToSingle(BitConverter.GetBytes((read() << 24) | (read() << 16) | (read() << 8) | (read())), 0); } @@ -417,15 +402,15 @@ namespace CSJ2K.j2k.io /// public override double readDouble() { - // CONVERSION PROBLEM? OPTIMIZE!!! - //byte[] doublebytes = new byte[8]; - //for (int i = doublebytes.Length-1; i >=0 ; i--) doublebytes[i] = (byte)read(); - //return BitConverter.ToDouble(doublebytes, 0); + // CONVERSION PROBLEM? OPTIMIZE!!! + //byte[] doublebytes = new byte[8]; + //for (int i = doublebytes.Length-1; i >=0 ; i--) doublebytes[i] = (byte)read(); + //return BitConverter.ToDouble(doublebytes, 0); //UPGRADE_ISSUE: Method 'java.lang.Double.longBitsToDouble' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javalangDoublelongBitsToDouble_long'" //return Double.longBitsToDouble(((long) read() << 56) | ((long) read() << 48) | ((long) read() << 40) | ((long) read() << 32) | ((long) read() << 24) | ((long) read() << 16) | ((long) read() << 8) | ((long) read())); - - return BitConverter.ToDouble(BitConverter.GetBytes(((long) read() << 56) | ((long) read() << 48) | ((long) read() << 40) | ((long) read() << 32) | ((long) read() << 24) | ((long) read() << 16) | ((long) read() << 8) | ((long) read())), 0); + + return BitConverter.ToDouble(BitConverter.GetBytes(((long) read() << 56) | ((long) read() << 48) | ((long) read() << 40) | ((long) read() << 32) | ((long) read() << 24) | ((long) read() << 16) | ((long) read() << 8) | ((long) read())), 0); } diff --git a/CSJ2K/j2k/io/BufferedRandomAccessFile.cs b/CSJ2K/j2k/io/BufferedRandomAccessFile.cs index b97d7150..ee337297 100644 --- a/CSJ2K/j2k/io/BufferedRandomAccessFile.cs +++ b/CSJ2K/j2k/io/BufferedRandomAccessFile.cs @@ -40,10 +40,13 @@ * * Copyright (c) 1999/2000 JJ2000 Partners. * */ -using System; namespace CSJ2K.j2k.io { - + using System; + using System.IO; + + using CSJ2K.Util; + /// This class defines a Buffered Random Access File. It implements the /// BinaryDataInput and BinaryDataOutput interfaces so that /// binary data input/output can be performed. This class is abstract since no @@ -116,7 +119,7 @@ namespace CSJ2K.j2k.io /// /// //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" - private System.IO.FileStream theFile; + private System.IO.Stream theFile; /// Buffer of bytes containing the part of the file that is currently being /// accessed @@ -153,7 +156,45 @@ namespace CSJ2K.j2k.io /* The endianess of the class */ protected internal int byte_Ordering; - + + /// Constructor. Always needs a size for the buffer. + /// + /// + /// The stream associated with the buffer + /// + /// + /// Indicates whether file is read-only or not. + /// The number of bytes to buffer + /// + /// + /// If an I/O error ocurred. + /// + /// + protected internal BufferedRandomAccessFile(Stream stream, bool isReadOnly, int bufferSize) + { + fileName = String.Empty; + theFile = stream; + this.isReadOnly = isReadOnly; + byteBuffer = new byte[bufferSize]; + readNewBuffer(0); + } + + /// Constructor. Uses the default value for the byte-buffer + /// size (512 bytes). + /// + /// + /// The stream associated with the buffer + /// + /// + /// Indicates whether file is read-only or not. + /// If an I/O error ocurred. + /// + /// + protected internal BufferedRandomAccessFile(Stream stream, bool isReadOnly) + : this(stream, isReadOnly, 512) + { + } + /// Constructor. Always needs a size for the buffer. /// /// @@ -169,10 +210,10 @@ namespace CSJ2K.j2k.io /// The number of bytes to buffer /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// - protected internal BufferedRandomAccessFile(System.IO.FileInfo file, System.String mode, int bufferSize) + protected internal BufferedRandomAccessFile(IFileInfo file, System.String mode, int bufferSize) { fileName = file.Name; @@ -182,29 +223,9 @@ namespace CSJ2K.j2k.io isReadOnly = false; if (mode.Equals("rw")) { - // mode read / (over)write - bool tmpBool; - if (System.IO.File.Exists(file.FullName)) - tmpBool = true; - else - tmpBool = System.IO.Directory.Exists(file.FullName); - if (tmpBool) - // Output file already exists + if (file.Exists && !file.Delete()) { - bool tmpBool2; - if (System.IO.File.Exists(file.FullName)) - { - System.IO.File.Delete(file.FullName); - tmpBool2 = true; - } - else if (System.IO.Directory.Exists(file.FullName)) - { - System.IO.Directory.Delete(file.FullName); - tmpBool2 = true; - } - else - tmpBool2 = false; - bool generatedAux = tmpBool2; + throw new System.IO.IOException("Could not delete existing file"); } } mode = "rw"; @@ -227,10 +248,10 @@ namespace CSJ2K.j2k.io /// file already exists). /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// - protected internal BufferedRandomAccessFile(System.IO.FileInfo file, System.String mode):this(file, mode, 512) + protected internal BufferedRandomAccessFile(IFileInfo file, System.String mode):this(file, mode, 512) { } @@ -249,10 +270,10 @@ namespace CSJ2K.j2k.io /// The number of bytes to buffer /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// - protected internal BufferedRandomAccessFile(System.String name, System.String mode, int bufferSize):this(new System.IO.FileInfo(name), mode, bufferSize) + protected internal BufferedRandomAccessFile(System.String name, System.String mode, int bufferSize):this(FileInfoFactory.New(name), mode, bufferSize) { } @@ -269,7 +290,7 @@ namespace CSJ2K.j2k.io /// file already exists). /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// protected internal BufferedRandomAccessFile(System.String name, System.String mode):this(name, mode, 512) @@ -284,7 +305,7 @@ namespace CSJ2K.j2k.io /// The offset where to move to. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// protected internal void readNewBuffer(int off) @@ -328,7 +349,7 @@ namespace CSJ2K.j2k.io /// Closes the buffered random access file /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public virtual void close() @@ -338,7 +359,6 @@ namespace CSJ2K.j2k.io */ flush(); byteBuffer = null; // Release the byte-buffer reference - theFile.Close(); } /// Returns the current length of the stream, in bytes, taking into @@ -348,7 +368,7 @@ namespace CSJ2K.j2k.io /// The length of the stream, in bytes. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public virtual int length() @@ -381,7 +401,7 @@ namespace CSJ2K.j2k.io /// If in read-only and seeking beyond EOF. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public virtual void seek(int off) @@ -410,14 +430,14 @@ namespace CSJ2K.j2k.io /// The byte read. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// /// If the end of file was reached /// /// - public byte readByte() { return read(); } - public byte readUnsignedByte() { return read(); } + public byte readByte() { return read(); } + public byte readUnsignedByte() { return read(); } public byte read() { if (position < maxByte) @@ -501,7 +521,7 @@ namespace CSJ2K.j2k.io /// written. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public void write(int b) @@ -535,7 +555,7 @@ namespace CSJ2K.j2k.io /// The byte to write. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public void write(byte b) @@ -575,7 +595,7 @@ namespace CSJ2K.j2k.io /// The number of bytes from b to write /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public void write(byte[] b, int offset, int length) @@ -604,7 +624,7 @@ namespace CSJ2K.j2k.io /// The value to write to the output /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public void writeByte(int v) @@ -617,7 +637,7 @@ namespace CSJ2K.j2k.io /// at the byte level. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public void flush() @@ -700,7 +720,7 @@ namespace CSJ2K.j2k.io /// all the bytes could be skipped. /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public virtual int skipBytes(int n) diff --git a/CSJ2K/j2k/quantization/GuardBitsSpec.cs b/CSJ2K/j2k/quantization/GuardBitsSpec.cs index b630e5ca..3c7a40b5 100644 --- a/CSJ2K/j2k/quantization/GuardBitsSpec.cs +++ b/CSJ2K/j2k/quantization/GuardBitsSpec.cs @@ -138,7 +138,7 @@ namespace CSJ2K.j2k.quantization { value_Renamed = System.Int32.Parse(word); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Bad parameter for " + "-Qguard_bits option" + " : " + word); } diff --git a/CSJ2K/j2k/quantization/QuantStepSizeSpec.cs b/CSJ2K/j2k/quantization/QuantStepSizeSpec.cs index 7856325a..a725f47d 100644 --- a/CSJ2K/j2k/quantization/QuantStepSizeSpec.cs +++ b/CSJ2K/j2k/quantization/QuantStepSizeSpec.cs @@ -138,7 +138,7 @@ namespace CSJ2K.j2k.quantization //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'" value_Renamed = System.Single.Parse(word); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Bad parameter for " + "-Qstep option : " + word); } diff --git a/CSJ2K/j2k/roi/encoder/ROIScaler.cs b/CSJ2K/j2k/roi/encoder/ROIScaler.cs index 44fd19b1..93ad6fff 100644 --- a/CSJ2K/j2k/roi/encoder/ROIScaler.cs +++ b/CSJ2K/j2k/roi/encoder/ROIScaler.cs @@ -42,6 +42,7 @@ * Copyright (c) 1999/2000 JJ2000 Partners. * */ using System; +using System.Collections.Generic; using CSJ2K.j2k.quantization.quantizer; using CSJ2K.j2k.codestream.writer; using CSJ2K.j2k.wavelet.analysis; @@ -284,7 +285,7 @@ namespace CSJ2K.j2k.roi.encoder /// public static ROIScaler createInstance(Quantizer src, ParameterList pl, EncoderSpecs encSpec) { - System.Collections.ArrayList roiVector = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + System.Collections.Generic.List roiVector = new List(10); ROIMaskGenerator maskGen = null; // Check parameters @@ -364,7 +365,7 @@ namespace CSJ2K.j2k.roi.encoder /// The ROIs specified in roiopt /// /// - protected internal static System.Collections.ArrayList parseROIs(System.String roiopt, int nc, System.Collections.ArrayList roiVector) + protected internal static System.Collections.Generic.List parseROIs(System.String roiopt, int nc, System.Collections.Generic.List roiVector) { //ROI[] ROIs; ROI roi; @@ -402,11 +403,11 @@ namespace CSJ2K.j2k.roi.encoder word = stok.NextToken(); h = (System.Int32.Parse(word)); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Bad parameter for " + "'-Rroi R' option : " + word); } - catch (System.ArgumentOutOfRangeException) + catch (System.ArgumentOutOfRangeException f) { throw new System.ArgumentException("Wrong number of " + "parameters for " + "h'-Rroi R' option."); } @@ -444,11 +445,11 @@ namespace CSJ2K.j2k.roi.encoder word = stok.NextToken(); rad = (System.Int32.Parse(word)); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Bad parameter for " + "'-Rroi C' option : " + word); } - catch (System.ArgumentOutOfRangeException) + catch (System.ArgumentOutOfRangeException f) { throw new System.ArgumentException("Wrong number of " + "parameters for " + "'-Rroi C' option."); } @@ -484,7 +485,7 @@ namespace CSJ2K.j2k.roi.encoder { filename = stok.NextToken(); } - catch (System.ArgumentOutOfRangeException) + catch (System.ArgumentOutOfRangeException e) { throw new System.ArgumentException("Wrong number of " + "parameters for " + "'-Rroi A' option."); } @@ -492,9 +493,9 @@ namespace CSJ2K.j2k.roi.encoder { maskPGM = new ImgReaderPGM(filename); } - catch (System.IO.IOException) + catch (System.IO.IOException e) { - throw new System.ApplicationException("Cannot read PGM file with ROI"); + throw new System.InvalidOperationException("Cannot read PGM file with ROI"); } // If the ROI is component-specific, check which comps. @@ -519,7 +520,7 @@ namespace CSJ2K.j2k.roi.encoder break; default: - throw new System.ApplicationException("Bad parameters for ROI nr " + roiVector.Count); + throw new System.InvalidOperationException("Bad parameters for ROI nr " + roiVector.Count); } } diff --git a/CSJ2K/j2k/util/CodestreamManipulator.cs b/CSJ2K/j2k/util/CodestreamManipulator.cs index 72459073..1b351ee2 100644 --- a/CSJ2K/j2k/util/CodestreamManipulator.cs +++ b/CSJ2K/j2k/util/CodestreamManipulator.cs @@ -40,12 +40,13 @@ * * Copyright (c) 1999/2000 JJ2000 Partners. * */ -using System; -using CSJ2K.j2k.codestream; -using CSJ2K.j2k.io; namespace CSJ2K.j2k.util { - + using System.Collections.Generic; + using System.IO; + + using CSJ2K.j2k.io; + /// This class takes a legal JPEG 2000 codestream and performs some /// manipulation on it. Currently the manipulations supported are: Tile-parts /// @@ -60,35 +61,35 @@ namespace CSJ2K.j2k.util /// Flag indicating whether packed packet headers in main header is used /// /// - private bool ppmUsed; + private readonly bool ppmUsed; /// Flag indicating whether packed packet headers in tile headers is used /// /// - private bool pptUsed; + private readonly bool pptUsed; /// Flag indicating whether SOP marker was only intended for parsing in /// This class and should be removed /// - private bool tempSop; + private readonly bool tempSop; /// Flag indicating whether EPH marker was only intended for parsing in /// This class and should be removed /// - private bool tempEph; + private readonly bool tempEph; /// The number of tiles in the image - private int nt; + private readonly int nt; /// The number of packets per tile-part private int pptp; /// The name of the outfile - private System.String outname; - + private readonly Stream stream; + /// The length of a SOT plus a SOD marker - private static int TP_HEAD_LEN = 14; - + private const int TP_HEAD_LEN = 14; + /// The maximum number of a tile part index (TPsot) //private static int MAX_TPSOT = 16; @@ -123,7 +124,7 @@ namespace CSJ2K.j2k.util /// Instantiates a codestream manipulator.. /// /// - /// The name of the original outfile + /// The output stream /// /// /// The number of tiles in the image @@ -145,10 +146,10 @@ namespace CSJ2K.j2k.util /// Flag indicating whether EPH merker should be removed /// /// - public CodestreamManipulator(System.String outname, int nt, int pptp, bool ppm, bool ppt, bool tempSop, bool tempEph) + public CodestreamManipulator(Stream stream, int nt, int pptp, bool ppm, bool ppt, bool tempSop, bool tempEph) { InitBlock(); - this.outname = outname; + this.stream = stream; this.nt = nt; this.pptp = pptp; this.ppmUsed = ppm; @@ -164,7 +165,7 @@ namespace CSJ2K.j2k.util /// The number of bytes that the file has increased by /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// public virtual int doCodestreamManipulation() @@ -183,7 +184,7 @@ namespace CSJ2K.j2k.util return 0; // Open file for reading and writing - fi = new BEBufferedRandomAccessFile(outname, "rw+"); + fi = new BEBufferedRandomAccessFile(stream, false); addedHeaderBytes -= fi.length(); // Parse the codestream for SOT, SOP and EPH markers @@ -192,9 +193,8 @@ namespace CSJ2K.j2k.util // Read and buffer the tile headers, packet headers and packet data readAndBuffer(fi); - // Close file and overwrite with new file - fi.close(); - fi = new BEBufferedRandomAccessFile(outname, "rw"); + // Rewind and overwrite with new contents + fi.seek(0); // Create tile-parts createTileParts(); @@ -218,7 +218,7 @@ namespace CSJ2K.j2k.util /// The file to parse the markers from /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// private void parseAndFind(BufferedRandomAccessFile fi) @@ -227,7 +227,7 @@ namespace CSJ2K.j2k.util short marker; int halfMarker; int tileEnd; - System.Collections.ArrayList markPos = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); + System.Collections.Generic.List markPos = new List(10); // Find position of first SOT marker marker = (short) fi.readUnsignedShort(); // read SOC marker @@ -333,7 +333,7 @@ namespace CSJ2K.j2k.util /// The file to read the headers and data from /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// private void readAndBuffer(BufferedRandomAccessFile fi) @@ -410,13 +410,13 @@ namespace CSJ2K.j2k.util /// packet headers and packet data /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// private void createTileParts() { int i, prem, t, length; - int pIndex; // phIndex removed + int pIndex; // phIndex removed int tppStart; int tilePart; int p, np, nomnp; @@ -569,11 +569,11 @@ namespace CSJ2K.j2k.util } //UPGRADE_ISSUE: Method 'java.io.ByteArrayOutputStream.reset' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javaioByteArrayOutputStreamreset'" //temp.reset(); - temp.SetLength(0); + temp.SetLength(0); prem -= np; } } - temp.Close(); + temp.Dispose(); } /// This method writes the new codestream to the file. @@ -582,7 +582,7 @@ namespace CSJ2K.j2k.util /// The file to write the new codestream to /// /// - /// If an I/O error ocurred. + /// If an I/O error ocurred. /// /// private void writeNewCodestream(BufferedRandomAccessFile fi) @@ -684,7 +684,7 @@ namespace CSJ2K.j2k.util // Start new PPM marker segment //UPGRADE_ISSUE: Method 'java.io.ByteArrayOutputStream.reset' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javaioByteArrayOutputStreamreset'" //ppmMarkerSegment.reset(); - ppmMarkerSegment.SetLength(0); + ppmMarkerSegment.SetLength(0); ppmMarkerSegment.WriteByte((System.Byte) SupportClass.URShift(CSJ2K.j2k.codestream.Markers.PPM, 8)); ppmMarkerSegment.WriteByte((System.Byte) (CSJ2K.j2k.codestream.Markers.PPM & 0x00FF)); ppmMarkerSegment.WriteByte((System.Byte) 0); // Temporary Lppm value @@ -721,7 +721,7 @@ namespace CSJ2K.j2k.util // Start new PPM marker segment //UPGRADE_ISSUE: Method 'java.io.ByteArrayOutputStream.reset' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javaioByteArrayOutputStreamreset'" //ppmMarkerSegment.reset(); - ppmMarkerSegment.SetLength(0); + ppmMarkerSegment.SetLength(0); ppmMarkerSegment.WriteByte((System.Byte) SupportClass.URShift(CSJ2K.j2k.codestream.Markers.PPM, 8)); ppmMarkerSegment.WriteByte((System.Byte) (CSJ2K.j2k.codestream.Markers.PPM & 0x00FF)); ppmMarkerSegment.WriteByte((System.Byte) 0); // Temp Lppm value diff --git a/CSJ2K/j2k/util/FacilityManager.cs b/CSJ2K/j2k/util/FacilityManager.cs index 661eeb5f..9dcede29 100644 --- a/CSJ2K/j2k/util/FacilityManager.cs +++ b/CSJ2K/j2k/util/FacilityManager.cs @@ -1,184 +1,102 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + /* -* CVS identifier: -* -* $Id: FacilityManager.java,v 1.12 2002/05/22 15:00:24 grosbois Exp $ -* -* Class: MsgLoggerManager -* -* Description: Manages common facilities across threads -* -* -* -* 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; + * JJ2000 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. + */ + namespace CSJ2K.j2k.util { - - /// This class manages common facilities for multi-threaded - /// environments, It can register different facilities for each thread, - /// and also a default one, so that they can be referred by static - /// methods, while possibly having different ones for different - /// threads. Also a default facility exists that is used for threads - /// for which no particular facility has been registerd registered. - /// - ///

Currently the only kind of facilities managed is MsgLogger.

- /// - ///

An example use of this class is if 2 instances of a decoder are running - /// in different threads and the messages of the 2 instances should be - /// separated. - /// - ///

The default MsgLogger is a StreamMsgLogger that uses System.out as - /// the 'out' stream and System.err as the 'err' stream, and a line width of - /// 78. This can be changed using the registerMsgLogger() method. - /// - ///

- /// - /// - /// - /// - /// - public class FacilityManager - { - /// Returns the ProgressWatch instance registered with the current - /// thread (the thread that calls this method). If the current - /// thread has no registered ProgressWatch, then the default one is used. - /// - /// - public static ProgressWatch ProgressWatch - { - get - { - ProgressWatch pw = (ProgressWatch) watchProgList[SupportClass.ThreadClass.Current()]; - return (pw == null)?defWatchProg:pw; - } - - } - - /// The loggers associated to different threads - //UPGRADE_NOTE: Final was removed from the declaration of 'loggerList '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private static readonly System.Collections.Hashtable loggerList = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); - - /// The default logger, for threads that have none associated with them - private static MsgLogger defMsgLogger = new StreamMsgLogger(System.Console.OpenStandardOutput(), System.Console.OpenStandardError(), 78); - - /// The ProgressWatch instance associated to different threads - //UPGRADE_NOTE: Final was removed from the declaration of 'watchProgList '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - private static readonly System.Collections.Hashtable watchProgList = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); - - /// The default ProgressWatch for threads that have none - /// associated with them. - /// - private static ProgressWatch defWatchProg = null; - - - internal static void registerProgressWatch(SupportClass.ThreadClass t, ProgressWatch pw) - { - if (pw == null) - { - throw new System.NullReferenceException(); - } - if (t == null) - { - defWatchProg = pw; - } - else - { - watchProgList[t] = pw; - } - } - - /// Registers the MsgLogger 'ml' as the logging facility of the - /// thread 't'. If any other logging facility was registered with - /// the thread 't' it is overriden by 'ml'. If 't' is null then - /// 'ml' is taken as the default message logger that is used for - /// threads that have no MsgLogger registered. - /// - /// - /// The thread to associate with 'ml' - /// - /// - /// The MsgLogger to associate with therad ml - /// - /// - internal static void registerMsgLogger(SupportClass.ThreadClass t, MsgLogger ml) - { - if (ml == null) - { - throw new System.NullReferenceException(); - } - if (t == null) - { - defMsgLogger = ml; - } - else - { - loggerList[t] = ml; - } - } - - /// Returns the MsgLogger registered with the current thread (the - /// thread that calls this method). If the current thread has no - /// registered MsgLogger then the default message logger is - /// returned. - /// - /// - /// The MsgLogger registerd for the current thread, or the - /// default one if there is none registered for it. - /// - /// - public static MsgLogger getMsgLogger() - { - MsgLogger ml = (MsgLogger) loggerList[SupportClass.ThreadClass.Current()]; - return (ml == null)?defMsgLogger:ml; - } - - /// Returns the MsgLogger registered with the thread 't' (the - /// thread that calls this method). If the thread 't' has no - /// registered MsgLogger then the default message logger is - /// returned. - /// - /// - /// The thread for which to return the MsgLogger - /// - /// - /// The MsgLogger registerd for the current thread, or the - /// default one if there is none registered for it. - /// - /// - internal static MsgLogger getMsgLogger(SupportClass.ThreadClass t) - { - MsgLogger ml = (MsgLogger) loggerList[t]; - return (ml == null)?defMsgLogger:ml; - } - } -} \ No newline at end of file + using System; + + /// This class manages common facilities for multi-threaded + /// environments, It can register different facilities for each thread, + /// and also a default one, so that they can be referred by static + /// methods, while possibly having different ones for different + /// threads. Also a default facility exists that is used for threads + /// for which no particular facility has been registerd registered. + ///

Currently the only kind of facilities managed is MsgLogger.

+ ///

An example use of this class is if 2 instances of a decoder are running + /// in different threads and the messages of the 2 instances should be + /// separated.

+ ///

The default MsgLogger is a StreamMsgLogger that uses System.out as + /// the 'out' stream and System.err as the 'err' stream, and a line width of + /// 78. This can be changed using the registerMsgLogger() method.

+ ///
+ /// + /// + /// + /// + public static class FacilityManager + { + #region FIELDS + + private static IMsgLogger _defMsgLogger; + + #endregion + + #region CONSTRUCTORS + + static FacilityManager() + { + _defMsgLogger = J2kSetup.GetSinglePlatformInstance(); + } + + #endregion + + #region PROPERTIES + + /// The default logger, for threads that have none associated with them + public static IMsgLogger DefaultMsgLogger + { + set + { + _defMsgLogger = value; + } + } + + #endregion + + /// Returns the MsgLogger registered with the current thread (the + /// thread that calls this method). If the current thread has no + /// registered MsgLogger then the default message logger is + /// returned. + /// + /// The MsgLogger registerd for the current thread, or the + /// default one if there is none registered for it. + /// + public static IMsgLogger getMsgLogger() + { + return _defMsgLogger; + } + } +} diff --git a/CSJ2K/j2k/util/IMsgLogger.cs b/CSJ2K/j2k/util/IMsgLogger.cs new file mode 100644 index 00000000..c340e032 --- /dev/null +++ b/CSJ2K/j2k/util/IMsgLogger.cs @@ -0,0 +1,119 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + +/* + * JJ2000 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. + */ + +namespace CSJ2K.j2k.util +{ + + /// This class provides a simple common abstraction of a facility that logs + /// and/or displays messages or simple strings. The underlying facility can be + /// a terminal, text file, text area in a GUI display, dialog boxes in a GUI + /// display, etc., or a combination of those. + ///

Messages are short strings (a couple of lines) that indicate some state + /// of the program, and that have a severity code associated with them (see + /// below). Simple strings is text (can be long) that has no severity code + /// associated with it. Typical use of simple strings is to display help + /// texts.

+ ///

Each message has a severity code, which can be one of the following: + /// LOG, INFO, WARNING, ERROR. Each implementation should treat each severity + /// code in a way which corresponds to the type of diplay used.

+ ///

Messages are printed via the 'printmsg()' method. Simple strings are + /// printed via the 'print()', 'println()' and 'flush()' methods, each simple + /// string is considered to be terminated once the 'flush()' method has been + /// called. The 'printmsg()' method should never be called before a previous + /// simple string has been terminated.

+ ///
+ public struct MsgLogger_Fields + { + /// Severity of message. LOG messages are just for bookkeeping and do not + /// need to be displayed in the majority of cases + /// + public const int LOG = 0; + + /// Severity of message. INFO messages should be displayed just for user + /// feedback. + /// + public const int INFO = 1; + + /// Severity of message. WARNING messages denote that an unexpected state + /// has been reached and should be given as feedback to the user. + /// + public const int WARNING = 2; + + /// Severity of message. ERROR messages denote that something has gone + /// wrong and probably that execution has ended. They should be definetely + /// displayed to the user. + /// + public const int ERROR = 3; + } + + public interface IMsgLogger + { + /// Prints the message 'msg' to the output device, appending a newline, + /// with severity 'sev'. Some implementations where the appended newline is + /// irrelevant may not append the newline. Depending on the implementation + /// the severity of the message may be added to it. The message is + /// reformatted as appropriate for the output devic, but any newline + /// characters are respected. + /// + /// The message severity (LOG, INFO, etc.) + /// + /// The message to display + /// + void printmsg(int sev, string msg); + + /// Prints the string 'str' to the output device, appending a line + /// return. The message is reformatted as appropriate to the particular + /// diplaying device, where 'flind' and 'ind' are used as hints for + /// performing that operation. However, any newlines appearing in 'str' are + /// respected. The output device may not display the string until flush() + /// is called. Some implementations may automatically flush when this + /// method is called. This method just prints the string, the string does + /// not make part of a "message" in the sense that no severity is + /// associated to it. + /// + /// The string to print + /// + /// Indentation of the first line + /// + /// Indentation of any other lines. + /// + void println(string str, int flind, int ind); + + /// Writes any buffered data from the println() method to the device. + /// + void flush(); + } +} diff --git a/CSJ2K/j2k/util/ISRandomAccessIO.cs b/CSJ2K/j2k/util/ISRandomAccessIO.cs index a3b634ef..a1d7d7e8 100644 --- a/CSJ2K/j2k/util/ISRandomAccessIO.cs +++ b/CSJ2K/j2k/util/ISRandomAccessIO.cs @@ -213,7 +213,7 @@ namespace CSJ2K.j2k.util { newbuf = new byte[buf.Length + inc]; } - catch (System.OutOfMemoryException) + catch (System.OutOfMemoryException e) { throw new System.IO.IOException("Out of memory to cache input data"); } @@ -270,7 +270,7 @@ namespace CSJ2K.j2k.util { /* we reached EOF */ complete = true; - is_Renamed.Close(); + is_Renamed.Dispose(); is_Renamed = null; } } @@ -288,7 +288,7 @@ namespace CSJ2K.j2k.util buf = null; if (!complete) { - is_Renamed.Close(); + is_Renamed.Dispose(); is_Renamed = null; } } diff --git a/CSJ2K/j2k/util/MathUtil.cs b/CSJ2K/j2k/util/MathUtil.cs index b945d981..b9330812 100644 --- a/CSJ2K/j2k/util/MathUtil.cs +++ b/CSJ2K/j2k/util/MathUtil.cs @@ -114,7 +114,7 @@ namespace CSJ2K.j2k.util return i * max; } } - throw new System.ApplicationException("Cannot find the least common multiple of numbers " + x1 + " and " + x2); + throw new System.InvalidOperationException("Cannot find the least common multiple of numbers " + x1 + " and " + x2); } /// Method that calculates the Least Common Multiple (LCM) of several @@ -128,7 +128,7 @@ namespace CSJ2K.j2k.util { if (x.Length < 2) { - throw new System.ApplicationException("Do not use this method if there are less than" + " two numbers."); + throw new System.InvalidOperationException("Do not use this method if there are less than" + " two numbers."); } int tmp = lcm(x[x.Length - 1], x[x.Length - 2]); for (int i = x.Length - 3; i >= 0; i--) @@ -190,7 +190,7 @@ namespace CSJ2K.j2k.util { if (x.Length < 2) { - throw new System.ApplicationException("Do not use this method if there are less than" + " two numbers."); + throw new System.InvalidOperationException("Do not use this method if there are less than" + " two numbers."); } int tmp = gcd(x[x.Length - 1], x[x.Length - 2]); for (int i = x.Length - 3; i >= 0; i--) diff --git a/CSJ2K/j2k/util/MsgLogger.cs b/CSJ2K/j2k/util/MsgLogger.cs deleted file mode 100644 index 9ac63d49..00000000 --- a/CSJ2K/j2k/util/MsgLogger.cs +++ /dev/null @@ -1,135 +0,0 @@ -/* -* CVS identifier: -* -* $Id: MsgLogger.java,v 1.7 2001/08/17 16:24:51 grosbois Exp $ -* -* Class: MsgLogger -* -* Description: Facility to log messages (abstract) -* -* -* -* 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; -namespace CSJ2K.j2k.util -{ - - /// This class provides a simple common abstraction of a facility that logs - /// and/or displays messages or simple strings. The underlying facility can be - /// a terminal, text file, text area in a GUI display, dialog boxes in a GUI - /// display, etc., or a combination of those. - /// - /// <>Messages are short strings (a couple of lines) that indicate some state - /// of the program, and that have a severity code associated with them (see - /// below). Simple strings is text (can be long) that has no severity code - /// associated with it. Typical use of simple strings is to display help - /// texts.

- /// - ///

Each message has a severity code, which can be one of the following: - /// LOG, INFO, WARNING, ERROR. Each implementation should treat each severity - /// code in a way which corresponds to the type of diplay used.

- /// - ///

Messages are printed via the 'printmsg()' method. Simple strings are - /// printed via the 'print()', 'println()' and 'flush()' methods, each simple - /// string is considered to be terminated once the 'flush()' method has been - /// called. The 'printmsg()' method should never be called before a previous - /// simple string has been terminated.

- /// - ///
- public struct MsgLogger_Fields{ - /// Severity of message. LOG messages are just for bookkeeping and do not - /// need to be displayed in the majority of cases - /// - public const int LOG = 0; - /// Severity of message. INFO messages should be displayed just for user - /// feedback. - /// - public const int INFO = 1; - /// Severity of message. WARNING messages denote that an unexpected state - /// has been reached and should be given as feedback to the user. - /// - public const int WARNING = 2; - /// Severity of message. ERROR messages denote that something has gone - /// wrong and probably that execution has ended. They should be definetely - /// displayed to the user. - /// - public const int ERROR = 3; - } - public interface MsgLogger - { - //UPGRADE_NOTE: Members of interface 'MsgLogger' were extracted into structure 'MsgLogger_Fields'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1045'" - - /// Prints the message 'msg' to the output device, appending a newline, - /// with severity 'sev'. Some implementations where the appended newline is - /// irrelevant may not append the newline. Depending on the implementation - /// the severity of the message may be added to it. The message is - /// reformatted as appropriate for the output devic, but any newline - /// characters are respected. - /// - /// - /// The message severity (LOG, INFO, etc.) - /// - /// - /// The message to display - /// - /// - void printmsg(int sev, System.String msg); - - /// Prints the string 'str' to the output device, appending a line - /// return. The message is reformatted as appropriate to the particular - /// diplaying device, where 'flind' and 'ind' are used as hints for - /// performing that operation. However, any newlines appearing in 'str' are - /// respected. The output device may not display the string until flush() - /// is called. Some implementations may automatically flush when this - /// method is called. This method just prints the string, the string does - /// not make part of a "message" in the sense that no severity is - /// associated to it. - /// - /// - /// The string to print - /// - /// - /// Indentation of the first line - /// - /// - /// Indentation of any other lines. - /// - /// - void println(System.String str, int flind, int ind); - - /// Writes any buffered data from the println() method to the device. - /// - /// - void flush(); - } -} \ No newline at end of file diff --git a/CSJ2K/j2k/util/ParameterList.cs b/CSJ2K/j2k/util/ParameterList.cs index a7583e32..732bd716 100644 --- a/CSJ2K/j2k/util/ParameterList.cs +++ b/CSJ2K/j2k/util/ParameterList.cs @@ -67,8 +67,7 @@ namespace CSJ2K.j2k.util /// /// //UPGRADE_ISSUE: Class hierarchy differences between 'java.util.Properties' and 'System.Collections.Specialized.NameValueCollection' may cause compilation errors. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1186'" - [Serializable] - public class ParameterList:System.Collections.Specialized.NameValueCollection + public class ParameterList:System.Collections.Generic.Dictionary { // COVNERSION PROBLEM? private ParameterList defaults; @@ -287,14 +286,16 @@ namespace CSJ2K.j2k.util { System.String pval; - pval = ((System.String) this[(System.String) pname]); //UPGRADE_ISSUE: Field 'java.util.Properties.defaults' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javautilPropertiesdefaults_f'" - if (pval == null && defaults != null) + if (!TryGetValue(pname, out pval) && defaults != null) { // if parameter is not there // Look in defaults //UPGRADE_ISSUE: Field 'java.util.Properties.defaults' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javautilPropertiesdefaults_f'" - pval = defaults.Get(pname); + if (!defaults.TryGetValue(pname, out pval)) + { + return null; + } } return pval; } diff --git a/CSJ2K/j2k/util/StreamMsgLogger.cs b/CSJ2K/j2k/util/StreamMsgLogger.cs index 9734bf4c..4defda81 100644 --- a/CSJ2K/j2k/util/StreamMsgLogger.cs +++ b/CSJ2K/j2k/util/StreamMsgLogger.cs @@ -1,244 +1,175 @@ +// Copyright (c) 2007-2016 CSJ2K contributors. +// Licensed under the BSD 3-Clause License. + /* -* CVS identifier: -* -* $Id: StreamMsgLogger.java,v 1.11 2000/09/05 09:25:30 grosbois Exp $ -* -* Class: StreamMsgLogger -* -* Description: Implementation of MsgLogger for streams -* -* -* -* 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; + * JJ2000 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. + */ + namespace CSJ2K.j2k.util { - - /// This class implements the MsgLogger interface for streams. Streams can - /// be simple files, terminals, stdout, stderr, etc. The messages or simple - /// strings are formatted using the linewidth given to the constructor. - /// - ///

Messages are printed to the 'err' stream if they are of severity WARNING - /// or ERROR, otherwise they are printed to the 'out' stream. Simple strings - /// are always printed the 'out' stream. - /// - ///

- public class StreamMsgLogger : MsgLogger - { - - /// The 'out' stream - private System.IO.StreamWriter out_Renamed; - - /// The 'err' stream - private System.IO.StreamWriter err; - - /// The printer that formats the text - private MsgPrinter mp; - - /// Constructs a StreamMsgLogger that uses 'outstr' as the 'out' stream, - /// and 'errstr' as the 'err' stream. Note that 'outstr' and 'errstr' can - /// be System.out and System.err. - /// - /// - /// Where to print simple strings and LOG and INFO messages. - /// - /// - /// Where to print WARNING and ERROR messages - /// - /// - /// The line width to use in formatting - /// - /// - /// - /// - public StreamMsgLogger(System.IO.Stream outstr, System.IO.Stream errstr, int lw) - { - System.IO.StreamWriter temp_writer; - temp_writer = new System.IO.StreamWriter(outstr, System.Text.Encoding.Default); - temp_writer.AutoFlush = true; - out_Renamed = temp_writer; - System.IO.StreamWriter temp_writer2; - temp_writer2 = new System.IO.StreamWriter(errstr, System.Text.Encoding.Default); - temp_writer2.AutoFlush = true; - err = temp_writer2; - mp = new MsgPrinter(lw); - } - - /// Constructs a StreamMsgLogger that uses 'outstr' as the 'out' stream, - /// and 'errstr' as the 'err' stream. Note that 'outstr' and 'errstr' can - /// be System.out and System.err. - /// - /// - /// Where to print simple strings and LOG and INFO messages. - /// - /// - /// Where to print WARNING and ERROR messages - /// - /// - /// The line width to use in formatting - /// - /// - /// - /// - //UPGRADE_ISSUE: Class hierarchy differences between 'java.io.Writer' and 'System.IO.StreamWriter' may cause compilation errors. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1186'" - public StreamMsgLogger(System.IO.StreamWriter outstr, System.IO.StreamWriter errstr, int lw) - { - System.IO.StreamWriter temp_writer; - temp_writer = new System.IO.StreamWriter(outstr.BaseStream, outstr.Encoding); - temp_writer.AutoFlush = true; - out_Renamed = temp_writer; - System.IO.StreamWriter temp_writer2; - temp_writer2 = new System.IO.StreamWriter(errstr.BaseStream, errstr.Encoding); - temp_writer2.AutoFlush = true; - err = temp_writer2; - mp = new MsgPrinter(lw); - } - - /// Constructs a StreamMsgLogger that uses 'outstr' as the 'out' stream, - /// and 'errstr' as the 'err' stream. Note that 'outstr' and 'errstr' can - /// be System.out and System.err. - /// - /// - /// Where to print simple strings and LOG and INFO messages. - /// - /// - /// Where to print WARNING and ERROR messages - /// - /// - /// The line width to use in formatting - /// - /// - /// - /// - /// - /* - public StreamMsgLogger(System.IO.StreamWriter outstr, System.IO.StreamWriter errstr, int lw) - { - out_Renamed = outstr; - err = errstr; - mp = new MsgPrinter(lw); - } - */ - /// Prints the message 'msg' to the output device, appending a newline, - /// with severity 'sev'. The severity of the message is prepended to the - /// message. - /// - /// - /// The message severity (LOG, INFO, etc.) - /// - /// - /// The message to display - /// - /// - /// - /// - public virtual void printmsg(int sev, System.String msg) - { - System.IO.StreamWriter lout; - //int ind; - System.String prefix; - - switch (sev) - { - - case CSJ2K.j2k.util.MsgLogger_Fields.LOG: - prefix = "[LOG]: "; - lout = out_Renamed; - break; - - case CSJ2K.j2k.util.MsgLogger_Fields.INFO: - prefix = "[INFO]: "; - lout = out_Renamed; - break; - - case CSJ2K.j2k.util.MsgLogger_Fields.WARNING: - prefix = "[WARNING]: "; - lout = err; - break; - - case CSJ2K.j2k.util.MsgLogger_Fields.ERROR: - prefix = "[ERROR]: "; - lout = err; - break; - - default: - throw new System.ArgumentException("Severity " + sev + " not valid."); - - } - - mp.print(lout, 0, prefix.Length, prefix + msg); - lout.Flush(); - } - - /// Prints the string 'str' to the 'out' stream, appending a newline. The - /// message is reformatted to the line width given to the constructors and - /// using 'flind' characters to indent the first line and 'ind' characters - /// to indent the second line. However, any newlines appearing in 'str' are - /// respected. The output device may or may not display the string until - /// flush() is called, depending on the autoflush state of the PrintWriter, - /// to be sure flush() should be called to write the string to the - /// device. This method just prints the string, the string does not make - /// part of a "message" in the sense that noe severity is associated to it. - /// - /// - /// The string to print - /// - /// - /// Indentation of the first line - /// - /// - /// Indentation of any other lines. - /// - /// - /// - /// - public virtual void println(System.String str, int flind, int ind) - { - mp.print(out_Renamed, flind, ind, str); - } - - /// Writes any buffered data from the print() and println() methods to the - /// device. - /// - /// - /// - /// - public virtual void flush() - { - out_Renamed.Flush(); - } - } -} \ No newline at end of file + using System.IO; + + /// This class implements the MsgLogger interface for streams. Streams can + /// be simple files, terminals, stdout, stderr, etc. The messages or simple + /// strings are formatted using the linewidth given to the constructor. + ///

Messages are printed to the 'err' stream if they are of severity WARNING + /// or ERROR, otherwise they are printed to the 'out' stream. Simple strings + /// are always printed the 'out' stream.

+ ///
+ public abstract class StreamMsgLogger : IMsgLogger + { + /// The 'out' stream + private StreamWriter out_Renamed; + + /// The 'err' stream + private readonly StreamWriter err; + + /// The printer that formats the text + private readonly MsgPrinter mp; + + /// Constructs a StreamMsgLogger that uses 'outstr' as the 'out' stream, + /// and 'errstr' as the 'err' stream. Note that 'outstr' and 'errstr' can + /// be System.out and System.err. + /// + /// Where to print simple strings and LOG and INFO messages. + /// + /// Where to print WARNING and ERROR messages + /// + /// The line width to use in formatting + /// + protected StreamMsgLogger(Stream outstr, Stream errstr, int lw) + { + var temp_writer = new StreamWriter(outstr, System.Text.Encoding.UTF8); + temp_writer.AutoFlush = true; + out_Renamed = temp_writer; + var temp_writer2 = new StreamWriter(errstr, System.Text.Encoding.UTF8); + temp_writer2.AutoFlush = true; + err = temp_writer2; + mp = new MsgPrinter(lw); + } + + /// Constructs a StreamMsgLogger that uses 'outstr' as the 'out' stream, + /// and 'errstr' as the 'err' stream. Note that 'outstr' and 'errstr' can + /// be System.out and System.err. + /// + /// Where to print simple strings and LOG and INFO messages. + /// + /// Where to print WARNING and ERROR messages + /// + /// The line width to use in formatting + /// + protected StreamMsgLogger(StreamWriter outstr, StreamWriter errstr, int lw) + { + var temp_writer = new StreamWriter(outstr.BaseStream, outstr.Encoding); + temp_writer.AutoFlush = true; + out_Renamed = temp_writer; + var temp_writer2 = new StreamWriter(errstr.BaseStream, errstr.Encoding); + temp_writer2.AutoFlush = true; + err = temp_writer2; + mp = new MsgPrinter(lw); + } + + /// Prints the message 'msg' to the output device, appending a newline, + /// with severity 'sev'. The severity of the message is prepended to the + /// message. + /// + /// The message severity (LOG, INFO, etc.) + /// + /// The message to display + /// + public virtual void printmsg(int sev, string msg) + { + StreamWriter lout; + string prefix; + + switch (sev) + { + + case MsgLogger_Fields.LOG: + prefix = "[LOG]: "; + lout = out_Renamed; + break; + + case MsgLogger_Fields.INFO: + prefix = "[INFO]: "; + lout = out_Renamed; + break; + + case MsgLogger_Fields.WARNING: + prefix = "[WARNING]: "; + lout = err; + break; + + case MsgLogger_Fields.ERROR: + prefix = "[ERROR]: "; + lout = err; + break; + + default: + throw new System.ArgumentException("Severity " + sev + " not valid."); + + } + + mp.print(lout, 0, prefix.Length, prefix + msg); + lout.Flush(); + } + + /// Prints the string 'str' to the 'out' stream, appending a newline. The + /// message is reformatted to the line width given to the constructors and + /// using 'flind' characters to indent the first line and 'ind' characters + /// to indent the second line. However, any newlines appearing in 'str' are + /// respected. The output device may or may not display the string until + /// flush() is called, depending on the autoflush state of the PrintWriter, + /// to be sure flush() should be called to write the string to the + /// device. This method just prints the string, the string does not make + /// part of a "message" in the sense that noe severity is associated to it. + /// + /// The string to print + /// + /// Indentation of the first line + /// + /// Indentation of any other lines. + /// + public virtual void println(string str, int flind, int ind) + { + mp.print(out_Renamed, flind, ind, str); + } + + /// Writes any buffered data from the print() and println() methods to the + /// device. + /// + public virtual void flush() + { + out_Renamed.Flush(); + } + } +} diff --git a/CSJ2K/j2k/util/StringFormatException.cs b/CSJ2K/j2k/util/StringFormatException.cs index de7fb6e1..4890557d 100644 --- a/CSJ2K/j2k/util/StringFormatException.cs +++ b/CSJ2K/j2k/util/StringFormatException.cs @@ -52,7 +52,6 @@ namespace CSJ2K.j2k.util /// badly formatted string. /// ///
- [Serializable] public class StringFormatException:System.ArgumentException { diff --git a/CSJ2K/j2k/util/ThreadPool.cs b/CSJ2K/j2k/util/ThreadPool.cs deleted file mode 100644 index 3033c76e..00000000 --- a/CSJ2K/j2k/util/ThreadPool.cs +++ /dev/null @@ -1,648 +0,0 @@ -/* -* CVS identifier: -* -* $Id: ThreadPool.java,v 1.9 2002/05/22 15:00:55 grosbois Exp $ -* -* Class: ThreadPool -* -* Description: A pool of threads -* -* -* -* 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; -namespace CSJ2K.j2k.util -{ - - /// This class implements a thread pool. The thread pool contains a set of - /// threads which can be given work to do. - /// - ///

If the Java Virtual Machine (JVM) uses native threads, then the - /// different threads will be able to execute in different processors in - /// parallel on multiprocessors machines. However, under some JVMs and - /// operating systems using native threads is not sufficient to allow the JVM - /// access to multiple processors. This is the case when native threads are - /// implemented using POSIX threads on lightweight processes - /// (i.e. PTHREAD_SCOPE_PROCESS sopce scheduling), which is the case on most - /// UNIX operating systems. In order to do provide access to multiple - /// processors it is necessary to set the concurrency level to the number of - /// processors or slightly higher. This can be achieved by setting the Java - /// system property with the name defined by CONCURRENCY_PROP_NAME to some - /// non-negative number. This will make use of the 'NativeServices' class and - /// supporting native libraries. See 'NativeServices' for details. See - /// 'CONCURRENCY_PROP_NAME' for the name of the property. - /// - ///

Initially the thread pool contains a user specified number of idle - /// threads. Idle threads can be given a target which is run. While running the - /// target the thread temporarily leaves the idle list. When the target - /// finishes, it joins the idle list again, waiting for a new target. When a - /// target is finished a thread can be notified on a particular object that is - /// given as a lock. - /// - ///

Jobs can be submitted using Runnable interfaces, using the 'runTarget()' - /// methods. When the job is submitted, an idle thread will be obtained, the - /// 'run()' method of the 'Runnable' interface will be executed and when it - /// completes the thread will be returned to the idle list. In general the - /// 'run()' method should complete in a rather short time, so that the threds - /// of the pool are not starved. - /// - ///

If using the non-asynchronous calls to 'runTarget()', it is important - /// that any target's 'run()' method, or any method called from it, does not - /// use non-asynchronous calls to 'runTarget()' on the same thread pool where - /// it was started. Otherwise this could create a dead-lock when there are not - /// enough idle threads. - /// - ///

The pool also has a global error and runtime exception condition (one - /// for 'Error' and one for 'RuntimeException'). If a target's 'run()' method - /// throws an 'Error' or 'RuntimeException' the corresponding exception - /// condition is set and the exception object saved. In any subsequent call to - /// 'checkTargetErrors()' the saved exception object is thrown. Likewise, if a - /// target's 'run()' method throws any other subclass of 'Throwable' a new - /// 'RuntimeException' is created and saved. It will be thrown on a subsequent - /// call to 'checkTargetErrors()'. If more than one exception occurs between - /// calls to 'checkTargetErrors()' only the last one is saved. Any 'Error' - /// condition has precedence on all 'RuntimeException' conditions. The threads - /// in the pool are unaffected by any exceptions thrown by targets. - /// - ///

The only exception to the above is the 'ThreadDeath' exception. If a - /// target's 'run()' method throws the 'ThreadDeath' exception a warning - /// message is printed and the exception is propagated, which will terminate - /// the thread in which it occurs. This could lead to instabilities of the - /// pool. The 'ThreadDeath' exception should never be thrown by the program. It - /// is thrown by the Java(TM) Virtual Machine when Thread.stop() is - /// called. This method is deprecated and should never be called. - /// - ///

All the threads in the pool are "daemon" threads and will automatically - /// terminate when no daemon threads are running. - /// - ///

- /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public class ThreadPool - { - /// Returns the size of the pool. That is the number of threads in this - /// pool (idle + busy). - /// - /// - /// The pool's size. - /// - /// - /// - virtual public int Size - { - get - { - return idle.Length; - } - - } - - /// The name of the property that sets the concurrency level: - /// jj2000.j2k.util.ThreadPool.concurrency - /// - public const System.String CONCURRENCY_PROP_NAME = "jj2000.j2k.util.ThreadPool.concurrency"; - - /// The array of idle threads and the lock for the manipulation of the - /// idle thread list. - /// - private ThreadPoolThread[] idle; - - /// The number of idle threads - private int nidle; - - /// The name of the pool - private System.String poolName; - - /// The priority for the pool - private int poolPriority; - - /// The last error thrown by a target. Null if none - // NOTE: needs to be volatile, so that only one copy exits in memory - private volatile System.ApplicationException targetE; - - /// The last runtime exception thrown by a target. Null if none - // NOTE: needs to be volatile, so that only one copy exits in memory - private volatile System.SystemException targetRE; - - //UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'ThreadPoolThread' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'" - /// The threads that are managed by the pool. - /// - /// - internal class ThreadPoolThread:SupportClass.ThreadClass - { - private void InitBlock(ThreadPool enclosingInstance) - { - this.enclosingInstance = enclosingInstance; - } - private ThreadPool enclosingInstance; - public ThreadPool Enclosing_Instance - { - get - { - return enclosingInstance; - } - - } - private IThreadRunnable target; - private System.Object lock_Renamed; - private bool doNotifyAll; - - /// Creates a ThreadPoolThread object, setting its name according to - /// the given 'idx', daemon type and the priority to the one of the - /// pool. - /// - /// - /// The index of this thread in the pool - /// - /// - /// The name of the thread - /// - /// - public ThreadPoolThread(ThreadPool enclosingInstance, int idx, System.String name):base(name) - { - InitBlock(enclosingInstance); - IsBackground = true; - //UPGRADE_TODO: The differences in the type of parameters for method 'java.lang.Thread.setPriority' may cause compilation errors. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1092'" - Priority = (System.Threading.ThreadPriority) Enclosing_Instance.poolPriority; - } - - /// The method that is run by the thread. This method first joins the - /// idle state in the pool and then enters an infinite loop. In this - /// loop it waits until a target to run exists and runs it. Once the - /// target's run() method is done it re-joins the idle state and - /// notifies the waiting lock object, if one exists. - /// - ///

An interrupt on this thread has no effect other than forcing a - /// check on the target. Normally the target is checked every time the - /// thread is woken up by notify, no interrupts should be done. - /// - ///

Any exception thrown by the target's 'run()' method is catched - /// and this thread is not affected, except for 'ThreadDeath'. If a - /// 'ThreadDeath' exception is catched a warning message is printed by - /// the 'FacilityManager' and the exception is propagated up. For - /// exceptions which are subclasses of 'Error' or 'RuntimeException' - /// the corresponding error condition is set and this thread is not - /// affected. For any other exceptions a new 'RuntimeException' is - /// created and the error condition is set, this thread is not affected. - /// - ///

- override public void Run() - { - // Join the idle threads list - Enclosing_Instance.putInIdleList(this); - // Permanently lock the object while running so that target can - // not be changed until we are waiting again. While waiting for a - // target the lock is released. - lock (this) - { - while (true) - { - // Wait until we get a target - while (target == null) - { - try - { - System.Threading.Monitor.Wait(this); - } - catch (System.Threading.ThreadInterruptedException) - { - } - } - // Run the target and catch all possible errors - try - { - target.Run(); - } - //UPGRADE_NOTE: Exception 'java.lang.ThreadDeath' was converted to 'System.ApplicationException' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - catch (System.Threading.ThreadAbortException td) - { - // We have been instructed to abruptly terminate - // the thread, which should never be done. This can - // cause another thread, or the system, to lock. - FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Thread.stop() called on a ThreadPool " + "thread or ThreadDeath thrown. This is " + "deprecated. Lock-up might occur."); - throw td; - } - catch (System.ApplicationException e) - { - Enclosing_Instance.targetE = e; - } - catch (System.SystemException re) - { - Enclosing_Instance.targetRE = re; - } - //UPGRADE_NOTE: Exception 'java.lang.Throwable' was converted to 'System.Exception' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" - catch (System.Exception) - { - // A totally unexpected error has occurred - // (Thread.stop(Throwable) has been used, which should - // never be. - Enclosing_Instance.targetRE = new System.SystemException("Unchecked exception " + "thrown by target's " + "run() method in pool " + Enclosing_Instance.poolName + "."); - } - // Join idle threads - Enclosing_Instance.putInIdleList(this); - // Release the target and notify lock (i.e. wakeup) - target = null; - if (lock_Renamed != null) - { - lock (lock_Renamed) - { - if (doNotifyAll) - { - System.Threading.Monitor.PulseAll(lock_Renamed); - } - else - { - System.Threading.Monitor.Pulse(lock_Renamed); - } - } - } - } - } - } - - /// Assigns a target to this thread, with an optional notify lock and a - /// notify mode. The another target is currently running the method - /// will block until it terminates. After setting the new target the - /// runner thread will be wakenup and execytion will start. - /// - /// - /// The runnable object containing the 'run()' method to - /// run. - /// - /// - /// An object on which notify will be called once the - /// target's run method has finished. A thread to be notified should be - /// waiting on that object. If null no thread is notified. - /// - /// - /// If true 'notifyAll()', instead of 'notify()', will - /// be called on tghe lock. - /// - /// - //UPGRADE_NOTE: Synchronized keyword was removed from method 'setTarget'. Lock expression was added. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1027'" - internal virtual void setTarget(IThreadRunnable target, System.Object lock_Renamed, bool notifyAll) - { - lock (this) - { - // Set the target - this.target = target; - this.lock_Renamed = lock_Renamed; - doNotifyAll = notifyAll; - // Wakeup the thread - System.Threading.Monitor.Pulse(this); - } - } - } - - /// Creates a new thread pool of the given size, thread priority and pool - /// name. - /// - ///

If the Java system property of the name defined by - /// 'CONCURRENCY_PROP_NAME' is set, then an attempt will be made to load - /// the library that supports concurrency setting (see - /// 'NativeServices'). If that succeds the concurrency level will be set to - /// the specified value. Otherwise a warning is printed. - /// - ///

- /// The size of the pool (number of threads to create in the - /// pool). - /// - /// - /// The priority to give to the threads in the pool. If - /// less than 'Thread.MIN_PRIORITY' it will be the same as the priority of - /// the calling thread. - /// - /// - /// The name of the pool. If null a default generic name is - /// chosen. - /// - /// - /// - /// - /// - /// - /// - /// - public ThreadPool(int size, int priority, System.String name) - { - int i; - ThreadPoolThread t; - //System.String prop; - //int clevel; - - // Initialize variables checking for special cases - if (size <= 0) - { - throw new System.ArgumentException("Pool must be of positive size"); - } - if (priority < (int) System.Threading.ThreadPriority.Lowest) - { - poolPriority = (System.Int32) SupportClass.ThreadClass.Current().Priority; - } - else - { - poolPriority = (priority < (int) System.Threading.ThreadPriority.Highest)?priority:(int) System.Threading.ThreadPriority.Highest; - } - if (name == null) - { - poolName = "Anonymous ThreadPool"; - } - else - { - poolName = name; - } - - // Allocate internal variables - idle = new ThreadPoolThread[size]; - nidle = 0; - - // Create and start the threads - for (i = 0; i < size; i++) - { - t = new ThreadPoolThread(this, i, poolName + "-" + i); - t.Start(); - } - } - - /// Runs the run method of the specified target in an idle thread of this - /// pool. When the target's run method completes, the thread waiting on the - /// lock object is notified, if any. If there is currently no idle thread - /// the method will block until a thread of the pool becomes idle or the - /// calling thread is interrupted. - /// - ///

This method is the same as runTarget(t,l,true,false). - /// - ///

- /// The target. The 'run()' method of this object will be run in - /// an idle thread of the pool. - /// - /// - /// The lock object. A thread waiting on the lock of the 'l' - /// object will be notified, through the 'notify()' call, when the target's - /// run method completes. If null no thread is notified. - /// - /// - /// True if the target was submitted to some thread. False if no - /// idle thread could be found and the target was not submitted for - /// execution. - /// - /// - /// - public virtual bool runTarget(IThreadRunnable t, System.Object l) - { - return runTarget(t, l, false, false); - } - - /// Runs the run method of the specified target in an idle thread of this - /// pool. When the target's run method completes, the thread waiting on the - /// lock object is notified, if any. If there is currently no idle thread - /// and the asynchronous mode is not used the method will block until a - /// thread of the pool becomes idle or the calling thread is - /// interrupted. If the asynchronous mode is used then the method will not - /// block and will return false. - /// - ///

This method is the same as runTarget(t,l,async,false). - /// - ///

- /// The target. The 'run()' method of this object will be run in - /// an idle thread of the pool. - /// - /// - /// The lock object. A thread waiting on the lock of the 'l' - /// object will be notified, through the 'notify()' call, when the target's - /// run method completes. If null no thread is notified. - /// - /// - /// If true the asynchronous mode will be used. - /// - /// - /// True if the target was submitted to some thread. False if no - /// idle thread could be found and the target was not submitted for - /// execution. - /// - /// - /// - public virtual bool runTarget(IThreadRunnable t, System.Object l, bool async) - { - return runTarget(t, l, async, false); - } - - /// Runs the run method of the specified target in an idle thread of this - /// pool. When the target's run method completes, the thread waiting on the - /// lock object is notified, if any. If there is currently no idle thread - /// and the asynchronous mode is not used the method will block until a - /// thread of the pool becomes idle or the calling thread is - /// interrupted. If the asynchronous mode is used then the method will not - /// block and will return false. - /// - /// - /// The target. The 'run()' method of this object will be run in - /// an idle thread of the pool. - /// - /// - /// The lock object. A thread waiting on the lock of the 'l' - /// object will be notified, through the 'notify()' call, when the target's - /// run method completes. If null no thread is notified. - /// - /// - /// If true the asynchronous mode will be used. - /// - /// - /// If true, threads waiting on the lock of the 'l' object - /// will be notified trough the 'notifyAll()' instead of the normal - /// 'notify()' call. This is not normally needed. - /// - /// - /// True if the target was submitted to some thread. False if no - /// idle thread could be found and the target was not submitted for - /// execution. - /// - /// - /// - public virtual bool runTarget(IThreadRunnable t, System.Object l, bool async, bool notifyAll) - { - ThreadPoolThread runner; // The thread to run the target - - // Get a thread to run - runner = getIdle(async); - // If no runner return failure - if (runner == null) - return false; - // Set the runner - runner.setTarget(t, l, notifyAll); - return true; - } - - /// Checks that no error or runtime exception in any target have occurred - /// so far. If an error or runtime exception has occurred in a target's run - /// method they are thrown by this method. - /// - /// - /// If an error condition has been thrown by a target - /// 'run()' method. - /// - /// - /// If a runtime exception has been thrown by a - /// target 'run()' method. - /// - /// - public virtual void checkTargetErrors() - { - // Check for Error - if (targetE != null) - throw targetE; - // Check for RuntimeException - if (targetRE != null) - throw targetRE; - } - - /// Clears the current target error conditions, if any. Note that a thread - /// in the pool might have set the error conditions since the last check - /// and that those error conditions will be lost. Likewise, before - /// returning from this method another thread might set the error - /// conditions. There is no guarantee that no error conditions exist when - /// returning from this method. - /// - ///

In order to ensure that no error conditions exist when returning - /// from this method cooperation from the targets and the thread using this - /// pool is necessary (i.e. currently no targets running or waiting to - /// run). - /// - ///

- public virtual void clearTargetErrors() - { - // Clear the error and runtime exception conditions - targetE = null; - targetRE = null; - } - - /// Puts the thread 't' in the idle list. The thread 't' should be in fact - /// idle and ready to accept a new target when it joins the idle list. - /// - ///

An idle thread that is already in the list should never add itself - /// to the list before it is removed. For efficiency reasons there is no - /// check to see if the thread is already in the list of idle threads. - /// - ///

If the idle list was empty 'notify()' will be called on the 'idle' - /// array, to wake up a thread that might be waiting (within the - /// 'getIdle()' method) on an idle thread to become available. - /// - ///

- /// The thread to put in the idle list. - /// - /// - private void putInIdleList(ThreadPoolThread t) - { - // NOTE: if already in idle => catastrophe! (should be OK since // - // this is private method) - // Lock the idle array to avoid races with 'getIdle()' - lock (idle) - { - idle[nidle] = t; - nidle++; - // If idle array was empty wakeup any waiting threads. - if (nidle == 1) - System.Threading.Monitor.Pulse(idle); - } - } - - /// Returns and idle thread and removes it from the list of idle - /// threads. In asynchronous mode it will immediately return an idle - /// thread, or null if none is available. In non-asynchronous mode it will - /// block until a thread of the pool becomes idle or the calling thread is - /// interrupted. - /// - ///

If in non-asynchronous mode and there are currently no idle threads - /// available the calling thread will wait on the 'idle' array lock, until - /// notified by 'putInIdleList()' that an idle thread might have become - /// available. - /// - ///

- /// If true asynchronous mode is used. - /// - /// - /// An idle thread of the pool, that has been removed from the idle - /// list, or null if none is available. - /// - /// - private ThreadPoolThread getIdle(bool async) - { - // Lock the idle array to avoid races with 'putInIdleList()' - lock (idle) - { - if (async) - { - // In asynchronous mode just return null if no idle thread - if (nidle == 0) - return null; - } - else - { - // In synchronous mode wait until a thread becomes idle - while (nidle == 0) - { - try - { - System.Threading.Monitor.Wait(idle); - } - catch (System.Threading.ThreadInterruptedException) - { - // If we were interrupted just return null - return null; - } - } - } - // Decrease the idle count and return one of the idle threads - nidle--; - return idle[nidle]; - } - } - } -} \ No newline at end of file diff --git a/CSJ2K/j2k/wavelet/Subband.cs b/CSJ2K/j2k/wavelet/Subband.cs index df90fb93..34998d51 100644 --- a/CSJ2K/j2k/wavelet/Subband.cs +++ b/CSJ2K/j2k/wavelet/Subband.cs @@ -503,7 +503,7 @@ namespace CSJ2K.j2k.wavelet break; default: - throw new System.ApplicationException("You have found a bug in JJ2000"); + throw new System.InvalidOperationException("You have found a bug in JJ2000"); } while (sb.isNode) @@ -513,7 +513,7 @@ namespace CSJ2K.j2k.wavelet return sb; default: - throw new System.ApplicationException("You have found a bug in JJ2000"); + throw new System.InvalidOperationException("You have found a bug in JJ2000"); } } diff --git a/CSJ2K/j2k/wavelet/WTDecompSpec.cs b/CSJ2K/j2k/wavelet/WTDecompSpec.cs index 4320c4c5..2ec56e4c 100644 --- a/CSJ2K/j2k/wavelet/WTDecompSpec.cs +++ b/CSJ2K/j2k/wavelet/WTDecompSpec.cs @@ -266,14 +266,14 @@ namespace CSJ2K.j2k.wavelet case DEC_SPEC_COMP_DEF: return compMainDefDecompType[n]; - case DEC_SPEC_TILE_DEF: - throw new NotImplementedException(); + case DEC_SPEC_TILE_DEF: + throw new NotImplementedException(); - case DEC_SPEC_TILE_COMP: - throw new NotImplementedException(); + case DEC_SPEC_TILE_COMP: + throw new NotImplementedException(); default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } } @@ -306,14 +306,14 @@ namespace CSJ2K.j2k.wavelet case DEC_SPEC_COMP_DEF: return compMainDefLevels[n]; - case DEC_SPEC_TILE_DEF: - throw new NotImplementedException(); + case DEC_SPEC_TILE_DEF: + throw new NotImplementedException(); - case DEC_SPEC_TILE_COMP: - throw new NotImplementedException(); + case DEC_SPEC_TILE_COMP: + throw new NotImplementedException(); default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } } diff --git a/CSJ2K/j2k/wavelet/analysis/ForwWTFull.cs b/CSJ2K/j2k/wavelet/analysis/ForwWTFull.cs index fb8a05b2..a13b35b9 100644 --- a/CSJ2K/j2k/wavelet/analysis/ForwWTFull.cs +++ b/CSJ2K/j2k/wavelet/analysis/ForwWTFull.cs @@ -507,7 +507,7 @@ namespace CSJ2K.j2k.wavelet.analysis break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } @@ -1195,7 +1195,7 @@ namespace CSJ2K.j2k.wavelet.analysis break; default: - throw new System.ApplicationException("Internal JJ2000 error"); + throw new System.InvalidOperationException("Internal JJ2000 error"); } if (sb.ulcx - acb0x < 0 || sb.ulcy - acb0y < 0) diff --git a/CSJ2K/j2k/wavelet/analysis/ForwardWT.cs b/CSJ2K/j2k/wavelet/analysis/ForwardWT.cs index 1335eb15..67e5ec5d 100644 --- a/CSJ2K/j2k/wavelet/analysis/ForwardWT.cs +++ b/CSJ2K/j2k/wavelet/analysis/ForwardWT.cs @@ -157,7 +157,7 @@ namespace CSJ2K.j2k.wavelet.analysis System.String str = ""; if (pl.getParameter("Wcboff") == null) { - throw new System.ApplicationException("You must specify an argument to the '-Wcboff' " + "option. See usage with the '-u' option"); + throw new System.InvalidOperationException("You must specify an argument to the '-Wcboff' " + "option. See usage with the '-u' option"); } SupportClass.Tokenizer stk = new SupportClass.Tokenizer(pl.getParameter("Wcboff")); if (stk.Count != 2) @@ -170,7 +170,7 @@ namespace CSJ2K.j2k.wavelet.analysis { cb0x = (System.Int32.Parse(str)); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Bad first parameter for the " + "'-Wcboff' option: " + str); } @@ -184,7 +184,7 @@ namespace CSJ2K.j2k.wavelet.analysis { cb0y = (System.Int32.Parse(str)); } - catch (System.FormatException) + catch (System.FormatException e) { throw new System.ArgumentException("Bad second parameter for the " + "'-Wcboff' option: " + str); } diff --git a/CSJ2K/j2k/wavelet/analysis/SubbandAn.cs b/CSJ2K/j2k/wavelet/analysis/SubbandAn.cs index e0a68fa9..0392f79f 100644 --- a/CSJ2K/j2k/wavelet/analysis/SubbandAn.cs +++ b/CSJ2K/j2k/wavelet/analysis/SubbandAn.cs @@ -386,7 +386,7 @@ namespace CSJ2K.j2k.wavelet.analysis { // There is an error! If all childs have non-negative // l2norm, then this node should have non-negative l2norm - throw new System.ApplicationException("You have found a bug in JJ2000!"); + throw new System.InvalidOperationException("You have found a bug in JJ2000!"); } } else @@ -403,7 +403,7 @@ namespace CSJ2K.j2k.wavelet.analysis { // This is an error! The calcBasisWaveForms() method is never // called on an element with non-negative l2norm - throw new System.ApplicationException("You have found a bug in JJ2000!"); + throw new System.InvalidOperationException("You have found a bug in JJ2000!"); } } @@ -453,7 +453,7 @@ namespace CSJ2K.j2k.wavelet.analysis { // There is an error! If all childs have non-negative // l2norm, then this node should have non-negative l2norm - throw new System.ApplicationException("You have found a bug in JJ2000!"); + throw new System.InvalidOperationException("You have found a bug in JJ2000!"); } } else @@ -466,7 +466,7 @@ namespace CSJ2K.j2k.wavelet.analysis { // This is an error! The assignL2Norm() method is never called on // an element with non-negative l2norm - throw new System.ApplicationException("You have found a bug in JJ2000!"); + throw new System.InvalidOperationException("You have found a bug in JJ2000!"); } } diff --git a/CSJ2K/j2k/wavelet/synthesis/InvWTFull.cs b/CSJ2K/j2k/wavelet/synthesis/InvWTFull.cs index 0e3ba9c3..109780e3 100644 --- a/CSJ2K/j2k/wavelet/synthesis/InvWTFull.cs +++ b/CSJ2K/j2k/wavelet/synthesis/InvWTFull.cs @@ -81,15 +81,9 @@ namespace CSJ2K.j2k.wavelet.synthesis public class InvWTFull:InverseWT { - /// Reference to the ProgressWatch instance if any - private ProgressWatch pw = null; - /// The total number of code-blocks to decode private int cblkToDecode = 0; - /// The number of already decoded code-blocks - private int nDecCblk = 0; - /// the code-block buffer's source i.e. the quantizer private CBlkWTDataSrcDec src; @@ -128,7 +122,6 @@ namespace CSJ2K.j2k.wavelet.synthesis int nc = src.NumComps; reconstructedComps = new DataBlk[nc]; ndl = new int[nc]; - pw = FacilityManager.ProgressWatch; } /// Returns the reversibility of the current subband. It computes @@ -298,10 +291,6 @@ namespace CSJ2K.j2k.wavelet.synthesis } //Reconstruct source image waveletTreeReconstruction(reconstructedComps[c], src.getSynSubbandTree(tIdx, c), c); - if (pw != null && c == src.NumComps - 1) - { - pw.terminateProgressWatch(); - } } if (blk.DataType != dtype) @@ -585,11 +574,7 @@ namespace CSJ2K.j2k.wavelet.synthesis { subbData = src.getInternCodeBlock(c, m, n, sb, subbData); src_data = subbData.Data; - if (pw != null) - { - nDecCblk++; - pw.updateProgressWatch(nDecCblk, null); - } + // Copy the data line by line for (i = subbData.h - 1; i >= 0; i--) { @@ -699,12 +684,6 @@ namespace CSJ2K.j2k.wavelet.synthesis } } // Loop on resolution levels } // Loop on components - nDecCblk = 0; - - if (pw != null) - { - pw.initProgressWatch(0, cblkToDecode, "Decoding tile " + tIdx + "..."); - } } /// Advances to the next tile, in standard scan-line order (by rows then diff --git a/CSJ2K/j2k/wavelet/synthesis/InverseWT.cs b/CSJ2K/j2k/wavelet/synthesis/InverseWT.cs index d8ffdb22..c4a0c6ac 100644 --- a/CSJ2K/j2k/wavelet/synthesis/InverseWT.cs +++ b/CSJ2K/j2k/wavelet/synthesis/InverseWT.cs @@ -48,72 +48,103 @@ using CSJ2K.j2k.decoder; using CSJ2K.j2k.image; using CSJ2K.j2k.util; using CSJ2K.j2k; + namespace CSJ2K.j2k.wavelet.synthesis { - - /// This abstract class extends the WaveletTransform one with the specifics of - /// inverse wavelet transforms. - /// - ///

The image can be reconstructed at different resolution levels. This is - /// controlled by the setResLevel() method. All the image, tile and component - /// dimensions are relative the the resolution level being used. The number of - /// resolution levels indicates the number of wavelet recompositions that will - /// be used, if it is equal as the number of decomposition levels then the full - /// resolution image is reconstructed.

- /// - ///

It is assumed in this class that all tiles and components the same - /// reconstruction resolution level. If that where not the case the - /// implementing class should have additional data structures to store those - /// values for each tile. However, the 'recResLvl' member variable always - /// contain the values applicable to the current tile, since many methods - /// implemented here rely on them.

- /// - ///
- public abstract class InverseWT:InvWTAdapter, BlkImgDataSrc - { - - /// Initializes this object with the given source of wavelet - /// coefficients. It initializes the resolution level for full resolutioin - /// reconstruction (i.e. the maximum resolution available from the 'src' - /// source). - /// - ///

It is assumed here that all tiles and components have the same - /// reconstruction resolution level. If that was not the case it should be - /// the value for the current tile of the source.

- /// - ///
- /// from where the wavelet coefficinets should be obtained. - /// - /// - /// The decoder specifications - /// - /// - public InverseWT(MultiResImgData src, DecoderSpecs decSpec):base(src, decSpec) - { - } - - /// Creates an InverseWT object that works on the data type of the source, - /// with the special additional parameters from the parameter - /// list. Currently the parameter list is ignored since no special - /// parameters can be specified for the inverse wavelet transform yet. - /// - /// - /// The source of data for the inverse wavelet - /// transform. - /// - /// - /// The parameter list containing parameters applicable to the - /// inverse wavelet transform (other parameters can also be present). - /// - /// - public static InverseWT createInstance(CBlkWTDataSrcDec src, DecoderSpecs decSpec) - { - - // full page wavelet transform - return new InvWTFull(src, decSpec); - } - public abstract int getFixedPoint(int param1); - public abstract CSJ2K.j2k.image.DataBlk getInternCompData(CSJ2K.j2k.image.DataBlk param1, int param2); - public abstract CSJ2K.j2k.image.DataBlk getCompData(CSJ2K.j2k.image.DataBlk param1, int param2); - } -} \ No newline at end of file + + /// This abstract class extends the WaveletTransform one with the specifics of + /// inverse wavelet transforms. + /// + ///

The image can be reconstructed at different resolution levels. This is + /// controlled by the setResLevel() method. All the image, tile and component + /// dimensions are relative the the resolution level being used. The number of + /// resolution levels indicates the number of wavelet recompositions that will + /// be used, if it is equal as the number of decomposition levels then the full + /// resolution image is reconstructed.

+ /// + ///

It is assumed in this class that all tiles and components the same + /// reconstruction resolution level. If that where not the case the + /// implementing class should have additional data structures to store those + /// values for each tile. However, the 'recResLvl' member variable always + /// contain the values applicable to the current tile, since many methods + /// implemented here rely on them.

+ /// + ///
+ public abstract class InverseWT : InvWTAdapter, BlkImgDataSrc + { + + /// Initializes this object with the given source of wavelet + /// coefficients. It initializes the resolution level for full resolutioin + /// reconstruction (i.e. the maximum resolution available from the 'src' + /// source). + /// + ///

It is assumed here that all tiles and components have the same + /// reconstruction resolution level. If that was not the case it should be + /// the value for the current tile of the source.

+ /// + ///
+ /// from where the wavelet coefficinets should be obtained. + /// + /// + /// The decoder specifications + /// + /// + public InverseWT(MultiResImgData src, DecoderSpecs decSpec) + : base(src, decSpec) + { + } + + /// Creates an InverseWT object that works on the data type of the source, + /// with the special additional parameters from the parameter + /// list. Currently the parameter list is ignored since no special + /// parameters can be specified for the inverse wavelet transform yet. + /// + /// + /// The source of data for the inverse wavelet + /// transform. + /// + /// + /// The parameter list containing parameters applicable to the + /// inverse wavelet transform (other parameters can also be present). + /// + /// + public static InverseWT createInstance(CBlkWTDataSrcDec src, DecoderSpecs decSpec) + { + + // full page wavelet transform + return new InvWTFull(src, decSpec); + } + + public abstract int getFixedPoint(int c); + + public abstract DataBlk getInternCompData(DataBlk blk, int c); + + public abstract DataBlk getCompData(DataBlk blk, int c); + + /// Closes the underlying file or network connection from where the + /// image data is being read. + /// + /// + /// If an I/O error occurs. + /// + public void close() + { + // Do nothing. + } + + /// Returns true if the data read was originally signed in the specified + /// component, false if not. + /// + /// + /// The index of the component, from 0 to C-1. + /// + /// + /// true if the data was originally signed, false if not. + /// + /// + public bool isOrigSigned(int c) + { + return false; + } + } +}