int gsm0610_pack_voip(uint8_t code[], gsm0610_frame_t *s) { int i; int j; uint8_t *c; bitstream_state_t bs; c = code; bitstream_init(&bs); bitstream_put2(&bs, &c, GSM0610_MAGIC, 4); bitstream_put2(&bs, &c, s->LARc[0], 6); bitstream_put2(&bs, &c, s->LARc[1], 6); bitstream_put2(&bs, &c, s->LARc[2], 5); bitstream_put2(&bs, &c, s->LARc[3], 5); bitstream_put2(&bs, &c, s->LARc[4], 4); bitstream_put2(&bs, &c, s->LARc[5], 4); bitstream_put2(&bs, &c, s->LARc[6], 3); bitstream_put2(&bs, &c, s->LARc[7], 3); for (i = 0; i < 4; i++) { bitstream_put2(&bs, &c, s->Nc[i], 7); bitstream_put2(&bs, &c, s->bc[i], 2); bitstream_put2(&bs, &c, s->Mc[i], 2); bitstream_put2(&bs, &c, s->xmaxc[i], 6); for (j = 0; j < 13; j++) bitstream_put2(&bs, &c, s->xMc[i][j], 3); } return 33; }
void __stdcall ac3_init(ac3_state *state) { state->frame_count=0; bitstream_init(state); imdct_init(); sanity_check_init(&state->syncinfo,&state->bsi,&state->audblk); }
int gsm0610_pack_wav49(uint8_t code[], gsm0610_frame_t *s, int half) { int i; int j; uint8_t *c; bitstream_state_t bs; c = code; if (half) bitstream_init(&bs); bitstream_put(&bs, &c, s->LARc[0], 6); bitstream_put(&bs, &c, s->LARc[1], 6); bitstream_put(&bs, &c, s->LARc[2], 5); bitstream_put(&bs, &c, s->LARc[3], 5); bitstream_put(&bs, &c, s->LARc[4], 4); bitstream_put(&bs, &c, s->LARc[5], 4); bitstream_put(&bs, &c, s->LARc[6], 3); bitstream_put(&bs, &c, s->LARc[7], 3); for (i = 0; i < 4; i++) { bitstream_put(&bs, &c, s->Nc[i], 7); bitstream_put(&bs, &c, s->bc[i], 2); bitstream_put(&bs, &c, s->Mc[i], 2); bitstream_put(&bs, &c, s->xmaxc[i], 6); for (j = 0; j < 13; j++) bitstream_put(&bs, &c, s->xMc[i][j], 3); } return (half) ? 32 : 33; }
int gsm0610_unpack_wav49(gsm0610_frame_t *s, const uint8_t code[], int half) { int i; int j; static bitstream_state_t bs; const uint8_t *c; c = code; if (half) bitstream_init(&bs); s->LARc[0] = (int16_t) bitstream_get(&bs, &c, 6); s->LARc[1] = (int16_t) bitstream_get(&bs, &c, 6); s->LARc[2] = (int16_t) bitstream_get(&bs, &c, 5); s->LARc[3] = (int16_t) bitstream_get(&bs, &c, 5); s->LARc[4] = (int16_t) bitstream_get(&bs, &c, 4); s->LARc[5] = (int16_t) bitstream_get(&bs, &c, 4); s->LARc[6] = (int16_t) bitstream_get(&bs, &c, 3); s->LARc[7] = (int16_t) bitstream_get(&bs, &c, 3); for (i = 0; i < 4; i++) { s->Nc[i] = (int16_t) bitstream_get(&bs, &c, 7); s->bc[i] = (int16_t) bitstream_get(&bs, &c, 2); s->Mc[i] = (int16_t) bitstream_get(&bs, &c, 2); s->xmaxc[i] = (int16_t) bitstream_get(&bs, &c, 6); for (j = 0; j < 13; j++) s->xMc[i][j] = (int16_t) bitstream_get(&bs, &c, 3); } return (half) ? 33 : 32; }
int gsm0610_unpack_voip(gsm0610_frame_t *s, const uint8_t code[]) { int i; int j; const uint8_t *c; unsigned int magic; bitstream_state_t bs; c = code; bitstream_init(&bs); magic = bitstream_get2(&bs, &c, 4); if (magic != GSM0610_MAGIC) return -1; s->LARc[0] = (int16_t) bitstream_get2(&bs, &c, 6); s->LARc[1] = (int16_t) bitstream_get2(&bs, &c, 6); s->LARc[2] = (int16_t) bitstream_get2(&bs, &c, 5); s->LARc[3] = (int16_t) bitstream_get2(&bs, &c, 5); s->LARc[4] = (int16_t) bitstream_get2(&bs, &c, 4); s->LARc[5] = (int16_t) bitstream_get2(&bs, &c, 4); s->LARc[6] = (int16_t) bitstream_get2(&bs, &c, 3); s->LARc[7] = (int16_t) bitstream_get2(&bs, &c, 3); for (i = 0; i < 4; i++) { s->Nc[i] = (int16_t) bitstream_get2(&bs, &c, 7); s->bc[i] = (int16_t) bitstream_get2(&bs, &c, 2); s->Mc[i] = (int16_t) bitstream_get2(&bs, &c, 2); s->xmaxc[i] = (int16_t) bitstream_get2(&bs, &c, 6); for (j = 0; j < 13; j++) s->xMc[i][j] = (int16_t) bitstream_get2(&bs, &c, 3); } return 33; }
void CMpeg2DecoderDXVA2::Slice(mpeg2dec_t *mpeg2dec, int code, const uint8_t *buffer, int bytes) { if (m_SliceCount >= MAX_SLICE) return; if (m_SliceDataSize + 4 + bytes > m_SliceBufferSize) { static const size_t GrowSize = 512 * 1024; size_t NewSize = ((m_SliceDataSize + 4 + bytes) + GrowSize) / GrowSize * GrowSize; uint8_t *pNewBuffer = static_cast<uint8_t *>(realloc(m_pSliceBuffer, NewSize)); if (!pNewBuffer) return; m_pSliceBuffer = pNewBuffer; m_SliceBufferSize = NewSize; } uint8_t *p = m_pSliceBuffer + m_SliceDataSize; p[0] = 0; p[1] = 0; p[2] = 1; p[3] = (uint8_t)code; memcpy(p + 4, buffer, bytes); bitstream_t bitstream; int Offset = 0; bitstream_init(&bitstream, buffer, bytes); if (mpeg2dec->decoder.vertical_position_extension) { bitstream_dumpbits(&bitstream, 3); Offset += 3; } int quantizer_scale_code = bitstream_ubits(&bitstream, 5); bitstream_dumpbits(&bitstream, 5); Offset += 5; for (;;) { Offset++; if (!(bitstream.buf & 0x80000000)) break; bitstream_dumpbits(&bitstream, 9); bitstream_needbits(&bitstream); Offset += 8; } DXVA_SliceInfo &SliceInfo = m_SliceInfo[m_SliceCount]; SliceInfo.wHorizontalPosition = 0; SliceInfo.wVerticalPosition = static_cast<WORD>(code - 1); SliceInfo.dwSliceBitsInBuffer = 8 * (4 + bytes); SliceInfo.dwSliceDataLocation = static_cast<DWORD>(m_SliceDataSize); SliceInfo.bStartCodeBitOffset = 0; SliceInfo.bReservedBits = 0; SliceInfo.wMBbitOffset = static_cast<WORD>(4 * 8 + Offset); SliceInfo.wNumberMBsInSlice = static_cast<WORD>(mpeg2dec->sequence.width >> 4); SliceInfo.wQuantizerScaleCode = quantizer_scale_code; SliceInfo.wBadSliceChopping = 0; m_SliceCount++; m_SliceDataSize += 4 + bytes; }
int ff_ccitt_unpack(AVCodecContext *avctx, const uint8_t *src, int srcsize, uint8_t *dst, int height, int stride, enum TiffCompr compr, int opts) { int j; BitstreamContext bc; int *runs, *ref = NULL, *runend; int ret; int runsize = avctx->width + 2; runs = av_malloc(runsize * sizeof(runs[0])); ref = av_malloc(runsize * sizeof(ref[0])); if (!runs || !ref) { ret = AVERROR(ENOMEM); goto fail; } ref[0] = avctx->width; ref[1] = 0; ref[2] = 0; bitstream_init(&bc, src, srcsize * 8); for (j = 0; j < height; j++) { runend = runs + runsize; if (compr == TIFF_G4) { ret = decode_group3_2d_line(avctx, &bc, avctx->width, runs, runend, ref); if (ret < 0) goto fail; } else { int g3d1 = (compr == TIFF_G3) && !(opts & 1); if (compr != TIFF_CCITT_RLE && find_group3_syncmarker(&bc, srcsize * 8) < 0) break; if (compr == TIFF_CCITT_RLE || g3d1 || bitstream_read_bit(&bc)) ret = decode_group3_1d_line(avctx, &bc, avctx->width, runs, runend); else ret = decode_group3_2d_line(avctx, &bc, avctx->width, runs, runend, ref); if (compr == TIFF_CCITT_RLE) bitstream_align(&bc); } if (avctx->err_recognition & AV_EF_EXPLODE && ret < 0) goto fail; if (ret < 0) { put_line(dst, stride, avctx->width, ref); } else { put_line(dst, stride, avctx->width, runs); FFSWAP(int *, runs, ref); } dst += stride; } ret = 0; fail: av_free(runs); av_free(ref); return ret; }
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { BinkAudioContext *s = avctx->priv_data; AVFrame *frame = data; BitstreamContext *bc = &s->bc; int ret, consumed = 0; if (!bitstream_bits_left(bc)) { uint8_t *buf; /* handle end-of-stream */ if (!avpkt->size) { *got_frame_ptr = 0; return 0; } if (avpkt->size < 4) { av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); return AVERROR_INVALIDDATA; } buf = av_realloc(s->packet_buffer, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE); if (!buf) return AVERROR(ENOMEM); s->packet_buffer = buf; memcpy(s->packet_buffer, avpkt->data, avpkt->size); bitstream_init(bc, s->packet_buffer, avpkt->size * 8); consumed = avpkt->size; /* skip reported size */ bitstream_skip(bc, 32); } /* get output buffer */ frame->nb_samples = s->frame_len; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } if (decode_block(s, (float **)frame->extended_data, avctx->codec->id == AV_CODEC_ID_BINKAUDIO_DCT)) { av_log(avctx, AV_LOG_ERROR, "Incomplete packet\n"); return AVERROR_INVALIDDATA; } get_bits_align32(bc); frame->nb_samples = s->block_size / avctx->channels; *got_frame_ptr = 1; return consumed; }
int main(int argc, char **argv) { int c, bit, bits_left, count, coeff_count; gint run,amp,used; unsigned char *p; static unsigned char buffer[256]; bitstream_t *bs; p = buffer; bits_left = 8; dv_construct_vlc_table(); bs = bitstream_init(); coeff_count=count=0; while((c=fgetc(stdin)) != EOF) { if(c=='0') bit = 0; else if(c=='1') bit = 1; else continue; count++; *p |= (bit << (bits_left -1)); bits_left--; if(!bits_left) { p++; bits_left=8; } } bitstream_new_buffer(bs,buffer,256); while(count >0) { used =dv_peek_vlc(bs,count,&run,&); if(used > 0) { printf("(%d,%d,%d)",run,amp,used); bitstream_flush(bs,used); count-=used; coeff_count+=(run+1); } else if(used == VLC_ERROR) { printf("X (%d tossed)\n", count); exit(-1); } else if(used == VLC_NOBITS) { printf("* (%d tossed)\n", count); printf("*coeff_count=%d \n",coeff_count); exit(0); } else if(used == 0) { printf("#"); bitstream_flush(bs,4); count-=4; coeff_count=0; } else { printf("danger! unknown return from vlc!\n"); exit(-2); } } exit(0); }
ssize_t th_unlzss( thtk_io_t* input, thtk_io_t* output, size_t output_size, thtk_error_t** error) { unsigned char dict[LZSS_DICTSIZE]; unsigned int dict_head = 1; unsigned int i; size_t bytes_written = 0; struct bitstream bs; if (!input || !output) { thtk_error_new(error, "input or output is NULL"); return -1; } bitstream_init(&bs, input); memset(dict, 0, sizeof(dict)); while (bytes_written < output_size) { if (bitstream_read1(&bs)) { unsigned char c = bitstream_read(&bs, 8); if (thtk_io_write(output, &c, 1, error) != 1) return -1; ++bytes_written; dict[dict_head] = c; dict_head = (dict_head + 1) & LZSS_DICTSIZE_MASK; } else { unsigned int match_offset = bitstream_read(&bs, 13); unsigned int match_len = bitstream_read(&bs, 4) + LZSS_MIN_MATCH; if (!match_offset) return bytes_written; for (i = 0; i < match_len; ++i) { unsigned char c = dict[(match_offset + i) & LZSS_DICTSIZE_MASK]; if (thtk_io_write(output, &c, 1, error) != 1) return -1; ++bytes_written; dict[dict_head] = c; dict_head = (dict_head + 1) & LZSS_DICTSIZE_MASK; } } } return bytes_written; }
static int gsm_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { AVFrame *frame = data; int res; BitstreamContext bc; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; int16_t *samples; if (buf_size < avctx->block_align) { av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); return AVERROR_INVALIDDATA; } /* get output buffer */ frame->nb_samples = avctx->frame_size; if ((res = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return res; } samples = (int16_t *)frame->data[0]; switch (avctx->codec_id) { case AV_CODEC_ID_GSM: bitstream_init(&bc, buf, buf_size * 8); if (bitstream_read(&bc, 4) != 0xd) av_log(avctx, AV_LOG_WARNING, "Missing GSM magic!\n"); res = gsm_decode_block(avctx, samples, &bc, GSM_13000); if (res < 0) return res; break; case AV_CODEC_ID_GSM_MS: res = ff_msgsm_decode_block(avctx, samples, buf, (GSM_MS_BLOCK_SIZE - avctx->block_align) / 3); if (res < 0) return res; } *got_frame_ptr = 1; return avctx->block_align; }
void mpeg2_xvmc_slice (mpeg2dec_accel_t * accel, picture_t * picture, int code, uint8_t buffer,int mba_inc) { xine_xvmc_t * xvmc = (xine_xvmc_t *) (size_t) bitstream_init (picture, (void *) (size_t) buffer); slice_xvmc_init (picture, code); while (1) { if (picture) break; switch (picture->bitstream_buf) { case 8: mba_inc += accel->xvmc_last_slice_code = code; xvmc->proc_macro_block (); while (mba_inc) ; } } }
uint_32 decode_buffer_syncframe(syncinfo_t *syncinfo, uint_8 **start, uint_8 *end) { uint_8 *cur = *start; uint_16 syncword = syncinfo->syncword; uint_32 ret = 0; // find an ac3 sync frame resync: while(syncword != 0x0b77) { if(cur >= end) { // ret = -1; goto done; } syncword = (syncword << 8) + *cur++; } // need the next 3 bytes to decide how big the frame is while(buffer_size < 3) { if(cur >= end) goto done; buffer[buffer_size++] = *cur++; } parse_syncinfo(syncinfo, buffer); if (syncinfo->frame_size==0) // CRITICAL CONDITION goto done; while (buffer_size < (syncinfo->frame_size<<1) - 2) { if(cur >= end) goto done; buffer[buffer_size++] = *cur++; } // check the crc over the entire frame if (crc_process_frame(buffer, (syncinfo->frame_size<<1) - 2)) { #ifdef _WIN32 Debug(8, "Audio error\n"); SetDlgItemText(hDlg, IDC_INFO, "A.E.!"); #else fprintf(stderr, "\nAudio error, skipping bad input frame\n"); #endif *start = cur; // Skip bad input frame syncword = 0xffff; buffer_size = 0; goto resync; } // if we got to this point, we found a valid ac3 frame to decode bitstream_init(buffer); // get rid of the syncinfo struct as we already parsed it bitstream_get(24); ret = 1; *start = cur; done: // reset the syncword for next time syncword = 0xffff; buffer_size = 0; //done: syncinfo->syncword = syncword; return ret; }
static GstFlowReturn gst_dvbvideosink_render(GstBaseSink *sink, GstBuffer *buffer) { GstDVBVideoSink *self = GST_DVBVIDEOSINK(sink); unsigned char *data = GST_BUFFER_DATA(buffer); size_t data_len = GST_BUFFER_SIZE(buffer); unsigned char *pes_header = GST_BUFFER_DATA(self->pesheader_buffer); size_t pes_header_len = 0; size_t payload_len = 0; GstBuffer *tmpbuf = NULL; #ifdef PACK_UNPACKED_XVID_DIVX5_BITSTREAM gboolean commit_prev_frame_data = FALSE, cache_prev_frame = FALSE; #endif if (self->fd < 0) return GST_FLOW_OK; #ifdef PACK_UNPACKED_XVID_DIVX5_BITSTREAM if (self->must_pack_bitstream) { cache_prev_frame = TRUE; unsigned int pos = 0; while (pos < data_len) { if (memcmp(&data[pos], "\x00\x00\x01", 3)) { pos++; continue; } pos += 3; if ((data[pos++] & 0xF0) == 0x20) { // we need time_inc_res gboolean low_delay=FALSE; unsigned int ver_id = 1, shape=0, time_inc_res=0, tmp=0; struct bitstream bit; bitstream_init(&bit, data+pos, 0); bitstream_get(&bit, 9); if (bitstream_get(&bit, 1)) { ver_id = bitstream_get(&bit, 4); // ver_id bitstream_get(&bit, 3); } if ((tmp = bitstream_get(&bit, 4)) == 15) { // Custom Aspect Ration bitstream_get(&bit, 8); // skip AR width bitstream_get(&bit, 8); // skip AR height } if (bitstream_get(&bit, 1)) { bitstream_get(&bit, 2); low_delay = bitstream_get(&bit, 1) ? TRUE : FALSE; if (bitstream_get(&bit, 1)) { bitstream_get(&bit, 32); bitstream_get(&bit, 32); bitstream_get(&bit, 15); } } shape = bitstream_get(&bit, 2); if (ver_id != 1 && shape == 3 /* Grayscale */) bitstream_get(&bit, 4); bitstream_get(&bit, 1); time_inc_res = bitstream_get(&bit, 16); self->time_inc_bits = 0; while (time_inc_res) { // count bits ++self->time_inc_bits; time_inc_res >>= 1; } } }
static int escape130_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; Escape130Context *s = avctx->priv_data; AVFrame *pic = data; BitstreamContext bc; int ret; uint8_t *old_y, *old_cb, *old_cr, *new_y, *new_cb, *new_cr; uint8_t *dstY, *dstU, *dstV; unsigned old_y_stride, old_cb_stride, old_cr_stride, new_y_stride, new_cb_stride, new_cr_stride; unsigned total_blocks = avctx->width * avctx->height / 4, block_index, block_x = 0; unsigned y[4] = { 0 }, cb = 0x10, cr = 0x10; int skip = -1, y_avg = 0, i, j; uint8_t *ya = s->old_y_avg; // first 16 bytes are header; no useful information in here if (buf_size <= 16) { av_log(avctx, AV_LOG_ERROR, "Insufficient frame data\n"); return AVERROR_INVALIDDATA; } if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; bitstream_init(&bc, buf + 16, (buf_size - 16) * 8); new_y = s->new_y; new_cb = s->new_u; new_cr = s->new_v; new_y_stride = s->linesize[0]; new_cb_stride = s->linesize[1]; new_cr_stride = s->linesize[2]; old_y = s->old_y; old_cb = s->old_u; old_cr = s->old_v; old_y_stride = s->linesize[0]; old_cb_stride = s->linesize[1]; old_cr_stride = s->linesize[2]; for (block_index = 0; block_index < total_blocks; block_index++) { // Note that this call will make us skip the rest of the blocks // if the frame ends prematurely. if (skip == -1) skip = decode_skip_count(&bc); if (skip == -1) { av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n"); return AVERROR_INVALIDDATA; } if (skip) { y[0] = old_y[0]; y[1] = old_y[1]; y[2] = old_y[old_y_stride]; y[3] = old_y[old_y_stride + 1]; y_avg = ya[0]; cb = old_cb[0]; cr = old_cr[0]; } else { if (bitstream_read_bit(&bc)) { unsigned sign_selector = bitstream_read(&bc, 6); unsigned difference_selector = bitstream_read(&bc, 2); y_avg = 2 * bitstream_read(&bc, 5); for (i = 0; i < 4; i++) { y[i] = av_clip(y_avg + offset_table[difference_selector] * sign_table[sign_selector][i], 0, 63); } } else if (bitstream_read_bit(&bc)) { if (bitstream_read_bit(&bc)) { y_avg = bitstream_read(&bc, 6); } else { unsigned adjust_index = bitstream_read(&bc, 3); y_avg = (y_avg + luma_adjust[adjust_index]) & 63; } for (i = 0; i < 4; i++) y[i] = y_avg; } if (bitstream_read_bit(&bc)) { if (bitstream_read_bit(&bc)) { cb = bitstream_read(&bc, 5); cr = bitstream_read(&bc, 5); } else { unsigned adjust_index = bitstream_read(&bc, 3); cb = (cb + chroma_adjust[0][adjust_index]) & 31; cr = (cr + chroma_adjust[1][adjust_index]) & 31; } } } *ya++ = y_avg; new_y[0] = y[0]; new_y[1] = y[1]; new_y[new_y_stride] = y[2]; new_y[new_y_stride + 1] = y[3]; *new_cb = cb; *new_cr = cr; old_y += 2; old_cb++; old_cr++; new_y += 2; new_cb++; new_cr++; block_x++; if (block_x * 2 == avctx->width) { block_x = 0; old_y += old_y_stride * 2 - avctx->width; old_cb += old_cb_stride - avctx->width / 2; old_cr += old_cr_stride - avctx->width / 2; new_y += new_y_stride * 2 - avctx->width; new_cb += new_cb_stride - avctx->width / 2; new_cr += new_cr_stride - avctx->width / 2; } skip--; } new_y = s->new_y; new_cb = s->new_u; new_cr = s->new_v; dstY = pic->data[0]; dstU = pic->data[1]; dstV = pic->data[2]; for (j = 0; j < avctx->height; j++) { for (i = 0; i < avctx->width; i++) dstY[i] = new_y[i] << 2; dstY += pic->linesize[0]; new_y += new_y_stride; } for (j = 0; j < avctx->height / 2; j++) { for (i = 0; i < avctx->width / 2; i++) { dstU[i] = chroma_vals[new_cb[i]]; dstV[i] = chroma_vals[new_cr[i]]; } dstU += pic->linesize[1]; dstV += pic->linesize[2]; new_cb += new_cb_stride; new_cr += new_cr_stride; } ff_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n", buf_size, bitstream_tell(&bc) >> 3); FFSWAP(uint8_t*, s->old_y, s->new_y); FFSWAP(uint8_t*, s->old_u, s->new_u); FFSWAP(uint8_t*, s->old_v, s->new_v); *got_frame = 1; return buf_size; }
ssize_t th_lzss( thtk_io_t* input, size_t input_size, thtk_io_t* output, thtk_error_t** error) { struct bitstream bs; hash_t hash; unsigned char dict[LZSS_DICTSIZE]; unsigned int dict_head = 1; unsigned int dict_head_key; unsigned int waiting_bytes = 0; size_t bytes_read = 0; unsigned int i; unsigned char c; if (!input || !output) { thtk_error_new(error, "input or output is NULL"); return -1; } bitstream_init(&bs, output); memset(&hash, 0, sizeof(hash)); memset(dict, 0, sizeof(dict)); /* Fill the forward-looking buffer. */ for (i = 0; i < LZSS_MAX_MATCH && i < input_size; ++i) { int ret = thtk_io_read(input, &c, 1, error); if (ret == -1) { return -1; } else if (ret != 1) { break; } ++bytes_read; dict[dict_head + i] = c; waiting_bytes++; } dict_head_key = generate_key(dict, dict_head); while (waiting_bytes) { unsigned int match_len = LZSS_MIN_MATCH - 1; unsigned int match_offset = 0; unsigned int offset; /* Find a good match. */ for (offset = hash.hash[dict_head_key]; offset != HASH_NULL && waiting_bytes > match_len; offset = hash.next[offset]) { /* First check a character further ahead to see if this match can * be any longer than the current match. */ if (dict[(dict_head + match_len) & LZSS_DICTSIZE_MASK] == dict[(offset + match_len) & LZSS_DICTSIZE_MASK]) { /* Then check the previous characters. */ for (i = 0; i < match_len && (dict[(dict_head + i) & LZSS_DICTSIZE_MASK] == dict[(offset + i) & LZSS_DICTSIZE_MASK]); ++i) ; if (i < match_len) continue; /* Finally try to extend the match. */ for (++match_len; match_len < waiting_bytes && (dict[(dict_head + match_len) & LZSS_DICTSIZE_MASK] == dict[(offset + match_len) & LZSS_DICTSIZE_MASK]); ++match_len) ; match_offset = offset; } } /* Write data to the output buffer. */ if (match_len < LZSS_MIN_MATCH) { match_len = 1; bitstream_write1(&bs, 1); bitstream_write(&bs, 8, dict[dict_head]); } else { bitstream_write1(&bs, 0); bitstream_write(&bs, 13, match_offset); bitstream_write(&bs, 4, match_len - LZSS_MIN_MATCH); } /* Add bytes to the dictionary. */ for (i = 0; i < match_len; ++i) { const unsigned int offset = (dict_head + LZSS_MAX_MATCH) & LZSS_DICTSIZE_MASK; if (offset != HASH_NULL) list_remove(&hash, generate_key(dict, offset), offset); if (dict_head != HASH_NULL) list_add(&hash, dict_head_key, dict_head); if (bytes_read < input_size) { int ret = thtk_io_read(input, &c, 1, error); if (ret == 1) { dict[offset] = c; ++bytes_read; } else if (ret == 0) { --waiting_bytes; } else { return -1; } } else { --waiting_bytes; } dict_head = (dict_head + 1) & LZSS_DICTSIZE_MASK; dict_head_key = generate_key(dict, dict_head); } } bitstream_write1(&bs, 0); bitstream_write(&bs, 13, HASH_NULL); bitstream_write(&bs, 4, 0); bitstream_finish(&bs); return bs.byte_count; }