00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "ig_decode.h"
00021
00022 #include "pg_decode.h"
00023 #include "../hdmv/mobj_parse.h"
00024 #include "../bdnav/mpls_parse.h"
00025
00026 #include "util/macro.h"
00027 #include "util/logging.h"
00028 #include "util/bits.h"
00029
00030 #include <string.h>
00031 #include <stdlib.h>
00032
00033
00034 static void _decode_button(BITBUFFER *bb, BD_IG_BUTTON *p)
00035 {
00036 unsigned ii;
00037
00038 p->id = bb_read(bb, 16);
00039
00040 p->numeric_select_value = bb_read(bb, 16);
00041 p->auto_action_flag = bb_read(bb, 1);
00042 bb_skip(bb, 7);
00043
00044 p->x_pos = bb_read(bb, 16);
00045 p->y_pos = bb_read(bb, 16);
00046
00047 p->upper_button_id_ref = bb_read(bb, 16);
00048 p->lower_button_id_ref = bb_read(bb, 16);
00049 p->left_button_id_ref = bb_read(bb, 16);
00050 p->right_button_id_ref = bb_read(bb, 16);
00051
00052 p->normal_start_object_id_ref = bb_read(bb, 16);
00053 p->normal_end_object_id_ref = bb_read(bb, 16);
00054 p->normal_repeat_flag = bb_read(bb, 1);
00055 bb_skip(bb, 7);
00056
00057 p->selected_sound_id_ref = bb_read(bb, 8);
00058 p->selected_start_object_id_ref = bb_read(bb, 16);
00059 p->selected_end_object_id_ref = bb_read(bb, 16);
00060 p->selected_repeat_flag = bb_read(bb, 1);
00061 bb_skip(bb, 7);
00062
00063 p->activated_sound_id_ref = bb_read(bb, 8);
00064 p->activated_start_object_id_ref = bb_read(bb, 16);
00065 p->activated_end_object_id_ref = bb_read(bb, 16);
00066
00067 p->num_nav_cmds = bb_read(bb, 16);
00068 p->nav_cmds = calloc(p->num_nav_cmds, sizeof(MOBJ_CMD));
00069
00070 for (ii = 0; ii < p->num_nav_cmds; ii++) {
00071 uint8_t buf[12];
00072 bb_read_bytes(bb, buf, 12);
00073
00074 mobj_parse_cmd(buf, &p->nav_cmds[ii]);
00075 }
00076 }
00077
00078 static void _clean_button(BD_IG_BUTTON *p)
00079 {
00080 X_FREE(p->nav_cmds);
00081 }
00082
00083 static void _decode_bog(BITBUFFER *bb, BD_IG_BOG *p)
00084 {
00085 unsigned ii;
00086
00087 p->default_valid_button_id_ref = bb_read(bb, 16);
00088
00089 p->num_buttons = bb_read(bb, 8);
00090 p->button = calloc(p->num_buttons, sizeof(BD_IG_BUTTON));
00091
00092 for (ii = 0; ii < p->num_buttons; ii++) {
00093 _decode_button(bb, &p->button[ii]);
00094 }
00095 }
00096
00097 static void _clean_bog(BD_IG_BOG *p)
00098 {
00099 unsigned ii;
00100
00101 for (ii = 0; ii < p->num_buttons; ii++) {
00102 _clean_button(&p->button[ii]);
00103 }
00104 X_FREE(p->button);
00105 }
00106
00107 static void _decode_effect(BITBUFFER *bb, BD_IG_EFFECT *p)
00108 {
00109 unsigned ii;
00110
00111 p->duration = bb_read(bb, 24);
00112 p->palette_id_ref = bb_read(bb, 8);
00113
00114 p->num_composition_objects = bb_read(bb, 8);
00115 p->composition_object = calloc(p->num_composition_objects, sizeof(BD_PG_COMPOSITION_OBJECT));
00116
00117 for (ii = 0; ii < p->num_composition_objects; ii++) {
00118 pg_decode_composition_object(bb, &p->composition_object[ii]);
00119 }
00120 }
00121
00122 static void _clean_effect(BD_IG_EFFECT *p)
00123 {
00124 X_FREE(p->composition_object);
00125 }
00126
00127 static void _decode_effect_sequence(BITBUFFER *bb, BD_IG_EFFECT_SEQUENCE *p)
00128 {
00129 unsigned ii;
00130
00131 p->num_windows = bb_read(bb, 8);
00132 p->window = calloc(p->num_windows, sizeof(BD_PG_WINDOW));
00133
00134 for (ii = 0; ii < p->num_windows; ii++) {
00135 pg_decode_window(bb, &p->window[ii]);
00136 }
00137
00138 p->num_effects = bb_read(bb, 8);
00139 p->effect = calloc(p->num_effects, sizeof(BD_IG_EFFECT));
00140
00141 for (ii = 0; ii < p->num_effects; ii++) {
00142 _decode_effect(bb, &p->effect[ii]);
00143 }
00144 }
00145
00146 static void _clean_effect_sequence(BD_IG_EFFECT_SEQUENCE *p)
00147 {
00148 unsigned ii;
00149
00150 for (ii = 0; ii < p->num_effects; ii++) {
00151 _clean_effect(&p->effect[ii]);
00152 }
00153 X_FREE(p->effect);
00154
00155 X_FREE(p->window);
00156 }
00157
00158
00159 static int _decode_uo_mask_table(BITBUFFER *bb, BD_UO_MASK *p)
00160 {
00161 uint8_t buf[8];
00162 bb_read_bytes(bb, buf, 8);
00163
00164 return mpls_parse_uo(buf, p);
00165 }
00166
00167 static void _decode_page(BITBUFFER *bb, BD_IG_PAGE *p)
00168 {
00169 unsigned ii;
00170
00171 p->id = bb_read(bb, 8);
00172 p->version = bb_read(bb, 8);
00173
00174 _decode_uo_mask_table(bb, &p->uo_mask_table);
00175
00176 _decode_effect_sequence(bb, &p->in_effects);
00177 _decode_effect_sequence(bb, &p->out_effects);
00178
00179 p->animation_frame_rate_code = bb_read(bb, 8);
00180 p->default_selected_button_id_ref = bb_read(bb, 16);
00181 p->default_activated_button_id_ref = bb_read(bb, 16);
00182 p->palette_id_ref = bb_read(bb, 8);
00183
00184 p->num_bogs = bb_read(bb, 8);
00185 p->bog = calloc(p->num_bogs, sizeof(BD_IG_BOG));
00186
00187 for (ii = 0; ii < p->num_bogs; ii++) {
00188 _decode_bog(bb, &p->bog[ii]);
00189 }
00190 }
00191
00192 static void _clean_page(BD_IG_PAGE *p)
00193 {
00194 unsigned ii;
00195
00196 _clean_effect_sequence(&p->in_effects);
00197 _clean_effect_sequence(&p->out_effects);
00198
00199 for (ii = 0; ii < p->num_bogs; ii++) {
00200 _clean_bog(&p->bog[ii]);
00201 }
00202 X_FREE(p->bog);
00203 }
00204
00205 static inline uint64_t bb_read_u64(BITBUFFER *bb, int i_count)
00206 {
00207 uint64_t result = 0;
00208 if (i_count > 32) {
00209 i_count -= 32;
00210 result = (uint64_t)bb_read(bb, 32) << i_count;
00211 }
00212 result |= bb_read(bb, i_count);
00213 return result;
00214 }
00215
00216 static int _decode_interactive_composition(BITBUFFER *bb, BD_IG_INTERACTIVE_COMPOSITION *p)
00217 {
00218 unsigned ii;
00219
00220 uint32_t data_len = bb_read(bb, 24);
00221 uint32_t buf_len = bb->p_end - bb->p;
00222 if (data_len != buf_len) {
00223 BD_DEBUG(DBG_DECODE, "ig_decode_interactive(): buffer size mismatch (expected %d, have %d)\n", data_len, buf_len);
00224 return 0;
00225 }
00226
00227 p->stream_model = bb_read(bb, 1);
00228 p->ui_model = bb_read(bb, 1);
00229 bb_skip(bb, 6);
00230
00231 if (p->stream_model == 0) {
00232 bb_skip(bb, 7);
00233 p->composition_timeout_pts = bb_read_u64(bb, 33);
00234 bb_skip(bb, 7);
00235 p->selection_timeout_pts = bb_read_u64(bb, 33);
00236 }
00237
00238 p->user_timeout_duration = bb_read(bb, 24);
00239
00240 p->num_pages = bb_read(bb, 8);
00241 p->page = calloc(p->num_pages, sizeof(BD_IG_PAGE));
00242
00243 for (ii = 0; ii < p->num_pages; ii++) {
00244 _decode_page(bb, &p->page[ii]);
00245 }
00246
00247 return 1;
00248 }
00249
00250 static void _clean_interactive_composition(BD_IG_INTERACTIVE_COMPOSITION *p)
00251 {
00252 unsigned ii;
00253
00254 for (ii = 0; ii < p->num_pages; ii++) {
00255 _clean_page(&p->page[ii]);
00256 }
00257 X_FREE(p->page);
00258 }
00259
00260
00261
00262
00263
00264 int ig_decode_interactive(BITBUFFER *bb, BD_IG_INTERACTIVE *p)
00265 {
00266 BD_PG_SEQUENCE_DESCRIPTOR sd;
00267
00268 pg_decode_video_descriptor(bb, &p->video_descriptor);
00269 pg_decode_composition_descriptor(bb, &p->composition_descriptor);
00270 pg_decode_sequence_descriptor(bb, &sd);
00271
00272 if (!sd.first_in_seq) {
00273 BD_DEBUG(DBG_DECODE, "ig_decode_interactive(): not first in seq\n");
00274 return 0;
00275 }
00276 if (!sd.last_in_seq) {
00277 BD_DEBUG(DBG_DECODE, "ig_decode_interactive(): not last in seq\n");
00278 return 0;
00279 }
00280 if (!bb_is_align(bb, 0x07)) {
00281 BD_DEBUG(DBG_DECODE, "ig_decode_interactive(): alignment error\n");
00282 return 0;
00283 }
00284
00285 return _decode_interactive_composition(bb, &p->interactive_composition);
00286 }
00287
00288 void ig_clean_interactive(BD_IG_INTERACTIVE *p)
00289 {
00290 _clean_interactive_composition(&p->interactive_composition);
00291 }
00292
00293 void ig_free_interactive(BD_IG_INTERACTIVE **p)
00294 {
00295 if (p && *p) {
00296 _clean_interactive_composition(&(*p)->interactive_composition);
00297 X_FREE(*p);
00298 }
00299 }