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