static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display, const uint8_t *buf, int buf_size, int top_bottom, int non_mod) { DVBSubContext *ctx = avctx->priv_data; DVBSubRegion *region = get_region(ctx, display->region_id); const uint8_t *buf_end = buf + buf_size; uint8_t *pbuf; int x_pos, y_pos; int i; uint8_t map2to4[] = { 0x0, 0x7, 0x8, 0xf}; uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff}; uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; uint8_t *map_table; #if 0 av_dlog(avctx, "DVB pixel block size %d, %s field:\n", buf_size, top_bottom ? "bottom" : "top"); for (i = 0; i < buf_size; i++) { if (i % 16 == 0) av_dlog(avctx, "0x%8p: ", buf+i); av_dlog(avctx, "%02x ", buf[i]); if (i % 16 == 15) av_dlog(avctx, "\n"); } if (i % 16) av_dlog(avctx, "\n"); #endif if (region == 0) return; pbuf = region->pbuf; region->dirty = 1; x_pos = display->x_pos; y_pos = display->y_pos; if ((y_pos & 1) != top_bottom) y_pos++; while (buf < buf_end) { if (x_pos > region->width || y_pos > region->height) { av_log(avctx, AV_LOG_ERROR, "Invalid object location!\n"); return; } switch (*buf++) { case 0x10: if (region->depth == 8) map_table = map2to8; else if (region->depth == 4) map_table = map2to4; else map_table = NULL; x_pos += dvbsub_read_2bit_string(pbuf + (y_pos * region->width) + x_pos, region->width - x_pos, &buf, buf_end - buf, non_mod, map_table); break; case 0x11: if (region->depth < 4) { av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth); return; } if (region->depth == 8) map_table = map4to8; else map_table = NULL; x_pos += dvbsub_read_4bit_string(pbuf + (y_pos * region->width) + x_pos, region->width - x_pos, &buf, buf_end - buf, non_mod, map_table); break; case 0x12: if (region->depth < 8) { av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth); return; } x_pos += dvbsub_read_8bit_string(pbuf + (y_pos * region->width) + x_pos, region->width - x_pos, &buf, buf_end - buf, non_mod, NULL); break; case 0x20: map2to4[0] = (*buf) >> 4; map2to4[1] = (*buf++) & 0xf; map2to4[2] = (*buf) >> 4; map2to4[3] = (*buf++) & 0xf; break; case 0x21: for (i = 0; i < 4; i++) map2to8[i] = *buf++; break; case 0x22: for (i = 0; i < 16; i++) map4to8[i] = *buf++; break; case 0xf0: x_pos = display->x_pos; y_pos += 2; break; default: av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1)); } } }