private int refineNonZeroes(Block b, int zig, int zigEnd, int nz, int delta) { for (; zig <= zigEnd; zig++) { int u = unzig[zig]; if (b[u] == 0) { if (nz == 0) { break; } nz--; continue; } var bit = Bytes.DecodeBit(); if (!bit) { continue; } if (b[u] >= 0) { b[u] += delta; } else { b[u] -= delta; } } return(zig); }
private void refine(Block b, Huffman h, int zigStart, int zigEnd, int delta) { if (zigStart == 0) { if (zigEnd != 0) { throw new Exception("Invalid state for zig DC component"); } var bit = Bytes.DecodeBit(); if (bit) { b[0] |= delta; } return; } int zig = zigStart; if (EndOfBlockRun == 0) { for (; zig <= zigEnd; zig++) { bool done = false; int z = 0; var val = h.DecodeHuffman(Bytes); int val0 = val >> 4; int val1 = val & 0x0f; switch (val1) { case 0: if (val0 != 0x0f) { EndOfBlockRun = (ushort)(1 << val0); if (val0 != 0) { var bits = Bytes.DecodeBits(val0); EndOfBlockRun |= (ushort)bits; } done = true; } break; case 1: z = delta; var bit = Bytes.DecodeBit(); if (!bit) { z = -z; } break; default: throw new Exception("unexpected Huffman code"); } if (done) { break; } zig = refineNonZeroes(b, zig, zigEnd, val0, delta); if (zig > zigEnd) { throw new Exception(string.Format("too many coefficients {0} > {1}", zig, zigEnd)); } if (z != 0) { b[unzig[zig]] = z; } } } if (EndOfBlockRun > 0) { EndOfBlockRun--; refineNonZeroes(b, zig, zigEnd, -1, delta); } }