static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap) { MPCContext *c = s->priv_data; AVStream *st; int t; t = get_le24(&s->pb); if(t != MKTAG('M', 'P', '+', 0)){ if(t != MKTAG('I', 'D', '3', 0)){ av_log(s, AV_LOG_ERROR, "Not a Musepack file\n"); return -1; } /* skip ID3 tags and try again */ url_fskip(&s->pb, 3); t = get_byte(&s->pb) << 21; t |= get_byte(&s->pb) << 14; t |= get_byte(&s->pb) << 7; t |= get_byte(&s->pb); av_log(s, AV_LOG_DEBUG, "Skipping %d(%X) bytes of ID3 data\n", t, t); url_fskip(&s->pb, t); if(get_le24(&s->pb) != MKTAG('M', 'P', '+', 0)){ av_log(s, AV_LOG_ERROR, "Not a Musepack file\n"); return -1; } } c->ver = get_byte(&s->pb); if(c->ver != 0x07 && c->ver != 0x17){ av_log(s, AV_LOG_ERROR, "Can demux Musepack SV7, got version %02X\n", c->ver); return -1; } c->fcount = get_le32(&s->pb); if((int64_t)c->fcount * sizeof(MPCFrame) >= UINT_MAX){ av_log(s, AV_LOG_ERROR, "Too many frames, seeking is not possible\n"); return -1; } c->frames = av_malloc(c->fcount * sizeof(MPCFrame)); c->curframe = 0; c->lastframe = -1; c->curbits = 8; c->frames_noted = 0; st = av_new_stream(s, 0); if (!st) return AVERROR_NOMEM; st->codec->codec_type = CODEC_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_MUSEPACK7; st->codec->channels = 2; st->codec->bits_per_sample = 16; st->codec->extradata_size = 16; st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE); get_buffer(&s->pb, st->codec->extradata, 16); st->codec->sample_rate = mpc_rate[st->codec->extradata[2] & 3]; av_set_pts_info(st, 32, MPC_FRAMESIZE, st->codec->sample_rate); /* scan for seekpoints */ s->start_time = 0; s->duration = (int64_t)c->fcount * MPC_FRAMESIZE * AV_TIME_BASE / st->codec->sample_rate; return 0; }
// Validates the VP8X header and skips over it. // Returns VP8_STATUS_BITSTREAM_ERROR for invalid VP8X header, // VP8_STATUS_NOT_ENOUGH_DATA in case of insufficient data, and // VP8_STATUS_OK otherwise. // If a VP8X chunk is found, found_vp8x is set to true and *width_ptr, // *height_ptr and *flags_ptr are set to the corresponding values extracted // from the VP8X chunk. static VP8StatusCode ParseVP8X(const uint8_t** const data, size_t* const data_size, int* const found_vp8x, int* const width_ptr, int* const height_ptr, uint32_t* const flags_ptr) { const uint32_t vp8x_size = CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE; assert(data != NULL); assert(data_size != NULL); assert(found_vp8x != NULL); *found_vp8x = 0; if (*data_size < CHUNK_HEADER_SIZE) { return VP8_STATUS_NOT_ENOUGH_DATA; // Insufficient data. } if (!memcmp(*data, "VP8X", TAG_SIZE)) { int width, height; uint32_t flags; const uint32_t chunk_size = get_le32(*data + TAG_SIZE); if (chunk_size != VP8X_CHUNK_SIZE) { return VP8_STATUS_BITSTREAM_ERROR; // Wrong chunk size. } // Verify if enough data is available to validate the VP8X chunk. if (*data_size < vp8x_size) { return VP8_STATUS_NOT_ENOUGH_DATA; // Insufficient data. } flags = get_le32(*data + 8); width = 1 + get_le24(*data + 12); height = 1 + get_le24(*data + 15); if (width * (uint64_t)height >= MAX_IMAGE_AREA) { return VP8_STATUS_BITSTREAM_ERROR; // image is too large } if (flags_ptr != NULL) *flags_ptr = flags; if (width_ptr != NULL) *width_ptr = width; if (height_ptr != NULL) *height_ptr = height; // Skip over VP8X header bytes. *data += vp8x_size; *data_size -= vp8x_size; *found_vp8x = 1; } return VP8_STATUS_OK; }
static VP8StatusCode ParseVP8X(const uint8_t** const data, size_t* const data_size, int* const found_vp8x, int* const width_ptr, int* const height_ptr, uint32_t* const flags_ptr) { const uint32_t vp8x_size = CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE; assert(data != NULL); assert(data_size != NULL); assert(found_vp8x != NULL); *found_vp8x = 0; if (*data_size < CHUNK_HEADER_SIZE) { return VP8_STATUS_NOT_ENOUGH_DATA; } if (!memcmp(*data, "VP8X", TAG_SIZE)) { int width, height; uint32_t flags; const uint32_t chunk_size = get_le32(*data + TAG_SIZE); if (chunk_size != VP8X_CHUNK_SIZE) { return VP8_STATUS_BITSTREAM_ERROR; } if (*data_size < vp8x_size) { return VP8_STATUS_NOT_ENOUGH_DATA; } flags = get_le32(*data + 8); width = 1 + get_le24(*data + 12); height = 1 + get_le24(*data + 15); if (width * (uint64_t)height >= MAX_IMAGE_AREA) { return VP8_STATUS_BITSTREAM_ERROR; } if (flags_ptr != NULL) *flags_ptr = flags; if (width_ptr != NULL) *width_ptr = width; if (height_ptr != NULL) *height_ptr = height; *data += vp8x_size; *data_size -= vp8x_size; *found_vp8x = 1; } return VP8_STATUS_OK; }
static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap) { MPCContext *c = s->priv_data; AVStream *st; if(get_le24(s->pb) != MKTAG('M', 'P', '+', 0)){ av_log(s, AV_LOG_ERROR, "Not a Musepack file\n"); return -1; } c->ver = get_byte(s->pb); if(c->ver != 0x07 && c->ver != 0x17){ av_log(s, AV_LOG_ERROR, "Can demux Musepack SV7, got version %02X\n", c->ver); return -1; } c->fcount = get_le32(s->pb); if((int64_t)c->fcount * sizeof(MPCFrame) >= UINT_MAX){ av_log(s, AV_LOG_ERROR, "Too many frames, seeking is not possible\n"); return -1; } c->frames = av_malloc(c->fcount * sizeof(MPCFrame)); c->curframe = 0; c->lastframe = -1; c->curbits = 8; c->frames_noted = 0; st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_MUSEPACK7; st->codec->channels = 2; st->codec->bits_per_coded_sample = 16; st->codec->extradata_size = 16; st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE); get_buffer(s->pb, st->codec->extradata, 16); st->codec->sample_rate = mpc_rate[st->codec->extradata[2] & 3]; av_set_pts_info(st, 32, MPC_FRAMESIZE, st->codec->sample_rate); /* scan for seekpoints */ st->start_time = 0; st->duration = c->fcount; /* try to read APE tags */ if (!url_is_streamed(s->pb)) { int64_t pos = url_ftell(s->pb); ff_ape_parse_tag(s); if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) ff_id3v1_read(s); url_fseek(s->pb, pos, SEEK_SET); } return 0; }
static int vc1t_read_header(AVFormatContext *s, AVFormatParameters *ap) { ByteIOContext *pb = s->pb; AVStream *st; int frames; uint32_t fps; frames = get_le24(pb); if(get_byte(pb) != 0xC5 || get_le32(pb) != 4) return -1; /* init video codec */ st = av_new_stream(s, 0); if (!st) return -1; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_WMV3; st->codec->extradata = av_malloc(VC1_EXTRADATA_SIZE); st->codec->extradata_size = VC1_EXTRADATA_SIZE; get_buffer(pb, st->codec->extradata, VC1_EXTRADATA_SIZE); st->codec->height = get_le32(pb); st->codec->width = get_le32(pb); if(get_le32(pb) != 0xC) return -1; url_fskip(pb, 8); fps = get_le32(pb); if(fps == 0xFFFFFFFF) av_set_pts_info(st, 32, 1, 1000); else{ if (!fps) { av_log(s, AV_LOG_ERROR, "Zero FPS specified, defaulting to 1 FPS\n"); fps = 1; } av_set_pts_info(st, 24, 1, fps); st->duration = frames; } return 0; }
static int vc1t_read_header(AVFormatContext *s, AVFormatParameters *ap) { ByteIOContext *pb = s->pb; AVStream *st; int fps, frames; frames = get_le24(pb); if(get_byte(pb) != 0xC5 || get_le32(pb) != 4) return -1; /* init video codec */ st = av_new_stream(s, 0); if (!st) return -1; st->codec->codec_type = CODEC_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_WMV3; st->codec->extradata = av_malloc(VC1_EXTRADATA_SIZE); st->codec->extradata_size = VC1_EXTRADATA_SIZE; get_buffer(pb, st->codec->extradata, VC1_EXTRADATA_SIZE); st->codec->height = get_le32(pb); st->codec->width = get_le32(pb); if(get_le32(pb) != 0xC) return -1; url_fskip(pb, 8); fps = get_le32(pb); if(fps == -1) av_set_pts_info(st, 32, 1, 1000); else{ av_set_pts_info(st, 24, 1, fps); st->duration = frames; } return 0; }
static int vc1t_read_packet(AVFormatContext *s, AVPacket *pkt) { ByteIOContext *pb = s->pb; int frame_size; int keyframe = 0; uint32_t pts; if(url_feof(pb)) return AVERROR(EIO); frame_size = get_le24(pb); if(get_byte(pb) & 0x80) keyframe = 1; pts = get_le32(pb); if(av_get_packet(pb, pkt, frame_size) < 0) return AVERROR(EIO); if(s->streams[0]->time_base.den == 1000) pkt->pts = pts; pkt->flags |= keyframe ? PKT_FLAG_KEY : 0; pkt->pos -= 8; return pkt->size; }
int voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) { voc_dec_context_t *voc = s->priv_data; AVCodecContext *dec = st->codec; ByteIOContext *pb = s->pb; voc_type_t type; int size; int sample_rate = 0; int channels = 1; while (!voc->remaining_size) { type = get_byte(pb); if (type == VOC_TYPE_EOF) return AVERROR(EIO); voc->remaining_size = get_le24(pb); max_size -= 4; switch (type) { case VOC_TYPE_VOICE_DATA: dec->sample_rate = 1000000 / (256 - get_byte(pb)); if (sample_rate) dec->sample_rate = sample_rate; dec->channels = channels; dec->codec_id = codec_get_id(voc_codec_tags, get_byte(pb)); dec->bits_per_sample = av_get_bits_per_sample(dec->codec_id); voc->remaining_size -= 2; max_size -= 2; channels = 1; break; case VOC_TYPE_VOICE_DATA_CONT: break; case VOC_TYPE_EXTENDED: sample_rate = get_le16(pb); get_byte(pb); channels = get_byte(pb) + 1; sample_rate = 256000000 / (channels * (65536 - sample_rate)); voc->remaining_size = 0; max_size -= 4; break; case VOC_TYPE_NEW_VOICE_DATA: dec->sample_rate = get_le32(pb); dec->bits_per_sample = get_byte(pb); dec->channels = get_byte(pb); dec->codec_id = codec_get_id(voc_codec_tags, get_le16(pb)); url_fskip(pb, 4); voc->remaining_size -= 12; max_size -= 12; break; default: url_fskip(pb, voc->remaining_size); max_size -= voc->remaining_size; voc->remaining_size = 0; break; } } dec->bit_rate = dec->sample_rate * dec->bits_per_sample; if (max_size <= 0) max_size = 2048; size = FFMIN(voc->remaining_size, max_size); voc->remaining_size -= size; return av_get_packet(pb, pkt, size); }
bool PackHeader::fillPackHeader(const upx_bytep buf, int blen) { int boff = find_le32(buf, blen, UPX_MAGIC_LE32); if (boff < 0) return false; if (boff + 8 <= 0 || boff + 8 > blen) throwCantUnpack("header corrupted 1"); const upx_bytep p = buf + boff; version = p[4]; format = p[5]; method = p[6]; level = p[7]; filter_cto = 0; const int size = getPackHeaderSize(); if (boff + size <= 0 || boff + size > blen) throwCantUnpack("header corrupted 2"); // // decode the new variable length header // int off_filter = 0; if (format < 128) { u_adler = get_le32(p+8); c_adler = get_le32(p+12); if (format == UPX_F_DOS_COM || format == UPX_F_DOS_SYS) { u_len = get_le16(p+16); c_len = get_le16(p+18); u_file_size = u_len; off_filter = 20; } else if (format == UPX_F_DOS_EXE || format == UPX_F_DOS_EXEH) { u_len = get_le24(p+16); c_len = get_le24(p+19); u_file_size = get_le24(p+22); off_filter = 25; } else { u_len = get_le32(p+16); c_len = get_le32(p+20); u_file_size = get_le32(p+24); off_filter = 28; filter_cto = p[29]; n_mru = p[30] ? 1 + p[30] : 0; } } else { u_len = get_be32(p+8); c_len = get_be32(p+12); u_adler = get_be32(p+16); c_adler = get_be32(p+20); u_file_size = get_be32(p+24); off_filter = 28; filter_cto = p[29]; n_mru = p[30] ? 1 + p[30] : 0; } if (version >= 10) filter = p[off_filter]; else if ((level & 128) == 0) filter = 0; else { // convert old flags to new filter id level &= 127; if (format == UPX_F_DOS_COM || format == UPX_F_DOS_SYS) filter = 0x06; else filter = 0x26; } level &= 15; // // now some checks // if (version == 0xff) throwCantUnpack("cannot unpack UPX ;-)"); // check header_checksum if (version > 9) if (p[size - 1] != get_packheader_checksum(p, size - 1)) throwCantUnpack("header corrupted 3"); // // success // this->buf_offset = boff; return true; }
static WEBP_INLINE uint32_t get_le32(const uint8_t* const data) { return (uint32_t)get_le24(data) | (data[3] << 24); }
int __acc_cdecl_qsort le24_compare(const void *e1, const void *e2) { const unsigned d1 = get_le24(e1); const unsigned d2 = get_le24(e2); return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0); }
static int wv_read_block_header(AVFormatContext *ctx, ByteIOContext *pb, int append) { WVContext *wc = ctx->priv_data; uint32_t tag, ver; int size; int rate, bpp, chan; uint32_t chmask; wc->pos = url_ftell(pb); if(!append){ tag = get_le32(pb); if (tag != MKTAG('w', 'v', 'p', 'k')) return -1; size = get_le32(pb); if(size < 24 || size > WV_BLOCK_LIMIT){ av_log(ctx, AV_LOG_ERROR, "Incorrect block size %i\n", size); return -1; } wc->blksize = size; ver = get_le16(pb); if(ver < 0x402 || ver > 0x410){ av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", ver); return -1; } get_byte(pb); // track no get_byte(pb); // track sub index wc->samples = get_le32(pb); // total samples in file wc->soff = get_le32(pb); // offset in samples of current block get_buffer(pb, wc->extra, WV_EXTRA_SIZE); }else{ size = wc->blksize; } wc->flags = AV_RL32(wc->extra + 4); //parse flags bpp = ((wc->flags & 3) + 1) << 3; chan = 1 + !(wc->flags & WV_MONO); chmask = wc->flags & WV_MONO ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; rate = wv_rates[(wc->flags >> 23) & 0xF]; wc->multichannel = !!((wc->flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK); if(wc->multichannel){ chan = wc->chan; chmask = wc->chmask; } if((rate == -1 || !chan) && !wc->block_parsed){ int64_t block_end = url_ftell(pb) + wc->blksize - 24; if(url_is_streamed(pb)){ av_log(ctx, AV_LOG_ERROR, "Cannot determine additional parameters\n"); return -1; } while(url_ftell(pb) < block_end){ int id, size; id = get_byte(pb); size = (id & 0x80) ? get_le24(pb) : get_byte(pb); size <<= 1; if(id&0x40) size--; switch(id&0x3F){ case 0xD: if(size <= 1){ av_log(ctx, AV_LOG_ERROR, "Insufficient channel information\n"); return -1; } chan = get_byte(pb); switch(size - 2){ case 0: chmask = get_byte(pb); break; case 1: chmask = get_le16(pb); break; case 2: chmask = get_le24(pb); break; case 3: chmask = get_le32(pb); break; case 5: url_fskip(pb, 1); chan |= (get_byte(pb) & 0xF) << 8; chmask = get_le24(pb); break; default: av_log(ctx, AV_LOG_ERROR, "Invalid channel info size %d\n", size); return -1; } break; case 0x27: rate = get_le24(pb); break; default: url_fskip(pb, size); } if(id&0x40) url_fskip(pb, 1); } if(rate == -1){ av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n"); return -1; } url_fseek(pb, block_end - wc->blksize + 24, SEEK_SET); } if(!wc->bpp) wc->bpp = bpp; if(!wc->chan) wc->chan = chan; if(!wc->chmask) wc->chmask = chmask; if(!wc->rate) wc->rate = rate; if(wc->flags && bpp != wc->bpp){ av_log(ctx, AV_LOG_ERROR, "Bits per sample differ, this block: %i, header block: %i\n", bpp, wc->bpp); return -1; } if(wc->flags && !wc->multichannel && chan != wc->chan){ av_log(ctx, AV_LOG_ERROR, "Channels differ, this block: %i, header block: %i\n", chan, wc->chan); return -1; } if(wc->flags && rate != -1 && rate != wc->rate){ av_log(ctx, AV_LOG_ERROR, "Sampling rate differ, this block: %i, header block: %i\n", rate, wc->rate); return -1; } wc->blksize = size - 24; return 0; }
static int mtv_read_header(AVFormatContext *s, AVFormatParameters *ap) { MTVDemuxContext *mtv = s->priv_data; ByteIOContext *pb = s->pb; AVStream *st; unsigned int audio_subsegments; url_fskip(pb, 3); mtv->file_size = get_le32(pb); mtv->segments = get_le32(pb); url_fskip(pb, 32); mtv->audio_identifier = get_le24(pb); mtv->audio_br = get_le16(pb); mtv->img_colorfmt = get_le24(pb); mtv->img_bpp = get_byte(pb); mtv->img_width = get_le16(pb); mtv->img_height = get_le16(pb); mtv->img_segment_size = get_le16(pb); url_fskip(pb, 4); audio_subsegments = get_le16(pb); mtv->full_segment_size = audio_subsegments * (MTV_AUDIO_PADDING_SIZE + MTV_ASUBCHUNK_DATA_SIZE) + mtv->img_segment_size; mtv->video_fps = (mtv->audio_br / 4) / audio_subsegments; // FIXME Add sanity check here // all systems go! init decoders // video - raw rgb565 st = av_new_stream(s, VIDEO_SID); if(!st) return AVERROR(ENOMEM); av_set_pts_info(st, 64, 1, mtv->video_fps); st->codec->codec_type = CODEC_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_RAWVIDEO; st->codec->codec_tag = MKTAG('R', 'G', 'B', mtv->img_bpp); st->codec->width = mtv->img_width; st->codec->height = mtv->img_height; st->codec->bits_per_coded_sample = mtv->img_bpp; st->codec->sample_rate = mtv->video_fps; // audio - mp3 st = av_new_stream(s, AUDIO_SID); if(!st) return AVERROR(ENOMEM); av_set_pts_info(st, 64, 1, AUDIO_SAMPLING_RATE); st->codec->codec_type = CODEC_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_MP3; st->codec->bit_rate = mtv->audio_br; st->need_parsing = AVSTREAM_PARSE_FULL; // Jump over header if(url_fseek(pb, MTV_HEADER_SIZE, SEEK_SET) != MTV_HEADER_SIZE) return AVERROR(EIO); return 0; }
static int wv_read_block_header(AVFormatContext *ctx, ByteIOContext *pb) { WVContext *wc = ctx->priv_data; uint32_t tag, ver; int size; int rate, bpp, chan; wc->pos = url_ftell(pb); tag = get_le32(pb); if (tag != MKTAG('w', 'v', 'p', 'k')) return -1; size = get_le32(pb); if(size < 24 || size > WV_BLOCK_LIMIT){ av_log(ctx, AV_LOG_ERROR, "Incorrect block size %i\n", size); return -1; } wc->blksize = size; ver = get_le16(pb); if(ver < 0x402 || ver > 0x410){ av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", ver); return -1; } get_byte(pb); // track no get_byte(pb); // track sub index wc->samples = get_le32(pb); // total samples in file wc->soff = get_le32(pb); // offset in samples of current block get_buffer(pb, wc->extra, WV_EXTRA_SIZE); wc->flags = AV_RL32(wc->extra + 4); //parse flags bpp = ((wc->flags & 3) + 1) << 3; chan = 1 + !(wc->flags & WV_MONO); rate = wv_rates[(wc->flags >> 23) & 0xF]; if(rate == -1 && !wc->block_parsed){ int64_t block_end = url_ftell(pb) + wc->blksize - 24; if(url_is_streamed(pb)){ av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n"); return -1; } while(url_ftell(pb) < block_end){ int id, size; id = get_byte(pb); size = (id & 0x80) ? get_le24(pb) : get_byte(pb); size <<= 1; if(id&0x40) size--; if((id&0x3F) == 0x27){ rate = get_le24(pb); break; }else{ url_fskip(pb, size); } } if(rate == -1){ av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n"); return -1; } url_fseek(pb, block_end - wc->blksize + 24, SEEK_SET); } if(!wc->bpp) wc->bpp = bpp; if(!wc->chan) wc->chan = chan; if(!wc->rate) wc->rate = rate; if(wc->flags && bpp != wc->bpp){ av_log(ctx, AV_LOG_ERROR, "Bits per sample differ, this block: %i, header block: %i\n", bpp, wc->bpp); return -1; } if(wc->flags && chan != wc->chan){ av_log(ctx, AV_LOG_ERROR, "Channels differ, this block: %i, header block: %i\n", chan, wc->chan); return -1; } if(wc->flags && rate != -1 && rate != wc->rate){ av_log(ctx, AV_LOG_ERROR, "Sampling rate differ, this block: %i, header block: %i\n", rate, wc->rate); return -1; } wc->blksize = size - 24; return 0; }