diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c index 6ddfdaf4fc..2ecc563fa4 100644 --- a/libavcodec/vmnc.c +++ b/libavcodec/vmnc.c @@ -68,50 +68,63 @@ typedef struct VmncContext { int cur_w, cur_h; int cur_x, cur_y; int cur_hx, cur_hy; - uint8_t* curbits, *curmask; - uint8_t* screendta; + uint8_t *curbits, *curmask; + uint8_t *screendta; } VmncContext; /* read pixel value from stream */ -static av_always_inline int vmnc_get_pixel(const uint8_t* buf, int bpp, int be) { - switch(bpp * 2 + be) { +static av_always_inline int vmnc_get_pixel(const uint8_t *buf, int bpp, int be) +{ + switch (bpp * 2 + be) { case 2: - case 3: return *buf; - case 4: return AV_RL16(buf); - case 5: return AV_RB16(buf); - case 8: return AV_RL32(buf); - case 9: return AV_RB32(buf); - default: return 0; + case 3: + return *buf; + case 4: + return AV_RL16(buf); + case 5: + return AV_RB16(buf); + case 8: + return AV_RL32(buf); + case 9: + return AV_RB32(buf); + default: + return 0; } } static void load_cursor(VmncContext *c, const uint8_t *src) { int i, j, p; - const int bpp = c->bpp2; - uint8_t *dst8 = c->curbits; - uint16_t *dst16 = (uint16_t*)c->curbits; - uint32_t *dst32 = (uint32_t*)c->curbits; + const int bpp = c->bpp2; + uint8_t *dst8 = c->curbits; + uint16_t *dst16 = (uint16_t *)c->curbits; + uint32_t *dst32 = (uint32_t *)c->curbits; - for(j = 0; j < c->cur_h; j++) { - for(i = 0; i < c->cur_w; i++) { + for (j = 0; j < c->cur_h; j++) { + for (i = 0; i < c->cur_w; i++) { p = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; - if(bpp == 1) *dst8++ = p; - if(bpp == 2) *dst16++ = p; - if(bpp == 4) *dst32++ = p; + if (bpp == 1) + *dst8++ = p; + if (bpp == 2) + *dst16++ = p; + if (bpp == 4) + *dst32++ = p; } } - dst8 = c->curmask; + dst8 = c->curmask; dst16 = (uint16_t*)c->curmask; dst32 = (uint32_t*)c->curmask; - for(j = 0; j < c->cur_h; j++) { - for(i = 0; i < c->cur_w; i++) { + for (j = 0; j < c->cur_h; j++) { + for (i = 0; i < c->cur_w; i++) { p = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; - if(bpp == 1) *dst8++ = p; - if(bpp == 2) *dst16++ = p; - if(bpp == 4) *dst32++ = p; + if (bpp == 1) + *dst8++ = p; + if (bpp == 2) + *dst16++ = p; + if (bpp == 4) + *dst32++ = p; } } } @@ -121,96 +134,101 @@ static void put_cursor(uint8_t *dst, int stride, VmncContext *c, int dx, int dy) int i, j; int w, h, x, y; w = c->cur_w; - if(c->width < c->cur_x + c->cur_w) w = c->width - c->cur_x; + if (c->width < c->cur_x + c->cur_w) + w = c->width - c->cur_x; h = c->cur_h; - if(c->height < c->cur_y + c->cur_h) h = c->height - c->cur_y; + if (c->height < c->cur_y + c->cur_h) + h = c->height - c->cur_y; x = c->cur_x; y = c->cur_y; - if(x < 0) { + if (x < 0) { w += x; - x = 0; + x = 0; } - if(y < 0) { + if (y < 0) { h += y; - y = 0; + y = 0; } - if((w < 1) || (h < 1)) return; + if ((w < 1) || (h < 1)) + return; dst += x * c->bpp2 + y * stride; - if(c->bpp2 == 1) { - uint8_t* cd = c->curbits, *msk = c->curmask; - for(j = 0; j < h; j++) { - for(i = 0; i < w; i++) + if (c->bpp2 == 1) { + uint8_t *cd = c->curbits, *msk = c->curmask; + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) dst[i] = (dst[i] & cd[i]) ^ msk[i]; msk += c->cur_w; - cd += c->cur_w; + cd += c->cur_w; dst += stride; } - } else if(c->bpp2 == 2) { - uint16_t* cd = (uint16_t*)c->curbits, *msk = (uint16_t*)c->curmask; - uint16_t* dst2; - for(j = 0; j < h; j++) { + } else if (c->bpp2 == 2) { + uint16_t *cd = (uint16_t*)c->curbits, *msk = (uint16_t*)c->curmask; + uint16_t *dst2; + for (j = 0; j < h; j++) { dst2 = (uint16_t*)dst; - for(i = 0; i < w; i++) + for (i = 0; i < w; i++) dst2[i] = (dst2[i] & cd[i]) ^ msk[i]; msk += c->cur_w; - cd += c->cur_w; + cd += c->cur_w; dst += stride; } - } else if(c->bpp2 == 4) { - uint32_t* cd = (uint32_t*)c->curbits, *msk = (uint32_t*)c->curmask; - uint32_t* dst2; - for(j = 0; j < h; j++) { + } else if (c->bpp2 == 4) { + uint32_t *cd = (uint32_t*)c->curbits, *msk = (uint32_t*)c->curmask; + uint32_t *dst2; + for (j = 0; j < h; j++) { dst2 = (uint32_t*)dst; - for(i = 0; i < w; i++) + for (i = 0; i < w; i++) dst2[i] = (dst2[i] & cd[i]) ^ msk[i]; msk += c->cur_w; - cd += c->cur_w; + cd += c->cur_w; dst += stride; } } } /* fill rectangle with given color */ -static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy, int w, int h, int color, int bpp, int stride) +static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy, + int w, int h, int color, + int bpp, int stride) { int i, j; dst += dx * bpp + dy * stride; - if(bpp == 1){ - for(j = 0; j < h; j++) { + if (bpp == 1) { + for (j = 0; j < h; j++) { memset(dst, color, w); dst += stride; } - }else if(bpp == 2){ - uint16_t* dst2; - for(j = 0; j < h; j++) { + } else if (bpp == 2) { + uint16_t *dst2; + for (j = 0; j < h; j++) { dst2 = (uint16_t*)dst; - for(i = 0; i < w; i++) { + for (i = 0; i < w; i++) *dst2++ = color; - } dst += stride; } - }else if(bpp == 4){ - uint32_t* dst2; - for(j = 0; j < h; j++) { + } else if (bpp == 4) { + uint32_t *dst2; + for (j = 0; j < h; j++) { dst2 = (uint32_t*)dst; - for(i = 0; i < w; i++) { + for (i = 0; i < w; i++) dst2[i] = color; - } dst += stride; } } } -static av_always_inline void paint_raw(uint8_t *dst, int w, int h, const uint8_t* src, int bpp, int be, int stride) +static av_always_inline void paint_raw(uint8_t *dst, int w, int h, + const uint8_t *src, int bpp, + int be, int stride) { int i, j, p; - for(j = 0; j < h; j++) { - for(i = 0; i < w; i++) { + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) { p = vmnc_get_pixel(src, bpp, be); src += bpp; - switch(bpp){ + switch (bpp) { case 1: dst[i] = p; break; @@ -226,58 +244,65 @@ static av_always_inline void paint_raw(uint8_t *dst, int w, int h, const uint8_t } } -static int decode_hextile(VmncContext *c, uint8_t* dst, const uint8_t* src, int ssize, int w, int h, int stride) +static int decode_hextile(VmncContext *c, uint8_t *dst, const uint8_t *src, + int ssize, int w, int h, int stride) { int i, j, k; int bg = 0, fg = 0, rects, color, flags, xy, wh; const int bpp = c->bpp2; uint8_t *dst2; int bw = 16, bh = 16; - const uint8_t *ssrc=src; + const uint8_t *ssrc = src; - for(j = 0; j < h; j += 16) { + for (j = 0; j < h; j += 16) { dst2 = dst; - bw = 16; - if(j + 16 > h) bh = h - j; - for(i = 0; i < w; i += 16, dst2 += 16 * bpp) { - if(src - ssrc >= ssize) { + bw = 16; + if (j + 16 > h) + bh = h - j; + for (i = 0; i < w; i += 16, dst2 += 16 * bpp) { + if (src - ssrc >= ssize) { av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n"); return -1; } - if(i + 16 > w) bw = w - i; + if (i + 16 > w) + bw = w - i; flags = *src++; - if(flags & HT_RAW) { - if(src - ssrc > ssize - bw * bh * bpp) { + if (flags & HT_RAW) { + if (src - ssrc > ssize - bw * bh * bpp) { av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n"); return -1; } paint_raw(dst2, bw, bh, src, bpp, c->bigendian, stride); src += bw * bh * bpp; } else { - if(flags & HT_BKG) { - bg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; + if (flags & HT_BKG) { + bg = vmnc_get_pixel(src, bpp, c->bigendian); + src += bpp; } - if(flags & HT_FG) { - fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; + if (flags & HT_FG) { + fg = vmnc_get_pixel(src, bpp, c->bigendian); + src += bpp; } rects = 0; - if(flags & HT_SUB) + if (flags & HT_SUB) rects = *src++; color = !!(flags & HT_CLR); paint_rect(dst2, 0, 0, bw, bh, bg, bpp, stride); - if(src - ssrc > ssize - rects * (color * bpp + 2)) { + if (src - ssrc > ssize - rects * (color * bpp + 2)) { av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n"); return -1; } - for(k = 0; k < rects; k++) { - if(color) { - fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; + for (k = 0; k < rects; k++) { + if (color) { + fg = vmnc_get_pixel(src, bpp, c->bigendian); + src += bpp; } xy = *src++; wh = *src++; - paint_rect(dst2, xy >> 4, xy & 0xF, (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride); + paint_rect(dst2, xy >> 4, xy & 0xF, (wh >> 4) + 1, + (wh & 0xF) + 1, fg, bpp, stride); } } } @@ -290,7 +315,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + int buf_size = avpkt->size; VmncContext * const c = avctx->priv_data; uint8_t *outptr; const uint8_t *src = buf; @@ -304,58 +329,72 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, c->pic.key_frame = 0; c->pic.pict_type = AV_PICTURE_TYPE_P; - //restore screen after cursor - if(c->screendta) { + // restore screen after cursor + if (c->screendta) { int i; w = c->cur_w; - if(c->width < c->cur_x + w) w = c->width - c->cur_x; + if (c->width < c->cur_x + w) + w = c->width - c->cur_x; h = c->cur_h; - if(c->height < c->cur_y + h) h = c->height - c->cur_y; + if (c->height < c->cur_y + h) + h = c->height - c->cur_y; dx = c->cur_x; - if(dx < 0) { + if (dx < 0) { w += dx; dx = 0; } dy = c->cur_y; - if(dy < 0) { + if (dy < 0) { h += dy; dy = 0; } - if((w > 0) && (h > 0)) { + if ((w > 0) && (h > 0)) { outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0]; - for(i = 0; i < h; i++) { - memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2, w * c->bpp2); + for (i = 0; i < h; i++) { + memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2, + w * c->bpp2); outptr += c->pic.linesize[0]; } } } src += 2; - chunks = AV_RB16(src); src += 2; - while(chunks--) { - dx = AV_RB16(src); src += 2; - dy = AV_RB16(src); src += 2; - w = AV_RB16(src); src += 2; - h = AV_RB16(src); src += 2; - enc = AV_RB32(src); src += 4; + chunks = AV_RB16(src); + src += 2; + while (chunks--) { + dx = AV_RB16(src); + src += 2; + dy = AV_RB16(src); + src += 2; + w = AV_RB16(src); + src += 2; + h = AV_RB16(src); + src += 2; + enc = AV_RB32(src); + src += 4; outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0]; size_left = buf_size - (src - buf); - switch(enc) { + switch (enc) { case MAGIC_WMVd: // cursor - if(size_left < 2 + w * h * c->bpp2 * 2) { - av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", 2 + w * h * c->bpp2 * 2, size_left); + if (size_left < 2 + w * h * c->bpp2 * 2) { + av_log(avctx, AV_LOG_ERROR, + "Premature end of data! (need %i got %i)\n", + 2 + w * h * c->bpp2 * 2, size_left); return -1; } src += 2; - c->cur_w = w; - c->cur_h = h; + c->cur_w = w; + c->cur_h = h; c->cur_hx = dx; c->cur_hy = dy; - if((c->cur_hx > c->cur_w) || (c->cur_hy > c->cur_h)) { - av_log(avctx, AV_LOG_ERROR, "Cursor hot spot is not in image: %ix%i of %ix%i cursor size\n", c->cur_hx, c->cur_hy, c->cur_w, c->cur_h); + if ((c->cur_hx > c->cur_w) || (c->cur_hy > c->cur_h)) { + av_log(avctx, AV_LOG_ERROR, + "Cursor hot spot is not in image: " + "%ix%i of %ix%i cursor size\n", + c->cur_hx, c->cur_hy, c->cur_w, c->cur_h); c->cur_hx = c->cur_hy = 0; } - c->curbits = av_realloc(c->curbits, c->cur_w * c->cur_h * c->bpp2); - c->curmask = av_realloc(c->curmask, c->cur_w * c->cur_h * c->bpp2); + c->curbits = av_realloc(c->curbits, c->cur_w * c->cur_h * c->bpp2); + c->curmask = av_realloc(c->curmask, c->cur_w * c->cur_h * c->bpp2); c->screendta = av_realloc(c->screendta, c->cur_w * c->cur_h * c->bpp2); load_cursor(c, src); src += w * h * c->bpp2 * 2; @@ -377,40 +416,52 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, c->pic.key_frame = 1; c->pic.pict_type = AV_PICTURE_TYPE_I; depth = *src++; - if(depth != c->bpp) { - av_log(avctx, AV_LOG_INFO, "Depth mismatch. Container %i bpp, Frame data: %i bpp\n", c->bpp, depth); + if (depth != c->bpp) { + av_log(avctx, AV_LOG_INFO, + "Depth mismatch. Container %i bpp, " + "Frame data: %i bpp\n", + c->bpp, depth); } src++; c->bigendian = *src++; - if(c->bigendian & (~1)) { - av_log(avctx, AV_LOG_INFO, "Invalid header: bigendian flag = %i\n", c->bigendian); + if (c->bigendian & (~1)) { + av_log(avctx, AV_LOG_INFO, + "Invalid header: bigendian flag = %i\n", c->bigendian); return -1; } - //skip the rest of pixel format data + // skip the rest of pixel format data src += 13; break; case MAGIC_WMVj: // unknown src += 2; break; case 0x00000000: // raw rectangle data - if((dx + w > c->width) || (dy + h > c->height)) { - av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height); + if ((dx + w > c->width) || (dy + h > c->height)) { + av_log(avctx, AV_LOG_ERROR, + "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", + w, h, dx, dy, c->width, c->height); return -1; } - if(size_left < w * h * c->bpp2) { - av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", w * h * c->bpp2, size_left); + if (size_left < w * h * c->bpp2) { + av_log(avctx, AV_LOG_ERROR, + "Premature end of data! (need %i got %i)\n", + w * h * c->bpp2, size_left); return -1; } - paint_raw(outptr, w, h, src, c->bpp2, c->bigendian, c->pic.linesize[0]); + paint_raw(outptr, w, h, src, c->bpp2, c->bigendian, + c->pic.linesize[0]); src += w * h * c->bpp2; break; case 0x00000005: // HexTile encoded rectangle - if((dx + w > c->width) || (dy + h > c->height)) { - av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height); + if ((dx + w > c->width) || (dy + h > c->height)) { + av_log(avctx, AV_LOG_ERROR, + "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", + w, h, dx, dy, c->width, c->height); return -1; } - res = decode_hextile(c, outptr, src, size_left, w, h, c->pic.linesize[0]); - if(res < 0) + res = decode_hextile(c, outptr, src, size_left, w, h, + c->pic.linesize[0]); + if (res < 0) return -1; src += res; break; @@ -419,34 +470,37 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, chunks = 0; // leave chunks decoding loop } } - if(c->screendta){ + if (c->screendta) { int i; - //save screen data before painting cursor + // save screen data before painting cursor w = c->cur_w; - if(c->width < c->cur_x + w) w = c->width - c->cur_x; + if (c->width < c->cur_x + w) + w = c->width - c->cur_x; h = c->cur_h; - if(c->height < c->cur_y + h) h = c->height - c->cur_y; + if (c->height < c->cur_y + h) + h = c->height - c->cur_y; dx = c->cur_x; - if(dx < 0) { + if (dx < 0) { w += dx; dx = 0; } dy = c->cur_y; - if(dy < 0) { + if (dy < 0) { h += dy; dy = 0; } - if((w > 0) && (h > 0)) { + if ((w > 0) && (h > 0)) { outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0]; - for(i = 0; i < h; i++) { - memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr, w * c->bpp2); + for (i = 0; i < h; i++) { + memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr, + w * c->bpp2); outptr += c->pic.linesize[0]; } outptr = c->pic.data[0]; put_cursor(outptr, c->pic.linesize[0], c, c->cur_x, c->cur_y); } } - *got_frame = 1; + *got_frame = 1; if ((ret = av_frame_ref(data, &c->pic)) < 0) return ret; @@ -454,26 +508,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return buf_size; } - - -/* - * - * Init VMnc decoder - * - */ static av_cold int decode_init(AVCodecContext *avctx) { VmncContext * const c = avctx->priv_data; - c->avctx = avctx; - - c->width = avctx->width; + c->avctx = avctx; + c->width = avctx->width; c->height = avctx->height; + c->bpp = avctx->bits_per_coded_sample; + c->bpp2 = c->bpp / 8; - c->bpp = avctx->bits_per_coded_sample; - c->bpp2 = c->bpp/8; - - switch(c->bpp){ + switch (c->bpp) { case 8: avctx->pix_fmt = AV_PIX_FMT_PAL8; break; @@ -493,13 +538,6 @@ static av_cold int decode_init(AVCodecContext *avctx) return 0; } - - -/* - * - * Uninit VMnc decoder - * - */ static av_cold int decode_end(AVCodecContext *avctx) { VmncContext * const c = avctx->priv_data;