// (c) 2002-2007 Electronic Arts Inc.
#include <stdio.h>
#include <stdlib.h>

static char buffer[200000];

static int find_start_code(FILE *fin)
{
    int count;
    int zeros;
    int byte;

    count = 0;
    zeros = 0;
    while ((byte = fgetc(fin)) != EOF)
    {
        ++count;

        if ((zeros>1) && (byte==1)) return(count);

        if (byte==0) ++zeros;
        else zeros = 0;
    }

    return(0);
}

static int get_packet_size(FILE *fin)
{
    return((fgetc(fin) << 8) + fgetc(fin));
}

int main(int argc, char *argv[])
{
    FILE    *fin;
    FILE    *fout;
    int     id;
    int     byte;
    int     size;
    int     hsize;

    if (argc < 2)
    {
        printf("Usage: RIP filename\n");
        return(1);
    }

    fin = fopen(argv[1], "rb");
    if (fin == NULL)
    {
        printf("Unable to open file %s\n", argv[1]);
        return(1);
    }

    fout = fopen("rip.m2v", "wb");

    while (find_start_code(fin))
    {
        id = fgetc(fin);
        if (id == 0xbd)
        {
            size = get_packet_size(fin);
            fseek(fin, size, SEEK_CUR);
        }
        else if (id == 0xe0)
        {
            size = get_packet_size(fin);

            byte = fgetc(fin);
            size -= 1;

            while (byte == 0xff)
            {
                byte = fgetc(fin);
                size -= 1;
            }

            if ((byte & 0xc0) == 0x80) // MPEG-2
            {
                fgetc(fin);
                hsize = fgetc(fin);
                fread(buffer, hsize, 1, fin);
                size -= hsize+2;
            }
            else // MPEG-1
            {
                if ((byte & 0xc0) == 0x40)
                {
                    fgetc(fin);
                    byte = fgetc(fin);
                    size -= 2;
                }

                if ((byte & 0xf0) == 0x20)
                {
                    fread(buffer, 4, 1, fin);
                    size -= 4;
                }
                else if ((byte & 0xf0) == 0x30)
                {
                    fread(buffer, 9, 1, fin);
                    size -= 9;
                }
            }

            fread(buffer, size, 1, fin);
            fwrite(buffer, size, 1, fout);
        }
    }

    fclose(fin);
    fclose(fout);

    return(0);
}
