|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
* This file is part of libbluray
|
|
Packit |
5e46da |
* Copyright (C) 2012 Petri Hintukainen <phintuka@users.sourceforge.net>
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* This library is free software; you can redistribute it and/or
|
|
Packit |
5e46da |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
5e46da |
* License as published by the Free Software Foundation; either
|
|
Packit |
5e46da |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
5e46da |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
5e46da |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
5e46da |
* Lesser General Public License for more details.
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
5e46da |
* License along with this library. If not, see
|
|
Packit |
5e46da |
* <http://www.gnu.org/licenses/>.
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#if HAVE_CONFIG_H
|
|
Packit |
5e46da |
#include "config.h"
|
|
Packit |
5e46da |
#endif
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#include "util/bits.h"
|
|
Packit |
5e46da |
#include "extdata_parse.h"
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#include <stdint.h>
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
int bdmv_parse_extension_data(BITSTREAM *bits,
|
|
Packit |
5e46da |
int start_address,
|
|
Packit |
5e46da |
int (*handler)(BITSTREAM*, int, int, void*),
|
|
Packit |
5e46da |
void *handle)
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
int64_t length;
|
|
Packit |
5e46da |
int num_entries, n;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (start_address < 1) return 0;
|
|
Packit |
5e46da |
if (start_address > bits->end - 12) return 0;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (bs_seek_byte(bits, start_address) < 0) {
|
|
Packit |
5e46da |
return 0;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
length = bs_read(bits, 32); /* length of extension data block */
|
|
Packit |
5e46da |
if (length < 1) return 0;
|
|
Packit |
5e46da |
bs_skip(bits, 32); /* relative start address of extension data */
|
|
Packit |
5e46da |
bs_skip(bits, 24); /* padding */
|
|
Packit |
5e46da |
num_entries = bs_read(bits, 8);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (start_address > bits->end - 12 - num_entries * 12) return 0;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
for (n = 0; n < num_entries; n++) {
|
|
Packit |
5e46da |
uint16_t id1 = bs_read(bits, 16);
|
|
Packit |
5e46da |
uint16_t id2 = bs_read(bits, 16);
|
|
Packit |
5e46da |
int64_t ext_start = bs_read(bits, 32);
|
|
Packit |
5e46da |
int64_t ext_len = bs_read(bits, 32);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
int64_t saved_pos = bs_pos(bits) >> 3;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (ext_start + start_address + ext_len > bits->end) return 0;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (bs_seek_byte(bits, start_address + ext_start) >= 0) {
|
|
Packit |
5e46da |
(handler)(bits, id1, id2, handle);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
if (bs_seek_byte(bits, saved_pos) < 0) {
|
|
Packit |
5e46da |
return 0;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return 1;
|
|
Packit |
5e46da |
}
|