spec: Use %license macro to copy license
[platform/upstream/libtheora.git] / examples / png2theora.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-2009,2009           *
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 png images
15   last mod: $Id: png2theora.c 16503 2009-08-22 18:14:02Z giles $
16              based on code from Vegard Nossum
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 <png.h>
39 #include <ogg/ogg.h>
40 #include "theora/theoraenc.h"
41
42 #define PROGRAM_NAME  "png2theora"
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.png to look for files file000001.png to file9999999.png \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(unsigned long w, unsigned long h, unsigned char *yuv, int last)
192 {
193   th_ycbcr_buffer ycbcr;
194   ogg_packet op;
195   ogg_page og;
196
197   unsigned long yuv_w;
198   unsigned long yuv_h;
199
200   unsigned char *yuv_y;
201   unsigned char *yuv_u;
202   unsigned char *yuv_v;
203
204   unsigned int x;
205   unsigned int y;
206
207   /* Must hold: yuv_w >= w */
208   yuv_w = (w + 15) & ~15;
209
210   /* Must hold: yuv_h >= h */
211   yuv_h = (h + 15) & ~15;
212
213   ycbcr[0].width = yuv_w;
214   ycbcr[0].height = yuv_h;
215   ycbcr[0].stride = yuv_w;
216   ycbcr[1].width = (chroma_format == TH_PF_444) ? yuv_w : (yuv_w >> 1);
217   ycbcr[1].stride = ycbcr[1].width;
218   ycbcr[1].height = (chroma_format == TH_PF_420) ? (yuv_h >> 1) : yuv_h;
219   ycbcr[2].width = ycbcr[1].width;
220   ycbcr[2].stride = ycbcr[1].stride;
221   ycbcr[2].height = ycbcr[1].height;
222
223   ycbcr[0].data = yuv_y = malloc(ycbcr[0].stride * ycbcr[0].height);
224   ycbcr[1].data = yuv_u = malloc(ycbcr[1].stride * ycbcr[1].height);
225   ycbcr[2].data = yuv_v = malloc(ycbcr[2].stride * ycbcr[2].height);
226
227   for(y = 0; y < h; y++) {
228     for(x = 0; x < w; x++) {
229       yuv_y[x + y * yuv_w] = yuv[3 * (x + y * w) + 0];
230     }
231   }
232
233   if (chroma_format == TH_PF_420) {
234     for(y = 0; y < h; y += 2) {
235       for(x = 0; x < w; x += 2) {
236         yuv_u[(x >> 1) + (y >> 1) * (yuv_w >> 1)] =
237           yuv[3 * (x + y * w) + 1];
238         yuv_v[(x >> 1) + (y >> 1) * (yuv_w >> 1)] =
239           yuv[3 * (x + y * w) + 2];
240       }
241     }
242   } else if (chroma_format == TH_PF_444) {
243     for(y = 0; y < h; y++) {
244       for(x = 0; x < w; x++) {
245         yuv_u[x + y * ycbcr[1].stride] = yuv[3 * (x + y * w) + 1];
246         yuv_v[x + y * ycbcr[2].stride] = yuv[3 * (x + y * w) + 2];
247       }
248     }
249   } else {  /* TH_PF_422 */
250     for(y = 0; y < h; y += 1) {
251       for(x = 0; x < w; x += 2) {
252         yuv_u[(x >> 1) + y * ycbcr[1].stride] =
253           yuv[3 * (x + y * w) + 1];
254         yuv_v[(x >> 1) + y * ycbcr[2].stride] =
255           yuv[3 * (x + y * w) + 2];
256       }
257     }    
258   }
259
260   /* Theora is a one-frame-in,one-frame-out system; submit a frame
261      for compression and pull out the packet */
262   /* in two-pass mode's second pass, we need to submit first-pass data */
263   if(passno==2){
264     int ret;
265     for(;;){
266       static unsigned char buffer[80];
267       static int buf_pos;
268       int bytes;
269       /*Ask the encoder how many bytes it would like.*/
270       bytes=th_encode_ctl(td,TH_ENCCTL_2PASS_IN,NULL,0);
271       if(bytes<0){
272         fprintf(stderr,"Error submitting pass data in second pass.\n");
273         exit(1);
274       }
275       /*If it's got enough, stop.*/
276       if(bytes==0)break;
277       /*Read in some more bytes, if necessary.*/
278       if(bytes>80-buf_pos)bytes=80-buf_pos;
279       if(bytes>0&&fread(buffer+buf_pos,1,bytes,twopass_file)<bytes){
280         fprintf(stderr,"Could not read frame data from two-pass data file!\n");
281         exit(1);
282       }
283       /*And pass them off.*/
284       ret=th_encode_ctl(td,TH_ENCCTL_2PASS_IN,buffer,bytes);
285       if(ret<0){
286         fprintf(stderr,"Error submitting pass data in second pass.\n");
287         exit(1);
288       }
289       /*If the encoder consumed the whole buffer, reset it.*/
290       if(ret>=bytes)buf_pos=0;
291       /*Otherwise remember how much it used.*/
292       else buf_pos+=ret;
293     }
294   }
295
296   if(th_encode_ycbcr_in(td, ycbcr)) {
297     fprintf(stderr, "%s: error: could not encode frame\n",
298       option_output);
299     return 1;
300   }
301
302   /* in two-pass mode's first pass we need to extract and save the pass data */
303   if(passno==1){
304     unsigned char *buffer;
305     int bytes = th_encode_ctl(td, TH_ENCCTL_2PASS_OUT, &buffer, sizeof(buffer));
306     if(bytes<0){
307       fprintf(stderr,"Could not read two-pass data from encoder.\n");
308       exit(1);
309     }
310     if(fwrite(buffer,1,bytes,twopass_file)<bytes){
311       fprintf(stderr,"Unable to write to two-pass data file.\n");
312       exit(1);
313     }
314     fflush(twopass_file);
315   }
316
317   if(!th_encode_packetout(td, last, &op)) {
318     fprintf(stderr, "%s: error: could not read packets\n",
319       option_output);
320     return 1;
321   }
322
323   if (passno!=1) { 
324     ogg_stream_packetin(&ogg_os, &op);
325     while(ogg_stream_pageout(&ogg_os, &og)) {
326       fwrite(og.header, og.header_len, 1, ogg_fp);
327       fwrite(og.body, og.body_len, 1, ogg_fp);
328     }
329   }  
330
331   free(yuv_y);
332   free(yuv_u);
333   free(yuv_v);
334
335   return 0;
336 }
337
338 static unsigned char
339 clamp(double d)
340 {
341   if(d < 0)
342     return 0;
343
344   if(d > 255)
345     return 255;
346
347   return d;
348 }
349
350 static void
351 rgb_to_yuv(png_bytep *png,
352            unsigned char *yuv,
353            unsigned int w, unsigned int h)
354 {
355   unsigned int x;
356   unsigned int y;
357
358   for(y = 0; y < h; y++) {
359     for(x = 0; x < w; x++) {
360       png_byte r;
361       png_byte g;
362       png_byte b;
363
364       r = png[y][3 * x + 0];
365       g = png[y][3 * x + 1];
366       b = png[y][3 * x + 2];
367
368       /* XXX: Cringe. */
369       yuv[3 * (x + w * y) + 0] = clamp(
370         0.299 * r
371         + 0.587 * g
372         + 0.114 * b);
373       yuv[3 * (x + w * y) + 1] = clamp((0.436 * 255
374         - 0.14713 * r
375         - 0.28886 * g
376         + 0.436 * b) / 0.872);
377       yuv[3 * (x + w * y) + 2] = clamp((0.615 * 255
378         + 0.615 * r
379         - 0.51499 * g
380         - 0.10001 * b) / 1.230);
381     }
382   }
383 }
384
385 static int
386 png_read(const char *pathname, unsigned int *w, unsigned int *h, unsigned char **yuv)
387 {
388   FILE *fp;
389   unsigned char header[8];
390   png_structp png_ptr;
391   png_infop info_ptr;
392   png_infop end_ptr;
393   png_bytep row_data;
394   png_bytep *row_pointers;
395   png_color_16p bkgd;
396   png_uint_32 width;
397   png_uint_32 height;
398   int bit_depth;
399   int color_type;
400   int interlace_type;
401   int compression_type;
402   int filter_method;
403   png_uint_32 y;
404
405   fp = fopen(pathname, "rb");
406   if(!fp) {
407     fprintf(stderr, "%s: error: %s\n",
408       pathname, strerror(errno));
409     return 1;
410   }
411
412   fread(header, 1, 8, fp);
413   if(png_sig_cmp(header, 0, 8)) {
414     fprintf(stderr, "%s: error: %s\n",
415       pathname, "not a PNG");
416     fclose(fp);
417     return 1;
418   }
419
420   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
421     NULL, NULL, NULL);
422   if(!png_ptr) {
423     fprintf(stderr, "%s: error: %s\n",
424       pathname, "couldn't create png read structure");
425     fclose(fp);
426     return 1;
427   }
428
429   info_ptr = png_create_info_struct(png_ptr);
430   if(!info_ptr) {
431     fprintf(stderr, "%s: error: %s\n",
432       pathname, "couldn't create png info structure");
433     png_destroy_read_struct(&png_ptr, NULL, NULL);
434     fclose(fp);
435     return 1;
436   }
437
438   end_ptr = png_create_info_struct(png_ptr);
439   if(!end_ptr) {
440     fprintf(stderr, "%s: error: %s\n",
441       pathname, "couldn't create png info structure");
442     png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
443     fclose(fp);
444     return 1;
445   }
446
447   png_init_io(png_ptr, fp);
448   png_set_sig_bytes(png_ptr, 8);
449   png_read_info(png_ptr, info_ptr);
450   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
451    &interlace_type, &compression_type, &filter_method);
452   png_set_expand(png_ptr);
453   if(bit_depth<8)png_set_packing(png_ptr);
454   if(bit_depth==16)png_set_strip_16(png_ptr);
455   if(!(color_type&PNG_COLOR_MASK_COLOR))png_set_gray_to_rgb(png_ptr);
456   if(png_get_bKGD(png_ptr, info_ptr, &bkgd)){
457     png_set_background(png_ptr, bkgd, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
458   }
459   /*Note that color_type 2 and 3 can also have alpha, despite not setting the
460      PNG_COLOR_MASK_ALPHA bit.
461     We always strip it to prevent libpng from overrunning our buffer.*/
462   png_set_strip_alpha(png_ptr);
463
464   row_data = (png_bytep)png_malloc(png_ptr,
465     3*height*width*png_sizeof(*row_data));
466   row_pointers = (png_bytep *)png_malloc(png_ptr,
467     height*png_sizeof(*row_pointers));
468   for(y = 0; y < height; y++) {
469     row_pointers[y] = row_data + y*(3*width);
470   }
471   png_read_image(png_ptr, row_pointers);
472   png_read_end(png_ptr, end_ptr);
473
474   *w = width;
475   *h = height;
476   *yuv = malloc(*w * *h * 3);
477   rgb_to_yuv(row_pointers, *yuv, *w, *h);
478
479   png_free(png_ptr, row_pointers);
480   png_free(png_ptr, row_data);
481   png_destroy_read_struct(&png_ptr, &info_ptr, &end_ptr);
482
483   fclose(fp);
484   return 0;
485 }
486
487 static int include_files (const struct dirent *de)
488 {
489   char name[1024];
490   int number = -1;
491   sscanf(de->d_name, input_filter, &number);
492   sprintf(name, input_filter, number);
493   return !strcmp(name, de->d_name);
494 }
495
496 static int ilog(unsigned _v){
497   int ret;
498   for(ret=0;_v;ret++)_v>>=1;
499   return ret;
500 }
501       
502 int
503 main(int argc, char *argv[])
504 {
505   int c,long_option_index;
506   int i, n;
507   char *input_mask;
508   char *input_directory;
509   char *scratch;
510   th_comment       tc;
511   struct dirent **png_files;
512   int soft_target=0;
513   int ret;
514       
515   while(1) {
516
517     c=getopt_long(argc,argv,optstring,options,&long_option_index);
518     if(c == EOF)
519       break;
520
521     switch(c) {
522       case 'h':
523         usage();
524         break;
525       case 'o':
526         option_output = optarg;
527         break;;
528       case 'v':
529         video_quality=rint(atof(optarg)*6.3);
530         if(video_quality<0 || video_quality>63){
531           fprintf(stderr,"Illegal video quality (choose 0 through 10)\n");
532           exit(1);
533         }
534         video_rate=0;
535         break;
536       case 'V':
537         video_rate=rint(atof(optarg)*1000);
538         if(video_rate<1){
539           fprintf(stderr,"Illegal video bitrate (choose > 0 please)\n");
540           exit(1);
541         }
542         video_quality=0;
543        break;
544     case '\1':
545       soft_target=1;
546       break;
547     case 'c':
548       vp3_compatible=1;
549       break;
550     case 'k':
551       keyframe_frequency=rint(atof(optarg));
552       if(keyframe_frequency<1 || keyframe_frequency>2147483647){
553         fprintf(stderr,"Illegal keyframe frequency\n");
554         exit(1);
555       }
556       break;
557
558     case 'd':
559       buf_delay=atoi(optarg);
560       if(buf_delay<=0){
561         fprintf(stderr,"Illegal buffer delay\n");
562         exit(1);
563       }
564       break;
565      case 's':
566        video_aspect_numerator=rint(atof(optarg));
567        break;
568      case 'S':
569        video_aspect_denominator=rint(atof(optarg));
570        break;
571      case 'f':
572        video_fps_numerator=rint(atof(optarg));
573        break;
574      case 'F':
575        video_fps_denominator=rint(atof(optarg));
576        break;
577      case '\5':
578        chroma_format=TH_PF_444;
579        break;
580      case '\6':
581        chroma_format=TH_PF_422;
582        break;
583     case '\2':
584       twopass=3; /* perform both passes */
585       twopass_file=tmpfile();
586       if(!twopass_file){
587         fprintf(stderr,"Unable to open temporary file for twopass data\n");
588         exit(1);
589       }
590       break;
591     case '\3':
592       twopass=1; /* perform first pass */
593       twopass_file=fopen(optarg,"wb");
594       if(!twopass_file){
595         fprintf(stderr,"Unable to open \'%s\' for twopass data\n",optarg);
596         exit(1);
597       }
598       break;
599     case '\4':
600       twopass=2; /* perform second pass */
601       twopass_file=fopen(optarg,"rb");
602       if(!twopass_file){
603         fprintf(stderr,"Unable to open twopass data file \'%s\'",optarg);
604         exit(1);
605       }
606       break;
607      default:
608         usage();
609         break;
610       }
611   }
612
613   if(argc < 3) {
614     usage();
615   }
616
617   if(soft_target){
618     if(video_rate<=0){
619       fprintf(stderr,"Soft rate target (--soft-target) requested without a bitrate (-V).\n");
620       exit(1);
621     }
622     if(video_quality==-1)
623       video_quality=0;
624   }else{
625     if(video_rate>0)
626       video_quality=0;
627     if(video_quality==-1)
628       video_quality=48;
629   }
630
631   if(keyframe_frequency<=0){
632     /*Use a default keyframe frequency of 64 for 1-pass (streaming) mode, and
633        256 for two-pass mode.*/
634     keyframe_frequency=twopass?256:64;
635   }
636
637   input_mask = argv[optind];
638   if (!input_mask) {
639     fprintf(stderr, "no input files specified; run with -h for help.\n");
640     exit(1);
641   }
642   /* dirname and basename must operate on scratch strings */
643   scratch = strdup(input_mask);
644   input_directory = strdup(dirname(scratch));
645   free(scratch);
646   scratch = strdup(input_mask);
647   input_filter = strdup(basename(scratch));
648   free(scratch);
649
650 #ifdef DEBUG
651   fprintf(stderr, "scanning %s with filter '%s'\n",
652   input_directory, input_filter);
653 #endif
654   n = scandir (input_directory, &png_files, include_files, alphasort);
655
656   if (!n) {
657     fprintf(stderr, "no input files found; run with -h for help.\n");
658     exit(1);
659   }
660
661   ogg_fp = fopen(option_output, "wb");
662   if(!ogg_fp) {
663     fprintf(stderr, "%s: error: %s\n",
664       option_output, "couldn't open output file");
665     return 1;
666   }
667
668   srand(time(NULL));
669   if(ogg_stream_init(&ogg_os, rand())) {
670     fprintf(stderr, "%s: error: %s\n",
671       option_output, "couldn't create ogg stream state");
672     return 1;
673   }
674
675   for(passno=(twopass==3?1:twopass);passno<=(twopass==3?2:twopass);passno++){
676     unsigned int w;
677     unsigned int h;
678     unsigned char *yuv;
679     char input_png[1024];
680     int last = 0;
681
682     snprintf(input_png, 1023,"%s/%s", input_directory, png_files[0]->d_name);
683     if(png_read(input_png, &w, &h, &yuv)) {
684       fprintf(stderr, "could not read %s\n", input_png);
685       exit(1);
686     }
687
688     if (passno!=2) fprintf(stderr,"%d frames, %dx%d\n",n,w,h);    
689
690     /* setup complete.  Raw processing loop */
691     switch(passno){
692     case 0: case 2:
693       fprintf(stderr,"\rCompressing....                                          \n");
694       break;
695     case 1:
696       fprintf(stderr,"\rScanning first pass....                                  \n");
697       break;
698     }
699
700     fprintf(stderr, "%s\n", input_png); 
701
702     th_info_init(&ti);    
703     ti.frame_width = ((w + 15) >>4)<<4;
704     ti.frame_height = ((h + 15)>>4)<<4;
705     ti.pic_width = w;
706     ti.pic_height = h;
707     ti.pic_x = 0;
708     ti.pic_y = 0;
709     ti.fps_numerator = video_fps_numerator;
710     ti.fps_denominator = video_fps_denominator;
711     ti.aspect_numerator = video_aspect_numerator;
712     ti.aspect_denominator = video_aspect_denominator;
713     ti.colorspace = TH_CS_UNSPECIFIED;
714     ti.pixel_fmt = chroma_format;
715     ti.target_bitrate = video_rate;
716     ti.quality = video_quality;
717     ti.keyframe_granule_shift=ilog(keyframe_frequency-1);
718
719     td=th_encode_alloc(&ti);  
720     th_info_clear(&ti);
721     /* setting just the granule shift only allows power-of-two keyframe
722        spacing.  Set the actual requested spacing. */
723     ret=th_encode_ctl(td,TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
724      &keyframe_frequency,sizeof(keyframe_frequency-1));
725     if(ret<0){
726       fprintf(stderr,"Could not set keyframe interval to %d.\n",(int)keyframe_frequency);
727     }
728     if(vp3_compatible){
729       ret=th_encode_ctl(td,TH_ENCCTL_SET_VP3_COMPATIBLE,&vp3_compatible,
730        sizeof(vp3_compatible));
731       if(ret<0||!vp3_compatible){
732         fprintf(stderr,"Could not enable strict VP3 compatibility.\n");
733         if(ret>=0){
734           fprintf(stderr,"Ensure your source format is supported by VP3.\n");
735           fprintf(stderr,
736            "(4:2:0 pixel format, width and height multiples of 16).\n");
737         }
738       }
739     }
740     if(soft_target){
741       /* reverse the rate control flags to favor a 'long time' strategy */
742       int arg = TH_RATECTL_CAP_UNDERFLOW;
743       ret=th_encode_ctl(td,TH_ENCCTL_SET_RATE_FLAGS,&arg,sizeof(arg));
744       if(ret<0)
745         fprintf(stderr,"Could not set encoder flags for --soft-target\n");
746       /* Default buffer control is overridden on two-pass */
747       if(!twopass&&buf_delay<0){
748         if((keyframe_frequency*7>>1) > 5*video_fps_numerator/video_fps_denominator)
749           arg=keyframe_frequency*7>>1;
750         else
751           arg=5*video_fps_numerator/video_fps_denominator;
752         ret=th_encode_ctl(td,TH_ENCCTL_SET_RATE_BUFFER,&arg,sizeof(arg));
753         if(ret<0)
754           fprintf(stderr,"Could not set rate control buffer for --soft-target\n");
755       }
756     }
757     /* set up two-pass if needed */
758     if(passno==1){
759       unsigned char *buffer;
760       int bytes;
761       bytes=th_encode_ctl(td,TH_ENCCTL_2PASS_OUT,&buffer,sizeof(buffer));
762       if(bytes<0){
763         fprintf(stderr,"Could not set up the first pass of two-pass mode.\n");
764         fprintf(stderr,"Did you remember to specify an estimated bitrate?\n");
765         exit(1);
766       }
767       /*Perform a seek test to ensure we can overwrite this placeholder data at
768          the end; this is better than letting the user sit through a whole
769          encode only to find out their pass 1 file is useless at the end.*/
770       if(fseek(twopass_file,0,SEEK_SET)<0){
771         fprintf(stderr,"Unable to seek in two-pass data file.\n");
772         exit(1);
773       }
774       if(fwrite(buffer,1,bytes,twopass_file)<bytes){
775         fprintf(stderr,"Unable to write to two-pass data file.\n");
776         exit(1);
777       }
778       fflush(twopass_file);
779     }
780     if(passno==2){
781       /*Enable the second pass here.
782         We make this call just to set the encoder into 2-pass mode, because
783          by default enabling two-pass sets the buffer delay to the whole file
784          (because there's no way to explicitly request that behavior).
785         If we waited until we were actually encoding, it would overwite our
786          settings.*/
787       if(th_encode_ctl(td,TH_ENCCTL_2PASS_IN,NULL,0)<0){
788         fprintf(stderr,"Could not set up the second pass of two-pass mode.\n");
789         exit(1);
790       }
791       if(twopass==3){
792         if(fseek(twopass_file,0,SEEK_SET)<0){
793           fprintf(stderr,"Unable to seek in two-pass data file.\n");
794           exit(1);
795         }
796       }
797     }
798     /*Now we can set the buffer delay if the user requested a non-default one
799        (this has to be done after two-pass is enabled).*/
800     if(passno!=1&&buf_delay>=0){
801       ret=th_encode_ctl(td,TH_ENCCTL_SET_RATE_BUFFER,
802        &buf_delay,sizeof(buf_delay));
803       if(ret<0){
804         fprintf(stderr,"Warning: could not set desired buffer delay.\n");
805       }
806     }
807     /* write the bitstream header packets with proper page interleave */
808     th_comment_init(&tc);
809     /* first packet will get its own page automatically */
810     if(th_encode_flushheader(td,&tc,&op)<=0){
811       fprintf(stderr,"Internal Theora library error.\n");
812       exit(1); 
813     }
814     th_comment_clear(&tc);
815     if(passno!=1){
816       ogg_stream_packetin(&ogg_os,&op);
817       if(ogg_stream_pageout(&ogg_os,&og)!=1){
818         fprintf(stderr,"Internal Ogg library error.\n");
819         exit(1);
820       }
821       fwrite(og.header,1,og.header_len,ogg_fp);
822       fwrite(og.body,1,og.body_len,ogg_fp);
823     }
824     /* create the remaining theora headers */
825     for(;;){
826       ret=th_encode_flushheader(td,&tc,&op);
827       if(ret<0){
828         fprintf(stderr,"Internal Theora library error.\n");
829         exit(1);
830       }
831       else if(!ret)break;
832       if(passno!=1)ogg_stream_packetin(&ogg_os,&op);
833     }
834     /* Flush the rest of our headers. This ensures
835        the actual data in each stream will start
836        on a new page, as per spec. */
837     if(passno!=1){
838       for(;;){
839         int result = ogg_stream_flush(&ogg_os,&og);
840         if(result<0){
841           /* can't get here */
842           fprintf(stderr,"Internal Ogg library error.\n");
843           exit(1);
844         }
845         if(result==0)break;
846         fwrite(og.header,1,og.header_len,ogg_fp);
847         fwrite(og.body,1,og.body_len,ogg_fp);
848       }
849     }
850
851     i=0; last=0;
852     do {
853       if(i >= n-1) last = 1;
854       if(theora_write_frame(w, h, yuv, last)) {
855           fprintf(stderr,"Encoding error.\n");
856         exit(1);
857       }
858       free(yuv);    
859       i++;
860       if (!last) {
861         snprintf(input_png, 1023,"%s/%s", input_directory, png_files[i]->d_name);
862         if(png_read(input_png, &w, &h, &yuv)) {
863           fprintf(stderr, "could not read %s\n", input_png);
864           exit(1);
865         }
866        fprintf(stderr, "%s\n", input_png);
867       }      
868     } while (!last);
869
870     if(passno==1){
871       /* need to read the final (summary) packet */
872       unsigned char *buffer;
873       int bytes = th_encode_ctl(td, TH_ENCCTL_2PASS_OUT, &buffer, sizeof(buffer));
874       if(bytes<0){
875         fprintf(stderr,"Could not read two-pass summary data from encoder.\n");
876         exit(1);
877       }
878       if(fseek(twopass_file,0,SEEK_SET)<0){
879         fprintf(stderr,"Unable to seek in two-pass data file.\n");
880         exit(1);
881       }
882       if(fwrite(buffer,1,bytes,twopass_file)<bytes){
883         fprintf(stderr,"Unable to write to two-pass data file.\n");
884         exit(1);
885       }
886       fflush(twopass_file);
887     }
888     th_encode_free(td);
889   }
890
891   if(ogg_stream_flush(&ogg_os, &og)) {
892     fwrite(og.header, og.header_len, 1, ogg_fp);
893     fwrite(og.body, og.body_len, 1, ogg_fp);
894   }            
895
896   free(input_directory);
897   free(input_filter);
898
899   while (n--) free(png_files[n]);
900   free(png_files);  
901
902   if(ogg_fp){
903     fflush(ogg_fp);
904     if(ogg_fp!=stdout)fclose(ogg_fp);
905   }
906
907   ogg_stream_clear(&ogg_os);
908   if(twopass_file)fclose(twopass_file);
909   fprintf(stderr,"\r   \ndone.\n\n");
910
911   return 0;
912 }