+ 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) {
+ 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);
+ return -1;
+ }
+ src += 2;
+ 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);
+ 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->screendta = av_realloc(c->screendta, c->cur_w * c->cur_h * c->bpp2);
+ load_cursor(c, src);
+ src += w * h * c->bpp2 * 2;
+ break;
+ case MAGIC_WMVe: // unknown
+ src += 2;
+ break;
+ case MAGIC_WMVf: // update cursor position
+ c->cur_x = dx - c->cur_hx;
+ c->cur_y = dy - c->cur_hy;
+ break;
+ case MAGIC_WMVg: // unknown
+ src += 10;
+ break;
+ case MAGIC_WMVh: // unknown
+ src += 4;
+ break;
+ case MAGIC_WMVi: // ServerInitialization struct
+ c->pic.key_frame = 1;
+ c->pic.pict_type = FF_I_TYPE;
+ 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);
+ }
+ src++;
+ c->bigendian = *src++;
+ 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
+ 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);
+ 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);
+ return -1;
+ }
+ 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);
+ return -1;
+ }
+ res = decode_hextile(c, outptr, src, size_left, w, h, c->pic.linesize[0]);
+ if(res < 0)
+ return -1;
+ src += res;
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Unsupported block type 0x%08X\n", enc);
+ chunks = 0; // leave chunks decoding loop