misc.c
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:3k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /*
  2.  *
  3.  * Copyright (C) 1998,1999  Thomas Mirlacher
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  * 
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  * 
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  * 
  19.  * The author may be reached as dent@cosy.sbg.ac.at, or
  20.  * Thomas Mirlacher, Jakob-Haringerstr. 2, A-5020 Salzburg,
  21.  * Austria
  22.  *
  23.  *------------------------------------------------------------
  24.  *
  25.  */
  26. #include <stdio.h>
  27. #include <sys/types.h>
  28. #include <unistd.h>
  29. #include <stdlib.h>
  30. #include "ifo.h"
  31. #include "misc.h"
  32. #if BYTE_ORDER == LITTLE_ENDIAN // x86
  33. inline u_int get4bytes (u_char *buf)
  34. {
  35.         u_int ret;
  36.         ret  = buf[0] << 24;
  37.         ret |= buf[1] << 16;
  38.         ret |= buf[2] << 8;
  39.         ret |= buf[3];
  40. return ret;
  41. }
  42. inline u_int get2bytes (u_char *buf)
  43. {
  44.         u_int ret;
  45.         ret = buf[0] << 8;
  46.         ret |= buf[1];
  47.         return ret;
  48. }
  49. #else // BIG_ENDIAN
  50. inline u_int get4bytes (u_char *buf)
  51. {
  52.         u_int ret;
  53.         ret  = buf[3] << 24;
  54.         ret |= buf[2] << 16;
  55.         ret |= buf[1] << 8;
  56.         ret |= buf[0];
  57. return ret;
  58. }
  59. inline u_int get2bytes (u_char *buf)
  60. {
  61.         u_int ret;
  62.         ret = buf[1] << 8;
  63.         ret |= buf[0];
  64.         return ret;
  65. }
  66. #endif
  67. int ifoReadTBL (ifo_t *ifo, u_int offset, u_int tbl_id)
  68. {
  69. u_char *data;
  70. u_int len = 0;
  71. if (!offset)
  72. return -1;
  73. if (!(data =  (u_char *) malloc (DVD_VIDEO_LB_LEN))) {
  74. perror ("malloc");
  75. return -1; 
  76. }
  77. if (ifoReadLB (ifo->fd, ifo->pos + offset * DVD_VIDEO_LB_LEN, DVD_VIDEO_LB_LEN, data) <= 0) {
  78. perror ("ifoReadLB");
  79. return -1;
  80. }
  81. switch (tbl_id) {
  82. case ID_TITLE_VOBU_ADDR_MAP:
  83. case ID_MENU_VOBU_ADDR_MAP:
  84. len = get4bytes (data);
  85. break;
  86. default: {
  87. ifo_hdr_t *hdr = (ifo_hdr_t *) data;
  88. len = ntohl (hdr->len);
  89. }
  90. }
  91. if (len > DVD_VIDEO_LB_LEN) {
  92. //free (data);
  93. if (!(data =  (u_char *) realloc ((void *) data, len))) {
  94. //if (!(data =  (char *) malloc (len))) {
  95. perror ("realloc");
  96. return -1; 
  97. }
  98. ifoReadLB (ifo->fd, ifo->pos + offset * DVD_VIDEO_LB_LEN, len, data);
  99. }
  100. ifo->data [tbl_id] = data;
  101. return 0;
  102. }
  103. /**
  104.  *
  105.  */
  106. int ifoReadLB (int fd, __off64_t pos, u_int count, u_char *data)
  107. {
  108. if ((pos = lseek64 (fd, pos, SEEK_SET)) == -1) {
  109.                 fprintf (stderr, "%s/%d: error in lseekn",
  110.                         __FILE__, __LINE__);
  111.                 return -1;
  112.         }
  113. return read (fd, data, count); 
  114. }