/// <summary> /// Create a copy by value. /// </summary> /// <returns> /// The newly created copy /// </returns> public IWBlock Duplicate() { IWBlock retval = null; try { retval = new IWBlock { _pdata = this._pdata }; short[][][] pdata = (short[][][])this._pdata.Clone(); ((IWBlock)retval)._pdata = pdata; for (int i = 0; i < pdata.Length; i++) { if (pdata[i] != null) { pdata[i] = (short[][])pdata[i].Clone(); for (int j = 0; j < pdata[i].Length; j++) { if (pdata[i][j] != null) { pdata[i][j] = new short[pdata[i][j].Length]; pdata[i][j].CopyTo(pdata[i][j], 0); } } } } } catch (Exception ignored) { } return retval; }
public IWMap Init(int w, int h) { Iw = w; Ih = h; Bw = ((w + 32) - 1) & unchecked ((int)0xffffffe0); Bh = ((h + 32) - 1) & unchecked ((int)0xffffffe0); Nb = (Bw * Bh) / 1024; Blocks = new IWBlock[Nb]; for (int i = 0; i < Blocks.Length; i++) { Blocks[i] = new IWBlock(); } return(this); }
/// <summary> /// Create a copy by value. /// </summary> /// <returns> /// The newly created copy /// </returns> public IWBlock Duplicate() { IWBlock retval = null; try { retval = new IWBlock { _pdata = this._pdata }; short[][][] pdata = (short[][][])this._pdata.Clone(); ((IWBlock)retval)._pdata = pdata; for (int i = 0; i < pdata.Length; i++) { if (pdata[i] != null) { pdata[i] = (short[][])pdata[i].Clone(); for (int j = 0; j < pdata[i].Length; j++) { if (pdata[i][j] != null) { pdata[i][j] = new short[pdata[i][j].Length]; pdata[i][j].CopyTo(pdata[i][j], 0); } } } } } catch (Exception ignored) { } return(retval); }
private void DecodeBuckets(ZPCodec zp, int bit, int band, IWBlock blk, int fbucket, int nbucket) { int thres = _quantHi[band]; int bbstate = 0; sbyte[] cstate = _coeffstate; int cidx = 0; for (int buckno = 0; buckno < nbucket; ) { int bstatetmp = 0; short[] pcoeff = blk.GetBlock(fbucket + buckno); if (pcoeff == null) { bstatetmp = 8; } else { for (int i = 0; i < 16; i++) { int cstatetmp = cstate[cidx + i] & 1; if (cstatetmp == 0) { if (pcoeff[i] != 0) { cstatetmp |= 2; } else { cstatetmp |= 8; } } cstate[cidx + i] = (sbyte)cstatetmp; bstatetmp |= cstatetmp; } } _bucketstate[buckno] = (sbyte)bstatetmp; bbstate |= bstatetmp; buckno++; cidx += 16; } if ((nbucket < 16) || ((bbstate & 2) != 0)) { bbstate |= 4; } else if ((bbstate & 8) != 0) { if (zp.Decoder(_ctxRoot) != 0) { bbstate |= 4; } } if ((bbstate & 4) != 0) { for (int buckno = 0; buckno < nbucket; buckno++) { if ((_bucketstate[buckno] & 8) != 0) { int ctx = 0; //if (!DjVuOptions.NOCTX_BUCKET_UPPER && (band > 0)) if ((band > 0)) { int k = (fbucket + buckno) << 2; short[] b = blk.GetBlock(k >> 4); if (b != null) { k &= 0xf; if (b[k] != 0) { ctx++; } if (b[k + 1] != 0) { ctx++; } if (b[k + 2] != 0) { ctx++; } if ((ctx < 3) && (b[k + 3] != 0)) { ctx++; } } } //if (!DjVuOptions.NOCTX_BUCKET_ACTIVE && ((bbstate & 2) != 0)) if (((bbstate & 2) != 0)) { ctx |= 4; } if (zp.Decoder(_ctxBucket[band][ctx]) != 0) { _bucketstate[buckno] |= 4; } } } } if ((bbstate & 4) != 0) { cstate = _coeffstate; cidx = 0; for (int buckno = 0; buckno < nbucket; ) { if ((_bucketstate[buckno] & 4) != 0) { short[] pcoeff = blk.GetBlock(fbucket + buckno); if (pcoeff == null) { pcoeff = blk.GetInitializedBlock(fbucket + buckno); for (int i = 0; i < 16; i++) { if ((cstate[cidx + i] & 1) == 0) { cstate[cidx + i] = 8; } } } int gotcha = 0; int maxgotcha = 7; //if (!DjVuOptions.NOCTX_EXPECT) { for (int i = 0; i < 16; i++) { if ((cstate[cidx + i] & 8) != 0) { gotcha++; } } } for (int i = 0; i < 16; i++) { if ((cstate[cidx + i] & 8) != 0) { if (band == 0) { thres = _quantLo[i]; } int ctx = 0; //if (!DjVuOptions.NOCTX_EXPECT) { if (gotcha >= maxgotcha) { ctx = maxgotcha; } else { ctx = gotcha; } } //if (!DjVuOptions.NOCTX_ACTIVE && ((bucketstate[buckno] & 2) != 0)) if (((_bucketstate[buckno] & 2) != 0)) { ctx |= 8; } if (zp.Decoder(_ctxStart[ctx]) != 0) { cstate[cidx + i] |= 4; int halfthres = thres >> 1; int coeff = (thres + halfthres) - (halfthres >> 2); if (zp.IWDecoder() != 0) { pcoeff[i] = (short)(-coeff); } else { pcoeff[i] = (short)coeff; } } //if (!DjVuOptions.NOCTX_EXPECT) { if ((cstate[cidx + i] & 4) != 0) { gotcha = 0; } else if (gotcha > 0) { gotcha--; } } } } } buckno++; cidx += 16; } } if ((bbstate & 2) != 0) { cstate = _coeffstate; cidx = 0; for (int buckno = 0; buckno < nbucket; ) { if ((_bucketstate[buckno] & 2) != 0) { short[] pcoeff = blk.GetBlock(fbucket + buckno); for (int i = 0; i < 16; i++) { if ((cstate[cidx + i] & 2) != 0) { int coeff = pcoeff[i]; if (coeff < 0) { coeff = -coeff; } if (band == 0) { thres = _quantLo[i]; } if (coeff <= (3 * thres)) { coeff += (thres >> 2); if (zp.Decoder(_ctxMant) != 0) { coeff += (thres >> 1); } else { coeff = (coeff - thres) + (thres >> 1); } } else { if (zp.IWDecoder() != 0) { coeff += (thres >> 1); } else { coeff = (coeff - thres) + (thres >> 1); } } if (pcoeff[i] > 0) { pcoeff[i] = (short)coeff; } else { pcoeff[i] = (short)(-coeff); } } } } buckno++; cidx += 16; } } }
public IWMap Init(int w, int h) { Iw = w; Ih = h; Bw = ((w + 32) - 1) & unchecked((int)0xffffffe0); Bh = ((h + 32) - 1) & unchecked((int)0xffffffe0); Nb = (Bw * Bh) / 1024; Blocks = new IWBlock[Nb]; for (int i = 0; i < Blocks.Length; i++) { Blocks[i] = new IWBlock(); } return this; }
private void DecodeBuckets(ZPCodec zp, int bit, int band, IWBlock blk, int fbucket, int nbucket) { int thres = _quantHi[band]; int bbstate = 0; sbyte[] cstate = _coeffstate; int cidx = 0; for (int buckno = 0; buckno < nbucket;) { int bstatetmp = 0; short[] pcoeff = blk.GetBlock(fbucket + buckno); if (pcoeff == null) { bstatetmp = 8; } else { for (int i = 0; i < 16; i++) { int cstatetmp = cstate[cidx + i] & 1; if (cstatetmp == 0) { if (pcoeff[i] != 0) { cstatetmp |= 2; } else { cstatetmp |= 8; } } cstate[cidx + i] = (sbyte)cstatetmp; bstatetmp |= cstatetmp; } } _bucketstate[buckno] = (sbyte)bstatetmp; bbstate |= bstatetmp; buckno++; cidx += 16; } if ((nbucket < 16) || ((bbstate & 2) != 0)) { bbstate |= 4; } else if ((bbstate & 8) != 0) { if (zp.Decoder(_ctxRoot) != 0) { bbstate |= 4; } } if ((bbstate & 4) != 0) { for (int buckno = 0; buckno < nbucket; buckno++) { if ((_bucketstate[buckno] & 8) != 0) { int ctx = 0; //if (!DjVuOptions.NOCTX_BUCKET_UPPER && (band > 0)) if ((band > 0)) { int k = (fbucket + buckno) << 2; short[] b = blk.GetBlock(k >> 4); if (b != null) { k &= 0xf; if (b[k] != 0) { ctx++; } if (b[k + 1] != 0) { ctx++; } if (b[k + 2] != 0) { ctx++; } if ((ctx < 3) && (b[k + 3] != 0)) { ctx++; } } } //if (!DjVuOptions.NOCTX_BUCKET_ACTIVE && ((bbstate & 2) != 0)) if (((bbstate & 2) != 0)) { ctx |= 4; } if (zp.Decoder(_ctxBucket[band][ctx]) != 0) { _bucketstate[buckno] |= 4; } } } } if ((bbstate & 4) != 0) { cstate = _coeffstate; cidx = 0; for (int buckno = 0; buckno < nbucket;) { if ((_bucketstate[buckno] & 4) != 0) { short[] pcoeff = blk.GetBlock(fbucket + buckno); if (pcoeff == null) { pcoeff = blk.GetInitializedBlock(fbucket + buckno); for (int i = 0; i < 16; i++) { if ((cstate[cidx + i] & 1) == 0) { cstate[cidx + i] = 8; } } } int gotcha = 0; int maxgotcha = 7; //if (!DjVuOptions.NOCTX_EXPECT) { for (int i = 0; i < 16; i++) { if ((cstate[cidx + i] & 8) != 0) { gotcha++; } } } for (int i = 0; i < 16; i++) { if ((cstate[cidx + i] & 8) != 0) { if (band == 0) { thres = _quantLo[i]; } int ctx = 0; //if (!DjVuOptions.NOCTX_EXPECT) { if (gotcha >= maxgotcha) { ctx = maxgotcha; } else { ctx = gotcha; } } //if (!DjVuOptions.NOCTX_ACTIVE && ((bucketstate[buckno] & 2) != 0)) if (((_bucketstate[buckno] & 2) != 0)) { ctx |= 8; } if (zp.Decoder(_ctxStart[ctx]) != 0) { cstate[cidx + i] |= 4; int halfthres = thres >> 1; int coeff = (thres + halfthres) - (halfthres >> 2); if (zp.IWDecoder() != 0) { pcoeff[i] = (short)(-coeff); } else { pcoeff[i] = (short)coeff; } } //if (!DjVuOptions.NOCTX_EXPECT) { if ((cstate[cidx + i] & 4) != 0) { gotcha = 0; } else if (gotcha > 0) { gotcha--; } } } } } buckno++; cidx += 16; } } if ((bbstate & 2) != 0) { cstate = _coeffstate; cidx = 0; for (int buckno = 0; buckno < nbucket;) { if ((_bucketstate[buckno] & 2) != 0) { short[] pcoeff = blk.GetBlock(fbucket + buckno); for (int i = 0; i < 16; i++) { if ((cstate[cidx + i] & 2) != 0) { int coeff = pcoeff[i]; if (coeff < 0) { coeff = -coeff; } if (band == 0) { thres = _quantLo[i]; } if (coeff <= (3 * thres)) { coeff += (thres >> 2); if (zp.Decoder(_ctxMant) != 0) { coeff += (thres >> 1); } else { coeff = (coeff - thres) + (thres >> 1); } } else { if (zp.IWDecoder() != 0) { coeff += (thres >> 1); } else { coeff = (coeff - thres) + (thres >> 1); } } if (pcoeff[i] > 0) { pcoeff[i] = (short)coeff; } else { pcoeff[i] = (short)(-coeff); } } } } buckno++; cidx += 16; } } }
public void Image(int subsample, Rectangle rect, int index, sbyte[] img8, int rowsize, int pixsep, bool fast) { int nlevel = 0; while ((nlevel < 5) && ((32 >> nlevel) > subsample)) { nlevel++; } int boxsize = 1 << nlevel; if (subsample != (32 >> nlevel)) { throw new ArgumentException("(Map::image) Unsupported subsampling factor"); } if (rect.Empty) { throw new ArgumentException("(Map::image) Rectangle is empty"); } Rectangle irect = new Rectangle(0, 0, ((Iw + subsample) - 1) / subsample, ((Ih + subsample) - 1) / subsample); if ((rect.Right < 0) || (rect.Bottom < 0) || (rect.Left > irect.Left) || (rect.Top > irect.Top)) { throw new ArgumentException("(Map::image) Rectangle is out of bounds: " + rect.Right + "," + rect.Bottom + "," + rect.Left + "," + rect.Top + "," + irect.Left + "," + irect.Top); } Rectangle[] needed = new Rectangle[8]; Rectangle[] recomp = new Rectangle[8]; for (int i = 0; i < 8;) { needed[i] = new Rectangle(); recomp[i++] = new Rectangle(); } int r = 1; needed[nlevel] = (Rectangle)rect.Duplicate(); recomp[nlevel] = (Rectangle)rect.Duplicate(); for (int i = nlevel - 1; i >= 0; i--) { needed[i] = recomp[i + 1]; needed[i].Inflate(3 * r, 3 * r); needed[i].Intersect(needed[i], irect); r += r; recomp[i].Right = ((needed[i].Right + r) - 1) & ~(r - 1); recomp[i].Left = needed[i].Left & ~(r - 1); recomp[i].Bottom = ((needed[i].Bottom + r) - 1) & ~(r - 1); recomp[i].Top = needed[i].Top & ~(r - 1); } Rectangle work = new Rectangle(); work.Right = needed[0].Right & ~(boxsize - 1); work.Bottom = needed[0].Bottom & ~(boxsize - 1); work.Left = ((needed[0].Left - 1) & ~(boxsize - 1)) + boxsize; work.Top = ((needed[0].Top - 1) & ~(boxsize - 1)) + boxsize; int dataw = work.Width; short[] data = new short[dataw * work.Height]; int blkw = Bw >> 5; int lblock = ((work.Bottom >> nlevel) * blkw) + (work.Right >> nlevel); short[] liftblock = new short[1024]; for (int by = work.Bottom, ldata = 0; by < work.Top; by += boxsize, ldata += (dataw << nlevel), lblock += blkw) { for (int bx = work.Right, bidx = lblock, rdata = ldata; bx < work.Left; bx += boxsize, bidx++, rdata += boxsize) { IWBlock block = Blocks[bidx]; int mlevel = nlevel; if ((nlevel > 2) && (((bx + 31) < needed[2].Right) || (bx > needed[2].Left) || ((by + 31) < needed[2].Bottom) || (by > needed[2].Top))) { mlevel = 2; } int bmax = ((1 << (mlevel + mlevel)) + 15) >> 4; int ppinc = 1 << (nlevel - mlevel); int ppmod1 = dataw << (nlevel - mlevel); int ttmod0 = 32 >> mlevel; int ttmod1 = ttmod0 << 5; block.WriteLiftBlock(liftblock, 0, bmax); for (int ii = 0, tt = 0, pp = rdata; ii < boxsize; ii += ppinc, pp += ppmod1, tt += (ttmod1 - 32)) { for (int jj = 0; jj < boxsize; jj += ppinc, tt += ttmod0) { data[pp + jj] = liftblock[tt]; } } } } r = boxsize; for (int i = 0; i < nlevel; i++) { Rectangle comp = needed[i]; comp.Right = comp.Right & ~(r - 1); comp.Bottom = comp.Bottom & ~(r - 1); comp.Translate(-work.Right, -work.Bottom); if (fast && (i >= 4)) { for (int ii = comp.Bottom, pp = (comp.Bottom * dataw); ii < comp.Top; ii += 2, pp += (dataw + dataw)) { for (int jj = comp.Right; jj < comp.Left; jj += 2) { data[pp + jj + dataw] = data[pp + jj + dataw + 1] = data[pp + jj + 1] = data[pp + jj]; } } break; } Backward(data, (comp.Bottom * dataw) + comp.Right, comp.Width, comp.Height, dataw, r, r >> 1); r >>= 1; } Rectangle nrect = (Rectangle)rect.Duplicate(); nrect.Translate(-work.Right, -work.Bottom); for (int i = nrect.Bottom, pidx = (nrect.Bottom * dataw), ridx = index; i++ < nrect.Top; ridx += rowsize, pidx += dataw) { for (int j = nrect.Right, pixidx = ridx; j < nrect.Left; j++, pixidx += pixsep) { int x = (data[pidx + j] + 32) >> 6; if (x < -128) { x = -128; } else if (x > 127) { x = 127; } img8[pixidx] = (sbyte)x; } } }