Anri-chan/Source/pgccount.cpp

From SDA Knowledge Base

< Anri-chan‎ | Source
Revision as of 23:20, 26 August 2008 by Njahnke (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
/*

  Creates number list of unique program chains in pgclist.txt.

  author: ballofsnow
  date: 11 November 2007
  license: none (public domain)
  target: win32 (MINGW), recommend using the free IDE from bloodshed.net
  version: beta 0.4

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <iostream>
using namespace std;

void usage(char *argv0);
unsigned char checkifo[12]= { 0x44, 0x56, 0x44, 0x56, 0x49, 0x44, 0x45, 0x4F, 0x2D, 0x56, 0x54, 0x53 }; /* DVDVIDEO-VTS */
unsigned char buffer[1024*1024];

int main (int argc, char **argv) {
  FILE *ifo;
  char *ifoname=NULL;
  int pgctable=0x1000;
  int pgctotal;
  unsigned long sectors[1024]; // obscene, I know.
  unsigned long pgcstart;
  unsigned long cellsector;
  int goodpgcs;
  int cellstart;
  int flag;
  int curpgc=0;
  
//cout << "PGC count v0.4, ballofsnow" << endl;
  if (argc==1) {
    usage(argv[0]);
    return -1;
  }

  ostream& pgclist = cout;
  
  for (int p=1;p<argc;p++) {
    /* LOAD AND VALIDATE THE IFO */
    ifoname=argv[p];
    //cout << argv[p] << endl;
    if ((ifo=fopen(ifoname,"rb"))==NULL) {
      cerr << "Failed to open IFO file " << ifoname << endl;
      return -1;
    } 
    fread(buffer,1,1024*1024,ifo);
    if (memcmp(checkifo,buffer,12) != 0) {
       cerr << "This isn't an IFO file." << endl;
       free(buffer);
       fclose(ifo);
       usage(argv[0]);
       return -1;
    }
    /* FINISHED VALIDATING */
  
    goodpgcs=1;
    pgctotal=buffer[pgctable]*0x100+buffer[pgctable+1];
    for (int i=1; i<=pgctotal; i++) {
      /* Get PGC start byte */
      pgcstart=buffer[pgctable+i*8+4]*0x1000000+buffer[pgctable+i*8+5]*0x10000+buffer[pgctable+i*8+6]*0x100+buffer[pgctable+i*8+7];
      cellstart=buffer[pgctable+pgcstart+0xE8]*0x100+buffer[pgctable+pgcstart+0xE9]+8;
      cellsector=buffer[pgctable+pgcstart+cellstart+0]*0x1000000+buffer[pgctable+pgcstart+cellstart+1]*0x10000+buffer[pgctable+pgcstart+cellstart+2]*0x100+buffer[pgctable+pgcstart+cellstart+3];
      //cout << pgcstart << endl;
      //cout << cellstart << endl;
      //cout << cellsector << endl << endl;    
      curpgc++;
      flag=0;
      for (int a=0; a<goodpgcs-1; a++) {
        if (cellsector==sectors[a]) {
          flag=1;
          break;
        }
      }
      if (flag==0) {
        sectors[goodpgcs-1]=cellsector;      
        goodpgcs++;
        //cout << "curpgc: " << curpgc << endl;
        pgclist << curpgc << "," << argv[p] << endl;
      }
    }
    free(buffer); // ifo buffer
    fclose(ifo);  
  } 
//cout << "pgclist.txt created successfully." << endl;
  return 0;
}

void usage(char *argv0) {
  cerr << "Usage: " << argv0 << " <VTS IFO file> [VTS IFO file] ... " << endl;
  cerr << "Creates number list of unique program chains in pgclist.txt." << endl;
}
Personal tools