static int tgq_decode_mb(TgqContext *s, AVFrame *frame, int mb_y, int mb_x) { int mode; int i; int8_t dc[6]; mode = bytestream2_get_byte(&s->gb); if (mode > 12) { GetBitContext gb; init_get_bits8(&gb, s->gb.buffer, FFMIN(bytestream2_get_bytes_left(&s->gb), mode)); for (i = 0; i < 6; i++) tgq_decode_block(s, s->block[i], &gb); tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y); bytestream2_skip(&s->gb, mode); } else { if (mode == 3) { memset(dc, bytestream2_get_byte(&s->gb), 4); dc[4] = bytestream2_get_byte(&s->gb); dc[5] = bytestream2_get_byte(&s->gb); } else if (mode == 6) { bytestream2_get_buffer(&s->gb, dc, 6); } else if (mode == 12) { for (i = 0; i < 6; i++) { dc[i] = bytestream2_get_byte(&s->gb); bytestream2_skip(&s->gb, 1); } } else { av_log(s->avctx, AV_LOG_ERROR, "unsupported mb mode %i\n", mode); return -1; } tgq_idct_put_mb_dconly(s, frame, mb_x, mb_y, dc); } return 0; }
static int latm_decode_frame(AVCodecContext *avctx, void *out, int *got_frame_ptr, AVPacket *avpkt) { struct LATMContext *latmctx = avctx->priv_data; int muxlength, err; GetBitContext gb; if ((err = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) return err; // check for LOAS sync word if (get_bits(&gb, 11) != LOAS_SYNC_WORD) return AVERROR_INVALIDDATA; muxlength = get_bits(&gb, 13) + 3; // not enough data, the parser should have sorted this out if (muxlength > avpkt->size) return AVERROR_INVALIDDATA; if ((err = read_audio_mux_element(latmctx, &gb)) < 0) return err; if (!latmctx->initialized) { if (!avctx->extradata) { *got_frame_ptr = 0; return avpkt->size; } else { push_output_configuration(&latmctx->aac_ctx); if ((err = decode_audio_specific_config( &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.oc[1].m4ac, avctx->extradata, avctx->extradata_size*8LL, 1)) < 0) { pop_output_configuration(&latmctx->aac_ctx); return err; } latmctx->initialized = 1; } } if (show_bits(&gb, 12) == 0xfff) { av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, "ADTS header detected, probably as result of configuration " "misparsing\n"); return AVERROR_INVALIDDATA; } switch (latmctx->aac_ctx.oc[1].m4ac.object_type) { case AOT_ER_AAC_LC: case AOT_ER_AAC_LTP: case AOT_ER_AAC_LD: case AOT_ER_AAC_ELD: err = aac_decode_er_frame(avctx, out, got_frame_ptr, &gb); break; default: err = aac_decode_frame_int(avctx, out, got_frame_ptr, &gb, avpkt); } if (err < 0) return err; return muxlength; }
static int atrac3p_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { ATRAC3PContext *ctx = avctx->priv_data; AVFrame *frame = data; int i, ret, ch_unit_id, ch_block = 0, out_ch_index = 0, channels_to_process; float **samples_p = (float **)frame->extended_data; frame->nb_samples = ATRAC3P_FRAME_SAMPLES; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; if ((ret = init_get_bits8(&ctx->gb, avpkt->data, avpkt->size)) < 0) return ret; if (get_bits1(&ctx->gb)) { av_log(avctx, AV_LOG_ERROR, "Invalid start bit!\n"); return AVERROR_INVALIDDATA; } while (get_bits_left(&ctx->gb) >= 2 && (ch_unit_id = get_bits(&ctx->gb, 2)) != CH_UNIT_TERMINATOR) { if (ch_unit_id == CH_UNIT_EXTENSION) { avpriv_report_missing_feature(avctx, "Channel unit extension"); return AVERROR_PATCHWELCOME; } if (ch_block >= ctx->num_channel_blocks || ctx->channel_blocks[ch_block] != ch_unit_id) { av_log(avctx, AV_LOG_ERROR, "Frame data doesn't match channel configuration!\n"); return AVERROR_INVALIDDATA; } ctx->ch_units[ch_block].unit_type = ch_unit_id; channels_to_process = ch_unit_id + 1; if ((ret = ff_atrac3p_decode_channel_unit(&ctx->gb, &ctx->ch_units[ch_block], channels_to_process, avctx)) < 0) return ret; decode_residual_spectrum(&ctx->ch_units[ch_block], ctx->samples, channels_to_process, avctx); reconstruct_frame(ctx, &ctx->ch_units[ch_block], channels_to_process, avctx); for (i = 0; i < channels_to_process; i++) memcpy(samples_p[out_ch_index + i], ctx->outp_buf[i], ATRAC3P_FRAME_SAMPLES * sizeof(**samples_p)); ch_block++; out_ch_index += channels_to_process; } *got_frame_ptr = 1; return FFMIN(avctx->block_align, avpkt->size); }
/** * Range decoder */ static int opus_rc_init(OpusRangeCoder *rc, const uint8_t *data, int size) { int ret = init_get_bits8(&rc->gb, data, size); if (ret < 0) return ret; rc->range = 128; rc->value = 127 - get_bits(&rc->gb, 7); rc->total_read_bits = 9; opus_rc_normalize(rc); return 0; }
static int ra288_decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; float *out; int i, ret; RA288Context *ractx = avctx->priv_data; GetBitContext gb; if (buf_size < avctx->block_align) { av_log(avctx, AV_LOG_ERROR, "Error! Input buffer is too small [%d<%d]\n", buf_size, avctx->block_align); return AVERROR_INVALIDDATA; } ret = init_get_bits8(&gb, buf, avctx->block_align); if (ret < 0) return ret; /* get output buffer */ frame->nb_samples = RA288_BLOCK_SIZE * RA288_BLOCKS_PER_FRAME; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; out = (float *)frame->data[0]; for (i=0; i < RA288_BLOCKS_PER_FRAME; i++) { float gain = amptable[get_bits(&gb, 3)]; int cb_coef = get_bits(&gb, 6 + (i&1)); decode(ractx, gain, cb_coef); memcpy(out, &ractx->sp_hist[70 + 36], RA288_BLOCK_SIZE * sizeof(*out)); out += RA288_BLOCK_SIZE; if ((i & 7) == 3) { backward_filter(ractx, ractx->sp_hist, ractx->sp_rec, syn_window, ractx->sp_lpc, syn_bw_tab, 36, 40, 35, 70); backward_filter(ractx, ractx->gain_hist, ractx->gain_rec, gain_window, ractx->gain_lpc, gain_bw_tab, 10, 8, 20, 28); } } *got_frame_ptr = 1; return avctx->block_align; }
int avpriv_dca_parse_core_frame_header(DCACoreFrameHeader *h, const uint8_t *buf, int size) { GetBitContext gb; int ret; ret = init_get_bits8(&gb, buf, size); if (ret < 0) return ret; if (ff_dca_parse_core_frame_header(h, &gb) < 0) return AVERROR_INVALIDDATA; return 0; }
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { BinkAudioContext *s = avctx->priv_data; AVFrame *frame = data; GetBitContext *gb = &s->gb; int ret, consumed = 0; if (!get_bits_left(gb)) { 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 + FF_INPUT_BUFFER_PADDING_SIZE); if (!buf) return AVERROR(ENOMEM); memset(buf + avpkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE); s->packet_buffer = buf; memcpy(s->packet_buffer, avpkt->data, avpkt->size); if ((ret = init_get_bits8(gb, s->packet_buffer, avpkt->size)) < 0) return ret; consumed = avpkt->size; /* skip reported size */ skip_bits_long(gb, 32); } /* get output buffer */ frame->nb_samples = s->frame_len; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) 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(gb); frame->nb_samples = s->block_size / avctx->channels; *got_frame_ptr = 1; return consumed; }
static void bitline2chunky(CDXLVideoContext *c, int linesize, uint8_t *out) { GetBitContext gb; int x, y, plane; if (init_get_bits8(&gb, c->video, c->video_size) < 0) return; for (y = 0; y < c->avctx->height; y++) { for (plane = 0; plane < c->bpp; plane++) { for (x = 0; x < c->avctx->width; x++) out[linesize * y + x] |= get_bits1(&gb) << plane; skip_bits(&gb, c->padded_bits); } } }
static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { MSS1Context *ctx = avctx->priv_data; MSS12Context *c = &ctx->ctx; GetBitContext gb; ArithCoder acoder; int pal_changed = 0; int ret; if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) return ret; arith_init(&acoder, &gb); if ((ret = ff_reget_buffer(avctx, ctx->pic)) < 0) return ret; c->pal_pic = ctx->pic->data[0] + ctx->pic->linesize[0] * (avctx->height - 1); c->pal_stride = -ctx->pic->linesize[0]; c->keyframe = !arith_get_bit(&acoder); if (c->keyframe) { c->corrupted = 0; ff_mss12_slicecontext_reset(&ctx->sc); pal_changed = decode_pal(c, &acoder); ctx->pic->key_frame = 1; ctx->pic->pict_type = AV_PICTURE_TYPE_I; } else { if (c->corrupted) return AVERROR_INVALIDDATA; ctx->pic->key_frame = 0; ctx->pic->pict_type = AV_PICTURE_TYPE_P; } c->corrupted = ff_mss12_decode_rect(&ctx->sc, &acoder, 0, 0, avctx->width, avctx->height); if (c->corrupted) return AVERROR_INVALIDDATA; memcpy(ctx->pic->data[1], c->pal, AVPALETTE_SIZE); ctx->pic->palette_has_changed = pal_changed; if ((ret = av_frame_ref(data, ctx->pic)) < 0) return ret; *got_frame = 1; /* always report that the buffer was completely consumed */ return avpkt->size; }
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { SmackVContext * const smk = avctx->priv_data; uint8_t *out; uint32_t *pal; GetByteContext gb2; GetBitContext gb; int blocks, blk, bw, bh; int i, ret; int stride; int flags; if (avpkt->size <= 769) return AVERROR_INVALIDDATA; if ((ret = ff_reget_buffer(avctx, smk->pic)) < 0) return ret; /* make the palette available on the way out */ pal = (uint32_t*)smk->pic->data[1]; bytestream2_init(&gb2, avpkt->data, avpkt->size); flags = bytestream2_get_byteu(&gb2); smk->pic->palette_has_changed = flags & 1; smk->pic->key_frame = !!(flags & 2); if (smk->pic->key_frame) smk->pic->pict_type = AV_PICTURE_TYPE_I; else smk->pic->pict_type = AV_PICTURE_TYPE_P; for(i = 0; i < 256; i++) *pal++ = 0xFFU << 24 | bytestream2_get_be24u(&gb2); last_reset(smk->mmap_tbl, smk->mmap_last); last_reset(smk->mclr_tbl, smk->mclr_last); last_reset(smk->full_tbl, smk->full_last); last_reset(smk->type_tbl, smk->type_last); if ((ret = init_get_bits8(&gb, avpkt->data + 769, avpkt->size - 769)) < 0) return ret; blk = 0; bw = avctx->width >> 2; bh = avctx->height >> 2; blocks = bw * bh; stride = smk->pic->linesize[0]; while(blk < blocks) { int type, run, mode; uint16_t pix; type = smk_get_code(&gb, smk->type_tbl, smk->type_last); run = block_runs[(type >> 2) & 0x3F]; switch(type & 3){ case SMK_BLK_MONO: while(run-- && blk < blocks){ int clr, map; int hi, lo; clr = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last); map = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last); out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; hi = clr >> 8; lo = clr & 0xFF; for(i = 0; i < 4; i++) { if(map & 1) out[0] = hi; else out[0] = lo; if(map & 2) out[1] = hi; else out[1] = lo; if(map & 4) out[2] = hi; else out[2] = lo; if(map & 8) out[3] = hi; else out[3] = lo; map >>= 4; out += stride; } blk++; } break; case SMK_BLK_FULL: mode = 0; if(avctx->codec_tag == MKTAG('S', 'M', 'K', '4')) { // In case of Smacker v4 we have three modes if(get_bits1(&gb)) mode = 1; else if(get_bits1(&gb)) mode = 2; } while(run-- && blk < blocks){ out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; switch(mode){ case 0: for(i = 0; i < 4; i++) { pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); AV_WL16(out+2,pix); pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); AV_WL16(out,pix); out += stride; } break; case 1: pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); out[0] = out[1] = pix & 0xFF; out[2] = out[3] = pix >> 8; out += stride; out[0] = out[1] = pix & 0xFF; out[2] = out[3] = pix >> 8; out += stride; pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); out[0] = out[1] = pix & 0xFF; out[2] = out[3] = pix >> 8; out += stride; out[0] = out[1] = pix & 0xFF; out[2] = out[3] = pix >> 8; break; case 2: for(i = 0; i < 2; i++) { uint16_t pix1, pix2; pix2 = smk_get_code(&gb, smk->full_tbl, smk->full_last); pix1 = smk_get_code(&gb, smk->full_tbl, smk->full_last); AV_WL16(out,pix1); AV_WL16(out+2,pix2); out += stride; AV_WL16(out,pix1); AV_WL16(out+2,pix2); out += stride; } break; } blk++; } break; case SMK_BLK_SKIP: while(run-- && blk < blocks) blk++; break; case SMK_BLK_FILL: mode = type >> 8; while(run-- && blk < blocks){ uint32_t col; out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; col = mode * 0x01010101; for(i = 0; i < 4; i++) { *((uint32_t*)out) = col; out += stride; } blk++; } break; } } if ((ret = av_frame_ref(data, smk->pic)) < 0) return ret; *got_frame = 1; /* always report that the buffer was completely consumed */ return avpkt->size; }
static int decode_header_trees(SmackVContext *smk) { GetBitContext gb; int mmap_size, mclr_size, full_size, type_size, ret; mmap_size = AV_RL32(smk->avctx->extradata); mclr_size = AV_RL32(smk->avctx->extradata + 4); full_size = AV_RL32(smk->avctx->extradata + 8); type_size = AV_RL32(smk->avctx->extradata + 12); ret = init_get_bits8(&gb, smk->avctx->extradata + 16, smk->avctx->extradata_size - 16); if (ret < 0) return ret; if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping MMAP tree\n"); smk->mmap_tbl = av_malloc(sizeof(int) * 2); if (!smk->mmap_tbl) return AVERROR(ENOMEM); smk->mmap_tbl[0] = 0; smk->mmap_last[0] = smk->mmap_last[1] = smk->mmap_last[2] = 1; } else { ret = smacker_decode_header_tree(smk, &gb, &smk->mmap_tbl, smk->mmap_last, mmap_size); if (ret < 0) return ret; } if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping MCLR tree\n"); smk->mclr_tbl = av_malloc(sizeof(int) * 2); if (!smk->mclr_tbl) return AVERROR(ENOMEM); smk->mclr_tbl[0] = 0; smk->mclr_last[0] = smk->mclr_last[1] = smk->mclr_last[2] = 1; } else { ret = smacker_decode_header_tree(smk, &gb, &smk->mclr_tbl, smk->mclr_last, mclr_size); if (ret < 0) return ret; } if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping FULL tree\n"); smk->full_tbl = av_malloc(sizeof(int) * 2); if (!smk->full_tbl) return AVERROR(ENOMEM); smk->full_tbl[0] = 0; smk->full_last[0] = smk->full_last[1] = smk->full_last[2] = 1; } else { ret = smacker_decode_header_tree(smk, &gb, &smk->full_tbl, smk->full_last, full_size); if (ret < 0) return ret; } if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping TYPE tree\n"); smk->type_tbl = av_malloc(sizeof(int) * 2); if (!smk->type_tbl) return AVERROR(ENOMEM); smk->type_tbl[0] = 0; smk->type_last[0] = smk->type_last[1] = smk->type_last[2] = 1; } else { ret = smacker_decode_header_tree(smk, &gb, &smk->type_tbl, smk->type_last, type_size); if (ret < 0) return ret; } return 0; }
int ff_hevc_split_packet(HEVCContext *s, HEVCPacket *pkt, const uint8_t *buf, int length, AVCodecContext *avctx, int is_nalff, int nal_length_size) { int consumed, ret = 0; pkt->nb_nals = 0; while (length >= 4) { HEVCNAL *nal; int extract_length = 0; if (is_nalff) { int i; for (i = 0; i < nal_length_size; i++) extract_length = (extract_length << 8) | buf[i]; buf += nal_length_size; length -= nal_length_size; if (extract_length > length) { av_log(avctx, AV_LOG_ERROR, "Invalid NAL unit size.\n"); return AVERROR_INVALIDDATA; } } else { /* search start code */ while (buf[0] != 0 || buf[1] != 0 || buf[2] != 1) { ++buf; --length; if (length < 4) { av_log(avctx, AV_LOG_ERROR, "No start code is found.\n"); return AVERROR_INVALIDDATA; } } buf += 3; length -= 3; extract_length = length; } if (pkt->nals_allocated < pkt->nb_nals + 1) { int new_size = pkt->nals_allocated + 1; void *tmp = av_realloc_array(pkt->nals, new_size, sizeof(*pkt->nals)); if (!tmp) return AVERROR(ENOMEM); pkt->nals = tmp; memset(pkt->nals + pkt->nals_allocated, 0, (new_size - pkt->nals_allocated) * sizeof(*pkt->nals)); nal = &pkt->nals[pkt->nb_nals]; nal->skipped_bytes_pos_size = 1024; // initial buffer size nal->skipped_bytes_pos = av_malloc_array(nal->skipped_bytes_pos_size, sizeof(*nal->skipped_bytes_pos)); if (!nal->skipped_bytes_pos) return AVERROR(ENOMEM); pkt->nals_allocated = new_size; } nal = &pkt->nals[pkt->nb_nals]; consumed = ff_hevc_extract_rbsp(s, buf, extract_length, nal); if (consumed < 0) return consumed; pkt->nb_nals++; ret = init_get_bits8(&nal->gb, nal->data, nal->size); if (ret < 0) return ret; ret = hls_nal_unit(nal, avctx); if (ret <= 0) { if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Invalid NAL unit %d, skipping.\n", nal->type); } pkt->nb_nals--; } buf += consumed; length -= consumed; } return 0; }
static int decode_speedhq_field(const SHQContext *s, const uint8_t *buf, int buf_size, AVFrame *frame, int field_number, int start, int end, int line_stride) { int ret, slice_number, slice_offsets[5]; int linesize_y = frame->linesize[0] * line_stride; int linesize_cb = frame->linesize[1] * line_stride; int linesize_cr = frame->linesize[2] * line_stride; int linesize_a; if (s->alpha_type != SHQ_NO_ALPHA) linesize_a = frame->linesize[3] * line_stride; if (end < start || end - start < 3 || end > buf_size) return AVERROR_INVALIDDATA; slice_offsets[0] = start; slice_offsets[4] = end; for (slice_number = 1; slice_number < 4; slice_number++) { uint32_t last_offset, slice_len; last_offset = slice_offsets[slice_number - 1]; slice_len = AV_RL24(buf + last_offset); slice_offsets[slice_number] = last_offset + slice_len; if (slice_len < 3 || slice_offsets[slice_number] > end - 3) return AVERROR_INVALIDDATA; } for (slice_number = 0; slice_number < 4; slice_number++) { GetBitContext gb; uint32_t slice_begin, slice_end; int x, y; slice_begin = slice_offsets[slice_number]; slice_end = slice_offsets[slice_number + 1]; if ((ret = init_get_bits8(&gb, buf + slice_begin + 3, slice_end - slice_begin - 3)) < 0) return ret; for (y = slice_number * 16 * line_stride; y < frame->height; y += line_stride * 64) { uint8_t *dest_y, *dest_cb, *dest_cr, *dest_a; int last_dc[4] = { 1024, 1024, 1024, 1024 }; uint8_t last_alpha[16]; memset(last_alpha, 255, sizeof(last_alpha)); dest_y = frame->data[0] + frame->linesize[0] * (y + field_number); if (s->subsampling == SHQ_SUBSAMPLING_420) { dest_cb = frame->data[1] + frame->linesize[1] * (y/2 + field_number); dest_cr = frame->data[2] + frame->linesize[2] * (y/2 + field_number); } else { dest_cb = frame->data[1] + frame->linesize[1] * (y + field_number); dest_cr = frame->data[2] + frame->linesize[2] * (y + field_number); } if (s->alpha_type != SHQ_NO_ALPHA) { dest_a = frame->data[3] + frame->linesize[3] * (y + field_number); } for (x = 0; x < frame->width; x += 16) { /* Decode the four luma blocks. */ if ((ret = decode_dct_block(s, &gb, last_dc, 0, dest_y, linesize_y)) < 0) return ret; if ((ret = decode_dct_block(s, &gb, last_dc, 0, dest_y + 8, linesize_y)) < 0) return ret; if ((ret = decode_dct_block(s, &gb, last_dc, 0, dest_y + 8 * linesize_y, linesize_y)) < 0) return ret; if ((ret = decode_dct_block(s, &gb, last_dc, 0, dest_y + 8 * linesize_y + 8, linesize_y)) < 0) return ret; /* * Decode the first chroma block. For 4:2:0, this is the only one; * for 4:2:2, it's the top block; for 4:4:4, it's the top-left block. */ if ((ret = decode_dct_block(s, &gb, last_dc, 1, dest_cb, linesize_cb)) < 0) return ret; if ((ret = decode_dct_block(s, &gb, last_dc, 2, dest_cr, linesize_cr)) < 0) return ret; if (s->subsampling != SHQ_SUBSAMPLING_420) { /* For 4:2:2, this is the bottom block; for 4:4:4, it's the bottom-left block. */ if ((ret = decode_dct_block(s, &gb, last_dc, 1, dest_cb + 8 * linesize_cb, linesize_cb)) < 0) return ret; if ((ret = decode_dct_block(s, &gb, last_dc, 2, dest_cr + 8 * linesize_cr, linesize_cr)) < 0) return ret; if (s->subsampling == SHQ_SUBSAMPLING_444) { /* Top-right and bottom-right blocks. */ if ((ret = decode_dct_block(s, &gb, last_dc, 1, dest_cb + 8, linesize_cb)) < 0) return ret; if ((ret = decode_dct_block(s, &gb, last_dc, 2, dest_cr + 8, linesize_cr)) < 0) return ret; if ((ret = decode_dct_block(s, &gb, last_dc, 1, dest_cb + 8 * linesize_cb + 8, linesize_cb)) < 0) return ret; if ((ret = decode_dct_block(s, &gb, last_dc, 2, dest_cr + 8 * linesize_cr + 8, linesize_cr)) < 0) return ret; dest_cb += 8; dest_cr += 8; } } dest_y += 16; dest_cb += 8; dest_cr += 8; if (s->alpha_type == SHQ_RLE_ALPHA) { /* Alpha coded using 16x8 RLE blocks. */ if ((ret = decode_alpha_block(s, &gb, last_alpha, dest_a, linesize_a)) < 0) return ret; if ((ret = decode_alpha_block(s, &gb, last_alpha, dest_a + 8 * linesize_a, linesize_a)) < 0) return ret; dest_a += 16; } else if (s->alpha_type == SHQ_DCT_ALPHA) { /* Alpha encoded exactly like luma. */ if ((ret = decode_dct_block(s, &gb, last_dc, 3, dest_a, linesize_a)) < 0) return ret; if ((ret = decode_dct_block(s, &gb, last_dc, 3, dest_a + 8, linesize_a)) < 0) return ret; if ((ret = decode_dct_block(s, &gb, last_dc, 3, dest_a + 8 * linesize_a, linesize_a)) < 0) return ret; if ((ret = decode_dct_block(s, &gb, last_dc, 3, dest_a + 8 * linesize_a + 8, linesize_a)) < 0) return ret; dest_a += 16; } } } } return 0; }
int ff_dca_exss_parse(DCAExssParser *s, uint8_t *data, int size) { int i, ret, offset, wide_hdr, header_size; if ((ret = init_get_bits8(&s->gb, data, size)) < 0) return ret; // Extension substream sync word skip_bits_long(&s->gb, 32); // User defined bits skip_bits(&s->gb, 8); // Extension substream index s->exss_index = get_bits(&s->gb, 2); // Flag indicating short or long header size wide_hdr = get_bits1(&s->gb); // Extension substream header length header_size = get_bits(&s->gb, 8 + 4 * wide_hdr) + 1; // Check CRC if (ff_dca_check_crc(s->avctx, &s->gb, 32 + 8, header_size * 8)) { av_log(s->avctx, AV_LOG_ERROR, "Invalid EXSS header checksum\n"); return AVERROR_INVALIDDATA; } s->exss_size_nbits = 16 + 4 * wide_hdr; // Number of bytes of extension substream s->exss_size = get_bits(&s->gb, s->exss_size_nbits) + 1; if (s->exss_size > size) { av_log(s->avctx, AV_LOG_ERROR, "Packet too short for EXSS frame\n"); return AVERROR_INVALIDDATA; } // Per stream static fields presence flag if (s->static_fields_present = get_bits1(&s->gb)) { int active_exss_mask[8]; // Reference clock code skip_bits(&s->gb, 2); // Extension substream frame duration skip_bits(&s->gb, 3); // Timecode presence flag if (get_bits1(&s->gb)) // Timecode data skip_bits_long(&s->gb, 36); // Number of defined audio presentations s->npresents = get_bits(&s->gb, 3) + 1; if (s->npresents > 1) { avpriv_request_sample(s->avctx, "%d audio presentations", s->npresents); return AVERROR_PATCHWELCOME; } // Number of audio assets in extension substream s->nassets = get_bits(&s->gb, 3) + 1; if (s->nassets > 1) { avpriv_request_sample(s->avctx, "%d audio assets", s->nassets); return AVERROR_PATCHWELCOME; } // Active extension substream mask for audio presentation for (i = 0; i < s->npresents; i++) active_exss_mask[i] = get_bits(&s->gb, s->exss_index + 1); // Active audio asset mask for (i = 0; i < s->npresents; i++) skip_bits_long(&s->gb, av_popcount(active_exss_mask[i]) * 8); // Mixing metadata enable flag if (s->mix_metadata_enabled = get_bits1(&s->gb)) { int spkr_mask_nbits; // Mixing metadata adjustment level skip_bits(&s->gb, 2); // Number of bits for mixer output speaker activity mask spkr_mask_nbits = (get_bits(&s->gb, 2) + 1) << 2; // Number of mixing configurations s->nmixoutconfigs = get_bits(&s->gb, 2) + 1; // Speaker layout mask for mixer output channels for (i = 0; i < s->nmixoutconfigs; i++) s->nmixoutchs[i] = ff_dca_count_chs_for_mask(get_bits(&s->gb, spkr_mask_nbits)); } } else { s->npresents = 1; s->nassets = 1; } // Size of encoded asset data in bytes offset = header_size; for (i = 0; i < s->nassets; i++) { s->assets[i].asset_offset = offset; s->assets[i].asset_size = get_bits(&s->gb, s->exss_size_nbits) + 1; offset += s->assets[i].asset_size; if (offset > s->exss_size) { av_log(s->avctx, AV_LOG_ERROR, "EXSS asset out of bounds\n"); return AVERROR_INVALIDDATA; } } // Audio asset descriptor for (i = 0; i < s->nassets; i++) { if ((ret = parse_descriptor(s, &s->assets[i])) < 0) return ret; if ((ret = set_exss_offsets(&s->assets[i])) < 0) { av_log(s->avctx, AV_LOG_ERROR, "Invalid extension size in EXSS asset descriptor\n"); return ret; } } // Backward compatible core present // Backward compatible core substream index // Backward compatible core asset index // Reserved // Byte align // CRC16 of extension substream header if (ff_dca_seek_bits(&s->gb, header_size * 8)) { av_log(s->avctx, AV_LOG_ERROR, "Read past end of EXSS header\n"); return AVERROR_INVALIDDATA; } return 0; }
static int magy_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { MagicYUVContext *s = avctx->priv_data; ThreadFrame frame = { .f = data }; AVFrame *p = data; GetByteContext gbyte; GetBitContext gbit; uint32_t first_offset, offset, next_offset, header_size, slice_width; int width, height, format, version, table_size; int ret, i, j; bytestream2_init(&gbyte, avpkt->data, avpkt->size); if (bytestream2_get_le32(&gbyte) != MKTAG('M', 'A', 'G', 'Y')) return AVERROR_INVALIDDATA; header_size = bytestream2_get_le32(&gbyte); if (header_size < 32 || header_size >= avpkt->size) { av_log(avctx, AV_LOG_ERROR, "header or packet too small %"PRIu32"\n", header_size); return AVERROR_INVALIDDATA; } version = bytestream2_get_byte(&gbyte); if (version != 7) { avpriv_request_sample(avctx, "Version %d", version); return AVERROR_PATCHWELCOME; } s->hshift[1] = s->vshift[1] = s->hshift[2] = s->vshift[2] = 0; s->decorrelate = 0; s->max = 256; s->huff_build = huff_build; s->magy_decode_slice = magy_decode_slice; format = bytestream2_get_byte(&gbyte); switch (format) { case 0x65: avctx->pix_fmt = AV_PIX_FMT_GBRP; s->decorrelate = 1; break; case 0x66: avctx->pix_fmt = AV_PIX_FMT_GBRAP; s->decorrelate = 1; break; case 0x67: avctx->pix_fmt = AV_PIX_FMT_YUV444P; break; case 0x68: avctx->pix_fmt = AV_PIX_FMT_YUV422P; s->hshift[1] = s->hshift[2] = 1; break; case 0x69: avctx->pix_fmt = AV_PIX_FMT_YUV420P; s->hshift[1] = s->vshift[1] = s->hshift[2] = s->vshift[2] = 1; break; case 0x6a: avctx->pix_fmt = AV_PIX_FMT_YUVA444P; break; case 0x6b: avctx->pix_fmt = AV_PIX_FMT_GRAY8; break; case 0x6c: avctx->pix_fmt = AV_PIX_FMT_YUV422P10; s->hshift[1] = s->hshift[2] = 1; s->max = 1024; s->huff_build = huff_build10; s->magy_decode_slice = magy_decode_slice10; break; case 0x6d: avctx->pix_fmt = AV_PIX_FMT_GBRP10; s->decorrelate = 1; s->max = 1024; s->huff_build = huff_build10; s->magy_decode_slice = magy_decode_slice10; break; case 0x6e: avctx->pix_fmt = AV_PIX_FMT_GBRAP10; s->decorrelate = 1; s->max = 1024; s->huff_build = huff_build10; s->magy_decode_slice = magy_decode_slice10; break; case 0x73: avctx->pix_fmt = AV_PIX_FMT_GRAY10; s->max = 1024; s->huff_build = huff_build10; s->magy_decode_slice = magy_decode_slice10; break; default: avpriv_request_sample(avctx, "Format 0x%X", format); return AVERROR_PATCHWELCOME; } s->planes = av_pix_fmt_count_planes(avctx->pix_fmt); bytestream2_skip(&gbyte, 2); s->interlaced = !!(bytestream2_get_byte(&gbyte) & 2); bytestream2_skip(&gbyte, 3); width = bytestream2_get_le32(&gbyte); height = bytestream2_get_le32(&gbyte); ret = ff_set_dimensions(avctx, width, height); if (ret < 0) return ret; slice_width = bytestream2_get_le32(&gbyte); if (slice_width != avctx->coded_width) { avpriv_request_sample(avctx, "Slice width %"PRIu32, slice_width); return AVERROR_PATCHWELCOME; } s->slice_height = bytestream2_get_le32(&gbyte); if (s->slice_height <= 0 || s->slice_height > INT_MAX - avctx->coded_height) { av_log(avctx, AV_LOG_ERROR, "invalid slice height: %d\n", s->slice_height); return AVERROR_INVALIDDATA; } bytestream2_skip(&gbyte, 4); s->nb_slices = (avctx->coded_height + s->slice_height - 1) / s->slice_height; if (s->nb_slices > INT_MAX / sizeof(Slice)) { av_log(avctx, AV_LOG_ERROR, "invalid number of slices: %d\n", s->nb_slices); return AVERROR_INVALIDDATA; } for (i = 0; i < s->planes; i++) { av_fast_malloc(&s->slices[i], &s->slices_size[i], s->nb_slices * sizeof(Slice)); if (!s->slices[i]) return AVERROR(ENOMEM); offset = bytestream2_get_le32(&gbyte); if (offset >= avpkt->size - header_size) return AVERROR_INVALIDDATA; if (i == 0) first_offset = offset; for (j = 0; j < s->nb_slices - 1; j++) { s->slices[i][j].start = offset + header_size; next_offset = bytestream2_get_le32(&gbyte); if (next_offset <= offset || next_offset >= avpkt->size - header_size) return AVERROR_INVALIDDATA; s->slices[i][j].size = next_offset - offset; offset = next_offset; } s->slices[i][j].start = offset + header_size; s->slices[i][j].size = avpkt->size - s->slices[i][j].start; } if (bytestream2_get_byte(&gbyte) != s->planes) return AVERROR_INVALIDDATA; bytestream2_skip(&gbyte, s->nb_slices * s->planes); table_size = header_size + first_offset - bytestream2_tell(&gbyte); if (table_size < 2) return AVERROR_INVALIDDATA; ret = init_get_bits8(&gbit, avpkt->data + bytestream2_tell(&gbyte), table_size); if (ret < 0) return ret; ret = build_huffman(avctx, &gbit, s->max); if (ret < 0) return ret; p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) return ret; s->buf = avpkt->data; s->p = p; avctx->execute2(avctx, s->magy_decode_slice, NULL, NULL, s->nb_slices); if (avctx->pix_fmt == AV_PIX_FMT_GBRP || avctx->pix_fmt == AV_PIX_FMT_GBRAP || avctx->pix_fmt == AV_PIX_FMT_GBRP10 || avctx->pix_fmt == AV_PIX_FMT_GBRAP10) { FFSWAP(uint8_t*, p->data[0], p->data[1]); FFSWAP(int, p->linesize[0], p->linesize[1]); }
static int tak_read_header(AVFormatContext *s) { TAKDemuxContext *tc = s->priv_data; AVIOContext *pb = s->pb; GetBitContext gb; AVStream *st; uint8_t *buffer = NULL; int ret; st = avformat_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_TAK; st->need_parsing = AVSTREAM_PARSE_FULL_RAW; tc->mlast_frame = 0; if (avio_rl32(pb) != MKTAG('t', 'B', 'a', 'K')) { avio_seek(pb, -4, SEEK_CUR); return 0; } while (!avio_feof(pb)) { enum TAKMetaDataType type; int size; type = avio_r8(pb) & 0x7f; size = avio_rl24(pb); switch (type) { case TAK_METADATA_STREAMINFO: case TAK_METADATA_LAST_FRAME: case TAK_METADATA_ENCODER: if (size <= 3) return AVERROR_INVALIDDATA; buffer = av_malloc(size - 3 + FF_INPUT_BUFFER_PADDING_SIZE); if (!buffer) return AVERROR(ENOMEM); memset(buffer + size - 3, 0, FF_INPUT_BUFFER_PADDING_SIZE); ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U); if (avio_read(pb, buffer, size - 3) != size - 3) { av_freep(&buffer); return AVERROR(EIO); } if (ffio_get_checksum(s->pb) != avio_rb24(pb)) { av_log(s, AV_LOG_ERROR, "%d metadata block CRC error.\n", type); if (s->error_recognition & AV_EF_EXPLODE) { av_freep(&buffer); return AVERROR_INVALIDDATA; } } init_get_bits8(&gb, buffer, size - 3); break; case TAK_METADATA_MD5: { uint8_t md5[16]; int i; if (size != 19) return AVERROR_INVALIDDATA; ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U); avio_read(pb, md5, 16); if (ffio_get_checksum(s->pb) != avio_rb24(pb)) { av_log(s, AV_LOG_ERROR, "MD5 metadata block CRC error.\n"); if (s->error_recognition & AV_EF_EXPLODE) return AVERROR_INVALIDDATA; } av_log(s, AV_LOG_VERBOSE, "MD5="); for (i = 0; i < 16; i++) av_log(s, AV_LOG_VERBOSE, "%02x", md5[i]); av_log(s, AV_LOG_VERBOSE, "\n"); break; } case TAK_METADATA_END: { int64_t curpos = avio_tell(pb); if (pb->seekable) { ff_ape_parse_tag(s); avio_seek(pb, curpos, SEEK_SET); } tc->data_end += curpos; return 0; } default: ret = avio_skip(pb, size); if (ret < 0) return ret; } if (type == TAK_METADATA_STREAMINFO) { TAKStreamInfo ti; avpriv_tak_parse_streaminfo(&gb, &ti); if (ti.samples > 0) st->duration = ti.samples; st->codec->bits_per_coded_sample = ti.bps; if (ti.ch_layout) st->codec->channel_layout = ti.ch_layout; st->codec->sample_rate = ti.sample_rate; st->codec->channels = ti.channels; st->start_time = 0; avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); st->codec->extradata = buffer; st->codec->extradata_size = size - 3; buffer = NULL; } else if (type == TAK_METADATA_LAST_FRAME) { if (size != 11) return AVERROR_INVALIDDATA; tc->mlast_frame = 1; tc->data_end = get_bits64(&gb, TAK_LAST_FRAME_POS_BITS) + get_bits(&gb, TAK_LAST_FRAME_SIZE_BITS); av_freep(&buffer); } else if (type == TAK_METADATA_ENCODER) { av_log(s, AV_LOG_VERBOSE, "encoder version: %0X\n", get_bits_long(&gb, TAK_ENCODER_VERSION_BITS)); av_freep(&buffer); } } return AVERROR_EOF; }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AVSubtitle *sub = data; const uint8_t *buf_end = buf + buf_size; uint8_t *bitmap; int w, h, x, y, i, ret; int64_t packet_time = 0; GetBitContext gb; int has_alpha = avctx->codec_tag == MKTAG('D','X','S','A'); // check that at least header fits if (buf_size < 27 + 7 * 2 + 4 * (3 + has_alpha)) { av_log(avctx, AV_LOG_ERROR, "coded frame size %d too small\n", buf_size); return -1; } // read start and end time if (buf[0] != '[' || buf[13] != '-' || buf[26] != ']') { av_log(avctx, AV_LOG_ERROR, "invalid time code\n"); return -1; } if (avpkt->pts != AV_NOPTS_VALUE) packet_time = av_rescale_q(avpkt->pts, AV_TIME_BASE_Q, (AVRational){1, 1000}); sub->start_display_time = parse_timecode(buf + 1, packet_time); sub->end_display_time = parse_timecode(buf + 14, packet_time); buf += 27; // read header w = bytestream_get_le16(&buf); h = bytestream_get_le16(&buf); if (av_image_check_size(w, h, 0, avctx) < 0) return -1; x = bytestream_get_le16(&buf); y = bytestream_get_le16(&buf); // skip bottom right position, it gives no new information bytestream_get_le16(&buf); bytestream_get_le16(&buf); // The following value is supposed to indicate the start offset // (relative to the palette) of the data for the second field, // however there are files in which it has a bogus value and thus // we just ignore it bytestream_get_le16(&buf); // allocate sub and set values sub->rects = av_mallocz(sizeof(*sub->rects)); if (!sub->rects) return AVERROR(ENOMEM); sub->rects[0] = av_mallocz(sizeof(*sub->rects[0])); if (!sub->rects[0]) { av_freep(&sub->rects); return AVERROR(ENOMEM); } sub->rects[0]->x = x; sub->rects[0]->y = y; sub->rects[0]->w = w; sub->rects[0]->h = h; sub->rects[0]->type = SUBTITLE_BITMAP; sub->rects[0]->linesize[0] = w; sub->rects[0]->data[0] = av_malloc(w * h); sub->rects[0]->nb_colors = 4; sub->rects[0]->data[1] = av_mallocz(AVPALETTE_SIZE); if (!sub->rects[0]->data[0] || !sub->rects[0]->data[1]) { av_freep(&sub->rects[0]->data[1]); av_freep(&sub->rects[0]->data[0]); av_freep(&sub->rects[0]); av_freep(&sub->rects); return AVERROR(ENOMEM); } sub->num_rects = 1; // read palette for (i = 0; i < sub->rects[0]->nb_colors; i++) ((uint32_t*)sub->rects[0]->data[1])[i] = bytestream_get_be24(&buf); if (!has_alpha) { // make all except background (first entry) non-transparent for (i = 1; i < sub->rects[0]->nb_colors; i++) ((uint32_t *)sub->rects[0]->data[1])[i] |= 0xff000000; } else { for (i = 0; i < sub->rects[0]->nb_colors; i++) ((uint32_t *)sub->rects[0]->data[1])[i] |= *buf++ << 24; } #if FF_API_AVPICTURE FF_DISABLE_DEPRECATION_WARNINGS { AVSubtitleRect *rect; int j; rect = sub->rects[0]; for (j = 0; j < 4; j++) { rect->pict.data[j] = rect->data[j]; rect->pict.linesize[j] = rect->linesize[j]; } } FF_ENABLE_DEPRECATION_WARNINGS #endif // process RLE-compressed data if ((ret = init_get_bits8(&gb, buf, buf_end - buf)) < 0) return ret; bitmap = sub->rects[0]->data[0]; for (y = 0; y < h; y++) { // interlaced: do odd lines if (y == (h + 1) / 2) bitmap = sub->rects[0]->data[0] + w; for (x = 0; x < w; ) { int log2 = ff_log2_tab[show_bits(&gb, 8)]; int run = get_bits(&gb, 14 - 4 * (log2 >> 1)); int color = get_bits(&gb, 2); run = FFMIN(run, w - x); // run length 0 means till end of row if (!run) run = w - x; memset(bitmap, color, run); bitmap += run; x += run; } // interlaced, skip every second line bitmap += w; align_get_bits(&gb); } *data_size = 1; return buf_size; }
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *pkt) { GetBitContext gb; AVFrame *frame = data; int16_t pcm_data[2]; uint32_t samples; int8_t channel_hint[2]; int ret, chan, channels = 1; if (pkt->size < 13) return AVERROR_INVALIDDATA; if ((ret = init_get_bits8(&gb, pkt->data, pkt->size)) < 0) return ret; samples = get_bits_long(&gb, 32); if (samples == 0xffffffff) { skip_bits_long(&gb, 32); samples = get_bits_long(&gb, 32); } if (samples > pkt->size * 2) return AVERROR_INVALIDDATA; channel_hint[0] = get_sbits(&gb, 8); if (channel_hint[0] & 0x80) { channel_hint[0] = ~channel_hint[0]; channels = 2; } avctx->channels = channels; avctx->channel_layout = (channels == 2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; pcm_data[0] = get_sbits(&gb, 16); if (channels > 1) { channel_hint[1] = get_sbits(&gb, 8); pcm_data[1] = get_sbits(&gb, 16); } frame->nb_samples = samples; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; for (chan = 0; chan < channels; chan++) { uint16_t *dest = (uint16_t*)frame->data[0] + chan; int step_index = channel_hint[chan]; int output = pcm_data[chan]; int sample; for (sample = 0; sample < samples; sample++) { int lookup_size, lookup, highbit, lowbits; step_index = av_clip(step_index, 0, 88); lookup_size = size_table[step_index]; lookup = get_bits(&gb, lookup_size); highbit = 1 << (lookup_size - 1); lowbits = highbit - 1; if (lookup & highbit) lookup ^= highbit; else highbit = 0; if (lookup == lowbits) { output = get_sbits(&gb, 16); } else { int predict_index, diff; predict_index = (lookup << (7 - lookup_size)) | (step_index << 6); predict_index = av_clip(predict_index, 0, 5785); diff = predict_table[predict_index]; if (lookup) diff += ff_adpcm_step_table[step_index] >> (lookup_size - 1); if (highbit) diff = -diff; output = av_clip_int16(output + diff); } *dest = output; dest += channels; step_index += step_index_tables[lookup_size - 2][lookup]; } } *got_frame_ptr = 1; return pkt->size; }
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; GetBitContext gb; int *runs, *ref = NULL, *runend; int ret; int runsize = avctx->width + 2; int has_eol; runs = av_malloc_array(runsize, sizeof(runs[0])); ref = av_malloc_array(runsize, sizeof(ref[0])); if (!runs || !ref) { ret = AVERROR(ENOMEM); goto fail; } ref[0] = avctx->width; ref[1] = 0; ref[2] = 0; if ((ret = init_get_bits8(&gb, src, srcsize)) < 0) goto fail; has_eol = show_bits(&gb, 12) == 1 || show_bits(&gb, 16) == 1; for (j = 0; j < height; j++) { runend = runs + runsize; if (compr == TIFF_G4) { ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref); if (ret < 0) goto fail; } else { int g3d1 = (compr == TIFF_G3) && !(opts & 1); if (compr != TIFF_CCITT_RLE && has_eol && find_group3_syncmarker(&gb, srcsize * 8) < 0) break; if (compr == TIFF_CCITT_RLE || g3d1 || get_bits1(&gb)) ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs, runend); else ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref); if (compr == TIFF_CCITT_RLE) align_get_bits(&gb); } 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; }
/** Uncompress one block (20 bytes -> 160*2 bytes). */ static int ra144_decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; static const uint8_t sizes[LPC_ORDER] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2}; unsigned int refl_rms[NBLOCKS]; // RMS of the reflection coefficients int16_t block_coefs[NBLOCKS][LPC_ORDER]; // LPC coefficients of each sub-block unsigned int lpc_refl[LPC_ORDER]; // LPC reflection coefficients of the frame int i, j; int ret; int16_t *samples; unsigned int energy; RA144Context *ractx = avctx->priv_data; GetBitContext gb; if (buf_size < FRAME_SIZE) { av_log(avctx, AV_LOG_ERROR, "Frame too small (%d bytes). Truncated file?\n", buf_size); *got_frame_ptr = 0; return AVERROR_INVALIDDATA; } /* get output buffer */ frame->nb_samples = NBLOCKS * BLOCKSIZE; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; samples = (int16_t *)frame->data[0]; init_get_bits8(&gb, buf, FRAME_SIZE); for (i = 0; i < LPC_ORDER; i++) lpc_refl[i] = ff_lpc_refl_cb[i][get_bits(&gb, sizes[i])]; ff_eval_coefs(ractx->lpc_coef[0], lpc_refl); ractx->lpc_refl_rms[0] = ff_rms(lpc_refl); energy = ff_energy_tab[get_bits(&gb, 5)]; refl_rms[0] = ff_interp(ractx, block_coefs[0], 1, 1, ractx->old_energy); refl_rms[1] = ff_interp(ractx, block_coefs[1], 2, energy <= ractx->old_energy, ff_t_sqrt(energy*ractx->old_energy) >> 12); refl_rms[2] = ff_interp(ractx, block_coefs[2], 3, 0, energy); refl_rms[3] = ff_rescale_rms(ractx->lpc_refl_rms[0], energy); ff_int_to_int16(block_coefs[3], ractx->lpc_coef[0]); for (i=0; i < NBLOCKS; i++) { do_output_subblock(ractx, block_coefs[i], refl_rms[i], &gb); for (j=0; j < BLOCKSIZE; j++) *samples++ = av_clip_int16(ractx->curr_sblock[j + 10] << 2); } ractx->old_energy = energy; ractx->lpc_refl_rms[1] = ractx->lpc_refl_rms[0]; FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]); *got_frame_ptr = 1; return FRAME_SIZE; }
static int tak_parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size) { TAKParseContext *t = s->priv_data; ParseContext *pc = &t->pc; int next = END_NOT_FOUND; GetBitContext gb; int consumed = 0; int needed = buf_size ? TAK_MAX_FRAME_HEADER_BYTES : 8; int ret; if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { TAKStreamInfo ti; if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0) return ret; if (!ff_tak_decode_frame_header(avctx, &gb, &ti, 127)) s->duration = t->ti.last_frame_samples ? t->ti.last_frame_samples : t->ti.frame_samples; *poutbuf = buf; *poutbuf_size = buf_size; return buf_size; } while (buf_size || t->index + needed <= pc->index) { if (buf_size && t->index + TAK_MAX_FRAME_HEADER_BYTES > pc->index) { int tmp_buf_size = FFMIN(2 * TAK_MAX_FRAME_HEADER_BYTES, buf_size); const uint8_t *tmp_buf = buf; if (ff_combine_frame(pc, END_NOT_FOUND, &tmp_buf, &tmp_buf_size) != -1) return AVERROR(ENOMEM); consumed += tmp_buf_size; buf += tmp_buf_size; buf_size -= tmp_buf_size; } for (; t->index + needed <= pc->index; t->index++) { if (pc->buffer[ t->index ] == 0xFF && pc->buffer[ t->index + 1 ] == 0xA0) { TAKStreamInfo ti; if ((ret = init_get_bits8(&gb, pc->buffer + t->index, pc->index - t->index)) < 0) return ret; if (!ff_tak_decode_frame_header(avctx, &gb, pc->frame_start_found ? &ti : &t->ti, 127) && !ff_tak_check_crc(pc->buffer + t->index, get_bits_count(&gb) / 8)) { if (!pc->frame_start_found) { pc->frame_start_found = 1; s->duration = t->ti.last_frame_samples ? t->ti.last_frame_samples : t->ti.frame_samples; s->key_frame = !!(t->ti.flags & TAK_FRAME_FLAG_HAS_INFO); } else { pc->frame_start_found = 0; next = t->index - pc->index; t->index = 0; goto found; } } } } } found: if (consumed && !buf_size && next == END_NOT_FOUND || ff_combine_frame(pc, next, &buf, &buf_size) < 0) { *poutbuf = NULL; *poutbuf_size = 0; return buf_size + consumed; } if (next != END_NOT_FOUND) { next += consumed; pc->overread = FFMAX(0, -next); } *poutbuf = buf; *poutbuf_size = buf_size; return next; }
static int escape124_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { int buf_size = avpkt->size; Escape124Context *s = avctx->priv_data; AVFrame *frame = data; GetBitContext gb; unsigned frame_flags, frame_size; unsigned i; unsigned superblock_index, cb_index = 1, superblock_col_index = 0, superblocks_per_row = avctx->width / 8, skip = -1; uint16_t* old_frame_data, *new_frame_data; unsigned old_stride, new_stride; int ret; if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) return ret; // This call also guards the potential depth reads for the // codebook unpacking. if (get_bits_left(&gb) < 64) return -1; frame_flags = get_bits_long(&gb, 32); frame_size = get_bits_long(&gb, 32); // Leave last frame unchanged // FIXME: Is this necessary? I haven't seen it in any real samples if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) { if (!s->frame->data[0]) return AVERROR_INVALIDDATA; av_log(avctx, AV_LOG_DEBUG, "Skipping frame\n"); *got_frame = 1; if ((ret = av_frame_ref(frame, s->frame)) < 0) return ret; return frame_size; } for (i = 0; i < 3; i++) { if (frame_flags & (1 << (17 + i))) { unsigned cb_depth, cb_size; if (i == 2) { // This codebook can be cut off at places other than // powers of 2, leaving some of the entries undefined. cb_size = get_bits_long(&gb, 20); cb_depth = av_log2(cb_size - 1) + 1; } else { cb_depth = get_bits(&gb, 4); if (i == 0) { // This is the most basic codebook: pow(2,depth) entries // for a depth-length key cb_size = 1 << cb_depth; } else { // This codebook varies per superblock // FIXME: I don't think this handles integer overflow // properly cb_size = s->num_superblocks << cb_depth; } } av_free(s->codebooks[i].blocks); s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size); if (!s->codebooks[i].blocks) return -1; } } if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; new_frame_data = (uint16_t*)frame->data[0]; new_stride = frame->linesize[0] / 2; old_frame_data = (uint16_t*)s->frame->data[0]; old_stride = s->frame->linesize[0] / 2; for (superblock_index = 0; superblock_index < s->num_superblocks; superblock_index++) { MacroBlock mb; SuperBlock sb; unsigned multi_mask = 0; if (skip == -1) { // Note that this call will make us skip the rest of the blocks // if the frame prematurely ends skip = decode_skip_count(&gb); } if (skip) { copy_superblock(new_frame_data, new_stride, old_frame_data, old_stride); } else { copy_superblock(sb.pixels, 8, old_frame_data, old_stride); while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) { unsigned mask; mb = decode_macroblock(s, &gb, &cb_index, superblock_index); mask = get_bits(&gb, 16); multi_mask |= mask; for (i = 0; i < 16; i++) { if (mask & mask_matrix[i]) { insert_mb_into_sb(&sb, mb, i); } } } if (!get_bits1(&gb)) { unsigned inv_mask = get_bits(&gb, 4); for (i = 0; i < 4; i++) { if (inv_mask & (1 << i)) { multi_mask ^= 0xF << i*4; } else { multi_mask ^= get_bits(&gb, 4) << i*4; } } for (i = 0; i < 16; i++) { if (multi_mask & mask_matrix[i]) { mb = decode_macroblock(s, &gb, &cb_index, superblock_index); insert_mb_into_sb(&sb, mb, i); } } } else if (frame_flags & (1 << 16)) { while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) { mb = decode_macroblock(s, &gb, &cb_index, superblock_index); insert_mb_into_sb(&sb, mb, get_bits(&gb, 4)); } } copy_superblock(new_frame_data, new_stride, sb.pixels, 8); } superblock_col_index++; new_frame_data += 8; if (old_frame_data) old_frame_data += 8; if (superblock_col_index == superblocks_per_row) { new_frame_data += new_stride * 8 - superblocks_per_row * 8; if (old_frame_data) old_frame_data += old_stride * 8 - superblocks_per_row * 8; superblock_col_index = 0; } skip--; } av_log(avctx, AV_LOG_DEBUG, "Escape sizes: %i, %i, %i\n", frame_size, buf_size, get_bits_count(&gb) / 8); av_frame_unref(s->frame); if ((ret = av_frame_ref(s->frame, frame)) < 0) return ret; *got_frame = 1; return frame_size; }
/** * Decode Smacker audio data */ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; GetBitContext gb; HuffContext h[4] = { { 0 } }; VLC vlc[4] = { { 0 } }; int16_t *samples; uint8_t *samples8; int val; int i, res, ret; int unp_size; int bits, stereo; int pred[2] = {0, 0}; if (buf_size <= 4) { av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); return AVERROR(EINVAL); } unp_size = AV_RL32(buf); if (unp_size > (1U<<24)) { av_log(avctx, AV_LOG_ERROR, "packet is too big\n"); return AVERROR_INVALIDDATA; } if ((ret = init_get_bits8(&gb, buf + 4, buf_size - 4)) < 0) return ret; if(!get_bits1(&gb)){ av_log(avctx, AV_LOG_INFO, "Sound: no data\n"); *got_frame_ptr = 0; return 1; } stereo = get_bits1(&gb); bits = get_bits1(&gb); if (stereo ^ (avctx->channels != 1)) { av_log(avctx, AV_LOG_ERROR, "channels mismatch\n"); return AVERROR(EINVAL); } if (bits == (avctx->sample_fmt == AV_SAMPLE_FMT_U8)) { av_log(avctx, AV_LOG_ERROR, "sample format mismatch\n"); return AVERROR(EINVAL); } /* get output buffer */ frame->nb_samples = unp_size / (avctx->channels * (bits + 1)); if (unp_size % (avctx->channels * (bits + 1))) { av_log(avctx, AV_LOG_ERROR, "unp_size %d is odd\n", unp_size); return AVERROR(EINVAL); } if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; samples = (int16_t *)frame->data[0]; samples8 = frame->data[0]; // Initialize for(i = 0; i < (1 << (bits + stereo)); i++) { h[i].length = 256; h[i].maxlength = 0; h[i].current = 0; h[i].bits = av_mallocz(256 * 4); h[i].lengths = av_mallocz(256 * sizeof(int)); h[i].values = av_mallocz(256 * sizeof(int)); if (!h[i].bits || !h[i].lengths || !h[i].values) { ret = AVERROR(ENOMEM); goto error; } skip_bits1(&gb); if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) { ret = AVERROR_INVALIDDATA; goto error; } skip_bits1(&gb); if(h[i].current > 1) { res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, h[i].lengths, sizeof(int), sizeof(int), h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); if(res < 0) { av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); ret = AVERROR_INVALIDDATA; goto error; } } } /* this codec relies on wraparound instead of clipping audio */ if(bits) { //decode 16-bit data for(i = stereo; i >= 0; i--) pred[i] = sign_extend(av_bswap16(get_bits(&gb, 16)), 16); for(i = 0; i <= stereo; i++) *samples++ = pred[i]; for(; i < unp_size / 2; i++) { if(get_bits_left(&gb)<0) return AVERROR_INVALIDDATA; if(i & stereo) { if(vlc[2].table) res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); else res = 0; if (res < 0) { av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); return AVERROR_INVALIDDATA; } val = h[2].values[res]; if(vlc[3].table) res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3); else res = 0; if (res < 0) { av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); return AVERROR_INVALIDDATA; } val |= h[3].values[res] << 8; pred[1] += sign_extend(val, 16); *samples++ = pred[1]; } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); else res = 0; if (res < 0) { av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); return AVERROR_INVALIDDATA; } val = h[0].values[res]; if(vlc[1].table) res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); else res = 0; if (res < 0) { av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); return AVERROR_INVALIDDATA; } val |= h[1].values[res] << 8; pred[0] += sign_extend(val, 16); *samples++ = pred[0]; } } } else { //8-bit data for(i = stereo; i >= 0; i--) pred[i] = get_bits(&gb, 8); for(i = 0; i <= stereo; i++) *samples8++ = pred[i]; for(; i < unp_size; i++) { if(get_bits_left(&gb)<0) return AVERROR_INVALIDDATA; if(i & stereo){ if(vlc[1].table) res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); else res = 0; if (res < 0) { av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); return AVERROR_INVALIDDATA; } pred[1] += sign_extend(h[1].values[res], 8); *samples8++ = pred[1]; } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); else res = 0; if (res < 0) { av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); return AVERROR_INVALIDDATA; } pred[0] += sign_extend(h[0].values[res], 8); *samples8++ = pred[0]; } } } *got_frame_ptr = 1; ret = buf_size; error: for(i = 0; i < 4; i++) { if(vlc[i].table) ff_free_vlc(&vlc[i]); av_free(h[i].bits); av_free(h[i].lengths); av_free(h[i].values); } return ret; }
static int escape130_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { int buf_size = avpkt->size; Escape130Context *s = avctx->priv_data; AVFrame *pic = data; GetBitContext gb; 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; if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) return ret; skip_bits_long(&gb, 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(&gb); 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 (get_bits1(&gb)) { unsigned sign_selector = get_bits(&gb, 6); unsigned difference_selector = get_bits(&gb, 2); y_avg = 2 * get_bits(&gb, 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 (get_bits1(&gb)) { if (get_bits1(&gb)) { y_avg = get_bits(&gb, 6); } else { unsigned adjust_index = get_bits(&gb, 3); y_avg = (y_avg + luma_adjust[adjust_index]) & 63; } for (i = 0; i < 4; i++) y[i] = y_avg; } if (get_bits1(&gb)) { if (get_bits1(&gb)) { cb = get_bits(&gb, 5); cr = get_bits(&gb, 5); } else { unsigned adjust_index = get_bits(&gb, 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; } av_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n", buf_size, get_bits_count(&gb) >> 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; }
CByteParser::CByteParser(const BYTE *pData, size_t length) : m_pData(pData), m_pEnd(pData+length) { m_gbCtx = (GetBitContext *)av_mallocz(sizeof(GetBitContext)); init_get_bits8(m_gbCtx, pData, (int)length); }
static int flac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { AVFrame *frame = data; ThreadFrame tframe = { .f = data }; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; FLACContext *s = avctx->priv_data; int bytes_read = 0; int ret; *got_frame_ptr = 0; if (s->max_framesize == 0) { s->max_framesize = ff_flac_get_max_frame_size(s->max_blocksize ? s->max_blocksize : FLAC_MAX_BLOCKSIZE, FLAC_MAX_CHANNELS, 32); } if (buf_size > 5 && !memcmp(buf, "\177FLAC", 5)) { av_log(s->avctx, AV_LOG_DEBUG, "skipping flac header packet 1\n"); return buf_size; } if (buf_size > 0 && (*buf & 0x7F) == FLAC_METADATA_TYPE_VORBIS_COMMENT) { av_log(s->avctx, AV_LOG_DEBUG, "skipping vorbis comment\n"); return buf_size; } /* check that there is at least the smallest decodable amount of data. this amount corresponds to the smallest valid FLAC frame possible. FF F8 69 02 00 00 9A 00 00 34 46 */ if (buf_size < FLAC_MIN_FRAME_SIZE) return buf_size; /* check for inline header */ if (AV_RB32(buf) == MKBETAG('f','L','a','C')) { if (!s->got_streaminfo && (ret = parse_streaminfo(s, buf, buf_size))) { av_log(s->avctx, AV_LOG_ERROR, "invalid header\n"); return ret; } return get_metadata_size(buf, buf_size); } /* decode frame */ if ((ret = init_get_bits8(&s->gb, buf, buf_size)) < 0) return ret; if ((ret = decode_frame(s)) < 0) { av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n"); return ret; } bytes_read = get_bits_count(&s->gb)/8; if ((s->avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_COMPLIANT)) && av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf, bytes_read)) { av_log(s->avctx, AV_LOG_ERROR, "CRC error at PTS %"PRId64"\n", avpkt->pts); if (s->avctx->err_recognition & AV_EF_EXPLODE) return AVERROR_INVALIDDATA; } /* get output buffer */ frame->nb_samples = s->blocksize; if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0) return ret; s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded, s->channels, s->blocksize, s->sample_shift); if (bytes_read > buf_size) { av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size); return AVERROR_INVALIDDATA; } if (bytes_read < buf_size) { av_log(s->avctx, AV_LOG_DEBUG, "underread: %d orig size: %d\n", buf_size - bytes_read, buf_size); } *got_frame_ptr = 1; return bytes_read; }
static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { GetByteContext gb; AVFrame * const p = data; int compressed, xmin, ymin, xmax, ymax, ret; unsigned int w, h, bits_per_pixel, bytes_per_line, nplanes, stride, y, x, bytes_per_scanline; uint8_t *ptr, *scanline; if (avpkt->size < 128) return AVERROR_INVALIDDATA; bytestream2_init(&gb, avpkt->data, avpkt->size); if (bytestream2_get_byteu(&gb) != 0x0a || bytestream2_get_byteu(&gb) > 5) { av_log(avctx, AV_LOG_ERROR, "this is not PCX encoded data\n"); return AVERROR_INVALIDDATA; } compressed = bytestream2_get_byteu(&gb); bits_per_pixel = bytestream2_get_byteu(&gb); xmin = bytestream2_get_le16u(&gb); ymin = bytestream2_get_le16u(&gb); xmax = bytestream2_get_le16u(&gb); ymax = bytestream2_get_le16u(&gb); avctx->sample_aspect_ratio.num = bytestream2_get_le16u(&gb); avctx->sample_aspect_ratio.den = bytestream2_get_le16u(&gb); if (xmax < xmin || ymax < ymin) { av_log(avctx, AV_LOG_ERROR, "invalid image dimensions\n"); return AVERROR_INVALIDDATA; } w = xmax - xmin + 1; h = ymax - ymin + 1; bytestream2_skipu(&gb, 49); nplanes = bytestream2_get_byteu(&gb); bytes_per_line = bytestream2_get_le16u(&gb); bytes_per_scanline = nplanes * bytes_per_line; if (bytes_per_scanline < (w * bits_per_pixel * nplanes + 7) / 8) { av_log(avctx, AV_LOG_ERROR, "PCX data is corrupted\n"); return AVERROR_INVALIDDATA; } switch ((nplanes<<8) + bits_per_pixel) { case 0x0308: avctx->pix_fmt = AV_PIX_FMT_RGB24; break; case 0x0108: case 0x0104: case 0x0102: case 0x0101: case 0x0401: case 0x0301: case 0x0201: avctx->pix_fmt = AV_PIX_FMT_PAL8; break; default: av_log(avctx, AV_LOG_ERROR, "invalid PCX file\n"); return AVERROR_INVALIDDATA; } bytestream2_skipu(&gb, 60); if ((ret = av_image_check_size(w, h, 0, avctx)) < 0) return ret; if (w != avctx->width || h != avctx->height) avcodec_set_dimensions(avctx, w, h); if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } p->pict_type = AV_PICTURE_TYPE_I; ptr = p->data[0]; stride = p->linesize[0]; scanline = av_malloc(bytes_per_scanline + FF_INPUT_BUFFER_PADDING_SIZE); if (!scanline) return AVERROR(ENOMEM); if (nplanes == 3 && bits_per_pixel == 8) { for (y=0; y<h; y++) { pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); for (x=0; x<w; x++) { ptr[3*x ] = scanline[x ]; ptr[3*x+1] = scanline[x+ bytes_per_line ]; ptr[3*x+2] = scanline[x+(bytes_per_line<<1)]; } ptr += stride; } } else if (nplanes == 1 && bits_per_pixel == 8) { int palstart = avpkt->size - 769; for (y=0; y<h; y++, ptr+=stride) { pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); memcpy(ptr, scanline, w); } if (bytestream2_tell(&gb) != palstart) { av_log(avctx, AV_LOG_WARNING, "image data possibly corrupted\n"); bytestream2_seek(&gb, palstart, SEEK_SET); } if (bytestream2_get_byte(&gb) != 12) { av_log(avctx, AV_LOG_ERROR, "expected palette after image data\n"); ret = AVERROR_INVALIDDATA; goto end; } } else if (nplanes == 1) { /* all packed formats, max. 16 colors */ GetBitContext s; for (y=0; y<h; y++) { init_get_bits8(&s, scanline, bytes_per_scanline); pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); for (x=0; x<w; x++) ptr[x] = get_bits(&s, bits_per_pixel); ptr += stride; } } else { /* planar, 4, 8 or 16 colors */ int i; for (y=0; y<h; y++) { pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed); for (x=0; x<w; x++) { int m = 0x80 >> (x&7), v = 0; for (i=nplanes - 1; i>=0; i--) { v <<= 1; v += !!(scanline[i*bytes_per_line + (x>>3)] & m); } ptr[x] = v; } ptr += stride; } } ret = bytestream2_tell(&gb); if (nplanes == 1 && bits_per_pixel == 8) { pcx_palette(&gb, (uint32_t *) p->data[1], 256); ret += 256 * 3; } else if (bits_per_pixel * nplanes == 1) { AV_WN32A(p->data[1] , 0xFF000000); AV_WN32A(p->data[1]+4, 0xFFFFFFFF); } else if (bits_per_pixel < 8) { bytestream2_seek(&gb, 16, SEEK_SET); pcx_palette(&gb, (uint32_t *) p->data[1], 16); } *got_frame = 1; end: av_free(scanline); return ret; }
static int magy_decode_slice(AVCodecContext *avctx, void *tdata, int j, int threadnr) { MagicYUVContext *s = avctx->priv_data; int interlaced = s->interlaced; AVFrame *p = s->p; int i, k, x; GetBitContext gb; uint8_t *dst; for (i = 0; i < s->planes; i++) { int left, lefttop, top; int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]); int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]); int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]); ptrdiff_t fake_stride = p->linesize[i] * (1 + interlaced); ptrdiff_t stride = p->linesize[i]; int flags, pred; int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start, s->slices[i][j].size); if (ret < 0) return ret; flags = get_bits(&gb, 8); pred = get_bits(&gb, 8); dst = p->data[i] + j * sheight * stride; if (flags & 1) { for (k = 0; k < height; k++) { for (x = 0; x < width; x++) dst[x] = get_bits(&gb, 8); dst += stride; } } else { for (k = 0; k < height; k++) { for (x = 0; x < width; x++) { int pix; if (get_bits_left(&gb) <= 0) return AVERROR_INVALIDDATA; pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3); if (pix < 0) return AVERROR_INVALIDDATA; dst[x] = 255 - pix; } dst += stride; } } switch (pred) { case LEFT: dst = p->data[i] + j * sheight * stride; s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); dst += stride; if (interlaced) { s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); dst += stride; } for (k = 1 + interlaced; k < height; k++) { s->hdsp.add_hfyu_left_pred(dst, dst, width, dst[-fake_stride]); dst += stride; } break; case GRADIENT: dst = p->data[i] + j * sheight * stride; s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); left = lefttop = 0; dst += stride; if (interlaced) { s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); left = lefttop = 0; dst += stride; } for (k = 1 + interlaced; k < height; k++) { top = dst[-fake_stride]; left = top + dst[0]; dst[0] = left; for (x = 1; x < width; x++) { top = dst[x - fake_stride]; lefttop = dst[x - (fake_stride + 1)]; left += top - lefttop + dst[x]; dst[x] = left; } dst += stride; } break; case MEDIAN: dst = p->data[i] + j * sheight * stride; lefttop = left = dst[0]; s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); dst += stride; if (interlaced) { lefttop = left = dst[0]; s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); dst += stride; } for (k = 1 + interlaced; k < height; k++) { s->hdsp.add_hfyu_median_pred(dst, dst - fake_stride, dst, width, &left, &lefttop); lefttop = left = dst[0]; dst += stride; } break; default: avpriv_request_sample(avctx, "Unknown prediction: %d", pred); } } if (s->decorrelate) { int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height); int width = avctx->coded_width; uint8_t *b = p->data[0] + j * s->slice_height * p->linesize[0]; uint8_t *g = p->data[1] + j * s->slice_height * p->linesize[1]; uint8_t *r = p->data[2] + j * s->slice_height * p->linesize[2]; for (i = 0; i < height; i++) { s->hdsp.add_bytes(b, g, width); s->hdsp.add_bytes(r, g, width); b += p->linesize[0]; g += p->linesize[1]; r += p->linesize[2]; } } return 0; }