/// <summary> /// Uses an integer long (32 bits) buffer to store the Huffman encoded bits /// and sends them to outStream by the byte. /// </summary> private void bufferIt(EndianBinaryWriter writer, int code, int size) { int PutBuffer = code; int PutBits = this.bufferPutBits; PutBuffer &= (1 << size) - 1; PutBits += size; PutBuffer <<= 24 - PutBits; PutBuffer |= this.bufferPutBuffer; while (PutBits >= 8) { int c = (PutBuffer >> 16) & 0xFF; writer.Write((byte)c); // FF must be escaped if (c == 0xFF) { writer.Write(0); } PutBuffer <<= 8; PutBits -= 8; } this.bufferPutBuffer = PutBuffer; this.bufferPutBits = PutBits; }
public void FlushBuffer(EndianBinaryWriter writer) { int PutBuffer = this.bufferPutBuffer; int PutBits = this.bufferPutBits; while (PutBits >= 8) { int c = (PutBuffer >> 16) & 0xFF; writer.Write((byte)c); // FF must be escaped if (c == 0xFF) writer.Write(0); PutBuffer <<= 8; PutBits -= 8; } if (PutBits > 0) { int c = (PutBuffer >> 16) & 0xFF; writer.Write((byte)c); } }
/// <summary> /// Figure F.16 - Reads the huffman code bit-by-bit. /// </summary> /// <param name="writer">The writer.</param> /// <param name="zigzag">The zigzag.</param> /// <param name="prec">The prec.</param> /// <param name="DCcode">The D Ccode.</param> /// <param name="ACcode">The A Ccode.</param> /// <summary> /// HuffmanBlockEncoder run length encodes and Huffman encodes the quantized data. /// </summary> internal void HuffmanBlockEncoder(EndianBinaryWriter writer, int[] zigzag, int prec, int DCcode, int ACcode) { int temp, temp2, nbits, k, r, i; this.NumOfDCTables = 2; this.NumOfACTables = 2; // The DC portion temp = temp2 = zigzag[0] - prec; if (temp < 0) { temp = -temp; temp2--; } nbits = 0; while (temp != 0) { nbits++; temp >>= 1; } // TODO: Why would this happen? //if (nbits > 11) nbits = 11; this.bufferIt(writer, this.DC_matrix[DCcode][nbits, 0], this.DC_matrix[DCcode][nbits, 1]); // The arguments in bufferIt are code and size. if (nbits != 0) { this.bufferIt(writer, temp2, nbits); } // The AC portion r = 0; for (k = 1; k < 64; k++) { if ((temp = zigzag[ZigZag.ZigZagMap[k]]) == 0) { r++; } else { while (r > 15) { this.bufferIt(writer, this.AC_matrix[ACcode][0xF0, 0], this.AC_matrix[ACcode][0xF0, 1]); r -= 16; } temp2 = temp; if (temp < 0) { temp = -temp; temp2--; } nbits = 1; while ((temp >>= 1) != 0) { nbits++; } i = (r << 4) + nbits; this.bufferIt(writer, this.AC_matrix[ACcode][i, 0], this.AC_matrix[ACcode][i, 1]); this.bufferIt(writer, temp2, nbits); r = 0; } } if (r > 0) { this.bufferIt(writer, this.AC_matrix[ACcode][0, 0], this.AC_matrix[ACcode][0, 1]); } }