int flow_window = 30, border = 0;
double limit_frames = 0;
+int interlace = 0, swap = 0;
+
+static void field_img(int width, int height, unsigned short *img, int odd)
+{
+ int y, x;
+ signed int value;
+
+ /* use even lines: 0, 2, 4... */
+ /* use odd lines: 1, 3, 5... */
+ for (y = (!!odd); y < height-2; y += 2) {
+ for (x = 0; x < width*3; x++) {
+ value = img[width * y * 3 + x];
+ value += img[width * (y+2) * 3 + x];
+ img[width * (y+1) * 3 + x] = (value >> 1);
+ }
+ }
+ /* duplicate border line that can't be interpolated */
+ if (!odd)
+ memcpy(img + width * (height-1) * 3, img + width * (height-2) * 3, width * 3 * sizeof(unsigned short));
+ else
+ memcpy(img, img + width * 3, width * 3 * sizeof(unsigned short));
+}
static inline void smooth_pixle(double *array, int width, int height, int i, int j)
{
printf(" -b --border <pixles> Remove border pixles, if darker than image (try 1)\n");
printf(" -w --window <size> Change optical flow window size (default %d)\n", flow_window);
printf(" -f --frames <number> Limit number of input frames (default infinite)\n");
+ printf(" -i --interlace Handle input image as interlaced image\n");
+ printf(" Note: oldfps refers to frames, not the individual fields\n");
+ printf(" -e --even Use even lines for first field, instead of odd lines\n");
printf(" input Input image sequence (e.g. input_%%05d.ppm)\n");
printf(" output Output image sequence (e.g. output_%%05d.ppm)\n");
printf(" first Index of first input and output image\n");
- printf(" oldfps Old frame rate\n");
+ printf(" oldfps Old frame rate (complete frames in case of interlace)\n");
printf(" newfps New frame rate\n");
}
{"border", 1, 0, 'b'},
{"window", 1, 0, 'w'},
{"frames", 1, 0, 'f'},
+ {"interlace", 0, 0, 'i'},
+ {"even", 0, 0, 'e'},
{0, 0, 0, 0},
};
- c = getopt_long(argc, argv, "hd:b:w:f:", long_options, &option_index);
+ c = getopt_long(argc, argv, "hd:b:w:f:ie", long_options, &option_index);
if (c == -1)
break;
limit_frames = atoi(optarg);
skip_args += 2;
break;
+ case 'i':
+ interlace = 1;
+ skip_args++;
+ break;
+ case 'e':
+ swap = 1;
+ skip_args++;
+ break;
default:
break;
}
offset = inputframe - baseframe;
if (offset < 0.001)
offset = 0.0;
+ else if (interlace && offset < 0.501 && offset > 0.499)
+ offset = 0.5;
else if (offset > 0.999) {
offset = 0.0;
baseframe++;
}
- if (offset == 0.0) {
- printf("Copy input frame %d, output frame %d\n", (int)baseframe, outputframe);
+ if (offset == 0.0 || (interlace && offset == 0.5)) {
+ if (interlace) {
+ if (offset < 0.5)
+ printf("Copy input frame %d (first field), output frame %d\n", (int)baseframe, outputframe);
+ else
+ printf("Copy input frame %d (second field), output frame %d\n", (int)baseframe, outputframe);
+ } else
+ printf("Copy input frame %d, output frame %d\n", (int)baseframe, outputframe);
res = load_img(&width, &height, inputname, baseframe);
if (!res)
goto end;
+ if (interlace) {
+ if (offset < 0.5)
+ field_img(width, height, res, (!swap)); // first field
+ else
+ field_img(width, height, res, swap); // second field
+ }
rc = save_img(res, width, height, 0, outputname, outputframe);
if (rc < 0)
goto out;
img1 = load_img(&width, &height, inputname, baseframe);
if (!img1)
goto end;
- img2 = load_img(&width2, &height2, inputname, baseframe+1);
- if (!img2)
- goto end;
+ if (interlace && offset < 0.5) {
+ field_img(width, height, img1, (!swap)); // first field of baseframe
+ img2 = load_img(&width2, &height2, inputname, baseframe);
+ if (!img2)
+ goto end;
+ field_img(width2, height2, img2, swap); // second field of baseframe
+ } else {
+ img2 = load_img(&width2, &height2, inputname, baseframe+1);
+ if (!img2)
+ goto end;
+ if (interlace) {
+ field_img(width, height, img1, swap); // second field of baseframe
+ field_img(width2, height2, img2, (!swap)); // first field of baseframe+1
+ }
+ }
if (width != width2) {
printf("Frame %d and %d have different width (%d != %d)\n", (int)baseframe, (int)baseframe+1, width, width2);
goto out;
printf("Frame %d and %d have different height (%d != %d)\n", (int)baseframe, (int)baseframe+1, height, height2);
goto out;
}
+ if (interlace && (height & 1)) {
+ printf("Interlaced frame %d must have even number of lines (not %d)\n", (int)baseframe, height);
+ goto out;
+ }
res = malloc(width * height * 3 * sizeof(unsigned short));
if (!res)
goto out;
- rc = interpolate(img1, img2, res, width, height, offset, (int)baseframe);
+ if (interlace) {
+ if (offset < 0.5)
+ rc = interpolate(img1, img2, res, width, height, offset * 2.0, ((int)baseframe) * 2);
+ else
+ rc = interpolate(img1, img2, res, width, height, (offset * 2.0) - 1.0, ((int)baseframe) * 2 + 1);
+ } else
+ rc = interpolate(img1, img2, res, width, height, offset, (int)baseframe);
if (rc < 0)
goto out;
rc = save_img(res, width, height, 0, outputname, outputframe);