summaryrefslogtreecommitdiff
path: root/src/input/vcd/libvcd/info.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/input/vcd/libvcd/info.c')
-rw-r--r--src/input/vcd/libvcd/info.c381
1 files changed, 309 insertions, 72 deletions
diff --git a/src/input/vcd/libvcd/info.c b/src/input/vcd/libvcd/info.c
index 6e13637c2..096cb0b84 100644
--- a/src/input/vcd/libvcd/info.c
+++ b/src/input/vcd/libvcd/info.c
@@ -1,5 +1,5 @@
/*
- $Id: info.c,v 1.1 2003/10/13 11:47:12 f1rmb Exp $
+ $Id: info.c,v 1.2 2004/04/11 12:20:32 miguelfreitas Exp $
Copyright (C) 2002,2003 Rocky Bernstein <rocky@panix.com>
@@ -26,7 +26,7 @@
/* Private headers */
#include "info_private.h"
-#include "assert.h"
+#include "vcd_assert.h"
#include "bytesex.h"
#include "pbc.h"
#include "util.h"
@@ -59,7 +59,7 @@
#include <stddef.h>
#include <errno.h>
-static const char _rcsid[] = "$Id: info.c,v 1.1 2003/10/13 11:47:12 f1rmb Exp $";
+static const char _rcsid[] = "$Id: info.c,v 1.2 2004/04/11 12:20:32 miguelfreitas Exp $";
#define MIN_ENCODED_TRACK_NUM 100
#define MIN_ENCODED_SEGMENT_NUM 1000
@@ -100,31 +100,76 @@ _init_segments (vcdinfo_obj_t *obj)
{
InfoVcd *info = vcdinfo_get_infoVcd(obj);
segnum_t num_segments = vcdinfo_get_num_segments(obj);
+ VcdListNode *entnode;
+ VcdList *entlist;
int i;
- iso9660_stat_t statbuf;
+ lsn_t last_lsn=0;
obj->first_segment_lsn = cdio_msf_to_lsn(&info->first_seg_addr);
-
obj->seg_sizes = _vcd_malloc( num_segments * sizeof(uint32_t *));
- if (NULL == obj->seg_sizes) return;
+ if (NULL == obj->seg_sizes || 0 == num_segments) return;
+
+ entlist = iso9660_fs_readdir(obj->img, "SEGMENT", true);
+
+ i=0;
+ _VCD_LIST_FOREACH (entnode, entlist) {
+ iso9660_stat_t *statbuf = _vcd_list_node_data (entnode);
+
+ if (statbuf->type == _STAT_DIR) continue;
+
+ while(info->spi_contents[i].item_cont) {
+ obj->seg_sizes[i] = VCDINFO_SEGMENT_SECTOR_SIZE;
+ i++;
+ }
+
+ /* Should have an entry in the ISO 9660 filesystem. Get and save
+ in statbuf.secsize this size.
+ */
+ obj->seg_sizes[i] = statbuf->secsize;
+
+ if (last_lsn >= statbuf->lsn)
+ vcd_warn ("Segments if ISO 9660 directory out of order lsn %ul >= %ul",
+ (unsigned int) last_lsn, (unsigned int) statbuf->lsn);
+ last_lsn = statbuf->lsn;
+
+ i++;
+ }
+
+ while(i < num_segments && info->spi_contents[i].item_cont) {
+ obj->seg_sizes[i] = VCDINFO_SEGMENT_SECTOR_SIZE;
+ i++;
+ }
+
+ if (i != num_segments)
+ vcd_warn ("Number of segments found %d is not number of segments %d",
+ i, num_segments);
+
+ _vcd_list_free (entlist, true);
+
+
+#if 0
/* Figure all of the segment sector sizes */
for (i=0; i < num_segments; i++) {
obj->seg_sizes[i] = VCDINFO_SEGMENT_SECTOR_SIZE;
if ( !info->spi_contents[i].item_cont ) {
- /* Should have an entry in the ISO 9660 filesytem. Get and save
+ /* Should have an entry in the ISO 9660 filesystem. Get and save
in statbuf.secsize this size.
*/
lsn_t lsn = vcdinfo_get_seg_lsn(obj, i);
- if (iso9660_find_fs_lsn(obj->img, lsn, &statbuf)) {
- obj->seg_sizes[i] = statbuf.secsize;
+ iso9660_stat_t *statbuf =iso9660_find_fs_lsn(obj->img, lsn);
+ if (NULL != statbuf) {
+ obj->seg_sizes[i] = statbuf->secsize;
+ free(statbuf);
} else {
vcd_warn ("Trouble finding ISO 9660 size for segment %d.", i);
}
}
}
+#endif
+
}
/*!
@@ -365,6 +410,68 @@ vcdinfo_get_cd_image (const vcdinfo_obj_t *vcd_obj)
}
+/*!
+ \fn vcdinfo_selection_get_lid(const vcdinfo_obj_t *obj, lid_t lid,
+ unsigned int selection);
+
+ \brief Get offset of a selection for a given lid.
+
+ Return the LID offset associated with a the selection number of the
+ passed-in LID parameter.
+
+ \return VCDINFO_INVALID_LID is returned if obj on error or obj
+ is NULL. Otherwise the LID offset is returned.
+*/
+lid_t vcdinfo_selection_get_lid(const vcdinfo_obj_t *obj, lid_t lid,
+ unsigned int selection)
+{
+ unsigned int offset;
+
+ if (NULL == obj) return VCDINFO_INVALID_LID;
+
+ offset = vcdinfo_selection_get_offset(obj, lid, selection);
+ switch (offset) {
+ case VCDINFO_INVALID_OFFSET:
+ case PSD_OFS_MULTI_DEF:
+ case PSD_OFS_MULTI_DEF_NO_NUM:
+ return VCDINFO_INVALID_LID;
+ default:
+ {
+ vcdinfo_offset_t *ofs = vcdinfo_get_offset_t(obj, offset);
+ return ofs->lid;
+ }
+ }
+}
+
+/*!
+ \fn vcdinfo_selection_get_offset(const vcdinfo_obj_t *obj, lid_t lid,
+ unsigned int selection);
+
+ \brief Get offset of a selection for a given lid.
+
+ Return the LID offset associated with a the selection number of the
+ passed-in LID parameter.
+
+ \return VCDINFO_INVALID_OFFSET is returned if obj on error or obj
+ is NULL. Otherwise the LID offset is returned.
+*/
+uint16_t vcdinfo_selection_get_offset(const vcdinfo_obj_t *obj, lid_t lid,
+ unsigned int selection)
+{
+ unsigned int bsn;
+
+ PsdListDescriptor pxd;
+ vcdinfo_lid_get_pxd(obj, &pxd, lid);
+ bsn=vcdinf_get_bsn(pxd.psd);
+
+ if ( (selection - bsn + 1) > 0) {
+ return vcdinfo_lid_get_offset(obj, lid, selection-bsn+1);
+ } else {
+ vcd_warn( "Selection number %u too small. bsn %u", selection, bsn );
+ return VCDINFO_INVALID_OFFSET;
+ }
+}
+
/**
\fn vcdinfo_get_default_offset(const vcdinfo_obj_t *obj, unsinged int lid);
\brief Get return offset for a given PLD selector descriptor.
@@ -372,7 +479,7 @@ vcdinfo_get_cd_image (const vcdinfo_obj_t *vcd_obj)
"return" entry or pld is NULL. Otherwise the LID offset is returned.
*/
uint16_t
-vcdinfo_get_default_offset(const vcdinfo_obj_t *obj, unsigned int lid)
+vcdinfo_get_default_offset(const vcdinfo_obj_t *obj, lid_t lid)
{
if (NULL != obj) {
@@ -395,6 +502,83 @@ vcdinfo_get_default_offset(const vcdinfo_obj_t *obj, unsigned int lid)
}
/*!
+ \brief Get default or multi-default LID.
+
+ Return the LID offset associated with a the "default" entry of the
+ passed-in LID parameter. Note "default" entries are associated
+ with PSDs that are (extended) selection lists. If the "default"
+ offset is a multi-default, we use entry_num to find the proper
+ "default" LID. Otherwise this routine is exactly like
+ vcdinfo_get_default_lid with the exception of requiring an
+ additional "entry_num" parameter.
+
+ \return VCDINFO_INVALID_LID is returned on error, or if the LID
+ is not a selection list or no "default" entry. Otherwise the LID
+ offset is returned.
+*/
+lid_t
+vcdinfo_get_multi_default_lid(const vcdinfo_obj_t *obj, lid_t lid,
+ unsigned int entry_num)
+{
+ unsigned int offset = vcdinfo_get_multi_default_offset(obj, lid, entry_num);
+ switch (offset) {
+ case VCDINFO_INVALID_OFFSET:
+ case PSD_OFS_MULTI_DEF:
+ case PSD_OFS_MULTI_DEF_NO_NUM:
+ return VCDINFO_INVALID_LID;
+ default:
+ {
+ vcdinfo_offset_t *ofs = vcdinfo_get_offset_t(obj, offset);
+ return ofs->lid;
+ }
+ }
+}
+
+/*!
+ \brief Get default or multi-default LID offset.
+
+ Return the LID offset associated with a the "default" entry of the
+ passed-in LID parameter. Note "default" entries are associated
+ with PSDs that are (extended) selection lists. If the "default"
+ offset is a multi-default, we use entry_num to find the proper
+ "default" offset. Otherwise this routine is exactly like
+ vcdinfo_get_default_offset with the exception of requiring an
+ additional "entry_num" parameter.
+
+ \return VCDINFO_INVALID_OFFSET is returned on error, or if the LID
+ is not a selection list or no "default" entry. Otherwise the LID
+ offset is returned.
+*/
+uint16_t
+vcdinfo_get_multi_default_offset(const vcdinfo_obj_t *obj, lid_t lid,
+ unsigned int entry_num)
+{
+ uint16_t offset=vcdinfo_get_default_offset(obj, lid);
+
+ switch (offset) {
+ case PSD_OFS_MULTI_DEF:
+ case PSD_OFS_MULTI_DEF_NO_NUM:
+ {
+ /* Have some work todo... Figure the selection number. */
+ unsigned int selection=0;
+ track_t track=vcdinfo_get_track(obj, entry_num);
+ track_t prev_track=VCDINFO_INVALID_TRACK;
+ for (selection=1;
+ track != VCDINFO_INVALID_TRACK
+ && track != prev_track
+ && entry_num > 0;
+ selection++) {
+ prev_track = track;
+ track=vcdinfo_get_track(obj, --entry_num);
+ }
+ return vcdinfo_selection_get_offset(obj, lid, selection);
+ }
+ default:
+ return offset;
+ }
+}
+
+/*!
Return a string containing the default VCD device if none is specified.
Return NULL we can't get this information.
*/
@@ -449,12 +633,15 @@ vcdinfo_get_entry_sect_count (const vcdinfo_obj_t *obj, unsigned int entry_num)
*/
track_t track = vcdinfo_get_track(obj, entry_num);
if (track != VCDINFO_INVALID_TRACK) {
- iso9660_stat_t statbuf;
+ iso9660_stat_t *statbuf;
const lsn_t lsn = vcdinfo_get_track_lsn(obj, track);
/* Try to get the sector count from the ISO 9660 filesystem */
- if (iso9660_find_fs_lsn(obj->img, lsn, &statbuf)) {
- next_lsn = lsn + statbuf.secsize;
+ statbuf = iso9660_find_fs_lsn(obj->img, lsn);
+
+ if (NULL != statbuf) {
+ next_lsn = lsn + statbuf->secsize;
+ free(statbuf);
} else {
/* Failed on ISO 9660 filesystem. Use next track or
LEADOUT track. */
@@ -653,7 +840,7 @@ vcdinfo_get_num_segments(const vcdinfo_obj_t *obj)
}
/*!
- \fn vcdinfo_get_offset_from_lid(const vcdinfo_obj_t *obj, unsigned int entry_num);
+ \fn vcdinfo_get_offset_lid(const vcdinfo_obj_t *obj, unsigned int entry_num);
\brief Get offset entry_num for a given LID.
\return VCDINFO_INVALID_OFFSET is returned if obj on error or obj
is NULL. Otherwise the LID offset is returned.
@@ -1150,12 +1337,14 @@ vcdinfo_get_track_sect_count(const vcdinfo_obj_t *obj, const track_t track_num)
return 0;
{
- iso9660_stat_t statbuf;
+ iso9660_stat_t *statbuf;
const lsn_t lsn = vcdinfo_get_track_lsn(obj, track_num);
/* Try to get the sector count from the ISO 9660 filesystem */
- if (obj->has_xa && iso9660_find_fs_lsn(obj->img, lsn, &statbuf)) {
- return statbuf.secsize;
+ if (obj->has_xa && (statbuf = iso9660_find_fs_lsn(obj->img, lsn))) {
+ unsigned int secsize = statbuf->secsize;
+ free(statbuf);
+ return secsize;
} else {
const lsn_t next_lsn=vcdinfo_get_track_lsn(obj, track_num+1);
/* Failed on ISO 9660 filesystem. Use track information. */
@@ -1185,7 +1374,7 @@ vcdinfo_get_track_size(const vcdinfo_obj_t *obj, track_t track_num)
const lsn_t lsn = cdio_lba_to_lsn(vcdinfo_get_track_lba(obj, track_num));
/* Try to get the sector count from the ISO 9660 filesystem */
- if (obj->has_xa && iso9660_find_fs_lsn(obj->img, lsn, &statbuf)) {
+ if (obj->has_xa && iso9660_find_fs_lsn(obj->img, lsn)) {
return statbuf.size;
}
#if 0
@@ -1357,7 +1546,7 @@ vcdinfo_msf2lsn (uint8_t min, uint8_t sec, int8_t frame)
lba_t lba=75*(60*min + sec) + frame;
if (lba < CDIO_PREGAP_SECTORS) {
vcd_error ("lba (%u) less than pregap sector (%u)",
- lba, CDIO_PREGAP_SECTORS);
+ (unsigned int) lba, CDIO_PREGAP_SECTORS);
return lba;
}
return lba - CDIO_PREGAP_SECTORS;
@@ -1373,7 +1562,7 @@ vcdinfo_ofs2str (const vcdinfo_obj_t *obj, unsigned int offset, bool ext)
case PSD_OFS_DISABLED:
return "disabled";
case PSD_OFS_MULTI_DEF:
- return "multi_def";
+ return "multi-default";
case PSD_OFS_MULTI_DEF_NO_NUM:
return "multi_def_no_num";
default: ;
@@ -1426,10 +1615,17 @@ vcdinfo_read_psd (vcdinfo_obj_t *obj)
return true;
}
-void
+/*!
+ Calls recursive routine to populate obj->offset_list or obj->offset_x_list
+ by going through LOT.
+
+ Returns false if there was some error.
+*/
+bool
vcdinfo_visit_lot (vcdinfo_obj_t *obj, bool extended)
{
struct _vcdinf_pbc_ctx pbc_ctx;
+ bool ret;
pbc_ctx.psd_size = vcdinfo_get_psd_size (obj);
pbc_ctx.psd_x_size = obj->psd_x_size;
@@ -1443,13 +1639,14 @@ vcdinfo_visit_lot (vcdinfo_obj_t *obj, bool extended)
pbc_ctx.lot_x = obj->lot_x;
pbc_ctx.extended = extended;
- vcdinf_visit_lot(&pbc_ctx);
+ ret = vcdinf_visit_lot(&pbc_ctx);
if (NULL != obj->offset_x_list)
_vcd_list_free(obj->offset_x_list, true);
obj->offset_x_list = pbc_ctx.offset_x_list;
if (NULL != obj->offset_list)
_vcd_list_free(obj->offset_list, true);
obj->offset_list = pbc_ctx.offset_list;
+ return ret;
}
/*!
@@ -1541,8 +1738,8 @@ vcdinfo_open(vcdinfo_obj_t **obj_p, char *source_name[],
driver_id_t source_type, const char access_mode[])
{
CdIo *img;
- iso9660_stat_t statbuf;
vcdinfo_obj_t *obj = _vcd_malloc(sizeof(vcdinfo_obj_t));
+ iso9660_stat_t *statbuf;
/* If we don't specify a driver_id or a source_name, scan the
@@ -1571,8 +1768,10 @@ vcdinfo_open(vcdinfo_obj_t **obj_p, char *source_name[],
if (access_mode != NULL)
cdio_set_arg (img, "access-mode", access_mode);
- if (NULL == *source_name)
+ if (NULL == *source_name) {
*source_name = cdio_get_default_device(img);
+ if (NULL == *source_name) return VCDINFO_OPEN_ERROR;
+ }
memset (obj, 0, sizeof (vcdinfo_obj_t));
obj->img = img; /* Note we do this after the above wipeout! */
@@ -1607,81 +1806,113 @@ vcdinfo_open(vcdinfo_obj_t **obj_p, char *source_name[],
}
if (obj->vcd_type == VCD_TYPE_SVCD || obj->vcd_type == VCD_TYPE_HQVCD) {
- if (!iso9660_fs_stat (obj->img, "MPEGAV", &statbuf, true))
+ statbuf = iso9660_fs_stat (obj->img, "MPEGAV", true);
+
+ if (NULL != statbuf) {
vcd_warn ("non compliant /MPEGAV folder detected!");
+ free(statbuf);
+ }
- if (!iso9660_fs_stat (obj->img, "SVCD/TRACKS.SVD;1", &statbuf, true))
- {
- if (statbuf.size != ISO_BLOCKSIZE)
- vcd_warn ("TRACKS.SVD filesize != %d!", ISO_BLOCKSIZE);
-
- obj->tracks_buf = _vcd_malloc (ISO_BLOCKSIZE);
-
- if (cdio_read_mode2_sector (obj->img, obj->tracks_buf, statbuf.lsn,
- false))
- return VCDINFO_OPEN_ERROR;
- }
+
+ statbuf = iso9660_fs_stat (obj->img, "SVCD/TRACKS.SVD;1", true);
+ if (NULL != statbuf) {
+ lsn_t lsn = statbuf->lsn;
+ if (statbuf->size != ISO_BLOCKSIZE)
+ vcd_warn ("TRACKS.SVD filesize != %d!", ISO_BLOCKSIZE);
+
+ obj->tracks_buf = _vcd_malloc (ISO_BLOCKSIZE);
+
+ free(statbuf);
+ if (cdio_read_mode2_sector (obj->img, obj->tracks_buf, lsn, false))
+ return VCDINFO_OPEN_ERROR;
+ }
}
_init_segments (obj);
switch (obj->vcd_type) {
case VCD_TYPE_VCD2: {
- if (!iso9660_fs_stat (img, "EXT/PSD_X.VCD;1", &statbuf, true)) {
- vcd_debug ("found /EXT/PSD_X.VCD at sector %lu",
- (long unsigned int) statbuf.lsn);
-
- obj->psd_x = _vcd_malloc (ISO_BLOCKSIZE * statbuf.secsize);
- obj->psd_x_size = statbuf.size;
+ /* FIXME: Can reduce CD reads by using
+ iso9660_fs_readdir(img, "EXT", true) and then scanning for
+ the files listed below.
+ */
+ statbuf = iso9660_fs_stat (img, "EXT/PSD_X.VCD;1", true);
+ if (NULL != statbuf) {
+ lsn_t lsn = statbuf->lsn;
+ uint32_t secsize = statbuf->secsize;
+
+ obj->psd_x = _vcd_malloc (ISO_BLOCKSIZE * secsize);
+ obj->psd_x_size = statbuf->size;
- if (cdio_read_mode2_sectors (img, obj->psd_x, statbuf.lsn,
- false, statbuf.secsize))
+ vcd_debug ("found /EXT/PSD_X.VCD at sector %lu",
+ (long unsigned int) lsn);
+
+ free(statbuf);
+ if (cdio_read_mode2_sectors (img, obj->psd_x, lsn, false, secsize))
return VCDINFO_OPEN_ERROR;
}
- if (!iso9660_fs_stat (img, "EXT/LOT_X.VCD;1", &statbuf, true)) {
+ statbuf = iso9660_fs_stat (img, "EXT/LOT_X.VCD;1", true);
+ if (NULL != statbuf) {
+ lsn_t lsn = statbuf->lsn;
+ uint32_t secsize = statbuf->secsize;
+ obj->lot_x = _vcd_malloc (ISO_BLOCKSIZE * secsize);
+
vcd_debug ("found /EXT/LOT_X.VCD at sector %lu",
- (unsigned long int) statbuf.lsn);
+ (unsigned long int) lsn);
- obj->lot_x = _vcd_malloc (ISO_BLOCKSIZE * statbuf.secsize);
-
- if (cdio_read_mode2_sectors (img, obj->lot_x, statbuf.lsn, false,
- statbuf.secsize))
+ if (statbuf->size != LOT_VCD_SIZE * ISO_BLOCKSIZE)
+ vcd_warn ("LOT_X.VCD size != 65535");
+
+ free(statbuf);
+ if (cdio_read_mode2_sectors (img, obj->lot_x, lsn, false, secsize))
return VCDINFO_OPEN_ERROR;
- if (statbuf.size != LOT_VCD_SIZE * ISO_BLOCKSIZE)
- vcd_warn ("LOT_X.VCD size != 65535");
}
break;
}
case VCD_TYPE_SVCD:
case VCD_TYPE_HQVCD: {
- if (!iso9660_fs_stat (img, "MPEGAV", &statbuf, true))
+ /* FIXME: Can reduce CD reads by using
+ iso9660_fs_readdir(img, "SVCD", true) and then scanning for
+ the files listed below.
+ */
+ statbuf = iso9660_fs_stat (img, "MPEGAV", true);
+ if (NULL != statbuf) {
vcd_warn ("non compliant /MPEGAV folder detected!");
+ free(statbuf);
+ }
- if (iso9660_fs_stat (img, "SVCD/TRACKS.SVD;1", &statbuf, true))
+ statbuf = iso9660_fs_stat (img, "SVCD/TRACKS.SVD;1", true);
+ if (NULL == statbuf)
vcd_warn ("mandatory /SVCD/TRACKS.SVD not found!");
- else
+ else {
vcd_debug ("found TRACKS.SVD signature at sector %lu",
- (unsigned long int) statbuf.lsn);
+ (unsigned long int) statbuf->lsn);
+ free(statbuf);
+ }
- if (iso9660_fs_stat (img, "SVCD/SEARCH.DAT;1", &statbuf, true))
+ statbuf = iso9660_fs_stat (img, "SVCD/SEARCH.DAT;1", true);
+ if (NULL == statbuf)
vcd_warn ("mandatory /SVCD/SEARCH.DAT not found!");
else {
+ lsn_t lsn = statbuf->lsn;
+ uint32_t secsize = statbuf->secsize;
+ uint32_t stat_size = statbuf->size;
uint32_t size;
- vcd_debug ("found SEARCH.DAT at sector %lu",
- (unsigned long int) statbuf.lsn);
+
+ vcd_debug ("found SEARCH.DAT at sector %lu", (unsigned long int) lsn);
- obj->search_buf = _vcd_malloc (ISO_BLOCKSIZE * statbuf.secsize);
+ obj->search_buf = _vcd_malloc (ISO_BLOCKSIZE * secsize);
- if (cdio_read_mode2_sectors (img, obj->search_buf, statbuf.lsn,
- false, statbuf.secsize))
+ if (cdio_read_mode2_sectors (img, obj->search_buf, lsn, false, secsize))
return VCDINFO_OPEN_ERROR;
size = (3 * uint16_from_be (((SearchDat *)obj->search_buf)->scan_points))
+ sizeof (SearchDat);
-
- if (size > statbuf.size) {
+
+ free(statbuf);
+ if (size > stat_size) {
vcd_warn ("number of scanpoints leads to bigger size than "
"file size of SEARCH.DAT! -- rereading");
@@ -1689,8 +1920,8 @@ vcdinfo_open(vcdinfo_obj_t **obj_p, char *source_name[],
obj->search_buf = _vcd_malloc (ISO_BLOCKSIZE
* _vcd_len2blocks(size, ISO_BLOCKSIZE));
- if (cdio_read_mode2_sectors (img, obj->search_buf,statbuf.lsn,
- false, statbuf.secsize))
+ if (cdio_read_mode2_sectors (img, obj->search_buf, lsn, false,
+ secsize))
return VCDINFO_OPEN_ERROR;
}
}
@@ -1700,13 +1931,17 @@ vcdinfo_open(vcdinfo_obj_t **obj_p, char *source_name[],
;
}
- if (!iso9660_fs_stat (img, "EXT/SCANDATA.DAT;1", &statbuf, true)) {
- vcd_debug ("found /EXT/SCANDATA.DAT at sector %d", statbuf.lsn);
-
- obj->scandata_buf = _vcd_malloc (ISO_BLOCKSIZE * statbuf.secsize);
+ statbuf = iso9660_fs_stat (img, "EXT/SCANDATA.DAT;1", true);
+ if (statbuf != NULL) {
+ lsn_t lsn = statbuf->lsn;
+ uint32_t secsize = statbuf->secsize;
+
+ vcd_debug ("found /EXT/SCANDATA.DAT at sector %u", (unsigned int) lsn);
- if (cdio_read_mode2_sectors (img, obj->scandata_buf, statbuf.lsn,
- false, statbuf.secsize))
+ obj->scandata_buf = _vcd_malloc (ISO_BLOCKSIZE * secsize);
+
+ free(statbuf);
+ if (cdio_read_mode2_sectors (img, obj->scandata_buf, lsn, false, secsize))
return VCDINFO_OPEN_ERROR;
}
@@ -1731,6 +1966,8 @@ vcdinfo_close(vcdinfo_obj_t *obj)
free(obj->seg_sizes);
free(obj->lot);
free(obj->lot_x);
+ if (obj->psd_x) free(obj->psd_x);
+ if (obj->scandata_buf) free(obj->scandata_buf);
free(obj->tracks_buf);
free(obj->search_buf);
free(obj->source_name);