📄 info.c
字号:
{ unsigned int offset; unsigned int entry_num; entry_num = vcdinfo_lsn_get_entry(obj, lsn); 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_tvcdinfo_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. */ PsdListDescriptor_t pxd; vcdinfo_lid_get_pxd(obj, &pxd, lid); switch (pxd.descriptor_type) { case PSD_TYPE_SELECTION_LIST: case PSD_TYPE_EXT_SELECTION_LIST: { vcdinfo_itemid_t selection_itemid; uint16_t selection_itemid_num; unsigned int start_entry_num; if (pxd.psd == NULL) return VCDINFO_INVALID_OFFSET; selection_itemid_num = vcdinf_psd_get_itemid(pxd.psd); vcdinfo_classify_itemid(selection_itemid_num, &selection_itemid); if (selection_itemid.type != VCDINFO_ITEM_TYPE_TRACK) { return VCDINFO_INVALID_OFFSET; } start_entry_num = vcdinfo_track_get_entry(obj, selection_itemid.num); return vcdinfo_selection_get_offset(obj, lid, entry_num-start_entry_num); } default: ; } } default: return VCDINFO_INVALID_OFFSET; }}/*! Return a string containing the default VCD device if none is specified. Return NULL we can't get this information.*/char *vcdinfo_get_default_device (const vcdinfo_obj_t *vcd_obj){ /* If device not already open, then we'll open it temporarily and let CdIo select a driver, get the default for that and then close/destroy the temporary we created. */ CdIo *cdio=NULL; if (vcd_obj != NULL && vcd_obj->img != NULL) cdio = vcd_obj->img; return cdio_get_default_device(cdio);}/*! Return number of sector units in of an entry. 0 is returned if entry_num is out of range. The first entry number is 0.*/uint32_tvcdinfo_get_entry_sect_count (const vcdinfo_obj_t *obj, unsigned int entry_num){ const EntriesVcd_t *entries = &obj->entries; const unsigned int entry_count = vcdinf_get_num_entries(entries); if (entry_num > entry_count) return 0; else { const lsn_t this_lsn = vcdinfo_get_entry_lsn(obj, entry_num); lsn_t next_lsn; if (entry_num < entry_count-1) { track_t track=vcdinfo_get_track(obj, entry_num); track_t next_track=vcdinfo_get_track(obj, entry_num+1); next_lsn = vcdinfo_get_entry_lsn(obj, entry_num+1); /* If we've changed tracks, don't include pregap sector between tracks. */ if (track != next_track) next_lsn -= CDIO_PREGAP_SECTORS; } else { /* entry_num == entry_count -1. Or the last entry. This is really really ugly. There's probably a better way to do it. Below we get the track of the current entry and then the LBA of the beginning of the following (leadout?) track. Wait! It's uglier than that! Since VCD's can be created *without* a pregap to the leadout track, we try not to use that if we can get the entry from the ISO 9660 filesystem. */ track_t track = vcdinfo_get_track(obj, entry_num); if (track != VCDINFO_INVALID_TRACK) { 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 */ 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. */ next_lsn = vcdinfo_get_track_lsn(obj, track+1); } if (next_lsn == VCDINFO_NULL_LSN) return 0; } else { /* Something went wrong. Set up size to zero. */ return 0; } } return (next_lsn - this_lsn); }}/*! Return the starting MSF (minutes/secs/frames) for sequence entry_num in obj. NULL is returned if there is no entry. The first entry number is 0.*/const msf_t *vcdinfo_get_entry_msf(const vcdinfo_obj_t *obj, unsigned int entry_num){ const EntriesVcd_t *entries = &obj->entries; return vcdinf_get_entry_msf(entries, entry_num);}/*! Return the starting LBA (logical block address) for sequence entry_num in obj. VCDINFO_NULL_LBA is returned if there is no entry.*/lba_tvcdinfo_get_entry_lba(const vcdinfo_obj_t *obj, unsigned int entry_num){ if ( NULL == obj ) return VCDINFO_NULL_LBA; else { const msf_t *msf = vcdinfo_get_entry_msf(obj, entry_num); msf = vcdinfo_get_entry_msf(obj, entry_num); return (msf != NULL) ? cdio_msf_to_lba(msf) : VCDINFO_NULL_LBA; }}/*! Return the starting LBA (logical block address) for sequence entry_num in obj. VCDINFO_NULL_LBA is returned if there is no entry.*/lsn_tvcdinfo_get_entry_lsn(const vcdinfo_obj_t *obj, unsigned int entry_num){ if ( NULL == obj ) return VCDINFO_NULL_LBA; else { const msf_t *msf = vcdinfo_get_entry_msf(obj, entry_num); return (msf != NULL) ? cdio_msf_to_lsn(msf) : VCDINFO_NULL_LSN; }}EntriesVcd_t * vcdinfo_get_entriesVcd (vcdinfo_obj_t *obj) { if (NULL == obj) return NULL; return &obj->entries;} /*! Get the VCD format (VCD 1.0 VCD 1.1, SVCD, ... for this object. The type is also set inside obj.*/vcd_type_tvcdinfo_get_format_version (vcdinfo_obj_t *obj){ return obj->vcd_type;}/*! Return a string giving VCD format (VCD 1.0 VCD 1.1, SVCD, ... for this object.*/const char *vcdinfo_get_format_version_str (const vcdinfo_obj_t *obj) { if (NULL == obj) return "*Uninitialized*"; return vcdinf_get_format_version_str(obj->vcd_type);}InfoVcd_t * vcdinfo_get_infoVcd (vcdinfo_obj_t *obj) { if (NULL == obj) return NULL; return &obj->info;} /*! Return the entry number closest and before the given LSN. */unsigned int vcdinfo_lsn_get_entry(const vcdinfo_obj_t *obj, lsn_t lsn) { /* Do a binary search to find the entry. */ unsigned int i = 0; unsigned int j = vcdinfo_get_num_entries(obj); unsigned int mid; unsigned int mid_lsn; do { mid = (i+j)/2; mid_lsn = vcdinfo_get_entry_lsn(obj, mid); if ( lsn <= mid_lsn ) j = mid-1; if ( lsn >= mid_lsn ) i = mid+1; } while (i <= j); /* We want the entry closest but before. */ return (lsn == mid_lsn) ? mid : mid-1;} void * vcdinfo_get_pvd (vcdinfo_obj_t *obj) { if (NULL == obj) return NULL; return &obj->pvd;} void * vcdinfo_get_scandata (vcdinfo_obj_t *obj) { if (NULL == obj) return NULL; return obj->scandata_buf;} void * vcdinfo_get_searchDat (vcdinfo_obj_t *obj) { if (NULL == obj) return NULL; return obj->search_buf;} void * vcdinfo_get_tracksSVD (vcdinfo_obj_t *obj) { if (NULL == obj) return NULL; return obj->tracks_buf;} /*! Get the itemid for a given list ID. VCDINFO_REJECTED_MASK is returned on error or if obj is NULL. */uint16_tvcdinfo_lid_get_itemid(const vcdinfo_obj_t *obj, lid_t lid){ PsdListDescriptor_t pxd; if (obj == NULL) return VCDINFO_REJECTED_MASK; vcdinfo_lid_get_pxd(obj, &pxd, lid); switch (pxd.descriptor_type) { case PSD_TYPE_SELECTION_LIST: case PSD_TYPE_EXT_SELECTION_LIST: if (pxd.psd == NULL) return VCDINFO_REJECTED_MASK; return vcdinf_psd_get_itemid(pxd.psd); break; case PSD_TYPE_PLAY_LIST: /* FIXME: There is an array of items */ case PSD_TYPE_END_LIST: case PSD_TYPE_COMMAND_LIST: return VCDINFO_REJECTED_MASK; } return VCDINFO_REJECTED_MASK;}/*! Get the LOT pointer. */LotVcd_t *vcdinfo_get_lot(const vcdinfo_obj_t *obj) { if (NULL == obj) return NULL; return obj->lot;}/*! Get the extended LOT pointer. */LotVcd_t *vcdinfo_get_lot_x(const vcdinfo_obj_t *obj) { if (NULL == obj) return NULL; return obj->lot_x;} /*! Return number of LIDs. */lid_tvcdinfo_get_num_LIDs (const vcdinfo_obj_t *obj) { /* Should probably use _vcd_pbc_max_lid instead? */ if (NULL==obj) return 0; return vcdinf_get_num_LIDs(&obj->info);}/*! Return the number of entries in the VCD.*/unsigned intvcdinfo_get_num_entries(const vcdinfo_obj_t *obj){ const EntriesVcd_t *entries = &obj->entries; return vcdinf_get_num_entries(entries);}/*! Return the number of segments in the VCD. Return 0 if there is some problem.*/segnum_tvcdinfo_get_num_segments(const vcdinfo_obj_t *obj){ if (NULL==obj) return 0; return vcdinf_get_num_segments(&obj->info);}/*! \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.*/uint16_tvcdinfo_lid_get_offset(const vcdinfo_obj_t *obj, lid_t lid, unsigned int entry_num) { PsdListDescriptor_t pxd; if (obj == NULL) return VCDINFO_INVALID_OFFSET; vcdinfo_lid_get_pxd(obj, &pxd, lid); switch (pxd.descriptor_type) { case PSD_TYPE_SELECTION_LIST: case PSD_TYPE_EXT_SELECTION_LIST: if (pxd.psd == NULL) return VCDINFO_INVALID_OFFSET; return vcdinf_psd_get_offset(pxd.psd, entry_num-1); break; case PSD_TYPE_PLAY_LIST: /* FIXME: There is an array of items */ case PSD_TYPE_END_LIST: case PSD_TYPE_COMMAND_LIST: return VCDINFO_INVALID_OFFSET; } return VCDINFO_INVALID_OFFSET;}/*! NULL is returned on error. */static vcdinfo_offset_t *_vcdinfo_get_offset_t (const vcdinfo_obj_t *obj, unsigned int offset, bool ext){ CdioListNode *node; CdioList *offset_list = ext ? obj->offset_x_list : obj->offset_list; switch (offset) { case PSD_OFS_DISABLED: case PSD_OFS_MULTI_DEF: case PSD_OFS_MULTI_DEF_NO_NUM: return NULL; default: ; } _CDIO_LIST_FOREACH (node, offset_list) { vcdinfo_offset_t *ofs = _cdio_list_node_data (node); if (offset == ofs->offset) return ofs; } return NULL;}/*! Get the VCD info list.*/CdioList *vcdinfo_get_offset_list(const vcdinfo_obj_t *obj){ if (NULL == obj) return NULL; return obj->offset_list;}/*! Get the VCD info extended offset list.*/CdioList *vcdinfo_get_offset_x_list(const vcdinfo_obj_t *obj){ if (NULL == obj) return NULL; return obj->offset_x_list;}/*! Get the VCD info offset multiplier.*/unsigned int vcdinfo_get_offset_mult(const vcdinfo_obj_t *obj) { if (NULL == obj) return 0xFFFF; return obj->info.offset_mult;}/*! Get entry in offset list for the item that has offset. This entry has for example the LID. NULL is returned on error. */vcdinfo_offset_t *vcdinfo_get_offset_t (const vcdinfo_obj_t *obj, unsigned int offset){ vcdinfo_offset_t *off_p= _vcdinfo_get_offset_t (obj, offset, true); if (NULL != off_p) return off_p; return _vcdinfo_get_offset_t (obj, offset, false);}/*! Return a string containing the VCD publisher id with trailing blanks removed, or NULL if there is some problem in getting this.*/const char *vcdinfo_get_preparer_id(const vcdinfo_obj_t *obj){ if ( NULL == obj ) return (NULL); return iso9660_get_preparer_id(&obj->pvd);}/*! Get the PSD.*/uint8_t *vcdinfo_get_psd(const vcdinfo_obj_t *obj) { if ( NULL == obj ) return (NULL); return obj->psd;}/*! Get the extended PSD.*/uint8_t *vcdinfo_get_psd_x(const vcdinfo_obj_t *obj){ if ( NULL == obj ) return (NULL); return obj->psd_x;}/*! Return number of bytes in PSD. Return 0 if there's an error.*/uint32_tvcdinfo_get_psd_size (const vcdinfo_obj_t *obj){ if ( NULL == obj ) return 0; return vcdinf_get_psd_size(&obj->info);}/*! Return number of bytes in the extended PSD. Return 0 if there's an error.*/uint32_tvcdinfo_get_psd_x_size (const vcdinfo_obj_t *obj){ if ( NULL == obj ) return 0; return obj->psd_x_size;}/*! Return a string containing the VCD publisher id with trailing blanks removed, or NULL if there is some problem in getting this.*/char *vcdinfo_get_publisher_id(const vcdinfo_obj_t *obj){ if ( NULL == obj ) return (NULL); return iso9660_get_publisher_id(&obj->pvd);}/*! Get the PSD Selection List Descriptor for a given lid. NULL is returned if error or not found.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -