/// <summary> Initializes the source of entropy coded data. /// /// </summary> /// <param name="src">The source of entropy coded data. /// /// </param> /// <param name="ln">The number of layers to create /// /// </param> /// <param name="pt">The progressive type, as defined in 'ProgressionType'. /// /// </param> /// <param name="bw">The packet bit stream writer. /// /// </param> /// <seealso cref="ProgressionType"> /// /// </seealso> public PostCompRateAllocator(CodedCBlkDataSrcEnc src, int nl, CodestreamWriter bw, EncoderSpecs encSpec) : base(src) { this.src = src; this.encSpec = encSpec; num_Layers = nl; bsWriter = bw; }
/// <summary> Calculates the maximum amount of magnitude bits for each /// tile-component, and stores it in the 'maxMagBits' array. This is called /// by the constructor /// /// </summary> /// <param name="encSpec">The encoder specifications for addition of roi specs /// /// </param> private void calcMaxMagBits(EncoderSpecs encSpec) { int tmp; MaxShiftSpec rois = encSpec.rois; int nt = src.getNumTiles(); int nc = src.NumComps; maxMagBits = new int[nt][]; for (int i = 0; i < nt; i++) { maxMagBits[i] = new int[nc]; } src.setTile(0, 0); for (int t = 0; t < nt; t++) { for (int c = nc - 1; c >= 0; c--) { tmp = src.getMaxMagBits(c); maxMagBits[t][c] = tmp; rois.setTileCompVal(t, c, (System.Object)tmp); } if (t < nt - 1) { src.nextTile(); } } // Reset to current initial tile position src.setTile(0, 0); }
/// <summary> Creates a ROIScaler object. The Quantizer is the source of data to /// scale. /// /// <p>The ROI Scaler creates a ROIMaskGenerator depending on what ROI /// information is in the ParameterList. If only rectangular ROI are used, /// the fast mask generator for rectangular ROI can be used.</p> /// /// </summary> /// <param name="src">The source of data to scale /// /// </param> /// <param name="pl">The parameter list (or options). /// /// </param> /// <param name="encSpec">The encoder specifications for addition of roi specs /// /// </param> /// <exception cref="IllegalArgumentException">If an error occurs while parsing /// the options in 'pl' /// /// </exception> public static ROIScaler createInstance(Quantizer src, ParameterList pl, EncoderSpecs encSpec) { System.Collections.ArrayList roiVector = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); ROIMaskGenerator maskGen = null; // Check parameters pl.checkList(OPT_PREFIX, CSJ2K.j2k.util.ParameterList.toNameArray(pinfo)); // Get parameters and check if there are and ROIs specified System.String roiopt = pl.getParameter("Rroi"); if (roiopt == null) { // No ROIs specified! Create ROIScaler with no mask generator return(new ROIScaler(src, null, false, -1, false, encSpec)); } // Check if the lowest resolution levels should belong to the ROI int sLev = pl.getIntParameter("Rstart_level"); // Check if the ROIs are block-aligned bool useBlockAligned = pl.getBooleanParameter("Ralign"); // Check if generic mask generation is specified bool onlyRect = !pl.getBooleanParameter("Rno_rect"); // Parse the ROIs parseROIs(roiopt, src.NumComps, roiVector); ROI[] roiArray = new ROI[roiVector.Count]; roiVector.CopyTo(roiArray); // If onlyRect has been forced, check if there are any non-rectangular // ROIs specified. Currently, only the presence of circular ROIs will // make this false if (onlyRect) { for (int i = roiArray.Length - 1; i >= 0; i--) { if (!roiArray[i].rect) { onlyRect = false; break; } } } if (onlyRect) { // It's possible to use the fast ROI mask generation when only // rectangular ROIs are specified. maskGen = new RectROIMaskGenerator(roiArray, src.NumComps); } else { // It's necessary to use the generic mask generation maskGen = new ArbROIMaskGenerator(roiArray, src.NumComps, src); } return(new ROIScaler(src, maskGen, true, sLev, useBlockAligned, encSpec)); }
public static byte[] EncodeJPEG(Image jpgImage) { Tiler imgtiler; ForwCompTransf fctransf; ImgDataConverter converter; EncoderSpecs encSpec; ForwardWT dwt; Quantizer quant; ROIScaler rois; EntropyCoder ecoder; PostCompRateAllocator ralloc; HeaderEncoder headenc; CodestreamWriter bwriter; float rate = Single.MaxValue; ImgReaderGDI imgsrc = new ImgReaderGDI(jpgImage); imgtiler = new Tiler(imgsrc, 0, 0, 0, 0, jpgImage.Width, jpgImage.Height); int ntiles = imgtiler.getNumTiles(); encSpec = new EncoderSpecs(ntiles, 3, imgsrc, pl); fctransf = new ForwCompTransf(imgtiler, encSpec); converter = new ImgDataConverter(fctransf); dwt = ForwardWT.createInstance(converter, pl, encSpec); quant = Quantizer.createInstance(dwt, encSpec); rois = ROIScaler.createInstance(quant, pl, encSpec); ecoder = EntropyCoder.createInstance(rois, pl, encSpec.cblks, encSpec.pss, encSpec.bms, encSpec.mqrs, encSpec.rts, encSpec.css, encSpec.sss, encSpec.lcs, encSpec.tts); using (MemoryStream stream = new MemoryStream()) { bwriter = new FileCodestreamWriter(stream, Int32.MaxValue); ralloc = PostCompRateAllocator.createInstance(ecoder, pl, rate, bwriter, encSpec); headenc = new HeaderEncoder(imgsrc, new bool[3], dwt, imgtiler, encSpec, rois, ralloc, pl); ralloc.HeaderEncoder = headenc; headenc.encodeMainHeader(); ralloc.initialize(); headenc.reset(); headenc.encodeMainHeader(); bwriter.commitBitstreamHeader(headenc); ralloc.runAndWrite(); bwriter.close(); return(stream.ToArray()); } }
/// <summary> Initializes this object with the given source of image data and with /// all the decompositon parameters /// /// </summary> /// <param name="src">From where the image data should be obtained. /// /// </param> /// <param name="encSpec">The encoder specifications /// /// </param> /// <param name="cb0x">The horizontal coordinate of the code-block partition /// origin on the reference grid. /// /// </param> /// <param name="cb0y">The vertical coordinate of the code-block partition origin /// on the reference grid. /// /// </param> /// <seealso cref="ForwardWT"> /// /// </seealso> public ForwWTFull(BlkImgDataSrc src, EncoderSpecs encSpec, int cb0x, int cb0y) : base(src) { this.src = src; this.cb0x = cb0x; this.cb0y = cb0y; this.dls = encSpec.dls; this.filters = encSpec.wfs; this.cblks = encSpec.cblks; this.pss = encSpec.pss; int ncomp = src.NumComps; int ntiles = src.getNumTiles(); currentSubband = new SubbandAn[ncomp]; decomposedComps = new DataBlk[ncomp]; subbTrees = new SubbandAn[ntiles][]; for (int i = 0; i < ntiles; i++) { subbTrees[i] = new SubbandAn[ncomp]; } lastn = new int[ncomp]; lastm = new int[ncomp]; }
/// <summary> Creates a PostCompRateAllocator object for the appropriate rate /// allocation parameters in the parameter list 'pl', having 'src' as the /// source of entropy coded data, 'rate' as the target bitrate and 'bw' as /// the bit stream writer object. /// /// </summary> /// <param name="src">The source of entropy coded data. /// /// </param> /// <param name="pl">The parameter lis (or options). /// /// </param> /// <param name="rate">The target bitrate for the rate allocation /// /// </param> /// <param name="bw">The bit stream writer object, where the bit stream data will /// be written. /// /// </param> public static PostCompRateAllocator createInstance(CodedCBlkDataSrcEnc src, ParameterList pl, float rate, CodestreamWriter bw, EncoderSpecs encSpec) { // Check parameters pl.checkList(OPT_PREFIX, CSJ2K.j2k.util.ParameterList.toNameArray(pinfo)); // Construct the layer specification from the 'Alayers' option LayersInfo lyrs = parseAlayers(pl.getParameter("Alayers"), rate); int nTiles = encSpec.nTiles; int nComp = encSpec.nComp; int numLayers = lyrs.TotNumLayers; // Parse the progressive type encSpec.pocs = new ProgressionSpec(nTiles, nComp, numLayers, encSpec.dls, ModuleSpec.SPEC_TYPE_TILE_COMP, pl); return(new EBCOTRateAllocator(src, lyrs, bw, encSpec, pl)); }
/// <summary> Initializes the source of wavelet transform coefficients. The /// constructor takes information on whether the quantizer is in /// reversible, derived or expounded mode. If the quantizer is reversible /// the value of 'derived' is ignored. If the source data is not integer /// (int) then the quantizer can not be reversible. /// /// <p>After initializing member attributes, getAnSubbandTree is called for /// all components setting the 'stepWMSE' for all subbands in the current /// tile.</p> /// /// </summary> /// <param name="src">The source of wavelet transform coefficients. /// /// </param> /// <param name="encSpec">The encoder specifications /// /// </param> public StdQuantizer(CBlkWTDataSrc src, EncoderSpecs encSpec) : base(src) { qts = encSpec.qts; qsss = encSpec.qsss; gbs = encSpec.gbs; }
/// <summary> Creates a ForwardWT object with the specified filters, and with other /// options specified in the parameter list 'pl'. /// /// </summary> /// <param name="src">The source of data to be transformed /// /// </param> /// <param name="pl">The parameter list (or options). /// /// </param> /// <param name="kers">The encoder specifications. /// /// </param> /// <returns> A new ForwardWT object with the specified filters and options /// from 'pl'. /// /// </returns> /// <exception cref="IllegalArgumentException">If mandatory parameters are missing /// or if invalid values are given. /// /// </exception> public static ForwardWT createInstance(BlkImgDataSrc src, ParameterList pl, EncoderSpecs encSpec) { int deflev; // defdec removed //System.String decompstr; //System.String wtstr; //System.String pstr; //SupportClass.StreamTokenizerSupport stok; //SupportClass.Tokenizer strtok; //int prefx, prefy; // Partitioning reference point coordinates // Check parameters pl.checkList(OPT_PREFIX, CSJ2K.j2k.util.ParameterList.toNameArray(pinfo)); deflev = ((System.Int32)encSpec.dls.getDefault()); // Code-block partition origin System.String str = ""; if (pl.getParameter("Wcboff") == null) { 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) { throw new System.ArgumentException("'-Wcboff' option needs two" + " arguments. See usage with " + "the '-u' option."); } int cb0x = 0; str = stk.NextToken(); try { cb0x = (System.Int32.Parse(str)); } catch (System.FormatException e) { throw new System.ArgumentException("Bad first parameter for the " + "'-Wcboff' option: " + str); } if (cb0x < 0 || cb0x > 1) { throw new System.ArgumentException("Invalid horizontal " + "code-block partition origin."); } int cb0y = 0; str = stk.NextToken(); try { cb0y = (System.Int32.Parse(str)); } catch (System.FormatException e) { throw new System.ArgumentException("Bad second parameter for the " + "'-Wcboff' option: " + str); } if (cb0y < 0 || cb0y > 1) { throw new System.ArgumentException("Invalid vertical " + "code-block partition origin."); } if (cb0x != 0 || cb0y != 0) { FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Code-blocks partition origin is " + "different from (0,0). This is defined in JPEG 2000" + " part 2 and may be not supported by all JPEG 2000 " + "decoders."); } return(new ForwWTFull(src, encSpec, cb0x, cb0y)); }
/// <summary> Constructs a new ForwCompTransf object that operates on the specified /// source of image data. /// /// </summary> /// <param name="imgSrc">The source from where to get the data to be transformed /// /// </param> /// <param name="encSpec">The encoder specifications /// /// </param> /// <seealso cref="BlkImgDataSrc"> /// /// </seealso> public ForwCompTransf(BlkImgDataSrc imgSrc, EncoderSpecs encSpec) : base(imgSrc) { this.cts = encSpec.cts; this.wfs = encSpec.wfs; src = imgSrc; }
/// <summary> Constructor of the ROI scaler, takes a Quantizer as source of data to /// scale. /// /// </summary> /// <param name="src">The quantizer that is the source of data. /// /// </param> /// <param name="mg">The mask generator that will be used for all components /// /// </param> /// <param name="roi">Flag indicating whether there are rois specified. /// /// </param> /// <param name="sLev">The resolution levels that belong entirely to ROI /// /// </param> /// <param name="uba">Flag indicating whether block aligning is used. /// /// </param> /// <param name="encSpec">The encoder specifications for addition of roi specs /// /// </param> public ROIScaler(Quantizer src, ROIMaskGenerator mg, bool roi, int sLev, bool uba, EncoderSpecs encSpec) : base(src) { this.src = src; this.roi = roi; this.useStartLevel = sLev; if (roi) { // If there is no ROI, no need to do this this.mg = mg; roiMask = new DataBlkInt(); calcMaxMagBits(encSpec); blockAligned = uba; } }
/// <summary> Creates a Quantizer object for the appropriate type of quantization /// specified in the options in the parameter list 'pl', and having 'src' /// as the source of data to be quantized. The 'rev' flag indicates if the /// quantization should be reversible. /// /// NOTE: At the moment only sources of wavelet data that implement the /// 'CBlkWTDataSrc' interface are supported. /// /// </summary> /// <param name="src">The source of data to be quantized /// /// </param> /// <param name="encSpec">Encoder specifications /// /// </param> /// <exception cref="IllegalArgumentException">If an error occurs while parsing /// the options in 'pl' /// /// </exception> public static Quantizer createInstance(CBlkWTDataSrc src, EncoderSpecs encSpec) { // Instantiate quantizer return(new StdQuantizer(src, encSpec)); }