static int tgq_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt){ const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; TgqContext *s = avctx->priv_data; int x,y; int big_endian; if (buf_size < 16) { av_log(avctx, AV_LOG_WARNING, "truncated header\n"); return -1; } big_endian = AV_RL32(&buf[4]) > 0x000FFFFF; bytestream2_init(&s->gb, buf + 8, buf_size - 8); if (big_endian) { s->width = bytestream2_get_be16u(&s->gb); s->height = bytestream2_get_be16u(&s->gb); } else { s->width = bytestream2_get_le16u(&s->gb); s->height = bytestream2_get_le16u(&s->gb); } if (s->avctx->width!=s->width || s->avctx->height!=s->height) { avcodec_set_dimensions(s->avctx, s->width, s->height); if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); } tgq_calculate_qtable(s, bytestream2_get_byteu(&s->gb)); bytestream2_skip(&s->gb, 3); if (!s->frame.data[0]) { s->frame.key_frame = 1; s->frame.pict_type = AV_PICTURE_TYPE_I; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; if (ff_get_buffer(avctx, &s->frame)) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } } for (y = 0; y < FFALIGN(avctx->height, 16) >> 4; y++) for (x = 0; x < FFALIGN(avctx->width, 16) >> 4; x++) if (tgq_decode_mb(s, y, x) < 0) return AVERROR_INVALIDDATA; *got_frame = 1; *(AVFrame*)data = s->frame; return avpkt->size; }
/** get coding parameters for a particular tile or whole image*/ static int get_cod(J2kDecoderContext *s, J2kCodingStyle *c, uint8_t *properties) { J2kCodingStyle tmp; int compno; if (bytestream2_get_bytes_left(&s->g) < 5) return AVERROR(EINVAL); tmp.log2_prec_width = tmp.log2_prec_height = 15; tmp.csty = bytestream2_get_byteu(&s->g); if (bytestream2_get_byteu(&s->g)){ // progression level av_log(s->avctx, AV_LOG_ERROR, "only LRCP progression supported\n"); return -1; } tmp.nlayers = bytestream2_get_be16u(&s->g); tmp.mct = bytestream2_get_byteu(&s->g); // multiple component transformation get_cox(s, &tmp); for (compno = 0; compno < s->ncomponents; compno++){ if (!(properties[compno] & HAD_COC)) memcpy(c + compno, &tmp, sizeof(J2kCodingStyle)); } return 0; }
static int tgq_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; TgqContext *s = avctx->priv_data; AVFrame *frame = data; int x, y, ret; int big_endian; if (buf_size < 16) { av_log(avctx, AV_LOG_WARNING, "truncated header\n"); return AVERROR_INVALIDDATA; } big_endian = AV_RL32(&buf[4]) > 0x000FFFFF; bytestream2_init(&s->gb, buf + 8, buf_size - 8); if (big_endian) { s->width = bytestream2_get_be16u(&s->gb); s->height = bytestream2_get_be16u(&s->gb); } else { s->width = bytestream2_get_le16u(&s->gb); s->height = bytestream2_get_le16u(&s->gb); } ret = ff_set_dimensions(s->avctx, s->width, s->height); if (ret < 0) return ret; tgq_calculate_qtable(s, bytestream2_get_byteu(&s->gb)); bytestream2_skip(&s->gb, 3); if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; frame->key_frame = 1; frame->pict_type = AV_PICTURE_TYPE_I; for (y = 0; y < FFALIGN(avctx->height, 16) >> 4; y++) for (x = 0; x < FFALIGN(avctx->width, 16) >> 4; x++) if (tgq_decode_mb(s, frame, y, x) < 0) return AVERROR_INVALIDDATA; *got_frame = 1; return avpkt->size; }
static int expand_rle_row16(SgiState *s, uint16_t *out_buf, int len, int pixelstride) { unsigned short pixel; unsigned char count; unsigned short *orig = out_buf; uint16_t *out_end = out_buf + len; while (out_buf < out_end) { if (bytestream2_get_bytes_left(&s->g) < 2) return AVERROR_INVALIDDATA; pixel = bytestream2_get_be16u(&s->g); if (!(count = (pixel & 0x7f))) break; /* Check for buffer overflow. */ if (pixelstride * (count - 1) >= len) { av_log(s->avctx, AV_LOG_ERROR, "Invalid pixel count.\n"); return AVERROR_INVALIDDATA; } if (pixel & 0x80) { while (count--) { pixel = bytestream2_get_ne16(&s->g); AV_WN16A(out_buf, pixel); out_buf += pixelstride; } } else { pixel = bytestream2_get_ne16(&s->g); while (count--) { AV_WN16A(out_buf, pixel); out_buf += pixelstride; } } } return (out_buf - orig) / pixelstride; }
static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { const uint8_t *src = avpkt->data; int buf_size = avpkt->size; PCMBRDecode *s = avctx->priv_data; GetByteContext gb; int num_source_channels, channel, retval; int sample_size, samples; int16_t *dst16; int32_t *dst32; if (buf_size < 4) { av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n"); return -1; } if (pcm_bluray_parse_header(avctx, src)) return -1; src += 4; buf_size -= 4; bytestream2_init(&gb, src, buf_size); /* There's always an even number of channels in the source */ num_source_channels = FFALIGN(avctx->channels, 2); sample_size = (num_source_channels * (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3; samples = buf_size / sample_size; /* get output buffer */ s->frame.nb_samples = samples; if ((retval = avctx->get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return retval; } dst16 = (int16_t *)s->frame.data[0]; dst32 = (int32_t *)s->frame.data[0]; if (samples) { switch (avctx->channel_layout) { /* cases with same number of source and coded channels */ case AV_CH_LAYOUT_STEREO: case AV_CH_LAYOUT_4POINT0: case AV_CH_LAYOUT_2_2: samples *= num_source_channels; if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { #if HAVE_BIGENDIAN bytestream2_get_buffer(&gb, dst16, buf_size); #else do { *dst16++ = bytestream2_get_be16u(&gb); } while (--samples); #endif } else { do { *dst32++ = bytestream2_get_be24u(&gb) << 8; } while (--samples); } break; /* cases where number of source channels = coded channels + 1 */ case AV_CH_LAYOUT_MONO: case AV_CH_LAYOUT_SURROUND: case AV_CH_LAYOUT_2_1: case AV_CH_LAYOUT_5POINT0: if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { do { #if HAVE_BIGENDIAN bytestream2_get_buffer(&gb, dst16, avctx->channels * 2); dst16 += avctx->channels; #else channel = avctx->channels; do { *dst16++ = bytestream2_get_be16u(&gb); } while (--channel); #endif bytestream2_skip(&gb, 2); } while (--samples); } else { do { channel = avctx->channels; do { *dst32++ = bytestream2_get_be24u(&gb) << 8; } while (--channel); bytestream2_skip(&gb, 3); } while (--samples); } break; /* remapping: L, R, C, LBack, RBack, LF */ case AV_CH_LAYOUT_5POINT1: if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { do { dst16[0] = bytestream2_get_be16u(&gb); dst16[1] = bytestream2_get_be16u(&gb); dst16[2] = bytestream2_get_be16u(&gb); dst16[4] = bytestream2_get_be16u(&gb); dst16[5] = bytestream2_get_be16u(&gb); dst16[3] = bytestream2_get_be16u(&gb); dst16 += 6; } while (--samples); } else { do { dst32[0] = bytestream2_get_be24u(&gb) << 8; dst32[1] = bytestream2_get_be24u(&gb) << 8; dst32[2] = bytestream2_get_be24u(&gb) << 8; dst32[4] = bytestream2_get_be24u(&gb) << 8; dst32[5] = bytestream2_get_be24u(&gb) << 8; dst32[3] = bytestream2_get_be24u(&gb) << 8; dst32 += 6; } while (--samples); } break; /* remapping: L, R, C, LSide, LBack, RBack, RSide, <unused> */ case AV_CH_LAYOUT_7POINT0: if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { do { dst16[0] = bytestream2_get_be16u(&gb); dst16[1] = bytestream2_get_be16u(&gb); dst16[2] = bytestream2_get_be16u(&gb); dst16[5] = bytestream2_get_be16u(&gb); dst16[3] = bytestream2_get_be16u(&gb); dst16[4] = bytestream2_get_be16u(&gb); dst16[6] = bytestream2_get_be16u(&gb); dst16 += 7; bytestream2_skip(&gb, 2); } while (--samples); } else { do { dst32[0] = bytestream2_get_be24u(&gb) << 8; dst32[1] = bytestream2_get_be24u(&gb) << 8; dst32[2] = bytestream2_get_be24u(&gb) << 8; dst32[5] = bytestream2_get_be24u(&gb) << 8; dst32[3] = bytestream2_get_be24u(&gb) << 8; dst32[4] = bytestream2_get_be24u(&gb) << 8; dst32[6] = bytestream2_get_be24u(&gb) << 8; dst32 += 7; bytestream2_skip(&gb, 3); } while (--samples); } break; /* remapping: L, R, C, LSide, LBack, RBack, RSide, LF */ case AV_CH_LAYOUT_7POINT1: if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { do { dst16[0] = bytestream2_get_be16u(&gb); dst16[1] = bytestream2_get_be16u(&gb); dst16[2] = bytestream2_get_be16u(&gb); dst16[6] = bytestream2_get_be16u(&gb); dst16[4] = bytestream2_get_be16u(&gb); dst16[5] = bytestream2_get_be16u(&gb); dst16[7] = bytestream2_get_be16u(&gb); dst16[3] = bytestream2_get_be16u(&gb); dst16 += 8; } while (--samples); } else { do { dst32[0] = bytestream2_get_be24u(&gb) << 8; dst32[1] = bytestream2_get_be24u(&gb) << 8; dst32[2] = bytestream2_get_be24u(&gb) << 8; dst32[6] = bytestream2_get_be24u(&gb) << 8; dst32[4] = bytestream2_get_be24u(&gb) << 8; dst32[5] = bytestream2_get_be24u(&gb) << 8; dst32[7] = bytestream2_get_be24u(&gb) << 8; dst32[3] = bytestream2_get_be24u(&gb) << 8; dst32 += 8; } while (--samples); } break; } } *got_frame_ptr = 1; *(AVFrame *)data = s->frame; retval = bytestream2_tell(&gb); if (avctx->debug & FF_DEBUG_BITSTREAM) av_dlog(avctx, "pcm_bluray_decode_frame: decoded %d -> %d bytes\n", retval, buf_size); return retval + 4; }
static unsigned tget_short(GetByteContext *gb, int le) { unsigned v = le ? bytestream2_get_le16u(gb) : bytestream2_get_be16u(gb); return v; }
/** get sizes and offsets of image, tiles; number of components */ static int get_siz(J2kDecoderContext *s) { int i, ret; if (bytestream2_get_bytes_left(&s->g) < 36) return AVERROR(EINVAL); bytestream2_get_be16u(&s->g); // Rsiz (skipped) s->width = bytestream2_get_be32u(&s->g); // width s->height = bytestream2_get_be32u(&s->g); // height s->image_offset_x = bytestream2_get_be32u(&s->g); // X0Siz s->image_offset_y = bytestream2_get_be32u(&s->g); // Y0Siz s->tile_width = bytestream2_get_be32u(&s->g); // XTSiz s->tile_height = bytestream2_get_be32u(&s->g); // YTSiz s->tile_offset_x = bytestream2_get_be32u(&s->g); // XT0Siz s->tile_offset_y = bytestream2_get_be32u(&s->g); // YT0Siz s->ncomponents = bytestream2_get_be16u(&s->g); // CSiz if(s->tile_width<=0 || s->tile_height<=0) return AVERROR(EINVAL); if (bytestream2_get_bytes_left(&s->g) < 3 * s->ncomponents) return AVERROR(EINVAL); for (i = 0; i < s->ncomponents; i++){ // Ssiz_i XRsiz_i, YRsiz_i uint8_t x = bytestream2_get_byteu(&s->g); s->cbps[i] = (x & 0x7f) + 1; s->precision = FFMAX(s->cbps[i], s->precision); s->sgnd[i] = !!(x & 0x80); s->cdx[i] = bytestream2_get_byteu(&s->g); s->cdy[i] = bytestream2_get_byteu(&s->g); } s->numXtiles = ff_j2k_ceildiv(s->width - s->tile_offset_x, s->tile_width); s->numYtiles = ff_j2k_ceildiv(s->height - s->tile_offset_y, s->tile_height); if(s->numXtiles * (uint64_t)s->numYtiles > INT_MAX/sizeof(J2kTile)) return AVERROR(EINVAL); s->tile = av_mallocz(s->numXtiles * s->numYtiles * sizeof(J2kTile)); if (!s->tile) return AVERROR(ENOMEM); for (i = 0; i < s->numXtiles * s->numYtiles; i++){ J2kTile *tile = s->tile + i; tile->comp = av_mallocz(s->ncomponents * sizeof(J2kComponent)); if (!tile->comp) return AVERROR(ENOMEM); } s->avctx->width = s->width - s->image_offset_x; s->avctx->height = s->height - s->image_offset_y; switch(s->ncomponents){ case 1: if (s->precision > 8) { s->avctx->pix_fmt = PIX_FMT_GRAY16; } else { s->avctx->pix_fmt = PIX_FMT_GRAY8; } break; case 3: if (s->precision > 8) { s->avctx->pix_fmt = PIX_FMT_RGB48; } else { s->avctx->pix_fmt = PIX_FMT_RGB24; } break; case 4: s->avctx->pix_fmt = PIX_FMT_RGBA; break; } if (s->picture.data[0]) s->avctx->release_buffer(s->avctx, &s->picture); if ((ret = s->avctx->get_buffer(s->avctx, &s->picture)) < 0) return ret; s->picture.pict_type = AV_PICTURE_TYPE_I; s->picture.key_frame = 1; return 0; }
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { SgiState *s = avctx->priv_data; AVFrame *p = data; unsigned int dimension, rle; int ret = 0; uint8_t *out_buf, *out_end; bytestream2_init(&s->g, avpkt->data, avpkt->size); if (bytestream2_get_bytes_left(&s->g) < SGI_HEADER_SIZE) { av_log(avctx, AV_LOG_ERROR, "buf_size too small (%d)\n", avpkt->size); return AVERROR_INVALIDDATA; } /* Test for SGI magic. */ if (bytestream2_get_be16u(&s->g) != SGI_MAGIC) { av_log(avctx, AV_LOG_ERROR, "bad magic number\n"); return AVERROR_INVALIDDATA; } rle = bytestream2_get_byteu(&s->g); s->bytes_per_channel = bytestream2_get_byteu(&s->g); dimension = bytestream2_get_be16u(&s->g); s->width = bytestream2_get_be16u(&s->g); s->height = bytestream2_get_be16u(&s->g); s->depth = bytestream2_get_be16u(&s->g); if (s->bytes_per_channel != 1 && (s->bytes_per_channel != 2 || rle)) { av_log(avctx, AV_LOG_ERROR, "wrong channel number\n"); return AVERROR_INVALIDDATA; } /* Check for supported image dimensions. */ if (dimension != 2 && dimension != 3) { av_log(avctx, AV_LOG_ERROR, "wrong dimension number\n"); return AVERROR_INVALIDDATA; } if (s->depth == SGI_GRAYSCALE) { avctx->pix_fmt = s->bytes_per_channel == 2 ? AV_PIX_FMT_GRAY16BE : AV_PIX_FMT_GRAY8; } else if (s->depth == SGI_RGB) { avctx->pix_fmt = s->bytes_per_channel == 2 ? AV_PIX_FMT_RGB48BE : AV_PIX_FMT_RGB24; } else if (s->depth == SGI_RGBA) { avctx->pix_fmt = s->bytes_per_channel == 2 ? AV_PIX_FMT_RGBA64BE : AV_PIX_FMT_RGBA; } else { av_log(avctx, AV_LOG_ERROR, "wrong picture format\n"); return AVERROR_INVALIDDATA; } if (av_image_check_size(s->width, s->height, 0, avctx)) return AVERROR_INVALIDDATA; avcodec_set_dimensions(avctx, s->width, s->height); if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; out_buf = p->data[0]; out_end = out_buf + p->linesize[0] * s->height; s->linesize = p->linesize[0]; /* Skip header. */ bytestream2_seek(&s->g, SGI_HEADER_SIZE, SEEK_SET); if (rle) { ret = read_rle_sgi(out_end, s); } else { ret = read_uncompressed_sgi(out_buf, s); } if (ret) return ret; *got_frame = 1; return avpkt->size; }
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { AVFrame *f = data; GetByteContext gb; int width, height, ret, bits_pixel, pixel; uint8_t *out_buf; uint8_t count; int x, y; bytestream2_init(&gb, avpkt->data, avpkt->size); if (bytestream2_get_bytes_left(&gb) < ALIAS_HEADER_SIZE) { av_log(avctx, AV_LOG_ERROR, "Header too small %d.\n", avpkt->size); return AVERROR_INVALIDDATA; } width = bytestream2_get_be16u(&gb); height = bytestream2_get_be16u(&gb); bytestream2_skipu(&gb, 4); // obsolete X, Y offset bits_pixel = bytestream2_get_be16u(&gb); if (bits_pixel == 24) avctx->pix_fmt = AV_PIX_FMT_BGR24; else if (bits_pixel == 8) avctx->pix_fmt = AV_PIX_FMT_GRAY8; else { av_log(avctx, AV_LOG_ERROR, "Invalid pixel format.\n"); return AVERROR_INVALIDDATA; } ret = ff_set_dimensions(avctx, width, height); if (ret < 0) return ret; ret = ff_get_buffer(avctx, f, 0); if (ret < 0) return ret; f->pict_type = AV_PICTURE_TYPE_I; f->key_frame = 1; x = 0; y = 1; out_buf = f->data[0]; while (bytestream2_get_bytes_left(&gb) > 0) { int i; /* set buffer at the right position at every new line */ if (x == avctx->width) { x = 0; out_buf = f->data[0] + f->linesize[0] * y++; if (y > avctx->height) { av_log(avctx, AV_LOG_ERROR, "Ended frame decoding with %d bytes left.\n", bytestream2_get_bytes_left(&gb)); return AVERROR_INVALIDDATA; } } /* read packet and copy data */ count = bytestream2_get_byteu(&gb); if (!count || x + count > avctx->width) { av_log(avctx, AV_LOG_ERROR, "Invalid run length %d.\n", count); return AVERROR_INVALIDDATA; } if (avctx->pix_fmt == AV_PIX_FMT_BGR24) { pixel = bytestream2_get_be24(&gb); for (i = 0; i < count; i++) { AV_WB24(out_buf, pixel); out_buf += 3; } } else { // AV_PIX_FMT_GRAY8 pixel = bytestream2_get_byte(&gb); for (i = 0; i < count; i++) *out_buf++ = pixel; } x += i; } if (x != width || y != height) { av_log(avctx, AV_LOG_ERROR, "Picture stopped at %d,%d.\n", x, y); return AVERROR_INVALIDDATA; } *got_frame = 1; return avpkt->size; }