/// <summary> /// Receive extend /// </summary> /// <param name="t">Byte</param> /// <param name="inputProcessor">The <see cref="InputProcessor"/></param> /// <param name="x">Read bits value</param> /// <returns>The <see cref="OrigDecoderErrorCode"/></returns> public OrigDecoderErrorCode ReceiveExtendUnsafe(int t, ref InputProcessor inputProcessor, out int x) { if (this.UnreadBits < t) { OrigDecoderErrorCode errorCode = this.EnsureNBitsUnsafe(t, ref inputProcessor); if (errorCode != OrigDecoderErrorCode.NoError) { x = int.MaxValue; return(errorCode); } } this.UnreadBits -= t; this.Mask >>= t; int s = 1 << t; x = (this.Accumulator >> this.UnreadBits) & (s - 1); if (x < (s >> 1)) { x += ((-1) << t) + 1; } return(OrigDecoderErrorCode.NoError); }
public int ReceiveExtend(int t, ref InputProcessor inputProcessor) { OrigDecoderErrorCode errorCode = this.ReceiveExtendUnsafe(t, ref inputProcessor, out int x); errorCode.EnsureNoError(); return(x); }
/// <summary> /// Reads bytes from the byte buffer to ensure that bits.UnreadBits is at /// least n. For best performance (avoiding function calls inside hot loops), /// the caller is the one responsible for first checking that bits.UnreadBits < n. /// This method does not throw. Returns <see cref="OrigDecoderErrorCode"/> instead. /// </summary> /// <param name="n">The number of bits to ensure.</param> /// <param name="inputProcessor">The <see cref="InputProcessor"/></param> /// <returns>Error code</returns> public OrigDecoderErrorCode EnsureNBitsUnsafe(int n, ref InputProcessor inputProcessor) { while (true) { OrigDecoderErrorCode errorCode = this.EnsureBitsStepImpl(ref inputProcessor); if (errorCode != OrigDecoderErrorCode.NoError || this.UnreadBits >= n) { return(errorCode); } } }
private OrigDecoderErrorCode EnsureBitsStepImpl(ref InputProcessor inputProcessor) { OrigDecoderErrorCode errorCode = inputProcessor.Bytes.ReadByteStuffedByteUnsafe(inputProcessor.InputStream, out int c); if (errorCode != OrigDecoderErrorCode.NoError) { return(errorCode); } this.Accumulator = (this.Accumulator << 8) | c; this.UnreadBits += 8; if (this.Mask == 0) { this.Mask = 1 << 7; } else { this.Mask <<= 8; } return(errorCode); }
/// <summary> /// Internal part of the DHT processor, whatever does it mean /// </summary> /// <param name="inputProcessor">The decoder instance</param> /// <param name="defineHuffmanTablesData">The temporary buffer that holds the data that has been read from the Jpeg stream</param> /// <param name="remaining">Remaining bits</param> public void ProcessDefineHuffmanTablesMarkerLoop( ref InputProcessor inputProcessor, byte[] defineHuffmanTablesData, ref int remaining) { // Read nCodes and huffman.Valuess (and derive h.Length). // nCodes[i] is the number of codes with code length i. // h.Length is the total number of codes. this.Length = 0; int[] ncodes = new int[MaxCodeLength]; for (int i = 0; i < ncodes.Length; i++) { ncodes[i] = defineHuffmanTablesData[i + 1]; this.Length += ncodes[i]; } if (this.Length == 0) { throw new ImageFormatException("Huffman table has zero length"); } if (this.Length > MaxNCodes) { throw new ImageFormatException("Huffman table has excessive length"); } remaining -= this.Length + 17; if (remaining < 0) { throw new ImageFormatException("DHT has wrong length"); } byte[] values = new byte[MaxNCodes]; inputProcessor.ReadFull(values, 0, this.Length); fixed(int *valuesPtr = this.Values.Data) fixed(int *lutPtr = this.Lut.Data) { for (int i = 0; i < values.Length; i++) { valuesPtr[i] = values[i]; } // Derive the look-up table. for (int i = 0; i < MaxNCodes; i++) { lutPtr[i] = 0; } int x = 0, code = 0; for (int i = 0; i < LutSizeLog2; i++) { code <<= 1; for (int j = 0; j < ncodes[i]; j++) { // The codeLength is 1+i, so shift code by 8-(1+i) to // calculate the high bits for every 8-bit sequence // whose codeLength's high bits matches code. // The high 8 bits of lutValue are the encoded value. // The low 8 bits are 1 plus the codeLength. int base2 = code << (7 - i); int lutValue = (valuesPtr[x] << 8) | (2 + i); for (int k = 0; k < 1 << (7 - i); k++) { lutPtr[base2 | k] = lutValue; } code++; x++; } } } fixed(int *minCodesPtr = this.MinCodes.Data) fixed(int *maxCodesPtr = this.MaxCodes.Data) fixed(int *indicesPtr = this.Indices.Data) { // Derive minCodes, maxCodes, and indices. int c = 0, index = 0; for (int i = 0; i < ncodes.Length; i++) { int nc = ncodes[i]; if (nc == 0) { minCodesPtr[i] = -1; maxCodesPtr[i] = -1; indicesPtr[i] = -1; } else { minCodesPtr[i] = c; maxCodesPtr[i] = c + nc - 1; indicesPtr[i] = index; c += nc; index += nc; } c <<= 1; } } }
/// <summary> /// Unrolled version of <see cref="EnsureNBitsUnsafe"/> for n==1 /// </summary> /// <param name="inputProcessor">The <see cref="InputProcessor"/></param> /// <returns>A <see cref="OrigDecoderErrorCode"/></returns> public OrigDecoderErrorCode Ensure1BitUnsafe(ref InputProcessor inputProcessor) { return(this.EnsureBitsStepImpl(ref inputProcessor)); }
public void EnsureNBits(int n, ref InputProcessor inputProcessor) { OrigDecoderErrorCode errorCode = this.EnsureNBitsUnsafe(n, ref inputProcessor); errorCode.EnsureNoError(); }
/// <summary> /// Unrolled version of <see cref="EnsureNBitsUnsafe"/> for n==8 /// </summary> /// <param name="inputProcessor">The <see cref="InputProcessor"/></param> /// <returns>A <see cref="GolangDecoderErrorCode"/></returns> public GolangDecoderErrorCode Ensure8BitsUnsafe(ref InputProcessor inputProcessor) { return(this.EnsureBitsStepImpl(ref inputProcessor)); }