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(); } }