Anri-chan/Source/fieldorder.cpp

From SDA Knowledge Base

< Anri-chan‎ | Source
Revision as of 02:33, 2 August 2007 by Ballofsnow (Talk | contribs)

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

  find field order by reading vob file
  
  start code: 00 00 01 B5
  picture coding extension id: 8
  field order in fourth byte after start code, first bit. tff=1, bff=0

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

  big thanks to DJ Grenola
  
*/

#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 BUFSIZE        1024*1024
#define STARTCODE_LEN  4
#define STARTCODE      { 0x00, 0x00, 0x01, 0xB5 }

#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

typedef long long int s64;

void usage(char *argv0);
unsigned char startcode[STARTCODE_LEN]=STARTCODE;
unsigned char buffer[BUFSIZE];

int main (int argc, char **argv) {
  FILE *vob;
  unsigned int bufstart=0;
  unsigned int bytes_to_read;
  unsigned int error=0;
  unsigned char idlo[1]= { 0x80 };
  unsigned char idhi[1]= { 0x8F };
    
  s64 br;
  OFF_T pos=0,tmp64;
  char *vobname=NULL;
  printf ("Determine field order\n");
  printf ("beta 0.1, ballofsnow\n");
  printf ("This software comes with no warranty.\n");
  printf ("Returns 1 for TFF, 0 for BFF.\n");
  
  if (argc!=2) {
    usage(argv[0]);
    return -1;
  } 
  
  vobname=argv[1];
  if ((vob=FOPEN(vobname,"rb"))==NULL) {
    printf ("[-] Failed to open file \"%s\".\n", vobname);
    return -1;
  }
  printf ("[+] Using %u KiB chunks.\n", BUFSIZE/1024);
  printf ("[+] Scanning file \"%s\".\n", vobname);
  while (~0) {
    int i;
    bytes_to_read=BUFSIZE-bufstart;
    br=fread(buffer+bufstart,1,bytes_to_read,vob);
    pos+=br;
#ifdef VERBOSE
    printf ("[+] Read %llu bytes.\n", pos);
#endif
    for (i=0;i<br+bufstart;i++) {
      if (!memcmp(startcode,buffer+i,STARTCODE_LEN)) {        
        if ( memcmp(buffer+i+4,idlo,1)>=0 && memcmp(buffer+i+4,idhi,1)<=0 ) {
          /* MASK THE BYTE TO GET THE RELEVANT BITS */
          bitset<CHAR_BIT> fo (buffer[i+7]); 
          fo &= 0x80;
          if (fo == 0x00) {
            printf ("BFF\n");
            free(buffer);
            fclose(vob);
            return 0;
          }
          else if (fo == 0x80) {
            printf ("TFF\n");
            free(buffer);
            fclose(vob);
            return 1;
          }
        }
      }
    }
    bufstart=STARTCODE_LEN-1;
    memmove(buffer,buffer+(BUFSIZE-(STARTCODE_LEN-1)),STARTCODE_LEN-1);
    if (br!=bytes_to_read)
      break;
  }  
  printf("Didn't find TFF flag!");
  free(buffer);
  fclose(vob);
  return -1;
}

void usage(char *argv0) {
  printf ("Usage: %s <VOB file>\n\n", argv0);
}
Personal tools