📄 jpc_bs.c
字号:
/* Get the number of bits requested from the specified bit stream. */ v = 0; while (--n >= 0) { if ((u = jpc_bitstream_getbit(bitstream)) < 0) { return -1; } v = (v << 1) | u; } return v;}/* Put one or more bits to a bit stream. */int jpc_bitstream_putbits(jpc_bitstream_t *bitstream, int n, long v){ int m; /* We can reliably put at most 31 bits since ISO/IEC 9899 only guarantees that a long can represent values up to 2^31-1. */ assert(n >= 0 && n < 32); /* Ensure that only the bits to be output are nonzero. */ assert(!(v & (~JAS_ONES(n)))); /* Put the desired number of bits to the specified bit stream. */ m = n - 1; while (--n >= 0) { if (jpc_bitstream_putbit(bitstream, (v >> m) & 1) == EOF) { return EOF; } v <<= 1; } return 0;}/******************************************************************************\* Code for buffer filling and flushing.\******************************************************************************//* Fill the buffer for a bit stream. */int jpc_bitstream_fillbuf(jpc_bitstream_t *bitstream){ int c; /* Note: The count has already been decremented by the caller. */ assert(bitstream->openmode_ & JPC_BITSTREAM_READ); assert(bitstream->cnt_ <= 0); if (bitstream->flags_ & JPC_BITSTREAM_ERR) { bitstream->cnt_ = 0; return -1; } if (bitstream->flags_ & JPC_BITSTREAM_EOF) { bitstream->buf_ = 0x7f; bitstream->cnt_ = 7; return 1; } bitstream->buf_ = (bitstream->buf_ << 8) & 0xffff; if ((c = jas_stream_getc((bitstream)->stream_)) == EOF) { bitstream->flags_ |= JPC_BITSTREAM_EOF; return 1; } bitstream->cnt_ = (bitstream->buf_ == 0xff00) ? 6 : 7; bitstream->buf_ |= c & ((1 << (bitstream->cnt_ + 1)) - 1); return (bitstream->buf_ >> bitstream->cnt_) & 1;}/******************************************************************************\* Code related to flushing.\******************************************************************************//* Does the bit stream need to be aligned to a byte boundary (considering the effects of bit stuffing)? */int jpc_bitstream_needalign(jpc_bitstream_t *bitstream){ if (bitstream->openmode_ & JPC_BITSTREAM_READ) { /* The bit stream is open for reading. */ /* If there are any bits buffered for reading, or the previous byte forced a stuffed bit, alignment is required. */ if ((bitstream->cnt_ < 8 && bitstream->cnt_ > 0) || ((bitstream->buf_ >> 8) & 0xff) == 0xff) { return 1; } } else if (bitstream->openmode_ & JPC_BITSTREAM_WRITE) { /* The bit stream is open for writing. */ /* If there are any bits buffered for writing, or the previous byte forced a stuffed bit, alignment is required. */ if ((bitstream->cnt_ < 8 && bitstream->cnt_ >= 0) || ((bitstream->buf_ >> 8) & 0xff) == 0xff) { return 1; } } else { /* This should not happen. Famous last words, eh? :-) */ assert(0); return -1; } return 0;}/* How many additional bytes would be output if we align the bit stream? */int jpc_bitstream_pending(jpc_bitstream_t *bitstream){ if (bitstream->openmode_ & JPC_BITSTREAM_WRITE) { /* The bit stream is being used for writing. */#if 1 /* XXX - Is this really correct? Check someday... */ if (bitstream->cnt_ < 8) { return 1; }#else if (bitstream->cnt_ < 8) { if (((bitstream->buf_ >> 8) & 0xff) == 0xff) { return 2; } return 1; }#endif return 0; } else { /* This operation should not be invoked on a bit stream that is being used for reading. */ return -1; }}/* Align the bit stream to a byte boundary. */int jpc_bitstream_align(jpc_bitstream_t *bitstream){ int ret; if (bitstream->openmode_ & JPC_BITSTREAM_READ) { ret = jpc_bitstream_inalign(bitstream, 0, 0); } else if (bitstream->openmode_ & JPC_BITSTREAM_WRITE) { ret = jpc_bitstream_outalign(bitstream, 0); } else { abort(); } return ret;}/* Align a bit stream in the input case. */int jpc_bitstream_inalign(jpc_bitstream_t *bitstream, int fillmask, int filldata){ int n; int v; int u; int numfill; int m; numfill = 7; m = 0; v = 0; if (bitstream->cnt_ > 0) { n = bitstream->cnt_; } else if (!bitstream->cnt_) { n = ((bitstream->buf_ & 0xff) == 0xff) ? 7 : 0; } else { n = 0; } if (n > 0) { if ((u = jpc_bitstream_getbits(bitstream, n)) < 0) { return -1; } m += n; v = (v << n) | u; } if ((bitstream->buf_ & 0xff) == 0xff) { if ((u = jpc_bitstream_getbits(bitstream, 7)) < 0) { return -1; } v = (v << 7) | u; m += 7; } if (m > numfill) { v >>= m - numfill; } else { filldata >>= numfill - m; fillmask >>= numfill - m; } if (((~(v ^ filldata)) & fillmask) != fillmask) { /* The actual fill pattern does not match the expected one. */ return 1; } return 0;}/* Align a bit stream in the output case. */int jpc_bitstream_outalign(jpc_bitstream_t *bitstream, int filldata){ int n; int v; /* Ensure that this bit stream is open for writing. */ assert(bitstream->openmode_ & JPC_BITSTREAM_WRITE); /* Ensure that the first bit of fill data is zero. */ /* Note: The first bit of fill data must be zero. If this were not the case, the fill data itself could cause further bit stuffing to be required (which would cause numerous complications). */ assert(!(filldata & (~0x3f))); if (!bitstream->cnt_) { if ((bitstream->buf_ & 0xff) == 0xff) { n = 7; v = filldata; } else { n = 0; v = 0; } } else if (bitstream->cnt_ > 0 && bitstream->cnt_ < 8) { n = bitstream->cnt_; v = filldata >> (7 - n); } else { n = 0; v = 0; return 0; } /* Write the appropriate fill data to the bit stream. */ if (n > 0) { if (jpc_bitstream_putbits(bitstream, n, v)) { return -1; } } if (bitstream->cnt_ < 8) { assert(bitstream->cnt_ >= 0 && bitstream->cnt_ < 8); assert((bitstream->buf_ & 0xff) != 0xff); /* Force the pending byte of output to be written to the underlying (character) stream. */ if (jas_stream_putc(bitstream->stream_, bitstream->buf_ & 0xff) == EOF) { return -1; } bitstream->cnt_ = 8; bitstream->buf_ = (bitstream->buf_ << 8) & 0xffff; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -