8 #include "../lib/darray.h"
9 #include "../lib/colorize.h"
13 #include "dir_seperator.h"
15 #include "opticalflow.h"
18 #define min(x,y) ((x < y) ? x : y)
20 static void print_help(const char *app);
21 static void print_test_help();
24 //#define SINGLE_K_TEST 2
33 static struct sequence *sequence = NULL;
35 /* load sequence list and return number of images in sequence */
36 static int load_sequence(int *start, int *next, char *first_filename)
38 const char *name = "sequence";
40 int i, j, keyframe_before_start, eof;
44 /* free previously used sequence */
50 /* get number of frames until next keyframe or end of squence */
51 fp = fopen(name, "r");
53 printf("failed to load sequence '%s'\n", name);
59 keyframe_before_start = 0;
60 while(fgets(buffer, sizeof(buffer), fp)) {
61 p = strchr(buffer + 1, '\"');
66 strcpy(first_filename, buffer + 1);
68 if ((*start) && j == (*start) - 1) {
69 if (strstr(p, "keyframe"))
70 keyframe_before_start = 1;
77 printf("counting %d\n", j);
81 /* skip start frame, since it is always a keyframe */
84 if (strstr(p, "keyframe")) {
91 /* end of file case */
100 #ifdef DEBUG_SEQUENCE
104 #ifdef DEBUG_SEQUENCE
105 puts("end of file at last frame");
110 /* we are done, because we already had the last sequence */
111 if (!keyframe_before_start) {
112 #ifdef DEBUG_SEQUENCE
113 puts("no keyframe before start");
118 #ifdef DEBUG_SEQUENCE
119 puts("keyframe before start");
121 /* we just have a single last frame */
123 (*next) = (*start) + 1;
125 /* if we have two keyframes side by side, we ignore it */
126 if (count == 2 && !eof) {
127 #ifdef DEBUG_SEQUENCE
130 /* only if the frame before start is not a keyframe
131 * and we are not the first sequence, because that would mean
132 * that the first frame is a single sequence */
133 if (!keyframe_before_start && (*start) > 0) {
134 #ifdef DEBUG_SEQUENCE
135 puts("no keyframe before start");
140 #ifdef DEBUG_SEQUENCE
141 puts("keyframe before start or first frame");
143 /* now the start frame has one keyframe before and one after */
145 (*next) = (*start) + 1;
147 (*next) = (*start) + count - 1;
150 /* alloc memory for sequence and fill with data */
151 sequence = (struct sequence *)malloc(sizeof(struct sequence) * count);
153 printf("no memory for sequence\n");
156 memset((struct sequence *)sequence, 0, sizeof(struct sequence) * count);
157 fp = fopen(name, "r");
159 printf("failed to load sequence '%s'\n", name);
164 while(fgets(buffer, sizeof(buffer), fp)) {
165 p = strchr(buffer + 1, '\"');
173 strcpy(sequence[i].filename, buffer + 1);
187 /* scale down image in img_buffer by calculating average */
188 static void scale_img(unsigned short *img_buffer, int width, int height, int scale)
190 int w, h, i, j, x, y;
199 for (i = 0; i < h; i++) {
200 for (j = 0; j < w; j++) {
202 for (y = 0; y < scale; y++) {
203 for (x = 0; x < scale; x++) {
204 r += img_buffer[((i*scale+y) * width + j*scale+x) * 3 + 0];
205 g += img_buffer[((i*scale+y) * width + j*scale+x) * 3 + 1];
206 b += img_buffer[((i*scale+y) * width + j*scale+x) * 3 + 2];
209 img_buffer[(i * w + j)*3 + 0] = r / scale / scale;
210 img_buffer[(i * w + j)*3 + 1] = g / scale / scale;
211 img_buffer[(i * w + j)*3 + 2] = b / scale / scale;
216 /* scale down mark map in mark_buffer */
217 static void scale_mark(unsigned char *mark_buffer, int width, int height, int scale)
219 int w, h, i, j, x, y;
220 unsigned char c, temp;
228 for (i = 0; i < h; i++) {
229 for (j = 0; j < w; j++) {
231 /* always use one index other than 0, if there is any in an areaa to be shrinked */
232 for (y = 0; y < scale; y++) {
233 for (x = 0; x < scale; x++) {
234 temp = mark_buffer[(i*scale+y) * width + j*scale+x];
239 mark_buffer[i * w + j] = c;
248 static int in_itr_num = 5, out_itr_num = 1, optical_flow = 1, bright_contrast = 1;
249 int scale = 1, scalexyz = 999;
262 static int parse_test(const char *arg)
264 if (!strcmp(arg, "help")) {
269 if (!strcmp(arg, "flow-next"))
271 if (!strcmp(arg, "flow-prev"))
274 if (!strcmp(arg, "marked"))
276 if (!strcmp(arg, "mask"))
278 if (!strcmp(arg, "mask+color"))
280 if (!strcmp(arg, "bc-only"))
282 if (!strcmp(arg, "bc-image"))
288 static int handle_options(int argc, char **argv)
293 int option_index = 0, c;
294 static struct option long_options[] = {
296 {"depth", 1, 0, 'd'},
297 {"in-itr-num", 1, 0, 'i'},
298 {"out-itr-num", 1, 0, 'o'},
299 {"zscale", 1, 0, 'z'},
300 {"brightness-contrast", 1, 0, 'b'},
301 {"optical-flow", 1, 0, 'f'},
302 {"scale", 1, 0, 's'},
307 c = getopt_long(argc, argv, "hd:i:o:z:b:f:s:t:", long_options, &option_index);
317 save_depth = atoi(optarg);
321 in_itr_num = atoi(optarg);
325 out_itr_num = atoi(optarg);
329 scalexyz = atoi(optarg);
333 bright_contrast = atoi(optarg);
337 optical_flow = atoi(optarg);
341 scale = atoi(optarg);
345 test = parse_test(optarg);
347 fprintf(stderr, "Invalid test '%s', use '--test help' to get a list of tests\n", optarg);
364 static void print_help(const char *app)
366 printf("Colorize version %s\n\n",
367 #include "../version.h"
369 printf("Usage: %s [options] <grey ppm image> <marked ppm image> <result ppm image> [<frames> <start>]\n", app);
370 printf(" Colorize grey image using maked image and save to result image.\n");
371 printf(" If frames and start frame is given, image names must include printf integer formatting (e.g. %%04d).\n");
372 printf("Usage: %s [options] <grey ppm image> marked <result ppm image>\n", app);
373 printf(" Colorize grey image using marked mask + palette and save to result image.\n");
374 printf("Usage: %s [options] sequence [list | <start with frame> [<stop with frame>]]\n", app);
375 printf(" Colorize movie sequence (generated by colorize gui) as found in the current directory.\n");
376 printf(" Use list to view sequence segments between keyframes.\n");
377 printf("\nOptions:\n");
378 printf(" -h --help This help\n");
379 printf(" -d --depth <bits> Save images with given color bit depth (default=%d)\n", save_depth);
380 printf(" -i --in-itr-num <num> Alter inner iterations (weightening count) of colorization algorithm (default=%d)\n", in_itr_num);
381 printf(" -o --out-itr-num <num> Alter outer iterations (complete turns) of colorization algorithm (default=%d)\n", out_itr_num);
382 printf(" -z --zscale <levels> How many grids (staring with the finest) should be scaled in z direction to generate the next coarse grid ");
384 printf("(default=%d)\n", scalexyz);
386 printf("(default=infinite)\n");
387 printf(" -b --brightness-contrast [0 | 1] Apply brightnes and contrast, if defined in palette by GUI (default=%d)\n", bright_contrast);
389 printf(" -f --optical-flow [0 | 1] Apply optical flow, if defined by GUI (default=%d)\n", optical_flow);
391 printf(" -s --scale [1..n] Scale down by the given factor for quick and dirty previews (default=%d)\n", scale);
392 printf(" -t --test <test> Generate test images. Use 'help' for list of tests\n");
395 static void print_test_help()
397 printf(" -t --test <test> Generate test images...\n");
399 printf(" flow-next Optical flow plane to next image\n");
400 printf(" flow-prev Optical flow plane to previous image\n");
402 printf(" marked Only apply makred colors to grey image\n");
403 printf(" mask Show mask of marked areas\n");
404 printf(" mask+color Show mask of marked areas + color\n");
405 printf(" bc-only Only apply brightness+contrast, leave colors of grey image as is\n");
406 printf(" bc-image Show brightness+contrast change on grey image as uv components\n");
413 int main(int argc, char *argv[])
415 darray_t *gI = NULL, *cI = NULL, *markIm = NULL, *ntscIm = NULL;
416 darray_t *flow = NULL, *flow_i = NULL;
417 double *ptr, *ptr2, *ptr3;
420 int w = 0, h = 0, load_w, load_h, k = 1, index = 0, z;
421 unsigned short *img_buffer, *img_buffer_all = NULL;
422 unsigned char *mark_buffer = NULL;
425 const char* filename;
426 char first_filename[256];
427 int seq_offset = 0, seq_next = 0;
428 int features, change_bc;
431 skip_args = handle_options(argc, argv);
441 if (argc > 1 && !strcmp(argv[1], "sequence")) {
442 k = load_sequence(&seq_offset, &seq_next, first_filename);
445 printf("Got %d frames from sequence (frames %d..%d)\n", k, seq_offset, seq_offset + k - 1);
446 if (argc > 2 && (!strcmp(argv[2], "list") || atoi(argv[2]) > seq_offset)) {
447 seq_offset = seq_next;
450 } else if (argc <= 3) {
453 } else if (argc > 5) {
455 index = atoi(argv[5]);
461 if (k > SINGLE_K_TEST)
468 for (z = 0; z < k; z++) {
470 filename = sequence[z].filename;
471 /* first_filename is set by load_sequence */
474 strcpy(first_filename, argv[1]);
477 // load flow settings
478 if (sequence || !strcmp(argv[2], "marked")) {
481 load_flow(first_filename);
482 if (flow_enable == 0 && (test == FLOW_NEXT || test == FLOW_PREV)) {
483 fprintf(stderr, "Cannot test optical flow, because it is not enabled by GUI.\n");
488 // load original image and convert their RGB components to double RGB array
489 rc = load_img(-1, &img_buffer, &load_w, &load_h, filename, index + z);
491 fprintf(stderr, "Failed to load grey image\n");
494 scale_img(img_buffer, load_w, load_h, scale);
499 if (load_w/scale != w || load_h/scale != h) {
500 fprintf(stderr, "Error: All input images must have equal dimenstions.\n");
503 // now we know the dimensions, so we can create input arrays
505 dims[0] = w; dims[1] = h; dims[2] = 3; dims[3] = k;
506 gI = darrayCreate(4, dims);
509 printf("failed to create grey image array\n");
513 dims[0] = w; dims[1] = h; dims[2] = 3; dims[3] = k;
514 cI = darrayCreate(4, dims);
517 printf("failed to create marked image array\n");
520 ptr = darrayGetPr(gI) + w*h*3*z;
521 img2array(img_buffer, w, h, ptr, w, h);
523 if (k > 1 && flow_enable) {
525 img_buffer_all = malloc(w*h*3*k*sizeof(unsigned short));
526 if (!img_buffer_all) {
527 printf("failed to create grey image array\n");
530 memcpy(img_buffer_all + w*h*3*z, img_buffer, w*h*3*sizeof(unsigned short));
535 if (sequence || !strcmp(argv[2], "marked")) {
538 // load marked mask and convert their RGB components to double YUV array
539 memcpy(darrayGetPr(cI) + w*h*3*z, darrayGetPr(gI) + w*h*3*z, w*h*3 * sizeof(double));
540 /* add extra memory for unscaled data to prevent buffer overflow */
542 mark_buffer = (unsigned char *)malloc(w*h*k + load_w*load_h);
544 printf("no memory for mark buffer\n");
547 if (load_palette(first_filename)) {
548 printf("failed to load palette for file: '%s'\n", filename);
551 sprintf(name, filename, index + z);
552 /* always load full unscaled image, then scale down */
553 if (load_marked(mark_buffer + w*h*z, load_w, load_h, name) == 0) {
554 scale_mark(mark_buffer + w*h*z, load_w, load_h, scale);
555 ptr = darrayGetPr(cI) + w*h*3*z;
556 for (y = 0; y < h; y++) {
557 for (x = 0; x < w; x++) {
558 /* do not apply mask on index 0 */
559 c = mark_buffer[y*w+x + w*h*z];
562 /* check for any brightness/contrast change */
563 if (bright_contrast && (mark_palette[c-1].bright != 0 || mark_palette[c-1].contrast != 1))
565 /* do not apply white pixles, this meas: keep original color */
566 if (mark_palette[c-1].r == 255 && mark_palette[c-1].g == 255 && mark_palette[c-1].b == 255)
568 ptr[y*w+x] = mark_palette[c-1].r / 255.0F;
569 ptr[y*w+x + w*h] = mark_palette[c-1].g / 255.0F;
570 ptr[y*w+x + w*h*2] = mark_palette[c-1].b / 255.0F;
574 memset(mark_buffer + w*h*z, 0, w*h);
576 // load marked image and convert their RGB components to double YUV array
577 rc = load_img(-1, &img_buffer, &load_w, &load_h, argv[2], index + z);
579 if (load_w/scale != w || load_h/scale != h) {
580 fprintf(stderr, "Error: All input images must have equal dimenstions.\n");
583 ptr = darrayGetPr(cI) + w*h*3*z;
584 img2array(img_buffer, w, h, ptr, w, h);
587 fprintf(stderr, "Failed to load marked image, omitting...\n");
588 memcpy(darrayGetPr(cI) + w*h*3*z, darrayGetPr(gI) + w*h*3*z, w*h*3 * sizeof(double));
593 /* create color mask and ntsc arrays for the colorization process */
594 dims[0] = w; dims[1] = h; dims[2] = k;
595 markIm = darrayCreate(3, dims);
597 printf("failed to create mark array\n");
600 features = (change_bc) ? 4 : 2;
601 dims[0] = w; dims[1] = h; dims[2] = features+1; dims[3] = k;
602 ntscIm = darrayCreate(4, dims);
604 printf("failed to create ntsc array\n");
608 for (z = 0; z < k; z++) {
609 if (sequence || !strcmp(argv[2], "marked")) {
611 ptr = darrayGetPr(markIm) + w*h*z;
612 // use marked mask to fill markIm
613 for (y = 0; y < h; y++) {
614 for (x = 0; x < w; x++) {
615 if (x < w && y < h) {
616 /* do not apply mask on index 0 */
617 c = mark_buffer[y*w+x + w*h*z];
627 // fill color image with marked pixles
628 // - calculate the difference between two images (original image - color image)
629 // - convert into absolute (positive values)
630 // - sum all components to get grey image
631 // - apply threshold (pixle is 1F, if the absolute difference is > 0.01F)
632 // original code: markIm=(sum(abs(gI-cI),3)>0.01);
633 ptr = darrayGetPr(gI) + w*h*3*z;
634 ptr2 = darrayGetPr(cI) + w*h*3*z;
635 ptr3 = darrayGetPr(markIm) + w*h*z;
636 for (i = 0, ii = w * h; i < ii; i++) {
638 sum = ptr[i] - ptr2[i];
643 sum = ptr[i + ii] - ptr2[i + ii];
648 sum = ptr[i + ii + ii] - ptr2[i + ii + ii];
660 // convert original image into YUV
661 ptr = darrayGetPr(gI) + w*h*3*z;
662 rgb2yuv(ptr, ptr, w, h);
664 // convert maked image into YUV
665 ptr = darrayGetPr(cI) + w*h*3*z;
666 rgb2yuv(ptr, ptr, w, h);
668 if (test != BC_ONLY) {
669 if (sequence || !strcmp(argv[2], "marked")) {
671 // generate NTSC image: use luminance from original image and chrominance from original or marked image
672 ptr = darrayGetPr(gI) + w*h*3*z;
673 ptr2 = darrayGetPr(cI) + w*h*3*z;
674 ptr3 = darrayGetPr(ntscIm) + w*h*(features+1)*z;
675 /* use original y component */
676 memcpy(ptr3, ptr, w * h * sizeof(double));
677 /* apply new uv components */
678 for (y = 0; y < h; y++) {
679 for (x = 0; x < w; x++) {
680 c = mark_buffer[y*w+x + w*h*z];
682 ptr3[w * h + w * y + x] = ptr[w * h + w * y + x];
683 ptr3[w * h * 2 + w * y + x] = ptr[w * h * 2 + w * y + x];
685 ptr3[w * h + w * y + x] = ptr2[w * h + w * y + x];
686 ptr3[w * h * 2 + w * y + x] = ptr2[w * h * 2 + w * y + x];
691 // generate NTSC image: use luminance from original image and chrominance from maked image
692 ptr = darrayGetPr(gI) + w*h*3*z;
693 ptr2 = darrayGetPr(cI) + w*h*3*z;
694 ptr3 = darrayGetPr(ntscIm) + w*h*(features+1)*z;
695 memcpy(ptr3, ptr, w * h * sizeof(double));
696 memcpy(ptr3 + w * h, ptr2 + w * h, w * h * sizeof(double));
697 memcpy(ptr3 + w * h * 2, ptr2 + w * h * 2, w * h * sizeof(double));
700 /* use grey image as result if BC_ONLY test is selected */
701 ptr = darrayGetPr(gI) + w*h*3*z;
702 ptr2 = darrayGetPr(ntscIm) + w*h*(features+1)*z;
703 memcpy(ptr2, ptr, w * h * 3 * sizeof(double));
708 ptr2 = darrayGetPr(ntscIm) + w*h*(features+1)*z;
709 /* use original y component */
710 memcpy(ptr2, ptr, w * h * sizeof(double));
711 /* apply brightness and contrast from makred pixles to uv components of grey image */
712 for (y = 0; y < h; y++) {
713 for (x = 0; x < w; x++) {
714 /* use unchanged brightness and contrast on index 0 */
715 c = mark_buffer[y*w+x + w*h*z];
717 ptr2[y*w+x + w*h*3] = 0;
718 ptr2[y*w+x + w*h*4] = 0.1;
720 ptr2[y*w+x + w*h*3] = mark_palette[c-1].bright / 10.0;
721 ptr2[y*w+x + w*h*4] = mark_palette[c-1].contrast / 10.0;
729 if (k > 1 && flow_enable) {
730 /* create flow vectors */
731 dims[0] = w; dims[1] = h; dims[2] = k - 1; dims[3] = 2;
732 flow = darrayCreate(4, dims);
734 printf("failed to create array\n");
737 flow_i = darrayCreate(4, dims);
739 printf("failed to create array\n");
742 printf("Calculating optical flow for %d frames: window=%d\n", k, flow_window/scale);
744 printf("Note: Optical flow is not activated!\n");
745 for (z = 0; z < k-1; z++) {
747 create_flow_maps(NULL, img_buffer_all + w*h*3*(z+1), img_buffer_all + w*h*3*z, w, h, flow_window/scale, 0, NULL, NULL, darrayGetPr(flow) + w*h*z, darrayGetPr(flow) + w*h*z + w*h*(k-1), NULL);
749 create_flow_maps(img_buffer_all + w*h*3*z, NULL, img_buffer_all + w*h*3*(z+1), w, h, flow_window/scale, 0, darrayGetPr(flow_i) + w*h*z, darrayGetPr(flow_i) + w*h*z + w*h*(k-1), NULL, NULL, NULL);
753 printf("Note: Optical flow is not compiled in!\n");
755 free(img_buffer_all);
756 img_buffer_all = NULL;
763 if (test != FLOW_NEXT && test != FLOW_PREV && test != MARKED && test != MASK && test != MASK_COLOR && test != BC_ONLY && test != BC_IMAGE) {
764 printf("Colorizing %d frames, please wait...\n", k);
765 rc = colorize(ntscIm, markIm, flow, flow_i, in_itr_num, out_itr_num, scalexyz);
768 printf("No memory! Use smaller frames or less frames between key frames or add more memory.");
770 printf("No memory! Use smaller image or add more memory.");
775 /* if we have a change, we apply brightness+contrast from ntscIm */
777 for (z = 0; z < k; z++) {
778 ptr = darrayGetPr(ntscIm) + w*h*(features+1)*z;
779 ptr2 = darrayGetPr(ntscIm) + w*h*(features+1)*z;
780 for (y = 0; y < h; y++) {
781 for (x = 0; x < w; x++) {
783 ptr2[w * y + x] = (ptr2[w * y + x] - 0.5) * ptr[w * h * 4 + w * y + x] * 10.0 + 0.5;
784 /* apply brightness */
785 ptr2[w * y + x] += ptr[w * h * 3 + w * y + x] * 10.0;
786 if (ptr2[w * y + x] < 0)
788 if (ptr2[w * y + x] > 1)
791 #warning TEST: show brightness and contrast change as uv vectors on a grey array */
792 ptr2[w * y + x] = 0.5;
793 ptr2[w * h + w * y + x] = ptr[w * h + w * y + x] * 10;
794 ptr2[w * h * 2 + w * y + x] = ptr[w * h * 2 + w * y + x] * 10 - 1;
802 if (test == FLOW_NEXT || test == FLOW_PREV) {
803 /* apply flow planes to result image as u and y vector */
804 for (z = 0; z < k; z++) {
805 ptr = darrayGetPr(ntscIm) + w*h*(features+1)*z;
806 if (test == FLOW_NEXT) {
807 ptr2 = darrayGetPr(flow) + w*h*z;
808 ptr3 = darrayGetPr(flow) + w*h*z*(k-1);
810 ptr2 = darrayGetPr(flow_i) + w*h*z;
811 ptr3 = darrayGetPr(flow_i) + w*h*z*(k-1);
813 for (y = 0; y < h; y++) {
814 for (x = 0; x < w; x++) {
815 ptr[w * y + x] = 0.5;
817 ptr[w * y + x + w*h] = ptr2[w * y + x] / 50;
818 ptr[w * y + x + w*h*2] = ptr3[w * y + x] / 50;
820 ptr[w * y + x + w*h] = 0;
821 ptr[w * y + x + w*h*2] = 0;
830 /* apply maked mask as image */
831 for (z = 0; z < k; z++) {
832 ptr = darrayGetPr(ntscIm) + w*h*(features+1)*z;
833 ptr2 = darrayGetPr(markIm) + w*h*z;
834 for (y = 0; y < h; y++) {
835 for (x = 0; x < w; x++) {
836 ptr[w * y + x] = ptr2[w * y + x];
837 ptr[w * y + x + w*h] = ptr2[w * y + x];
838 ptr[w * y + x + w*h*2] = ptr2[w * y + x];
844 if (test == MASK_COLOR) {
845 /* apply maked mask on grey image */
846 for (z = 0; z < k; z++) {
847 ptr = darrayGetPr(ntscIm) + w*h*(features+1)*z;
848 ptr2 = darrayGetPr(markIm) + w*h*z;
849 for (y = 0; y < h; y++) {
850 for (x = 0; x < w; x++) {
851 /* darken unmarked areas, make maked areas with uniformed brightness */
852 if (ptr2[w * y + x] < 0.5F)
853 ptr[w * y + x] = ptr[w * y + x] / 4;
855 ptr[w * y + x] = 0.5F;
861 if (test == BC_IMAGE) {
862 /* apply bc image as result image */
863 for (z = 0; z < k; z++) {
864 ptr = darrayGetPr(ntscIm) + w*h*(features+1)*z;
865 ptr2 = darrayGetPr(ntscIm) + w*h*(features+1)*z;
866 /* use uniformed brightness as y component */
867 for (y = 0; y < h; y++) {
868 for (x = 0; x < w; x++) {
869 ptr[w * y + x] = 0.5F;
873 ptr2 = darrayGetPr(ntscIm) + w*h*(features+1)*z;
874 memcpy(ptr+w*h, ptr2+w*h*3, w * h * sizeof(double));
875 memcpy(ptr+w*h*2, ptr2+w*h*4, w * h * sizeof(double));
877 memset(ptr+w*h, 0, w * h * sizeof(double));
878 memset(ptr+w*h*2, 0, w * h * sizeof(double));
883 // save result YUV array to image with RGB components
884 img_buffer = (unsigned short *)malloc(w*h*3*sizeof(unsigned short));
886 fprintf(stderr, "Failed to allocate image buffer\n");
889 for (z = 0; z < k; z++) {
890 ptr = darrayGetPr(ntscIm) + w*h*(features+1)*z;
891 yuv2rgb(ptr, ptr, w, h);
892 array2img(ptr, w, h, img_buffer, w, h);
894 static char name[256], *p, *q;
895 p = sequence[z].filename;
896 while((q = strchr(p, DIR_SEPERATOR)))
898 strcpy(name, sequence[z].filename);
899 name[p - sequence[z].filename] = '\0';
900 strcat(name, "colorized_");
905 save_img(img_buffer, w, h, filename, index + z);
910 printf("Elapsed time: %d minutes, %d seconds\n", (int)(end-start)/60, (int)(end-start)%60);
913 darrayDestroy(ntscIm);
917 darrayDestroy(flow_i);
919 darrayDestroy(markIm);
931 /* if end frame is not given or if not reached */
932 if (argc <= 3 || atoi(argv[3]) > seq_offset + k) {
933 seq_offset = seq_offset + k - 1;