implement scrolling a frame
Stefan Schuermans

Stefan Schuermans commited on 2016-12-18 13:18:36
Showing 1 changed files, with 130 additions and 0 deletions.

... ...
@@ -214,6 +214,114 @@ static void copy_rect(stBlinkenMovie *pMovie, char *str_file,
214 214
   }
215 215
 }
216 216
 
217
+static stBlinkenMovie * scroll(stBlinkenMovie *pMovie,
218
+                               const char * str_direction,
219
+                               const char * str_width_height,
220
+                               const char * str_duration)
221
+{
222
+  enum {
223
+    DirNone, DirLeft, DirRight, DirUp, DirDown,
224
+  } dir = DirNone;
225
+  int width_height, duration, height, width, channels, maxval,
226
+      new_height, new_width, sy, sx, dy, dx, steps, step;
227
+  stBlinkenFrame *pScroll, *pFrame;
228
+
229
+  // direction
230
+  if (strcmp(str_direction, "left") == 0)
231
+    dir = DirLeft;
232
+  else if (strcmp(str_direction, "right") == 0)
233
+    dir = DirRight;
234
+  else if (strcmp(str_direction, "up") == 0)
235
+    dir = DirUp;
236
+  else if (strcmp(str_direction, "down") == 0)
237
+    dir = DirDown;
238
+
239
+  // check
240
+  if (dir == DirNone) {
241
+    printf("invalid direction \"%s\" for \"-S\" (left, right, up, down)\n",
242
+           str_direction);
243
+    return pMovie;
244
+  }
245
+  if (sscanf(str_width_height, "%u", &width_height) != 1 || width_height < 1) {
246
+    printf("invalid width/height \"%s\" for \"-S\"\n", str_width_height);
247
+    return pMovie;
248
+  }
249
+  if (sscanf(str_duration, "%u", &duration) != 1 || duration < 1) {
250
+    printf("invalid duration \"%s\" for \"-S\"\n", str_duration);
251
+    return pMovie;
252
+  }
253
+  if (BlinkenMovieGetFrameCnt(pMovie) < 1) {
254
+    printf("empty movie not allowed for \"-S\"\n");
255
+    return pMovie;
256
+  }
257
+
258
+  // get number of steps
259
+  height = BlinkenMovieGetHeight(pMovie);
260
+  width = BlinkenMovieGetWidth(pMovie);
261
+  channels = BlinkenMovieGetChannels(pMovie);
262
+  maxval = BlinkenMovieGetMaxval(pMovie);
263
+  new_height = height;
264
+  new_width = width;
265
+  sy = 0;
266
+  sx = 0;
267
+  dy = 1;
268
+  dx = 1;
269
+  switch (dir) {
270
+    case DirNone:
271
+      return pMovie;
272
+    case DirRight:
273
+      sx = 1; // prepare for sx *= steps
274
+      dx = -1;
275
+      // fall through
276
+    case DirLeft:
277
+      dy = 0;
278
+      steps = width - width_height + 1;
279
+      sx *= (steps - 1); // before this line, sx was 0 or 1
280
+      if (steps < 1) {
281
+        printf("invalid width %u for \"-S left/right\" on movie of width %u\n",
282
+               width_height, width);
283
+        return pMovie;
284
+      }
285
+      new_width = width_height;
286
+      break;
287
+    case DirDown:
288
+      sy = 1; // prepare for sy *= steps
289
+      dy = -1;
290
+      // fall through
291
+    case DirUp:
292
+      dx = 0;
293
+      steps = height - width_height + 1;
294
+      sy *= (steps - 1); // before this line, sy was 0 or 1
295
+      if (steps < 1) {
296
+        printf("invalid height %u for \"-S up/down\" on movie of height %u\n",
297
+               width_height, width);
298
+        return pMovie;
299
+      }
300
+      new_height = width_height;
301
+      break;
302
+  }
303
+
304
+  // get copy of first frame
305
+  pScroll = BlinkenFrameClone(BlinkenMovieGetFrame(pMovie, 1));
306
+  BlinkenFrameSetDuration(pScroll, duration);
307
+
308
+  // free old movie
309
+  BlinkenMovieFree(pMovie);
310
+
311
+  // create new movie scrolling the frame
312
+  pMovie = BlinkenMovieNew(new_height, new_width, channels, maxval);
313
+  for (step = 0; step < steps; ++step, sy += dy, sx += dx) {
314
+    pFrame = BlinkenFrameClone(pScroll);
315
+    BlinkenFrameCrop(pFrame, sy, sx, new_height, new_width);
316
+    BlinkenMovieAppendFrame(pMovie, pFrame);
317
+  }
318
+
319
+  // free scrolled frame
320
+  BlinkenFrameFree(pScroll);
321
+
322
+  return pMovie;
323
+}
324
+
217 325
 int main(int argCnt, char **args)
218 326
 {
219 327
   stBlinkenMovie *pMovie;
... ...
@@ -273,6 +381,8 @@ int main(int argCnt, char **args)
273 381
            "     generate a test movie and append it to current video\n"
274 382
            "  -C <file> <src-x>,<src-y> <width>x<height> <dest-x>,<dest-y>\n"
275 383
            "     copy rectangular section of other movie\n"
384
+           "  -S {left|right|up|down} <width/height> <duration>\n"
385
+           "     scroll first frame of current movie (duration in ms)\n"
276 386
            "  -Rcw\n"
277 387
            "     rotate movie 90 degrees clockwise\n"
278 388
            "  -Rccw\n"
... ...
@@ -639,6 +749,26 @@ int main(int argCnt, char **args)
639 749
       } else
640 750
         printf("missing file name of source movie for \"-C\"\n");
641 751
     }
752
+    // scroll first frame of current movie
753
+    else if (strcmp(args[i], "-S") == 0) {
754
+      if (i + 3 < argCnt) {
755
+        const char *str_direction, *str_width_height, *str_duration;
756
+        i++;
757
+        str_direction = args[i];
758
+        i++;
759
+        str_width_height = args[i];
760
+        i++;
761
+        str_duration = args[i];
762
+        pMovie = scroll(pMovie, str_direction, str_width_height, str_duration);
763
+      } else if (i + 2 < argCnt) {
764
+        printf("missing duration for \"-S\"\n");
765
+        i += 2;
766
+      } else if (i + 1 < argCnt) {
767
+        printf("missing width/height for \"-S\"\n");
768
+        i++;
769
+      } else
770
+        printf("missing direction (left, right, up, down) for \"-S\"\n");
771
+    }
642 772
     // rotate movie 90 degrees clockwise
643 773
     else if (strcmp(args[i], "-Rcw") == 0) {
644 774
       if (pMovie == NULL)
645 775