/*
 * Simple quicktime frame extrator. Works great on my Olympus D490Z movies
 * (jpeg compressed frames). I make no other claims about it.
 * (c) 2001 Jorj Bauer <jorj@seas.upenn.edu>
 *
 * Compiling: 
 * gcc quicktime-to-jpegs.c -I /usr/include/quicktime -lquicktime -o quicktime-to-jpegs
 *
 * (YMMV.)
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <quicktime.h>

int main(int argc, char *argv[])
{
  quicktime_t *qt_desc;
  unsigned long frameno;
  long ret;
  char buf[255];

  if (argc != 2) {
    fprintf(stderr, "Usage: %s <file.mov>\n", argv[0]);
    exit(-1);
  }

  if (quicktime_check_sig(argv[1])) {
    printf("It's a quicktime movie.\n");
  } else {
    printf("Movie failed quicktime signature check.\n");
    exit(-1);
  }

  qt_desc = quicktime_open(argv[1], 1, 0);
  if (!qt_desc) {
    printf("couldn't open it\n");
    exit(-1);
  }
  // this call fails for some reason. Dunno why.
  //  if (!quicktime_read_info(qt_desc)) {
  //    printf("couldn't read_info\n");
  //    exit(-1);
  //  }
  printf("%d quicktime video tracks present\n", quicktime_video_tracks(qt_desc));
  printf("%d quicktime audio tracks present\n", quicktime_audio_tracks(qt_desc));
  // cheat: I know we've only got video for the movies I'm playing with.
  // should really check to make sure we're doing the right thing before we 
  // move off on this tangent.
  if (quicktime_has_video(qt_desc)) {
    printf("Video information:\n");
    printf("\tname: %s\n", quicktime_get_name(qt_desc));
    printf("\tinfo: %s\n", quicktime_get_info(qt_desc));
    printf("\tcopyright: %s\n", quicktime_get_copyright(qt_desc));
    printf("\tsize: %d x %d\n\tdepth: %d\n\tframe rate:%f\n\tcompressor: %s\n", 
	   quicktime_video_width(qt_desc, 0), quicktime_video_height(qt_desc, 0),
	   quicktime_video_depth(qt_desc, 0),
	   quicktime_frame_rate(qt_desc, 0),
	   quicktime_video_compressor(qt_desc, 0));
  }

  // read the frames.
  quicktime_seek_start(qt_desc);
  frameno = 0;
  do {
    FILE *f;
    long size;

    unsigned char *videobuf;
    size = quicktime_frame_size(qt_desc, frameno, 0);
    if (!size) {
      printf("No size returned?\n");
      break;
    }
    printf("Frame is %d bytes\n", size);
    videobuf = malloc(size);
    if (!videobuf) {
      printf("Error: no videobuf?\n");
      exit(-1);
    }

    ret = quicktime_read_frame(qt_desc, videobuf, 0);

    printf("ret: %d\n", ret);
    if (ret) {
      int outfile;

      sprintf(buf, "frame%.3d.jpg", frameno); // hack: .jpg & .3
      printf("Creating data file '%s' for frame\n", buf);
      outfile = open(buf, O_RDWR|O_CREAT|S_IREAD|S_IWRITE);
      if (!outfile) {
	printf("Unable to open outfile: bailing\n");
	exit(-1);
      }
      write(outfile, videobuf, size);
      close(outfile);
      frameno++;
    }
    free(videobuf);
  }while (ret);
  printf("Done! %d frames processed.\n", frameno);

  quicktime_close(qt_desc);
}
