
/*
 *
 * Copyright (C) 1998,1999  Thomas Mirlacher
 *
 * This program 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.
 * 
 * This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 * 
 * The author may be reached as dent@cosy.sbg.ac.at, or
 * Thomas Mirlacher, Jakob-Haringerstr. 2, A-5020 Salzburg,
 * Austria
 *
 *------------------------------------------------------------
 *
 */


#include <stdio.h>
#include <io.h>

#include <sys/types.h>
//#include <unistd.h>
#include <stdlib.h>

#include "ifo.h"
#include "misc.h"

 u_int  get4bytes (u_char *buf)
{
	return bswap_32 (*((u_int32_t *)buf));
}

u_int get2bytes (u_char *buf)
{
	return bswap_16 (*((u_int16_t *)buf));
}

int ifoReadTBL (ifo_t *ifo, u_int offset, u_int tbl_id)
{
	u_char *data;
	u_int len = 0;

	if (!offset)
		return -1;

	if (!(data =  (u_char *) malloc (DVD_VIDEO_LB_LEN))) {
		perror ("malloc");
		return -1; 
	}

	if (ifoReadLB (ifo->fd, ifo->pos + offset * DVD_VIDEO_LB_LEN, DVD_VIDEO_LB_LEN, data) <= 0) {
		perror ("ifoReadLB");
		return -1;
	}

	switch (tbl_id) {
		case ID_TITLE_VOBU_ADDR_MAP:
		case ID_MENU_VOBU_ADDR_MAP:
			len = get4bytes (data) + 1;
			break;

		default: {
			ifo_hdr_t *hdr = (ifo_hdr_t *) data;
			len = bswap_32 (hdr->len) + 1;
		}
	}

	if (len > DVD_VIDEO_LB_LEN) {
		if (!(data =  (u_char *) realloc ((void *) data, len))) {
			perror ("realloc");
			return -1; 
		}

		ifoReadLB (ifo->fd, ifo->pos + offset * DVD_VIDEO_LB_LEN, len, data);
	}

	ifo->data [tbl_id] = data;

{	int i;
	u_int32_t *ptr = (u_int32_t *)data;

	len/=4;

	if (tbl_id == ID_TMT) 
		for (i=0; i<len; i++)
			ptr[i] = bswap_32 (ptr[i]);
		
}

	return 0;
}


/**
 *
 */

int ifoReadLB (int fd, __off64_t pos, u_int count, u_char *data)
{
	if ((pos = _lseeki64 (fd, pos, SEEK_SET)) == -1) {
                fprintf (stderr, "%s/%d: error in lseek (pos: 0x%x)\n",
                        __FILE__, __LINE__, pos);
                return -1;
        }

	return read (fd, data, count); 
}
