public void Build(IBitStream B, short blockSize) { this.N = (int)B.CountBits; this.BlockSize = (short)blockSize; this.InitClasses(); this.Offsets = new BitStream32 (); IList<int> _L = new ListIFS (15, B); IList<int> L; if ((B.CountBits % 15) == 0) { L = _L; } else { int D = _L.Count; int C = 15 * D; var ctx = new BitStreamCtx(0); ctx.Seek(C); int last_block = (int)B.Read(((int)B.CountBits) - C, ctx); L = new ListGen<int>(delegate(int a) { if (a == D) { return last_block; } else { return _L[a]; } }, D+1); } this.AbsRank = new int[(int)Math.Ceiling(((float)L.Count) / this.BlockSize)]; this.AbsOffset = new int[ this.AbsRank.Count ]; int I = 0; int acc = 0; for (int i = 0; i < L.Count; i++) { var u = (short)L[i]; var klass = GetClass(u); this.EncodeClass(klass); if (i % this.BlockSize == 0) { this.AbsRank[I] = acc; this.AbsOffset[I] = (int)this.Offsets.CountBits; I++; } var numbits = NumBits[klass]; if (numbits > 0) { int offset = this.GetOffset (u, klass); this.Offsets.Write (offset, numbits); } acc += klass; } }
/// <summary> /// Locates ctx at index. Returns the remaining run_len value if any /// </summary> /// <returns> protected int LocateAt(int index, BitStreamCtx ctx) { if (index == -1) { ctx.Seek (0); return 0; } int offset_index = index / this.BlockSize; if (offset_index == 0) { ctx.Seek (0); } else { ctx.Seek (this.Offsets [offset_index - 1]); } int left = 1 + index - offset_index * this.BlockSize; int run_len = 0; for (int i = 0; i < left;) { if (run_len > 0) { // run_len--; i += run_len; run_len = 0; if (left < i) { run_len = i - left; i = left; } } else { var res = this.GetNext (ctx); if (res == 1) { run_len = this.GetNext (ctx) - 1; } i++; } } // Console.WriteLine ("** index: {0}, run_len: {1}, left: {2}", index, run_len, left); return run_len; }
public void PrintDebug() { var ctx = new BitStreamCtx (); ctx.Seek (0); int i = 0; while (ctx.Offset < this.Stream.CountBits) { var c = this.Coder.Decode (this.Stream, ctx); Console.WriteLine ("=> i: {0}, c: {1}", i, c); } }
/// <summary> /// Unlocked Select1 useful /// </summary> int BackendSelect1(int rank, BitStreamCtx ctx) { if (rank < 1) { return -1; } this.ResetReader(); int start_index = (rank - 1) / this.B; int acc; int left; if (start_index == 0) { acc = AccStart; ctx.Seek (0); left = rank; } else { acc = this.Samples[start_index - 1]; ctx.Seek (this.Offsets[start_index - 1]); left = rank - start_index * this.B; } // int start_acc = acc; for (int i = 0; i < left; i++) { int read = this.ReadNext(ctx); acc += read; } return acc; }
int BackendAccessRank1(int pos, out int found_pos, BitStreamCtx ctx) { if (pos < 0) { found_pos = -1; return 0; } this.ResetReader (); int start_index = -1; if (this.Samples.Count > 0) { start_index = GenericSearch.FindFirst<int> (pos, this.Samples); } int count; if (start_index < 0) { ctx.Seek (0); count = Math.Min (this.B, this.M); return this.SeqAccessRank1 (AccStart, pos, count, out found_pos, ctx); } ctx.Seek (this.Offsets[start_index]); int rel_rank = (start_index + 1) * this.B; count = Math.Min (this.B, this.M - rel_rank); return rel_rank + this.SeqAccessRank1 (this.Samples[start_index], pos, count, out found_pos, ctx); }
/// <summary> /// Extract 'count' differences starting from 'start_index', it saves the output in 'output'. /// Returns the previous absolute value to start_index (start_index - 1), i.e. the reference /// </summary> public int ExtractFrom(int start_index, int count, IList<int> output) { int acc; BitStreamCtx ctx = new BitStreamCtx (); if (start_index == 0) { this.ResetReader (); acc = -1; ctx.Seek (0); } else { acc = this.BackendSelect1 (start_index, ctx); } for (int i = 0; i < count; i++) { int val = this.ReadNext (ctx); if (i < output.Count) { output[i] = val; } else { output.Add (val); } } return acc; }