X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fprosumer.c;h=505de71980103f748d17df79843a21886cb61fc2;hb=c6db2e97dcd246234b958814450d3fd12a5c8c27;hp=b7e417aa0bd13223bc1e073e9ce7c514c741e13f;hpb=3c9ebcbc4dceef385e20e76704bf3c2e370b9368;p=ffmpeg diff --git a/libavcodec/prosumer.c b/libavcodec/prosumer.c index b7e417aa0bd..505de719801 100644 --- a/libavcodec/prosumer.c +++ b/libavcodec/prosumer.c @@ -39,7 +39,7 @@ typedef struct ProSumerContext { unsigned stride; unsigned size; uint32_t lut[0x10000]; - uint8_t *table_b; + uint8_t *initial_line; uint8_t *decbuffer; } ProSumerContext; @@ -57,25 +57,25 @@ static int decompress(GetByteContext *gb, int size, PutByteContext *pb, const ui b = lut[2 * idx]; while (1) { - if (((b & 0xFF00u) != 0x8000u) || (b & 0xFFu)) { + if (bytestream2_get_bytes_left_p(pb) <= 0 || bytestream2_get_eof(pb)) + return 0; + if ((b & 0xFF00u) != 0x8000u || (b & 0xFFu)) { if ((b & 0xFF00u) != 0x8000u) { bytestream2_put_le16(pb, b); - } else if (b & 0xFFu) { + } else { idx = 0; for (int i = 0; i < (b & 0xFFu); i++) bytestream2_put_le32(pb, 0); } c = b >> 16; if (c & 0xFF00u) { - c = (((c >> 8) & 0xFFu) | (c & 0xFF00)) & 0xF00F; fill = lut[2 * idx + 1]; - if ((c & 0xFF00u) == 0x1000) { + if ((c & 0xF000u) == 0x1000) { bytestream2_put_le16(pb, fill); - c &= 0xFFFF00FFu; } else { bytestream2_put_le32(pb, fill); - c &= 0xFFFF00FFu; } + c = (c >> 8) & 0x0Fu; } while (c) { a <<= 4; @@ -132,15 +132,13 @@ static int decompress(GetByteContext *gb, int size, PutByteContext *pb, const ui return 0; } -static void do_shift(uint32_t *dst, int offset, uint32_t *src, int stride, int height) +static void vertical_predict(uint32_t *dst, int offset, const uint32_t *src, int stride, int height) { - uint32_t x = (0x7F7F7F7F >> 1) & 0x7F7F7F7F; - dst += offset >> 2; for (int i = 0; i < height; i++) { for (int j = 0; j < stride >> 2; j++) { - dst[j] = (((src[j] >> 3) + (x & dst[j])) << 3) & 0xFCFCFCFC; + dst[j] = (((src[j] >> 3) + (0x3F3F3F3F & dst[j])) << 3) & 0xFCFCFCFC; } dst += stride >> 2; @@ -163,8 +161,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, bytestream2_init_writer(&s->pb, s->decbuffer, s->size); decompress(&s->gb, AV_RL32(avpkt->data + 28) >> 1, &s->pb, s->lut); - do_shift((uint32_t *)s->decbuffer, 0, (uint32_t *)s->table_b, s->stride, 1); - do_shift((uint32_t *)s->decbuffer, s->stride, (uint32_t *)s->decbuffer, s->stride, avctx->height - 1); + vertical_predict((uint32_t *)s->decbuffer, 0, (uint32_t *)s->initial_line, s->stride, 1); + vertical_predict((uint32_t *)s->decbuffer, s->stride, (uint32_t *)s->decbuffer, s->stride, avctx->height - 1); ret = ff_get_buffer(avctx, frame, 0); if (ret < 0) @@ -174,7 +172,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, uint8_t *y = &frame->data[0][i * frame->linesize[0]]; uint8_t *u = &frame->data[1][i * frame->linesize[1]]; uint8_t *v = &frame->data[2][i * frame->linesize[2]]; - uint8_t *src = s->decbuffer + (avctx->height - 1 - i) * s->stride; + const uint8_t *src = s->decbuffer + (avctx->height - 1 - i) * s->stride; for (int j = 0; j < avctx->width; j += 8) { *(u++) = *src++; @@ -276,7 +274,6 @@ static const uint16_t table[] = { 0x8022, 0xDAC, 0x8023, 0xDAD, 0x8024, 0xDAE, 0x8025, 0xDAF, 0x8026, 0xDB0, 0x8027, 0xDB1, 0x8028, 0xDB2, 0x8029, 0xDB3, 0x802A, 0xDB4, 0x802B, 0xDB5, 0x802C, 0xDB6, 0x802D, 0xDB7, 0x802E, 0xDB8, 0x802F, 0xDB9, 0x80FF, 0xDBA, - 0x0001 }; static void fill_elements(uint32_t idx, uint32_t shift, uint32_t *e0, uint32_t *e1) @@ -344,11 +341,11 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_YUV411P; - s->table_b = av_malloc(s->stride); + s->initial_line = av_malloc(s->stride); s->decbuffer = av_malloc(s->size); - if (!s->table_b || !s->decbuffer) + if (!s->initial_line || !s->decbuffer) return AVERROR(ENOMEM); - memset(s->table_b, 0x80u, s->stride); + memset(s->initial_line, 0x80u, s->stride); fill_lut(s->lut); @@ -359,7 +356,7 @@ static av_cold int decode_close(AVCodecContext *avctx) { ProSumerContext *s = avctx->priv_data; - av_freep(&s->table_b); + av_freep(&s->initial_line); av_freep(&s->decbuffer); return 0;