TIFFReadRGBAImage doesn't actually return errors unless you ask it to.
[theora.git] / examples / tiff2theora.c
1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
7  *                                                                  *
8  * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2011                *
9  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
10  *                                                                  *
11  ********************************************************************
12
13   function: example encoder application; makes an Ogg Theora
14             file from a sequence of tiff images
15   last mod: $Id$
16              based on png2theora
17
18  ********************************************************************/
19
20 #define _FILE_OFFSET_BITS 64
21
22 #include <errno.h>
23 #include <getopt.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <time.h>
29 #include <math.h>
30 #include <libgen.h>
31 #include <sys/types.h>
32 #include <dirent.h>
33
34 #ifdef HAVE_CONFIG_H
35 # include <config.h>
36 #endif
37
38 #include <tiffio.h>
39 #include <ogg/ogg.h>
40 #include "theora/theoraenc.h"
41
42 #define PROGRAM_NAME  "tiff2theora"
43 #define PROGRAM_VERSION  "1.1"
44
45 static const char *option_output = NULL;
46 static int video_fps_numerator = 24;
47 static int video_fps_denominator = 1;
48 static int video_aspect_numerator = 0;
49 static int video_aspect_denominator = 0;
50 static int video_rate = -1;
51 static int video_quality = -1;
52 ogg_uint32_t keyframe_frequency=0;
53 int buf_delay=-1;
54 int vp3_compatible=0;
55 static int chroma_format = TH_PF_420;
56
57 static FILE *twopass_file = NULL;
58 static  int twopass=0;
59 static  int passno;
60
61 static FILE *ogg_fp = NULL;
62 static ogg_stream_state ogg_os;
63 static ogg_packet op;
64 static ogg_page og;
65
66 static th_enc_ctx      *td;
67 static th_info          ti;
68
69 static char *input_filter;
70
71 const char *optstring = "o:hv:\4:\2:V:s:S:f:F:ck:d:\1\2\3\4\5\6";
72 struct option options [] = {
73  {"output",required_argument,NULL,'o'},
74  {"help",no_argument,NULL,'h'},
75  {"chroma-444",no_argument,NULL,'\5'},
76  {"chroma-422",no_argument,NULL,'\6'},
77  {"video-rate-target",required_argument,NULL,'V'},
78  {"video-quality",required_argument,NULL,'v'},
79  {"aspect-numerator",required_argument,NULL,'s'},
80  {"aspect-denominator",required_argument,NULL,'S'},
81  {"framerate-numerator",required_argument,NULL,'f'},
82  {"framerate-denominator",required_argument,NULL,'F'},
83  {"vp3-compatible",no_argument,NULL,'c'},
84  {"soft-target",no_argument,NULL,'\1'},
85  {"keyframe-freq",required_argument,NULL,'k'},
86  {"buf-delay",required_argument,NULL,'d'},
87  {"two-pass",no_argument,NULL,'\2'},
88  {"first-pass",required_argument,NULL,'\3'},
89  {"second-pass",required_argument,NULL,'\4'},
90  {NULL,0,NULL,0}
91 };
92
93 static void usage(void){
94   fprintf(stderr,
95           "%s %s\n"
96           "Usage: %s [options] <input>\n\n"
97           "The input argument uses C printf format to represent a list of files,\n"
98           "  i.e. file-%%06d.tiff to look for files file000001.tiff to file9999999.tiff \n\n"
99           "Options: \n\n"
100           "  -o --output <filename.ogv>      file name for encoded output (required);\n"
101           "  -v --video-quality <n>          Theora quality selector fro 0 to 10\n"
102           "                                  (0 yields smallest files but lowest\n"
103           "                                  video quality. 10 yields highest\n"
104           "                                  fidelity but large files)\n\n"
105           "  -V --video-rate-target <n>      bitrate target for Theora video\n\n"
106           "     --soft-target                Use a large reservoir and treat the rate\n"
107           "                                  as a soft target; rate control is less\n"
108           "                                  strict but resulting quality is usually\n"
109           "                                  higher/smoother overall. Soft target also\n"
110           "                                  allows an optional -v setting to specify\n"
111           "                                  a minimum allowed quality.\n\n"
112           "     --two-pass                   Compress input using two-pass rate control\n"
113           "                                  This option performs both passes automatically.\n\n"
114           "     --first-pass <filename>      Perform first-pass of a two-pass rate\n"
115           "                                  controlled encoding, saving pass data to\n"
116           "                                  <filename> for a later second pass\n\n"
117           "     --second-pass <filename>     Perform second-pass of a two-pass rate\n"
118           "                                  controlled encoding, reading first-pass\n"
119           "                                  data from <filename>.  The first pass\n"
120           "                                  data must come from a first encoding pass\n"
121           "                                  using identical input video to work\n"
122           "                                  properly.\n\n"
123           "   -k --keyframe-freq <n>         Keyframe frequency\n"
124           "   -d --buf-delay <n>             Buffer delay (in frames). Longer delays\n"
125           "                                  allow smoother rate adaptation and provide\n"
126           "                                  better overall quality, but require more\n"
127           "                                  client side buffering and add latency. The\n"
128           "                                  default value is the keyframe interval for\n"
129           "                                  one-pass encoding (or somewhat larger if\n"
130           "                                  --soft-target is used) and infinite for\n"
131           "                                  two-pass encoding.\n"
132           "  --chroma-444                    Use 4:4:4 chroma subsampling\n"
133           "  --chroma-422                    Use 4:2:2 chroma subsampling\n"
134           "                                  (4:2:0 is default)\n\n"
135           "  -s --aspect-numerator <n>       Aspect ratio numerator, default is 0\n"
136           "  -S --aspect-denominator <n>     Aspect ratio denominator, default is 0\n"
137           "  -f --framerate-numerator <n>    Frame rate numerator\n"
138           "  -F --framerate-denominator <n>  Frame rate denominator\n"
139           "                                  The frame rate nominator divided by this\n"
140           "                                  determines the frame rate in units per tick\n"
141           ,PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_NAME
142   );
143   exit(0);
144 }
145
146 #ifdef WIN32
147 int
148 alphasort (const void *a, const void *b)
149 {
150   return strcoll ((*(const struct dirent **) a)->d_name,
151                   (*(const struct dirent **) b)->d_name);
152 }
153
154 int
155 scandir (const char *dir, struct dirent ***namelist,
156          int (*select)(const struct dirent *), int (*compar)(const void *, const void *))
157 {
158   DIR *d;
159   struct dirent *entry;
160   register int i=0;
161   size_t entrysize;
162
163   if ((d=opendir(dir)) == NULL)
164     return(-1);
165
166   *namelist=NULL;
167   while ((entry=readdir(d)) != NULL)
168   {
169     if (select == NULL || (select != NULL && (*select)(entry)))
170     {
171       *namelist=(struct dirent **)realloc((void *)(*namelist),
172                  (size_t)((i+1)*sizeof(struct dirent *)));
173       if (*namelist == NULL) return(-1);
174       entrysize=sizeof(struct dirent)-sizeof(entry->d_name)+strlen(entry->d_name)+1;
175       (*namelist)[i]=(struct dirent *)malloc(entrysize);
176       if ((*namelist)[i] == NULL) return(-1);
177         memcpy((*namelist)[i], entry, entrysize);
178       i++;
179     }
180   }
181   if (closedir(d)) return(-1);
182   if (i == 0) return(-1);
183   if (compar != NULL)
184     qsort((void *)(*namelist), (size_t)i, sizeof(struct dirent *), compar);
185
186   return(i);
187 }
188 #endif
189
190 static int
191 theora_write_frame(th_ycbcr_buffer ycbcr, int last)
192 {
193   ogg_packet op;
194   ogg_page og;
195
196   /* Theora is a one-frame-in,one-frame-out system; submit a frame
197      for compression and pull out the packet */
198   /* in two-pass mode's second pass, we need to submit first-pass data */
199   if(passno==2){
200     int ret;
201     for(;;){
202       static unsigned char buffer[80];
203       static int buf_pos;
204       int bytes;
205       /*Ask the encoder how many bytes it would like.*/
206       bytes=th_encode_ctl(td,TH_ENCCTL_2PASS_IN,NULL,0);
207       if(bytes<0){
208         fprintf(stderr,"Error submitting pass data in second pass.\n");
209         exit(1);
210       }
211       /*If it's got enough, stop.*/
212       if(bytes==0)break;
213       /*Read in some more bytes, if necessary.*/
214       if(bytes>80-buf_pos)bytes=80-buf_pos;
215       if(bytes>0&&fread(buffer+buf_pos,1,bytes,twopass_file)<bytes){
216         fprintf(stderr,"Could not read frame data from two-pass data file!\n");
217         exit(1);
218       }
219       /*And pass them off.*/
220       ret=th_encode_ctl(td,TH_ENCCTL_2PASS_IN,buffer,bytes);
221       if(ret<0){
222         fprintf(stderr,"Error submitting pass data in second pass.\n");
223         exit(1);
224       }
225       /*If the encoder consumed the whole buffer, reset it.*/
226       if(ret>=bytes)buf_pos=0;
227       /*Otherwise remember how much it used.*/
228       else buf_pos+=ret;
229     }
230   }
231
232   if(th_encode_ycbcr_in(td, ycbcr)) {
233     fprintf(stderr, "%s: error: could not encode frame\n",
234       option_output);
235     return 1;
236   }
237
238   /* in two-pass mode's first pass we need to extract and save the pass data */
239   if(passno==1){
240     unsigned char *buffer;
241     int bytes = th_encode_ctl(td, TH_ENCCTL_2PASS_OUT, &buffer, sizeof(buffer));
242     if(bytes<0){
243       fprintf(stderr,"Could not read two-pass data from encoder.\n");
244       exit(1);
245     }
246     if(fwrite(buffer,1,bytes,twopass_file)<bytes){
247       fprintf(stderr,"Unable to write to two-pass data file.\n");
248       exit(1);
249     }
250     fflush(twopass_file);
251   }
252
253   if(!th_encode_packetout(td, last, &op)) {
254     fprintf(stderr, "%s: error: could not read packets\n",
255       option_output);
256     return 1;
257   }
258
259   if (passno!=1) {
260     ogg_stream_packetin(&ogg_os, &op);
261     while(ogg_stream_pageout(&ogg_os, &og)) {
262       fwrite(og.header, og.header_len, 1, ogg_fp);
263       fwrite(og.body, og.body_len, 1, ogg_fp);
264     }
265   }
266
267   return 0;
268 }
269
270 static unsigned char
271 clamp(int d)
272 {
273   if(d < 0)
274     return 0;
275
276   if(d > 255)
277     return 255;
278
279   return d;
280 }
281
282 static void
283 rgb_to_yuv(uint32 *raster,
284            th_ycbcr_buffer ycbcr,
285            unsigned int w, unsigned int h)
286 {
287   unsigned int x;
288   unsigned int y;
289
290   unsigned int x1;
291   unsigned int y1;
292
293   unsigned long yuv_w;
294   unsigned long yuv_h;
295
296   unsigned char *yuv_y;
297   unsigned char *yuv_u;
298   unsigned char *yuv_v;
299
300   yuv_w = ycbcr[0].width;
301   yuv_h = ycbcr[0].height;
302
303   yuv_y = ycbcr[0].data;
304   yuv_u = ycbcr[1].data;
305   yuv_v = ycbcr[2].data;
306
307   /*This ignores gamma and RGB primary/whitepoint differences.
308     It also isn't terribly fast (though a decent compiler will
309     strength-reduce the division to a multiplication).*/
310   /*TIFF is upside down relative to the libtheora api*/
311   if (chroma_format == TH_PF_420) {
312     for(y = 0; y < h; y += 2) {
313       y1=y+(y+1<h);
314       for(x = 0; x < w; x += 2) {
315         x1=x+(x+1<w);
316         uint8 r0 = TIFFGetR(raster[(h-y)*w + x]);
317         uint8 g0 = TIFFGetG(raster[(h-y)*w + x]);
318         uint8 b0 = TIFFGetB(raster[(h-y)*w + x]);
319         uint8 r1 = TIFFGetR(raster[(h-y)*w + x1]);
320         uint8 g1 = TIFFGetG(raster[(h-y)*w + x1]);
321         uint8 b1 = TIFFGetB(raster[(h-y)*w + x1]);
322         uint8 r2 = TIFFGetR(raster[(h-y1)*w + x]);
323         uint8 g2 = TIFFGetG(raster[(h-y1)*w + x]);
324         uint8 b2 = TIFFGetB(raster[(h-y1)*w + x]);
325         uint8 r3 = TIFFGetR(raster[(h-y1)*w + x1]);
326         uint8 g3 = TIFFGetG(raster[(h-y1)*w + x1]);
327         uint8 b3 = TIFFGetB(raster[(h-y1)*w + x1]);
328
329         yuv_y[x  + y * yuv_w]  = clamp((65481*r0+128553*g0+24966*b0+4207500)/255000);
330         yuv_y[x1 + y * yuv_w]  = clamp((65481*r1+128553*g1+24966*b1+4207500)/255000);
331         yuv_y[x  + y1 * yuv_w] = clamp((65481*r2+128553*g2+24966*b2+4207500)/255000);
332         yuv_y[x1 + y1 * yuv_w] = clamp((65481*r3+128553*g3+24966*b3+4207500)/255000);
333
334         yuv_u[(x >> 1) + (y >> 1) * ycbcr[1].stride] =
335           clamp( ((-33488*r0-65744*g0+99232*b0+29032005)/4 +
336                   (-33488*r0-65744*g0+99232*b0+29032005)/4 +
337                   (-33488*r2-65744*g2+99232*b2+29032005)/4 +
338                   (-33488*r3-65744*g3+99232*b3+29032005)/4)/225930);
339         yuv_v[(x >> 1) + (y >> 1) * ycbcr[2].stride] =
340           clamp( ((157024*r0-131488*g0-25536*b0+45940035)/4 +
341                   (157024*r1-131488*g1-25536*b1+45940035)/4 +
342                   (157024*r2-131488*g2-25536*b2+45940035)/4 +
343                   (157024*r3-131488*g3-25536*b3+45940035)/4)/357510);
344       }
345     }
346   } else if (chroma_format == TH_PF_444) {
347     for(y = 0; y < h; y++) {
348       for(x = 0; x < w; x++) {
349         uint8 r = TIFFGetR(raster[(h-y)*w + x]);
350         uint8 g = TIFFGetG(raster[(h-y)*w + x]);
351         uint8 b = TIFFGetB(raster[(h-y)*w + x]);
352
353         yuv_y[x + y * yuv_w] = clamp((65481*r+128553*g+24966*b+4207500)/255000);
354         yuv_u[x + y * yuv_w] = clamp((-33488*r-65744*g+99232*b+29032005)/225930);
355         yuv_v[x + y * yuv_w] = clamp((157024*r-131488*g-25536*b+45940035)/357510);
356       }
357     }
358   } else {  /* TH_PF_422 */
359     for(y = 0; y < h; y += 1) {
360       for(x = 0; x < w; x += 2) {
361         x1=x+(x+1<w);
362         uint8 r0 = TIFFGetR(raster[(h-y)*w + x]);
363         uint8 g0 = TIFFGetG(raster[(h-y)*w + x]);
364         uint8 b0 = TIFFGetB(raster[(h-y)*w + x]);
365         uint8 r1 = TIFFGetR(raster[(h-y)*w + x1]);
366         uint8 g1 = TIFFGetG(raster[(h-y)*w + x1]);
367         uint8 b1 = TIFFGetB(raster[(h-y)*w + x1]);
368
369         yuv_y[x  + y * yuv_w] = clamp((65481*r0+128553*g0+24966*b0+4207500)/255000);
370         yuv_y[x1 + y * yuv_w] = clamp((65481*r1+128553*g1+24966*b1+4207500)/255000);
371
372         yuv_u[(x >> 1) + y * ycbcr[1].stride] =
373           clamp( ((-33488*r0-65744*g0+99232*b0+29032005)/2 +
374                   (-33488*r1-65744*g1+99232*b1+29032005)/2)/225930);
375         yuv_v[(x >> 1) + y * ycbcr[2].stride] =
376           clamp( ((157024*r0-131488*g0-25536*b0+45940035)/2 +
377                   (157024*r1-131488*g1-25536*b1+45940035)/2)/357510);
378       }
379     }
380   }
381
382 }
383
384 static int
385 tiff_read(const char *pathname,
386  unsigned int *w, unsigned int *h, th_ycbcr_buffer ycbcr)
387 {
388   TIFF *tiff;
389   uint32 width;
390   uint32 height;
391   size_t pixels;
392   uint32 *raster;
393   unsigned long yuv_w;
394   unsigned long yuv_h;
395
396   tiff = TIFFOpen(pathname, "r");
397   if(!tiff) {
398     fprintf(stderr, "%s: error: couldn't open as a tiff file.\n",
399      pathname);
400     return 1;
401   }
402
403   TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &width);
404   TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &height);
405   pixels = width*height;
406   raster = malloc(pixels*sizeof(uint32));
407   if(!raster) {
408     fprintf(stderr, "%s: error: couldn't allocate storage for tiff raster.\n",
409      pathname);
410     TIFFClose(tiff);
411     return 1;
412   }
413   if(!TIFFReadRGBAImage(tiff, width, height, raster, 1)) {
414     fprintf(stderr, "%s: error: couldn't read tiff data.\n", pathname);
415     free(raster);
416     TIFFClose(tiff);
417     return 1;
418   }
419
420   *w = width;
421   *h = height;
422   /* Must hold: yuv_w >= w */
423   yuv_w = (*w + 15) & ~15;
424   /* Must hold: yuv_h >= h */
425   yuv_h = (*h + 15) & ~15;
426
427   /* Do we need to allocate a buffer */
428   if (!ycbcr[0].data){
429     ycbcr[0].width = yuv_w;
430     ycbcr[0].height = yuv_h;
431     ycbcr[0].stride = yuv_w;
432     ycbcr[1].width = (chroma_format == TH_PF_444) ? yuv_w : (yuv_w >> 1);
433     ycbcr[1].stride = ycbcr[1].width;
434     ycbcr[1].height = (chroma_format == TH_PF_420) ? (yuv_h >> 1) : yuv_h;
435     ycbcr[2].width = ycbcr[1].width;
436     ycbcr[2].stride = ycbcr[1].stride;
437     ycbcr[2].height = ycbcr[1].height;
438
439     ycbcr[0].data = malloc(ycbcr[0].stride * ycbcr[0].height);
440     ycbcr[1].data = malloc(ycbcr[1].stride * ycbcr[1].height);
441     ycbcr[2].data = malloc(ycbcr[2].stride * ycbcr[2].height);
442   } else {
443     if ((ycbcr[0].width != yuv_w) || (ycbcr[0].height != yuv_h)){
444       fprintf(stderr, "Input size %lux%lu does not match %dx%d\n", yuv_w,yuv_h,ycbcr[0].width,ycbcr[0].height);
445       exit(1);
446     }
447   }
448
449   rgb_to_yuv(raster, ycbcr, *w, *h);
450
451   _TIFFfree(raster);
452   TIFFClose(tiff);
453
454   return 0;
455 }
456
457 static int include_files (const struct dirent *de)
458 {
459   char name[1024];
460   int number = -1;
461   sscanf(de->d_name, input_filter, &number);
462   sprintf(name, input_filter, number);
463   return !strcmp(name, de->d_name);
464 }
465
466 static int ilog(unsigned _v){
467   int ret;
468   for(ret=0;_v;ret++)_v>>=1;
469   return ret;
470 }
471
472 int
473 main(int argc, char *argv[])
474 {
475   int c,long_option_index;
476   int i, n;
477   char *input_mask;
478   char *input_directory;
479   char *scratch;
480   th_comment       tc;
481   struct dirent **files;
482   int soft_target=0;
483   int ret;
484
485   while(1) {
486
487     c=getopt_long(argc,argv,optstring,options,&long_option_index);
488     if(c == EOF)
489       break;
490
491     switch(c) {
492       case 'h':
493         usage();
494         break;
495       case 'o':
496         option_output = optarg;
497         break;;
498       case 'v':
499         video_quality=rint(atof(optarg)*6.3);
500         if(video_quality<0 || video_quality>63){
501           fprintf(stderr,"Illegal video quality (choose 0 through 10)\n");
502           exit(1);
503         }
504         video_rate=0;
505         break;
506       case 'V':
507         video_rate=rint(atof(optarg)*1000);
508         if(video_rate<1){
509           fprintf(stderr,"Illegal video bitrate (choose > 0 please)\n");
510           exit(1);
511         }
512         video_quality=0;
513        break;
514     case '\1':
515       soft_target=1;
516       break;
517     case 'c':
518       vp3_compatible=1;
519       break;
520     case 'k':
521       keyframe_frequency=rint(atof(optarg));
522       if(keyframe_frequency<1 || keyframe_frequency>2147483647){
523         fprintf(stderr,"Illegal keyframe frequency\n");
524         exit(1);
525       }
526       break;
527
528     case 'd':
529       buf_delay=atoi(optarg);
530       if(buf_delay<=0){
531         fprintf(stderr,"Illegal buffer delay\n");
532         exit(1);
533       }
534       break;
535      case 's':
536        video_aspect_numerator=rint(atof(optarg));
537        break;
538      case 'S':
539        video_aspect_denominator=rint(atof(optarg));
540        break;
541      case 'f':
542        video_fps_numerator=rint(atof(optarg));
543        break;
544      case 'F':
545        video_fps_denominator=rint(atof(optarg));
546        break;
547      case '\5':
548        chroma_format=TH_PF_444;
549        break;
550      case '\6':
551        chroma_format=TH_PF_422;
552        break;
553     case '\2':
554       twopass=3; /* perform both passes */
555       twopass_file=tmpfile();
556       if(!twopass_file){
557         fprintf(stderr,"Unable to open temporary file for twopass data\n");
558         exit(1);
559       }
560       break;
561     case '\3':
562       twopass=1; /* perform first pass */
563       twopass_file=fopen(optarg,"wb");
564       if(!twopass_file){
565         fprintf(stderr,"Unable to open \'%s\' for twopass data\n",optarg);
566         exit(1);
567       }
568       break;
569     case '\4':
570       twopass=2; /* perform second pass */
571       twopass_file=fopen(optarg,"rb");
572       if(!twopass_file){
573         fprintf(stderr,"Unable to open twopass data file \'%s\'",optarg);
574         exit(1);
575       }
576       break;
577      default:
578         usage();
579         break;
580       }
581   }
582
583   if(argc < 3) {
584     usage();
585   }
586
587   if(soft_target){
588     if(video_rate<=0){
589       fprintf(stderr,"Soft rate target (--soft-target) requested without a bitrate (-V).\n");
590       exit(1);
591     }
592     if(video_quality==-1)
593       video_quality=0;
594   }else{
595     if(video_rate>0)
596       video_quality=0;
597     if(video_quality==-1)
598       video_quality=48;
599   }
600
601   if(keyframe_frequency<=0){
602     /*Use a default keyframe frequency of 64 for 1-pass (streaming) mode, and
603        256 for two-pass mode.*/
604     keyframe_frequency=twopass?256:64;
605   }
606
607   input_mask = argv[optind];
608   if (!input_mask) {
609     fprintf(stderr, "no input files specified; run with -h for help.\n");
610     exit(1);
611   }
612   /* dirname and basename must operate on scratch strings */
613   scratch = strdup(input_mask);
614   input_directory = strdup(dirname(scratch));
615   free(scratch);
616   scratch = strdup(input_mask);
617   input_filter = strdup(basename(scratch));
618   free(scratch);
619
620 #ifdef DEBUG
621   fprintf(stderr, "scanning %s with filter '%s'\n",
622   input_directory, input_filter);
623 #endif
624   n = scandir (input_directory, &files, include_files, alphasort);
625
626   if (!n) {
627     fprintf(stderr, "no input files found; run with -h for help.\n");
628     exit(1);
629   }
630
631   ogg_fp = fopen(option_output, "wb");
632   if(!ogg_fp) {
633     fprintf(stderr, "%s: error: %s\n",
634       option_output, "couldn't open output file");
635     return 1;
636   }
637
638   srand(time(NULL));
639   if(ogg_stream_init(&ogg_os, rand())) {
640     fprintf(stderr, "%s: error: %s\n",
641       option_output, "couldn't create ogg stream state");
642     return 1;
643   }
644
645   for(passno=(twopass==3?1:twopass);passno<=(twopass==3?2:twopass);passno++){
646     unsigned int w;
647     unsigned int h;
648     char input_path[1024];
649     th_ycbcr_buffer ycbcr;
650
651     ycbcr[0].data = 0;
652     int last = 0;
653
654     snprintf(input_path, 1023,"%s/%s", input_directory, files[0]->d_name);
655     if(tiff_read(input_path, &w, &h, ycbcr)) {
656       fprintf(stderr, "could not read %s\n", input_path);
657       exit(1);
658     }
659
660     if (passno!=2) fprintf(stderr,"%d frames, %dx%d\n",n,w,h);
661
662     /* setup complete.  Raw processing loop */
663     switch(passno){
664     case 0: case 2:
665       fprintf(stderr,"\rCompressing....                                          \n");
666       break;
667     case 1:
668       fprintf(stderr,"\rScanning first pass....                                  \n");
669       break;
670     }
671
672     fprintf(stderr, "%s\n", input_path);
673
674     th_info_init(&ti);
675     ti.frame_width = ((w + 15) >>4)<<4;
676     ti.frame_height = ((h + 15)>>4)<<4;
677     ti.pic_width = w;
678     ti.pic_height = h;
679     ti.pic_x = 0;
680     ti.pic_y = 0;
681     ti.fps_numerator = video_fps_numerator;
682     ti.fps_denominator = video_fps_denominator;
683     ti.aspect_numerator = video_aspect_numerator;
684     ti.aspect_denominator = video_aspect_denominator;
685     ti.colorspace = TH_CS_UNSPECIFIED;
686     ti.pixel_fmt = chroma_format;
687     ti.target_bitrate = video_rate;
688     ti.quality = video_quality;
689     ti.keyframe_granule_shift=ilog(keyframe_frequency-1);
690
691     td=th_encode_alloc(&ti);
692     th_info_clear(&ti);
693     /* setting just the granule shift only allows power-of-two keyframe
694        spacing.  Set the actual requested spacing. */
695     ret=th_encode_ctl(td,TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
696      &keyframe_frequency,sizeof(keyframe_frequency-1));
697     if(ret<0){
698       fprintf(stderr,"Could not set keyframe interval to %d.\n",(int)keyframe_frequency);
699     }
700     if(vp3_compatible){
701       ret=th_encode_ctl(td,TH_ENCCTL_SET_VP3_COMPATIBLE,&vp3_compatible,
702        sizeof(vp3_compatible));
703       if(ret<0||!vp3_compatible){
704         fprintf(stderr,"Could not enable strict VP3 compatibility.\n");
705         if(ret>=0){
706           fprintf(stderr,"Ensure your source format is supported by VP3.\n");
707           fprintf(stderr,
708            "(4:2:0 pixel format, width and height multiples of 16).\n");
709         }
710       }
711     }
712     if(soft_target){
713       /* reverse the rate control flags to favor a 'long time' strategy */
714       int arg = TH_RATECTL_CAP_UNDERFLOW;
715       ret=th_encode_ctl(td,TH_ENCCTL_SET_RATE_FLAGS,&arg,sizeof(arg));
716       if(ret<0)
717         fprintf(stderr,"Could not set encoder flags for --soft-target\n");
718       /* Default buffer control is overridden on two-pass */
719       if(!twopass&&buf_delay<0){
720         if((keyframe_frequency*7>>1) > 5*video_fps_numerator/video_fps_denominator)
721           arg=keyframe_frequency*7>>1;
722         else
723           arg=5*video_fps_numerator/video_fps_denominator;
724         ret=th_encode_ctl(td,TH_ENCCTL_SET_RATE_BUFFER,&arg,sizeof(arg));
725         if(ret<0)
726           fprintf(stderr,"Could not set rate control buffer for --soft-target\n");
727       }
728     }
729     /* set up two-pass if needed */
730     if(passno==1){
731       unsigned char *buffer;
732       int bytes;
733       bytes=th_encode_ctl(td,TH_ENCCTL_2PASS_OUT,&buffer,sizeof(buffer));
734       if(bytes<0){
735         fprintf(stderr,"Could not set up the first pass of two-pass mode.\n");
736         fprintf(stderr,"Did you remember to specify an estimated bitrate?\n");
737         exit(1);
738       }
739       /*Perform a seek test to ensure we can overwrite this placeholder data at
740          the end; this is better than letting the user sit through a whole
741          encode only to find out their pass 1 file is useless at the end.*/
742       if(fseek(twopass_file,0,SEEK_SET)<0){
743         fprintf(stderr,"Unable to seek in two-pass data file.\n");
744         exit(1);
745       }
746       if(fwrite(buffer,1,bytes,twopass_file)<bytes){
747         fprintf(stderr,"Unable to write to two-pass data file.\n");
748         exit(1);
749       }
750       fflush(twopass_file);
751     }
752     if(passno==2){
753       /*Enable the second pass here.
754         We make this call just to set the encoder into 2-pass mode, because
755          by default enabling two-pass sets the buffer delay to the whole file
756          (because there's no way to explicitly request that behavior).
757         If we waited until we were actually encoding, it would overwite our
758          settings.*/
759       if(th_encode_ctl(td,TH_ENCCTL_2PASS_IN,NULL,0)<0){
760         fprintf(stderr,"Could not set up the second pass of two-pass mode.\n");
761         exit(1);
762       }
763       if(twopass==3){
764         if(fseek(twopass_file,0,SEEK_SET)<0){
765           fprintf(stderr,"Unable to seek in two-pass data file.\n");
766           exit(1);
767         }
768       }
769     }
770     /*Now we can set the buffer delay if the user requested a non-default one
771        (this has to be done after two-pass is enabled).*/
772     if(passno!=1&&buf_delay>=0){
773       ret=th_encode_ctl(td,TH_ENCCTL_SET_RATE_BUFFER,
774        &buf_delay,sizeof(buf_delay));
775       if(ret<0){
776         fprintf(stderr,"Warning: could not set desired buffer delay.\n");
777       }
778     }
779     /* write the bitstream header packets with proper page interleave */
780     th_comment_init(&tc);
781     /* first packet will get its own page automatically */
782     if(th_encode_flushheader(td,&tc,&op)<=0){
783       fprintf(stderr,"Internal Theora library error.\n");
784       exit(1);
785     }
786     th_comment_clear(&tc);
787     if(passno!=1){
788       ogg_stream_packetin(&ogg_os,&op);
789       if(ogg_stream_pageout(&ogg_os,&og)!=1){
790         fprintf(stderr,"Internal Ogg library error.\n");
791         exit(1);
792       }
793       fwrite(og.header,1,og.header_len,ogg_fp);
794       fwrite(og.body,1,og.body_len,ogg_fp);
795     }
796     /* create the remaining theora headers */
797     for(;;){
798       ret=th_encode_flushheader(td,&tc,&op);
799       if(ret<0){
800         fprintf(stderr,"Internal Theora library error.\n");
801         exit(1);
802       }
803       else if(!ret)break;
804       if(passno!=1)ogg_stream_packetin(&ogg_os,&op);
805     }
806     /* Flush the rest of our headers. This ensures
807        the actual data in each stream will start
808        on a new page, as per spec. */
809     if(passno!=1){
810       for(;;){
811         int result = ogg_stream_flush(&ogg_os,&og);
812         if(result<0){
813           /* can't get here */
814           fprintf(stderr,"Internal Ogg library error.\n");
815           exit(1);
816         }
817         if(result==0)break;
818         fwrite(og.header,1,og.header_len,ogg_fp);
819         fwrite(og.body,1,og.body_len,ogg_fp);
820       }
821     }
822
823     i=0; last=0;
824     do {
825       if(i >= n-1) last = 1;
826       if(theora_write_frame(ycbcr, last)) {
827           fprintf(stderr,"Encoding error.\n");
828         exit(1);
829       }
830
831       i++;
832       if (!last) {
833         snprintf(input_path, 1023,"%s/%s", input_directory, files[i]->d_name);
834         if(tiff_read(input_path, &w, &h, ycbcr)) {
835           fprintf(stderr, "could not read %s\n", input_path);
836           exit(1);
837         }
838        fprintf(stderr, "%s\n", input_path);
839       }
840     } while (!last);
841
842     if(passno==1){
843       /* need to read the final (summary) packet */
844       unsigned char *buffer;
845       int bytes = th_encode_ctl(td, TH_ENCCTL_2PASS_OUT, &buffer, sizeof(buffer));
846       if(bytes<0){
847         fprintf(stderr,"Could not read two-pass summary data from encoder.\n");
848         exit(1);
849       }
850       if(fseek(twopass_file,0,SEEK_SET)<0){
851         fprintf(stderr,"Unable to seek in two-pass data file.\n");
852         exit(1);
853       }
854       if(fwrite(buffer,1,bytes,twopass_file)<bytes){
855         fprintf(stderr,"Unable to write to two-pass data file.\n");
856         exit(1);
857       }
858       fflush(twopass_file);
859     }
860     th_encode_free(td);
861     free(ycbcr[0].data);
862     free(ycbcr[1].data);
863     free(ycbcr[2].data);
864   }
865
866   if(ogg_stream_flush(&ogg_os, &og)) {
867     fwrite(og.header, og.header_len, 1, ogg_fp);
868     fwrite(og.body, og.body_len, 1, ogg_fp);
869   }
870
871   free(input_directory);
872   free(input_filter);
873
874   while (n--) free(files[n]);
875   free(files);
876
877   if(ogg_fp){
878     fflush(ogg_fp);
879     if(ogg_fp!=stdout)fclose(ogg_fp);
880   }
881
882   ogg_stream_clear(&ogg_os);
883   if(twopass_file)fclose(twopass_file);
884   fprintf(stderr,"\r   \ndone.\n\n");
885
886   return 0;
887 }