/*
gets dimensions from IFO file, plugs them into diminit.vob to be used for indexing with anri-chan
author: DJ Grenola & ballofsnow
date: 2 August 2007
license: none (public domain)
target: win32 (MINGW), recommend using the free IDE from bloodshed.net
version: beta 0.3
*/
#define LARGE_FILE_SUPPORT
#ifdef LARGE_FILE_SUPPORT
/* not necessary for mingw/win32 but will probably become so if we start
trying to compile it on linux and friends */
#define _FILE_OFFSET_BITS 64
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <bitset>
using namespace std;
/* #define VERBOSE */
#define CHECKIFO_LEN 12 /* DVDVIDEO-VTS */
#define CHECKIFO { 0x44, 0x56, 0x44, 0x56, 0x49, 0x44, 0x45, 0x4F, 0x2D, 0x56, 0x54, 0x53 }
#define BUFSIZE 1024*1024
#ifdef LARGE_FILE_SUPPORT
#define FOPEN fopen64
#define FSEEK fseeko64
#define FTELL ftello64
#define OFF_T off64_t
#else
#define FOPEN fopen
#define FSEEK fseek
#define FTELL ftell
#define OFF_T int
#endif
void usage(char *argv0);
unsigned char checkifo[CHECKIFO_LEN]=CHECKIFO;
unsigned char buffer[BUFSIZE];
int main (int argc, char **argv) {
FILE *ifo;
FILE *vob;
char *ifoname=NULL;
char *vobname=NULL;
unsigned char repbytes[4];
printf ("VOB dimensions corrector\n");
printf ("beta 0.3, DJ Grenola & ballofsnow\n\n");
printf ("This software comes with no warranty.\n\n");
if (argc!=4 || ( strcmp(argv[3],"1") && strcmp(argv[3],"0") ) ) {
usage(argv[0]);
return 0;
}
/* LOAD THE IFO */
ifoname=argv[1];
if ((ifo=FOPEN(ifoname,"rb"))==NULL) {
printf ("[-] Failed to open IFO file \"%s\".\n", ifoname);
return 1;
}
// Source res is at offset 0x0200, or 512 decimal, 2 bytes.
fread(buffer,1,520,ifo);
if (memcmp(checkifo,buffer,12) != 0) {
printf ("This isn't an IFO file.\n");
free(buffer);
fclose(ifo);
usage(argv[0]);
return 1;
}
bitset<CHAR_BIT> ntscorpal (buffer[512]);
ntscorpal &= 0x10;
bitset<CHAR_BIT> dimensions (buffer[513]);
dimensions &= 0x18;
if (ntscorpal == 0x00) {
/* Potential bug if we want to support widescreen. The 2 in byte 4 represents 4:3. */
printf ("NTSC\n");
repbytes[3] = 0x24;
if (dimensions == 0x00) {
printf ("720x480\n");
repbytes[0] = 0x2D;
repbytes[1] = 0x01;
repbytes[2] = 0xE0;
}
else if (dimensions == 0x08) {
printf ("704x480\n");
repbytes[0] = 0x2C;
repbytes[1] = 0x01;
repbytes[2] = 0xE0;
}
else if (dimensions == 0x10) {
printf ("352x480\n");
repbytes[0] = 0x16;
repbytes[1] = 0x01;
repbytes[2] = 0xE0;
}
else if (dimensions == 0x18) {
printf ("352x240\n");
repbytes[0] = 0x16;
repbytes[1] = 0x00;
repbytes[2] = 0xF0;
}
}
else if (ntscorpal == 0x10) {
printf ("PAL\n");
repbytes[3] = 0x23;
if (dimensions == 0x00) {
printf ("720x576\n");
repbytes[0] = 0x2D;
repbytes[1] = 0x02;
repbytes[2] = 0x40;
}
else if (dimensions == 0x08) {
printf ("704x576\n");
repbytes[0] = 0x2C;
repbytes[1] = 0x02;
repbytes[2] = 0x40;
}
else if (dimensions == 0x10) {
printf ("352x576\n");
repbytes[0] = 0x16;
repbytes[1] = 0x02;
repbytes[2] = 0x40;
}
else if (dimensions == 0x18) {
printf ("352x288\n");
repbytes[0] = 0x16;
repbytes[1] = 0x01;
repbytes[2] = 0x20;
}
}
free(buffer); // ifo buffer
fclose(ifo);
/* Finished with IFO */
/* LOAD DIMINIT.VOB */
vobname=argv[2];
if ((vob=FOPEN(vobname,"r+b"))==NULL) {
printf ("[-] Failed to open VOB file \"%s\".\n", vobname);
return 1;
}
// Offset 828, or 2088 decimal.
fread(buffer,1,2196,vob);
fseek ( vob , 2088 , SEEK_SET );
fwrite (repbytes , 1 , 4 , vob );
// Offset 891, or 2193 decimal
// Set field order
fseek ( vob , 2193 , SEEK_SET );
// Writing hard value for now. Fix this later!!!!!!
bitset<CHAR_BIT> fo (buffer[2193]);
unsigned char rep[1];
if (strcmp(argv[3],"1")==0) {
//fo.set(7);
rep[0]=0xD1;
fwrite (rep , 1 , 1 , vob );
}
else if (strcmp(argv[3],"0")==0) {
//fo.set(7,0);
rep[0]=0x51;
fwrite (rep , 1 , 1 , vob );
}
printf ("Vob file has been modified.\n");
free(buffer); // vob buffer
fclose(vob);
return 0;
}
void usage(char *argv0) {
printf ("Usage: %s <VTS IFO file> DIMINIT.VOB <1=TFF, 0=BFF>\n\n", argv0);
}