⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 remap.c

📁 linux下的MPEG1
💻 C
字号:
/* * This file is part of libdvdnav, a DVD navigation library. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA * * $Id: remap.c,v 1.6 2006/12/08 16:26:10 mshopf Exp $ */#include <stdlib.h>#include <string.h>#include <stdio.h>#ifdef HAVE_SYS_PARAM_H#include <sys/param.h>#endif#ifdef HAVE_SYS_FCNTL_H#include <sys/fcntl.h>#else#ifndef MAXPATHLEN#define MAXPATHLEN 255#endif#endif /* HAVE fcntl.h */#include <assert.h>#include "remap.h"#include "dvdnav_internal.h"struct block_s {    int domain;    int title;    int program;    unsigned long start_block;    unsigned long end_block;};struct remap_s {    char *title;    int maxblocks;    int nblocks;    int debug;    struct block_s *blocks;};static remap_t* remap_new( char *title) {    remap_t *map = malloc( sizeof(remap_t));    map->title = strdup(title);    map->maxblocks = 0;    map->nblocks = 0;    map->blocks = NULL;    map->debug = 0;    return map;}static int compare_block( block_t *a, block_t *b) {    /* returns -1 if a precedes b, 1 if a follows b, and 0 if a and b overlap */    if (a->domain < b->domain) {	return -1;    } else if (a->domain > b->domain) {	return 1;    }    if (a->title < b->title) {	return -1;    } else if (a->title > b->title) {	return 1;    }    if (a->program < b->program) {	return -1;    } else if (a->program > b->program) {	return 1;    }    if (a->end_block < b->start_block) {	return -1;    } else if (a->start_block > b->end_block) {	/*	 * if a->start_block == b->end_block then the two regions	 * aren't strictly overlapping, but they should be merged 	 * anyway since there are zero blocks between them	 */	return 1;    }    return 0;}static block_t *findblock( remap_t *map, block_t *key) {    int lb = 0;    int ub = map->nblocks - 1;    int mid;    int res;    while (lb <= ub) {	mid = lb + (ub - lb)/2;	res = compare_block( key, &map->blocks[mid]);	if (res < 0) {	    ub = mid-1;	} else if (res > 0) {	    lb = mid+1;	} else {	    return &map->blocks[mid];	}    }    return NULL;}static void mergeblock( block_t *b, block_t tmp) {    if (tmp.start_block < b->start_block) b->start_block = tmp.start_block;    if (tmp.end_block > b->end_block) b->end_block = tmp.end_block;}static void remap_add_node( remap_t *map, block_t block) {    block_t *b;    int n;    b = findblock( map, &block);    if (b) {	/* overlaps an existing block */	mergeblock( b, block);    } else {        /* new block */	if (map->nblocks >= map->maxblocks) {	    map->maxblocks += 20;	    map->blocks = realloc( map->blocks, sizeof( block_t)*map->maxblocks);	}	n = map->nblocks++;	while (n > 0 && compare_block( &block, &map->blocks[ n-1]) < 0) {	    map->blocks[ n] = map->blocks[ n-1];	    n--;	}	map->blocks[ n] = block;    }}static int parseblock(char *buf, int *dom, int *tt, int *pg, 		      unsigned long *start, unsigned long *end) {    long tmp;    char *tok;    char *epos;    char *marker[]={"domain", "title", "program", "start", "end"};    int st = 0;    tok = strtok( buf, " ");    while (st < 5) {        if (strcmp(tok, marker[st])) return -st-1000;        tok = strtok( NULL, " ");        if (!tok) return -st-2000;        tmp = strtol( tok, &epos, 0);        if (*epos != 0 && *epos != ',') return -st-3000;        switch (st) {	    case 0:		*dom = (int)tmp;		break;	    case 1:		*tt = (int)tmp;		break;	    case 2:		*pg = (int)tmp;		break;	    case 3:		*start = tmp;		break;	    case 4:		*end = tmp;		break;	} 	st++;        tok = strtok( NULL, " ");    }    return st;}remap_t* remap_loadmap( char *title) {    char buf[160];    char fname[MAXPATHLEN];    char *home;    int res;    FILE *fp;    block_t tmp;    remap_t *map;    /* Build the map filename */    home = getenv("HOME"); assert(home);    snprintf (fname, sizeof(fname), "%s/.dvdnav/%s.map", home, title);    /* Open the map file */    fp = fopen( fname, "r");    if (!fp) {	fprintf(MSG_OUT, "libdvdnav: Unable to find map file '%s'\n", fname);	return NULL;    }    /* Load the map file */    map = remap_new( title);    while (fgets( buf, sizeof(buf), fp) != NULL) {        if (buf[0] == '\n' || buf[0] == '#' || buf[0] == 0) continue;        if (strncasecmp( buf, "debug", 5) == 0) {	    map->debug = 1;	} else {	    res = parseblock( buf, 		&tmp.domain, &tmp.title, &tmp.program, &tmp.start_block, &tmp.end_block);	    if (res != 5) {		fprintf(MSG_OUT, "libdvdnav: Ignoring map line (%d): %s\n", res, buf);		continue;	    }	    remap_add_node( map, tmp);	}    }    if (map->nblocks == 0 && map->debug == 0) return NULL;    return map;}unsigned long remap_block( 	remap_t *map, int domain, int title, int program, 	unsigned long cblock, unsigned long offset) {    block_t key;    block_t *b;    if (map->debug) {	fprintf(MSG_OUT, "libdvdnav: %s: domain %d, title %d, program %d, start %lx, next %lx\n",	    map->title, domain, title, program, cblock, cblock+offset);    }    key.domain = domain;    key.title = title;    key.program = program;    key.start_block = key.end_block = cblock + offset;    b = findblock( map, &key);        if (b) {       if (map->debug) {	   fprintf(MSG_OUT, "libdvdnav: Redirected to %lx\n", b->end_block);       }       return b->end_block - cblock;    }    return offset;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -