static int _decode_effect_sequence(BITBUFFER *bb, BD_IG_EFFECT_SEQUENCE *p) { unsigned ii; p->num_windows = bb_read(bb, 8); p->window = calloc(p->num_windows, sizeof(BD_PG_WINDOW)); if (!p->window) { BD_DEBUG(DBG_DECODE | DBG_CRIT, "out of memory\n"); return 0; } for (ii = 0; ii < p->num_windows; ii++) { pg_decode_window(bb, &p->window[ii]); } p->num_effects = bb_read(bb, 8); p->effect = calloc(p->num_effects, sizeof(BD_IG_EFFECT)); if (!p->effect) { BD_DEBUG(DBG_DECODE | DBG_CRIT, "out of memory\n"); return 0; } for (ii = 0; ii < p->num_effects; ii++) { if (!_decode_effect(bb, &p->effect[ii])) { return 0; } } return 1; }
void pg_decode_video_descriptor(BITBUFFER *bb, BD_PG_VIDEO_DESCRIPTOR *p) { p->video_width = bb_read(bb, 16); p->video_height = bb_read(bb, 16); p->frame_rate = bb_read(bb, 4); bb_skip(bb, 4); }
static int _decode_interactive_composition(BITBUFFER *bb, BD_IG_INTERACTIVE_COMPOSITION *p) { unsigned ii; uint32_t data_len = bb_read(bb, 24); uint32_t buf_len = bb->p_end - bb->p; if (data_len != buf_len) { ERROR("ig_decode_interactive(): buffer size mismatch (expected %d, have %d)\n", data_len, buf_len); return 0; } p->stream_model = bb_read(bb, 1); p->ui_model = bb_read(bb, 1); bb_skip(bb, 6); if (p->stream_model == 0) { bb_skip(bb, 7); p->composition_timeout_pts = bb_read_u64(bb, 33); bb_skip(bb, 7); p->selection_timeout_pts = bb_read_u64(bb, 33); } p->user_timeout_duration = bb_read(bb, 24); p->num_pages = bb_read(bb, 8); p->page = calloc(p->num_pages, sizeof(BD_IG_PAGE)); for (ii = 0; ii < p->num_pages; ii++) { _decode_page(bb, &p->page[ii]); } return 1; }
static int _decode_segment(PG_DISPLAY_SET *s, PES_BUFFER *p) { BITBUFFER bb; bb_init(&bb, p->buf, p->len); uint8_t type = bb_read(&bb, 8); /*uint16_t len = */ bb_read(&bb, 16); switch (type) { case PGS_OBJECT: return _decode_ods(s, &bb, p); case PGS_PALETTE: return _decode_pds(s, &bb, p); case PGS_WINDOW: return _decode_wds(s, &bb, p); case PGS_PG_COMPOSITION: return _decode_pcs(s, &bb, p); case PGS_IG_COMPOSITION: return _decode_ics(s, &bb, p); case PGS_END_OF_DISPLAY: s->complete = 1; return 1; default: BD_DEBUG(DBG_DECODE | DBG_CRIT, "unknown segment type 0x%x\n", type); break; } return 0; }
void pg_decode_window(BITBUFFER *bb, BD_PG_WINDOW *p) { p->id = bb_read(bb, 8); p->x = bb_read(bb, 16); p->y = bb_read(bb, 16); p->width = bb_read(bb, 16); p->height = bb_read(bb, 16); }
static inline uint64_t bb_read_u64(BITBUFFER *bb, int i_count) { uint64_t result = 0; if (i_count > 32) { i_count -= 32; result = (uint64_t)bb_read(bb, 32) << i_count; } result |= bb_read(bb, i_count); return result; }
static void _decode_bog(BITBUFFER *bb, BD_IG_BOG *p) { unsigned ii; p->default_valid_button_id_ref = bb_read(bb, 16); p->num_buttons = bb_read(bb, 8); p->button = calloc(p->num_buttons, sizeof(BD_IG_BUTTON)); for (ii = 0; ii < p->num_buttons; ii++) { _decode_button(bb, &p->button[ii]); } }
static void _decode_effect(BITBUFFER *bb, BD_IG_EFFECT *p) { unsigned ii; p->duration = bb_read(bb, 24); p->palette_id_ref = bb_read(bb, 8); p->num_composition_objects = bb_read(bb, 8); p->composition_object = calloc(p->num_composition_objects, sizeof(BD_PG_COMPOSITION_OBJECT)); for (ii = 0; ii < p->num_composition_objects; ii++) { pg_decode_composition_object(bb, &p->composition_object[ii]); } }
static int _decode_dialog_style(PG_DISPLAY_SET *s, BITBUFFER *bb) { _free_dialogs(s); s->style = calloc(1, sizeof(*s->style)); if (!textst_decode_dialog_style(bb, s->style)) { textst_free_dialog_style(&s->style); return 0; } if (bb->p != bb->p_end - 2 || bb->i_left != 8) { BD_DEBUG(DBG_DECODE | DBG_CRIT, "_decode_dialog_style() failed: bytes in buffer %d\n", (int)(bb->p_end - bb->p)); textst_free_dialog_style(&s->style); return 0; } s->total_dialog = bb_read(bb, 16); if (s->total_dialog < 1) { BD_DEBUG(DBG_DECODE | DBG_CRIT, "_decode_dialog_style(): no dialog segments\n"); textst_free_dialog_style(&s->style); return 0; } s->dialog = calloc(s->total_dialog, sizeof(*s->dialog)); BD_DEBUG(DBG_DECODE, "_decode_dialog_style(): %d dialogs in stream\n", s->total_dialog); return 1; }
static int _decode_ods(PG_DISPLAY_SET *s, BITBUFFER *bb, PES_BUFFER *p) { /* search for object to be updated */ if (s->object) { BITBUFFER bb_tmp = *bb; uint16_t id = bb_read(&bb_tmp, 16); unsigned ii; for (ii = 0; ii < s->num_object; ii++) { if (s->object[ii].id == id) { if (pg_decode_object(bb, &s->object[ii])) { s->object[ii].pts = p->pts; return 1; } return 0; } } } /* add and decode new object */ s->object = realloc(s->object, sizeof(s->object[0]) * (s->num_object + 1)); memset(&s->object[s->num_object], 0, sizeof(s->object[0])); if (pg_decode_object(bb, &s->object[s->num_object])) { s->object[s->num_object].pts = p->pts; s->num_object++; return 1; } return 0; }
static void _decode_effect_sequence(BITBUFFER *bb, BD_IG_EFFECT_SEQUENCE *p) { unsigned ii; p->num_windows = bb_read(bb, 8); p->window = calloc(p->num_windows, sizeof(BD_PG_WINDOW)); for (ii = 0; ii < p->num_windows; ii++) { pg_decode_window(bb, &p->window[ii]); } p->num_effects = bb_read(bb, 8); p->effect = calloc(p->num_effects, sizeof(BD_IG_EFFECT)); for (ii = 0; ii < p->num_effects; ii++) { _decode_effect(bb, &p->effect[ii]); } }
/* Get bit data*/ static int sh_get_mdio(struct mdiobb_ctrl *ctrl) { struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); if (bitbang->set_gate) bitbang->set_gate(bitbang->addr); return bb_read(bitbang->addr, bitbang->mdi_msk); }
void pg_decode_composition_object(BITBUFFER *bb, BD_PG_COMPOSITION_OBJECT *p) { p->object_id_ref = bb_read(bb, 16); p->window_id_ref = bb_read(bb, 8); p->crop_flag = bb_read(bb, 1); p->forced_on_flag = bb_read(bb, 1); bb_skip(bb, 6); p->x = bb_read(bb, 16); p->y = bb_read(bb, 16); if (p->crop_flag) { p->crop_x = bb_read(bb, 16); p->crop_y = bb_read(bb, 16); p->crop_w = bb_read(bb, 16); p->crop_h = bb_read(bb, 16); } }
static int _decode_effect(BITBUFFER *bb, BD_IG_EFFECT *p) { unsigned ii; p->duration = bb_read(bb, 24); p->palette_id_ref = bb_read(bb, 8); p->num_composition_objects = bb_read(bb, 8); p->composition_object = calloc(p->num_composition_objects, sizeof(BD_PG_COMPOSITION_OBJECT)); if (!p->composition_object) { BD_DEBUG(DBG_DECODE | DBG_CRIT, "out of memory\n"); return 0; } for (ii = 0; ii < p->num_composition_objects; ii++) { pg_decode_composition_object(bb, &p->composition_object[ii]); } return 1; }
int pg_decode_composition(BITBUFFER *bb, BD_PG_COMPOSITION *p) { unsigned ii; pg_decode_video_descriptor(bb, &p->video_descriptor); pg_decode_composition_descriptor(bb, &p->composition_descriptor); p->palette_update_flag = bb_read(bb, 1); bb_skip(bb, 7); p->palette_id_ref = bb_read(bb, 8); p->num_composition_objects = bb_read(bb, 8); p->composition_object = calloc(p->num_composition_objects, sizeof(BD_PG_COMPOSITION_OBJECT)); for (ii = 0; ii < p->num_composition_objects; ii++) { pg_decode_composition_object(bb, &p->composition_object[ii]); } return 1; }
static int _decode_bog(BITBUFFER *bb, BD_IG_BOG *p) { unsigned ii; p->default_valid_button_id_ref = bb_read(bb, 16); p->num_buttons = bb_read(bb, 8); p->button = calloc(p->num_buttons, sizeof(BD_IG_BUTTON)); if (!p->button) { BD_DEBUG(DBG_DECODE | DBG_CRIT, "out of memory\n"); return 0; } for (ii = 0; ii < p->num_buttons; ii++) { if (!_decode_button(bb, &p->button[ii])) { return 0; } } return 1; }
int pg_decode_windows(BITBUFFER *bb, BD_PG_WINDOWS *p) { unsigned ii; p->num_windows = bb_read(bb, 8); p->window = calloc(p->num_windows, sizeof(BD_PG_WINDOW)); for (ii = 0; ii < p->num_windows; ii++) { pg_decode_window(bb, &p->window[ii]); } return 1; }
void mobj_parse_cmd(uint8_t *buf, MOBJ_CMD *cmd) { BITBUFFER bb; bb_init(&bb, buf, 12); cmd->insn.op_cnt = bb_read(&bb, 3); cmd->insn.grp = bb_read(&bb, 2); cmd->insn.sub_grp = bb_read(&bb, 3); cmd->insn.imm_op1 = bb_read(&bb, 1); cmd->insn.imm_op2 = bb_read(&bb, 1); bb_skip(&bb, 2); /* reserved */ cmd->insn.branch_opt = bb_read(&bb, 4); bb_skip(&bb, 4); /* reserved */ cmd->insn.cmp_opt = bb_read(&bb, 4); bb_skip(&bb, 3); /* reserved */ cmd->insn.set_opt = bb_read(&bb, 5); cmd->dst = bb_read(&bb, 32); cmd->src = bb_read(&bb, 32); }
int pg_decode_object(BITBUFFER *bb, BD_PG_OBJECT *p) { BD_PG_SEQUENCE_DESCRIPTOR sd; p->id = bb_read(bb, 16); p->version = bb_read(bb, 8); pg_decode_sequence_descriptor(bb, &sd); /* splitted segments should be already joined */ if (!sd.first_in_seq) { BD_DEBUG(DBG_DECODE, "pg_decode_object(): not first in sequence\n"); return 0; } if (!sd.last_in_seq) { BD_DEBUG(DBG_DECODE, "pg_decode_object(): not last in sequence\n"); return 0; } if (!bb_is_align(bb, 0x07)) { BD_DEBUG(DBG_DECODE, "pg_decode_object(): alignment error\n"); return 0; } uint32_t data_len = bb_read(bb, 24); uint32_t buf_len = bb->p_end - bb->p; if (data_len != buf_len) { BD_DEBUG(DBG_DECODE, "pg_decode_object(): buffer size mismatch (expected %d, have %d)\n", data_len, buf_len); return 0; } p->width = bb_read(bb, 16); p->height = bb_read(bb, 16); return _decode_rle(bb, p); }
int pg_decode_palette_update(BITBUFFER *bb, BD_PG_PALETTE *p) { p->id = bb_read(bb, 8); p->version = bb_read(bb, 8); while (!bb_eof(bb)) { uint8_t entry_id = bb_read(bb, 8); p->entry[entry_id].Y = bb_read(bb, 8); p->entry[entry_id].Cr = bb_read(bb, 8); p->entry[entry_id].Cb = bb_read(bb, 8); p->entry[entry_id].T = bb_read(bb, 8); } return 1; }
static int _decode_pds(PG_DISPLAY_SET *s, BITBUFFER *bb, PES_BUFFER *p) { /* search for palette to be updated */ if (s->palette) { BITBUFFER bb_tmp = *bb; uint8_t id = bb_read(&bb_tmp, 8); unsigned ii; for (ii = 0; ii < s->num_palette; ii++) { if (s->palette[ii].id == id) { int rr; if ( (s->ics && s->ics->composition_descriptor.state == 0) || (s->pcs && s->pcs->composition_descriptor.state == 0)) { /* 8.8.3.1.1 */ rr = pg_decode_palette_update(bb, &s->palette[ii]); } else { rr = pg_decode_palette(bb, &s->palette[ii]); } if (rr) { s->palette[ii].pts = p->pts; return 1; } return 0; } } } /* add and decode new palette */ s->palette = realloc(s->palette, sizeof(s->palette[0]) * (s->num_palette + 1)); memset(&s->palette[s->num_palette], 0, sizeof(s->palette[0])); if (pg_decode_palette(bb, &s->palette[s->num_palette])) { s->palette[s->num_palette].pts = p->pts; s->num_palette++; return 1; } return 0; }
static int _decode_page(BITBUFFER *bb, BD_IG_PAGE *p) { unsigned ii; p->id = bb_read(bb, 8); p->version = bb_read(bb, 8); _decode_uo_mask_table(bb, &p->uo_mask_table); if (!_decode_effect_sequence(bb, &p->in_effects)) { return 0; } if (!_decode_effect_sequence(bb, &p->out_effects)) { return 0; } p->animation_frame_rate_code = bb_read(bb, 8); p->default_selected_button_id_ref = bb_read(bb, 16); p->default_activated_button_id_ref = bb_read(bb, 16); p->palette_id_ref = bb_read(bb, 8); p->num_bogs = bb_read(bb, 8); p->bog = calloc(p->num_bogs, sizeof(BD_IG_BOG)); if (!p->bog) { BD_DEBUG(DBG_DECODE | DBG_CRIT, "out of memory\n"); return 0; } for (ii = 0; ii < p->num_bogs; ii++) { if (!_decode_bog(bb, &p->bog[ii])) { return 0; } } return 1; }
static void _decode_page(BITBUFFER *bb, BD_IG_PAGE *p) { unsigned ii; p->id = bb_read(bb, 8); p->version = bb_read(bb, 8); _decode_uo_mask_table(bb, &p->uo_mask_table); _decode_effect_sequence(bb, &p->in_effects); _decode_effect_sequence(bb, &p->out_effects); p->animation_frame_rate_code = bb_read(bb, 8); p->default_selected_button_id_ref = bb_read(bb, 16); p->default_activated_button_id_ref = bb_read(bb, 16); p->palette_id_ref = bb_read(bb, 8); p->num_bogs = bb_read(bb, 8); p->bog = calloc(p->num_bogs, sizeof(BD_IG_BOG)); for (ii = 0; ii < p->num_bogs; ii++) { _decode_bog(bb, &p->bog[ii]); } }
void pg_decode_sequence_descriptor(BITBUFFER *bb, BD_PG_SEQUENCE_DESCRIPTOR *p) { p->first_in_seq = bb_read(bb, 1); p->last_in_seq = bb_read(bb, 1); bb_skip(bb, 6); }
static void _decode_button(BITBUFFER *bb, BD_IG_BUTTON *p) { unsigned ii; p->id = bb_read(bb, 16); p->numeric_select_value = bb_read(bb, 16); p->auto_action_flag = bb_read(bb, 1); bb_skip(bb, 7); p->x_pos = bb_read(bb, 16); p->y_pos = bb_read(bb, 16); p->upper_button_id_ref = bb_read(bb, 16); p->lower_button_id_ref = bb_read(bb, 16); p->left_button_id_ref = bb_read(bb, 16); p->right_button_id_ref = bb_read(bb, 16); p->normal_start_object_id_ref = bb_read(bb, 16); p->normal_end_object_id_ref = bb_read(bb, 16); p->normal_repeat_flag = bb_read(bb, 1); bb_skip(bb, 7); p->selected_sound_id_ref = bb_read(bb, 8); p->selected_start_object_id_ref = bb_read(bb, 16); p->selected_end_object_id_ref = bb_read(bb, 16); p->selected_repeat_flag = bb_read(bb, 1); bb_skip(bb, 7); p->activated_sound_id_ref = bb_read(bb, 8); p->activated_start_object_id_ref = bb_read(bb, 16); p->activated_end_object_id_ref = bb_read(bb, 16); p->num_nav_cmds = bb_read(bb, 16); p->nav_cmds = calloc(p->num_nav_cmds, sizeof(MOBJ_CMD)); for (ii = 0; ii < p->num_nav_cmds; ii++) { uint8_t buf[12]; bb_read_bytes(bb, buf, 12); mobj_parse_cmd(buf, &p->nav_cmds[ii]); } }
static inline int mdio_read(struct mdiobb_ctrl *ctrl) { struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); return bb_read(bitbang->dat, bitbang->mdio_msk); }
static int _decode_rle(BITBUFFER *bb, BD_PG_OBJECT *p) { int pixels_left = p->width * p->height; int num_rle = 0; int rle_size = p->width * p->height / 4; if (rle_size < 1) rle_size = 1; p->img = realloc(p->img, rle_size * sizeof(BD_PG_RLE_ELEM)); if (!p->img) { BD_DEBUG(DBG_DECODE | DBG_CRIT, "pg_decode_object(): relloc(%zu) failed\n", rle_size * sizeof(BD_PG_RLE_ELEM)); return 0; } while (!bb_eof(bb)) { uint32_t len = 1; uint8_t color = 0; if (!(color = bb_read(bb, 8))) { if (!bb_read(bb, 1)) { if (!bb_read(bb, 1)) { len = bb_read(bb, 6); } else { len = bb_read(bb, 14); } } else { if (!bb_read(bb, 1)) { len = bb_read(bb, 6); } else { len = bb_read(bb, 14); } color = bb_read(bb, 8); } } p->img[num_rle].len = len; p->img[num_rle].color = color; pixels_left -= len; if (pixels_left < 0) { BD_DEBUG(DBG_DECODE, "pg_decode_object(): too many pixels (%d)\n", -pixels_left); return 0; } num_rle++; if (num_rle >= rle_size) { void *tmp = p->img; rle_size *= 2; p->img = realloc(p->img, rle_size * sizeof(BD_PG_RLE_ELEM)); if (!p->img) { BD_DEBUG(DBG_DECODE | DBG_CRIT, "pg_decode_object(): relloc(%zu) failed\n", rle_size * sizeof(BD_PG_RLE_ELEM)); X_FREE(tmp); return 0; } } } if (pixels_left > 0) { BD_DEBUG(DBG_DECODE, "pg_decode_object(): missing %d pixels\n", pixels_left); return 0; } return 1; }
void pg_decode_composition_descriptor(BITBUFFER *bb, BD_PG_COMPOSITION_DESCRIPTOR *p) { p->number = bb_read(bb, 16); p->state = bb_read(bb, 2); bb_skip(bb, 6); }