static void mm_decode_pal(MmContext *s) { int i; bytestream2_skip(&s->gb, 4); for (i = 0; i < 128; i++) { s->palette[i] = 0xFFU << 24 | bytestream2_get_be24(&s->gb); s->palette[i+128] = s->palette[i]<<2; } }
static int mm_decode_pal(MmContext *s) { int i; bytestream2_skip(&s->gb, 4); for (i = 0; i < 128; i++) { s->palette[i] = bytestream2_get_be24(&s->gb); s->palette[i+128] = s->palette[i]<<2; } return 0; }
static int hq_decode_frame(HQContext *ctx, AVFrame *pic, int prof_num, size_t data_size) { const HQProfile *profile; GetBitContext gb; const uint8_t *perm, *src = ctx->gbc.buffer; uint32_t slice_off[21]; int slice, start_off, next_off, i, ret; if ((unsigned)prof_num >= NUM_HQ_PROFILES) { profile = &ff_hq_profile[0]; avpriv_request_sample(ctx->avctx, "HQ Profile %d", prof_num); } else { profile = &ff_hq_profile[prof_num]; av_log(ctx->avctx, AV_LOG_VERBOSE, "HQ Profile %d\n", prof_num); } ctx->avctx->coded_width = FFALIGN(profile->width, 16); ctx->avctx->coded_height = FFALIGN(profile->height, 16); ctx->avctx->width = profile->width; ctx->avctx->height = profile->height; ctx->avctx->bits_per_raw_sample = 8; ctx->avctx->pix_fmt = AV_PIX_FMT_YUV422P; ret = ff_get_buffer(ctx->avctx, pic, 0); if (ret < 0) return ret; /* Offsets are stored from CUV position, so adjust them accordingly. */ for (i = 0; i < profile->num_slices + 1; i++) slice_off[i] = bytestream2_get_be24(&ctx->gbc) - 4; next_off = 0; for (slice = 0; slice < profile->num_slices; slice++) { start_off = next_off; next_off = profile->tab_h * (slice + 1) / profile->num_slices; perm = profile->perm_tab + start_off * profile->tab_w * 2; if (slice_off[slice] < (profile->num_slices + 1) * 3 || slice_off[slice] >= slice_off[slice + 1] || slice_off[slice + 1] > data_size) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid slice size %zu.\n", data_size); break; } init_get_bits(&gb, src + slice_off[slice], (slice_off[slice + 1] - slice_off[slice]) * 8); for (i = 0; i < (next_off - start_off) * profile->tab_w; i++) { ret = hq_decode_mb(ctx, pic, &gb, perm[0] * 16, perm[1] * 16); if (ret < 0) { av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding macroblock %d at slice %d.\n", i, slice); return ret; } perm += 2; } } return 0; }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; C93DecoderContext * const c93 = avctx->priv_data; AVFrame * const newpic = &c93->pictures[c93->currentpic]; AVFrame * const oldpic = &c93->pictures[c93->currentpic^1]; AVFrame *picture = data; GetByteContext gb; uint8_t *out; int stride, i, x, y, b, bt = 0; c93->currentpic ^= 1; newpic->reference = 3; newpic->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE; if (avctx->reget_buffer(avctx, newpic)) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return -1; } stride = newpic->linesize[0]; bytestream2_init(&gb, buf, buf_size); b = bytestream2_get_byte(&gb); if (b & C93_FIRST_FRAME) { newpic->pict_type = AV_PICTURE_TYPE_I; newpic->key_frame = 1; } else { newpic->pict_type = AV_PICTURE_TYPE_P; newpic->key_frame = 0; } for (y = 0; y < HEIGHT; y += 8) { out = newpic->data[0] + y * stride; for (x = 0; x < WIDTH; x += 8) { uint8_t *copy_from = oldpic->data[0]; unsigned int offset, j; uint8_t cols[4], grps[4]; C93BlockType block_type; if (!bt) bt = bytestream2_get_byte(&gb); block_type= bt & 0x0F; switch (block_type) { case C93_8X8_FROM_PREV: offset = bytestream2_get_le16(&gb); if (copy_block(avctx, out, copy_from, offset, 8, stride)) return -1; break; case C93_4X4_FROM_CURR: copy_from = newpic->data[0]; case C93_4X4_FROM_PREV: for (j = 0; j < 8; j += 4) { for (i = 0; i < 8; i += 4) { offset = bytestream2_get_le16(&gb); if (copy_block(avctx, &out[j*stride+i], copy_from, offset, 4, stride)) return -1; } } break; case C93_8X8_2COLOR: bytestream2_get_buffer(&gb, cols, 2); for (i = 0; i < 8; i++) { draw_n_color(out + i*stride, stride, 8, 1, 1, cols, NULL, bytestream2_get_byte(&gb)); } break; case C93_4X4_2COLOR: case C93_4X4_4COLOR: case C93_4X4_4COLOR_GRP: for (j = 0; j < 8; j += 4) { for (i = 0; i < 8; i += 4) { if (block_type == C93_4X4_2COLOR) { bytestream2_get_buffer(&gb, cols, 2); draw_n_color(out + i + j*stride, stride, 4, 4, 1, cols, NULL, bytestream2_get_le16(&gb)); } else if (block_type == C93_4X4_4COLOR) { bytestream2_get_buffer(&gb, cols, 4); draw_n_color(out + i + j*stride, stride, 4, 4, 2, cols, NULL, bytestream2_get_le32(&gb)); } else { bytestream2_get_buffer(&gb, grps, 4); draw_n_color(out + i + j*stride, stride, 4, 4, 1, cols, grps, bytestream2_get_le16(&gb)); } } } break; case C93_NOOP: break; case C93_8X8_INTRA: for (j = 0; j < 8; j++) bytestream2_get_buffer(&gb, out + j*stride, 8); break; default: av_log(avctx, AV_LOG_ERROR, "unexpected type %x at %dx%d\n", block_type, x, y); return -1; } bt >>= 4; out += 8; } } if (b & C93_HAS_PALETTE) { uint32_t *palette = (uint32_t *) newpic->data[1]; for (i = 0; i < 256; i++) { palette[i] = 0xFFU << 24 | bytestream2_get_be24(&gb); } } else { if (oldpic->data[1]) memcpy(newpic->data[1], oldpic->data[1], 256 * 4); } *picture = *newpic; *data_size = sizeof(AVFrame); return buf_size; }
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; C93DecoderContext * const c93 = avctx->priv_data; AVFrame * const newpic = c93->pictures[c93->currentpic]; AVFrame * const oldpic = c93->pictures[c93->currentpic^1]; GetByteContext gb; uint8_t *out; int stride, ret, i, x, y, b, bt = 0; if ((ret = ff_set_dimensions(avctx, WIDTH, HEIGHT)) < 0) return ret; c93->currentpic ^= 1; if ((ret = ff_reget_buffer(avctx, newpic)) < 0) return ret; stride = newpic->linesize[0]; bytestream2_init(&gb, buf, buf_size); b = bytestream2_get_byte(&gb); if (b & C93_FIRST_FRAME) { newpic->pict_type = AV_PICTURE_TYPE_I; newpic->key_frame = 1; } else { newpic->pict_type = AV_PICTURE_TYPE_P; newpic->key_frame = 0; } for (y = 0; y < HEIGHT; y += 8) { out = newpic->data[0] + y * stride; for (x = 0; x < WIDTH; x += 8) { uint8_t *copy_from = oldpic->data[0]; unsigned int offset, j; uint8_t cols[4], grps[4]; C93BlockType block_type; if (!bt) bt = bytestream2_get_byte(&gb); block_type= bt & 0x0F; switch (block_type) { case C93_8X8_FROM_PREV: offset = bytestream2_get_le16(&gb); if ((ret = copy_block(avctx, out, copy_from, offset, 8, stride)) < 0) return ret; break; case C93_4X4_FROM_CURR: copy_from = newpic->data[0]; case C93_4X4_FROM_PREV: for (j = 0; j < 8; j += 4) { for (i = 0; i < 8; i += 4) { int offset = bytestream2_get_le16(&gb); int from_x = offset % WIDTH; int from_y = offset / WIDTH; if (block_type == C93_4X4_FROM_CURR && from_y == y+j && (FFABS(from_x - x-i) < 4 || FFABS(from_x - x-i) > WIDTH-4)) { avpriv_request_sample(avctx, "block overlap %d %d %d %d\n", from_x, x+i, from_y, y+j); return AVERROR_INVALIDDATA; } if ((ret = copy_block(avctx, &out[j*stride+i], copy_from, offset, 4, stride)) < 0) return ret; } } break; case C93_8X8_2COLOR: bytestream2_get_buffer(&gb, cols, 2); for (i = 0; i < 8; i++) { draw_n_color(out + i*stride, stride, 8, 1, 1, cols, NULL, bytestream2_get_byte(&gb)); } break; case C93_4X4_2COLOR: case C93_4X4_4COLOR: case C93_4X4_4COLOR_GRP: for (j = 0; j < 8; j += 4) { for (i = 0; i < 8; i += 4) { if (block_type == C93_4X4_2COLOR) { bytestream2_get_buffer(&gb, cols, 2); draw_n_color(out + i + j*stride, stride, 4, 4, 1, cols, NULL, bytestream2_get_le16(&gb)); } else if (block_type == C93_4X4_4COLOR) { bytestream2_get_buffer(&gb, cols, 4); draw_n_color(out + i + j*stride, stride, 4, 4, 2, cols, NULL, bytestream2_get_le32(&gb)); } else { bytestream2_get_buffer(&gb, grps, 4); draw_n_color(out + i + j*stride, stride, 4, 4, 1, cols, grps, bytestream2_get_le16(&gb)); } } } break; case C93_NOOP: break; case C93_8X8_INTRA: for (j = 0; j < 8; j++) bytestream2_get_buffer(&gb, out + j*stride, 8); break; default: av_log(avctx, AV_LOG_ERROR, "unexpected type %x at %dx%d\n", block_type, x, y); return AVERROR_INVALIDDATA; } bt >>= 4; out += 8; } } if (b & C93_HAS_PALETTE) { uint32_t *palette = (uint32_t *) newpic->data[1]; for (i = 0; i < 256; i++) { palette[i] = 0xFFU << 24 | bytestream2_get_be24(&gb); } newpic->palette_has_changed = 1; } else { if (oldpic->data[1]) memcpy(newpic->data[1], oldpic->data[1], 256 * 4); } if ((ret = av_frame_ref(data, newpic)) < 0) return ret; *got_frame = 1; return buf_size; }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { PicContext *s = avctx->priv_data; uint32_t *palette; int bits_per_plane, bpp, etype, esize, npal, pos_after_pal; int i, x, y, plane, tmp; bytestream2_init(&s->g, avpkt->data, avpkt->size); if (bytestream2_get_bytes_left(&s->g) < 11) return AVERROR_INVALIDDATA; if (bytestream2_get_le16u(&s->g) != 0x1234) return AVERROR_INVALIDDATA; s->width = bytestream2_get_le16u(&s->g); s->height = bytestream2_get_le16u(&s->g); bytestream2_skip(&s->g, 4); tmp = bytestream2_get_byteu(&s->g); bits_per_plane = tmp & 0xF; s->nb_planes = (tmp >> 4) + 1; bpp = bits_per_plane * s->nb_planes; if (bits_per_plane > 8 || bpp < 1 || bpp > 32) { av_log_ask_for_sample(s, "unsupported bit depth\n"); return AVERROR_INVALIDDATA; } if (bytestream2_peek_byte(&s->g) == 0xFF) { bytestream2_skip(&s->g, 2); etype = bytestream2_get_le16(&s->g); esize = bytestream2_get_le16(&s->g); if (bytestream2_get_bytes_left(&s->g) < esize) return AVERROR_INVALIDDATA; } else { etype = -1; esize = 0; } avctx->pix_fmt = PIX_FMT_PAL8; if (s->width != avctx->width && s->height != avctx->height) { if (av_image_check_size(s->width, s->height, 0, avctx) < 0) return -1; avcodec_set_dimensions(avctx, s->width, s->height); if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); } if (avctx->get_buffer(avctx, &s->frame) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } memset(s->frame.data[0], 0, s->height * s->frame.linesize[0]); s->frame.pict_type = AV_PICTURE_TYPE_I; s->frame.palette_has_changed = 1; pos_after_pal = bytestream2_tell(&s->g) + esize; palette = (uint32_t*)s->frame.data[1]; if (etype == 1 && esize > 1 && bytestream2_peek_byte(&s->g) < 6) { int idx = bytestream2_get_byte(&s->g); npal = 4; for (i = 0; i < npal; i++) palette[i] = ff_cga_palette[ cga_mode45_index[idx][i] ]; } else if (etype == 2) { npal = FFMIN(esize, 16); for (i = 0; i < npal; i++) { int pal_idx = bytestream2_get_byte(&s->g); palette[i] = ff_cga_palette[FFMIN(pal_idx, 16)]; } } else if (etype == 3) { npal = FFMIN(esize, 16); for (i = 0; i < npal; i++) { int pal_idx = bytestream2_get_byte(&s->g); palette[i] = ff_ega_palette[FFMIN(pal_idx, 63)]; } } else if (etype == 4 || etype == 5) { npal = FFMIN(esize / 3, 256); for (i = 0; i < npal; i++) palette[i] = bytestream2_get_be24(&s->g) << 2; } else { if (bpp == 1) { npal = 2; palette[0] = 0x000000; palette[1] = 0xFFFFFF; } else if (bpp == 2) { npal = 4; for (i = 0; i < npal; i++) palette[i] = ff_cga_palette[ cga_mode45_index[0][i] ]; } else { npal = 16; memcpy(palette, ff_cga_palette, npal * 4); } } // fill remaining palette entries memset(palette + npal, 0, AVPALETTE_SIZE - npal * 4); // skip remaining palette bytes bytestream2_seek(&s->g, pos_after_pal, SEEK_SET); x = 0; y = s->height - 1; plane = 0; if (bytestream2_get_le16(&s->g)) { while (bytestream2_get_bytes_left(&s->g) >= 6) { int stop_size, marker, t1, t2; t1 = bytestream2_get_bytes_left(&s->g); t2 = bytestream2_get_le16(&s->g); stop_size = t1 - FFMIN(t1, t2); // ignore uncompressed block size bytestream2_skip(&s->g, 2); marker = bytestream2_get_byte(&s->g); while (plane < s->nb_planes && bytestream2_get_bytes_left(&s->g) > stop_size) { int run = 1; int val = bytestream2_get_byte(&s->g); if (val == marker) { run = bytestream2_get_byte(&s->g); if (run == 0) run = bytestream2_get_le16(&s->g); val = bytestream2_get_byte(&s->g); } if (!bytestream2_get_bytes_left(&s->g)) break; if (bits_per_plane == 8) { picmemset_8bpp(s, val, run, &x, &y); if (y < 0) break; } else { picmemset(s, val, run, &x, &y, &plane, bits_per_plane); } } } } else { av_log_ask_for_sample(s, "uncompressed image\n"); return avpkt->size; } *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; 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; }