public virtual void writeResPosCompLy(int t, int rs, int re, int cs, int ce, int[][] lys, int lye)
{
bool sopUsed; // Should SOP markers be used ?
bool ephUsed; // Should EPH markers be used ?
int nc = src.NumComps;
int mrl;
SubbandAn sb;
float threshold;
BitOutputBuffer hBuff = null;
byte[] bBuff = null;
// Computes current tile offset in the reference grid
Coord nTiles = src.getNumTiles(null);
Coord tileI = src.getTile(null);
int x0siz = src.ImgULX;
int y0siz = src.ImgULY;
int xsiz = x0siz + src.ImgWidth;
int ysiz = y0siz + src.ImgHeight;
int xt0siz = src.TilePartULX;
int yt0siz = src.TilePartULY;
int xtsiz = src.NomTileWidth;
int ytsiz = src.NomTileHeight;
int tx0 = (tileI.x == 0)?x0siz:xt0siz + tileI.x * xtsiz;
int ty0 = (tileI.y == 0)?y0siz:yt0siz + tileI.y * ytsiz;
int tx1 = (tileI.x != nTiles.x - 1)?xt0siz + (tileI.x + 1) * xtsiz:xsiz;
int ty1 = (tileI.y != nTiles.y - 1)?yt0siz + (tileI.y + 1) * ytsiz:ysiz;
// Get precinct information (number,distance between two consecutive
// precincts in the reference grid) in each component and resolution
// level
PrecInfo prec; // temporary variable
int p; // Current precinct index
int gcd_x = 0; // Horiz. distance between 2 precincts in the ref. grid
int gcd_y = 0; // Vert. distance between 2 precincts in the ref. grid
int nPrec = 0; // Total number of found precincts
int[][] nextPrec = new int[ce][]; // Next precinct index in each
// component and resolution level
int minlys = 100000; // minimum layer start index of each component
int minx = tx1; // Horiz. offset of the second precinct in the
// reference grid
int miny = ty1; // Vert. offset of the second precinct in the
// reference grid.
int maxx = tx0; // Max. horiz. offset of precincts in the ref. grid
int maxy = ty0; // Max. vert. offset of precincts in the ref. grid
for (int c = cs; c < ce; c++)
{
mrl = src.getAnSubbandTree(t, c).resLvl;
nextPrec[c] = new int[mrl + 1];
for (int r = rs; r < re; r++)
{
if (r > mrl)
continue;
if (r < lys[c].Length && lys[c][r] < minlys)
{
minlys = lys[c][r];
}
p = numPrec[t][c][r].y * numPrec[t][c][r].x - 1;
for (; p >= 0; p--)
{
prec = pktEnc.getPrecInfo(t, c, r, p);
if (prec.rgulx != tx0)
{
if (prec.rgulx < minx)
minx = prec.rgulx;
if (prec.rgulx > maxx)
maxx = prec.rgulx;
}
if (prec.rguly != ty0)
{
if (prec.rguly < miny)
miny = prec.rguly;
if (prec.rguly > maxy)
maxy = prec.rguly;
}
if (nPrec == 0)
{
gcd_x = prec.rgw;
gcd_y = prec.rgh;
}
else
{
gcd_x = MathUtil.gcd(gcd_x, prec.rgw);
gcd_y = MathUtil.gcd(gcd_y, prec.rgh);
}
nPrec++;
} // precincts
} // resolution levels
} // components
if (nPrec == 0)
{
throw new System.InvalidOperationException("Image cannot have no precinct");
}
int pyend = (maxy - miny) / gcd_y + 1;
int pxend = (maxx - minx) / gcd_x + 1;
int x, y;
for (int r = rs; r < re; r++)
{
// Resolution levels
y = ty0;
x = tx0;
for (int py = 0; py <= pyend; py++)
{
// Vertical precincts
for (int px = 0; px <= pxend; px++)
{
// Horiz. precincts
for (int c = cs; c < ce; c++)
{
// Components
mrl = src.getAnSubbandTree(t, c).resLvl;
if (r > mrl)
continue;
if (nextPrec[c][r] >= numPrec[t][c][r].x * numPrec[t][c][r].y)
{
continue;
}
prec = pktEnc.getPrecInfo(t, c, r, nextPrec[c][r]);
if ((prec.rgulx != x) || (prec.rguly != y))
{
continue;
}
for (int l = minlys; l < lye; l++)
{
if (r >= lys[c].Length)
continue;
if (l < lys[c][r])
continue;
// set boolean sopUsed here (SOP markers)
sopUsed = ((System.String) encSpec.sops.getTileDef(t)).Equals("on");
// set boolean ephUsed here (EPH markers)
ephUsed = ((System.String) encSpec.ephs.getTileDef(t)).Equals("on");
sb = src.getAnSubbandTree(t, c);
for (int i = mrl; i > r; i--)
{
sb = sb.subb_LL;
}
threshold = layers[l].rdThreshold;
findTruncIndices(l, c, r, t, sb, threshold, nextPrec[c][r]);
hBuff = pktEnc.encodePacket(l + 1, c, r, t, cblks[t][c][r], truncIdxs[t][l][c][r], hBuff, bBuff, nextPrec[c][r]);
if (pktEnc.PacketWritable)
{
bsWriter.writePacketHead(hBuff.Buffer, hBuff.Length, false, sopUsed, ephUsed);
bsWriter.writePacketBody(pktEnc.LastBodyBuf, pktEnc.LastBodyLen, false, pktEnc.ROIinPkt, pktEnc.ROILen);
}
} // layers
nextPrec[c][r]++;
} // Components
if (px != pxend)
{
x = minx + px * gcd_x;
}
else
{
x = tx0;
}
} // Horizontal precincts
if (py != pyend)
{
y = miny + py * gcd_y;
}
else
{
y = ty0;
}
} // Vertical precincts
} // Resolution levels
// Check that all precincts have been written
for (int c = cs; c < ce; c++)
{
mrl = src.getAnSubbandTree(t, c).resLvl;
for (int r = rs; r < re; r++)
{
if (r > mrl)
continue;
if (nextPrec[c][r] < numPrec[t][c][r].x * numPrec[t][c][r].y - 1)
{
throw new System.InvalidOperationException("JJ2000 bug: One precinct at least has " + "not been written for resolution level " + r + " of component " + c + " in tile " + t + ".");
}
}
}
}