implemented copying rectangular section
Stefan Schuermans

Stefan Schuermans commited on 2011-10-16 14:44:35
Showing 9 changed files, with 296 additions and 9 deletions.

... ...
@@ -23,19 +23,19 @@ static void gen_test_movie(stBlinkenMovie ** ppMovie, const char *str_format,
23 23
     mode = ModeTrans;
24 24
   if (sscanf(str_format, "%ux%u-%u/%u", &width, &height, &channels, &colors)
25 25
       != 4)
26
-    printf("invalid movie format \"%s\"\n", str_format);
26
+    printf("invalid movie format \"%s\" for \"-t\"\n", str_format);
27 27
   else if (mode == ModeNone)
28
-    printf("invalid test mode \"%s\"\n", str_mode);
28
+    printf("invalid test mode \"%s\" for \"-t\"\n", str_mode);
29 29
   else if (sscanf(str_duration, "%u", &duration) != 1)
30
-    printf("invalid duration \"%s\"\n", str_duration);
30
+    printf("invalid duration \"%s\" for \"-t\"\n", str_duration);
31 31
   else {
32 32
 
33 33
     if (*ppMovie != NULL)
34 34
       BlinkenMovieFree(*ppMovie);
35 35
     *ppMovie = BlinkenMovieNew(height, width, channels, colors - 1);
36 36
     if (*ppMovie == NULL)
37
-      printf("could not create movie with format \"%ux%u-%x/%u\"\n", width,
38
-             height, channels, colors);
37
+      printf("could not create movie with format \"%ux%u-%x/%u\" for \"-t\"\n",
38
+             width, height, channels, colors);
39 39
     else {
40 40
 
41 41
       unsigned int y, x, c, c2, c3, o, b, yy, xx, cc, oo;
... ...
@@ -124,6 +124,33 @@ static void gen_test_movie(stBlinkenMovie ** ppMovie, const char *str_format,
124 124
   }     // else
125 125
 }
126 126
 
127
+static void copy_rect(stBlinkenMovie *pMovie, char *str_file,
128
+                      const char *str_src_pos, const char *str_dim,
129
+                      const char *str_dest_pos)
130
+{
131
+  unsigned int sy, sx, h, w, dy, dx;
132
+  stBlinkenMovie *pSrcMovie;
133
+
134
+  if (sscanf(str_src_pos, "%u,%u", &sx, &sy) != 2)
135
+    printf("invalid source position \"%s\" for \"-C\"\n", str_src_pos);
136
+  else if (sscanf(str_dim, "%ux%u", &w, &h) != 2)
137
+    printf("invalid dimensions \"%s\" for \"-C\"\n", str_dim);
138
+  else if (sscanf(str_dest_pos, "%u,%u", &dx, &dy) != 2)
139
+    printf("invalid destination position \"%s\" for \"-C\"\n", str_dest_pos);
140
+  else {
141
+
142
+    pSrcMovie = BlinkenMovieLoad(str_file);
143
+    if (pSrcMovie == NULL)
144
+      printf("could not read movie \"%s\"\n", str_file);
145
+    else {
146
+
147
+      BlinkenMovieCopyRect(pMovie, dy, dx, pSrcMovie, sy, sx, h, w);
148
+      BlinkenMovieFree(pSrcMovie);
149
+
150
+    }
151
+  }
152
+}
153
+
127 154
 int main(int argCnt, char **args)
128 155
 {
129 156
   stBlinkenMovie *pMovie;
... ...
@@ -168,6 +195,8 @@ int main(int argCnt, char **args)
168 195
            "     delete frames\n"
169 196
            "  -t <width>x<height>-<channels>/<colors> [dots|lines|trans] <duration>\n"
170 197
            "     generate a test movie\n"
198
+           "  -C <file> <src-x>,<src-y> <width>x<height> <dest-x>,<dest-y>\n"
199
+           "     copy rectangular section of other movie\n"
171 200
            "  -o <file>\n"
172 201
            "     write movie to file (*.blm, *.bmm, *.bml, *.bbm)\n\n"
173 202
            "old syntax: %s <input-file> [<output-file>]\n\n",
... ...
@@ -407,6 +436,32 @@ int main(int argCnt, char **args)
407 436
       } else
408 437
         printf("missing format for \"-t\"\n");
409 438
     }
439
+    // copy rectangular section of other movie
440
+    else if (strcmp(args[i], "-C") == 0) {
441
+      if (i + 4 < argCnt) {
442
+        char *str_file;
443
+        const char *str_src_pos, *str_dim, *str_dest_pos;
444
+        i++;
445
+        str_file = args[i];
446
+        i++;
447
+        str_src_pos = args[i];
448
+        i++;
449
+        str_dim = args[i];
450
+        i++;
451
+        str_dest_pos = args[i];
452
+        copy_rect(pMovie, str_file, str_src_pos, str_dim, str_dest_pos);
453
+      } else if (i + 3 < argCnt) {
454
+        printf("missing destination position for \"-C\"\n");
455
+        i += 3;
456
+      } else if (i + 2 < argCnt) {
457
+        printf("missing dimensions for \"-C\"\n");
458
+        i += 2;
459
+      } else if (i + 1 < argCnt) {
460
+        printf("missing source position for \"-C\"\n");
461
+        i++;
462
+      } else
463
+        printf("missing file name of source movie for \"-C\"\n");
464
+    }
410 465
     // write movie
411 466
     else if (strcmp(args[i], "-o") == 0) {
412 467
       if (i + 1 < argCnt) {
... ...
@@ -646,6 +646,73 @@ void BlinkenFrameColorize(stBlinkenFrame *pFrame, int channels, int mode,
646 646
   pFrame->ppData = ppData;
647 647
 }
648 648
 
649
+void BlinkenFrameCopyRect(stBlinkenFrame *pDest, int destY, int destX,
650
+                          stBlinkenFrame *pSrc, int srcY, int srcX,
651
+                          int height, int width)
652
+{
653
+  int bFreeSrc = 0;
654
+  int destI, srcI, y, x, c, dy, sy, di, si;
655
+
656
+  if (pDest == NULL || pSrc == NULL)
657
+    return;
658
+
659
+  // make sure source frame matches dest frame in channels and maxval
660
+  if (pSrc->channels != pDest->channels || pSrc->maxval != pDest->maxval) {
661
+    pSrc = BlinkenFrameClone(pSrc);
662
+    if (pSrc == NULL)
663
+      return;
664
+    BlinkenFrameResize(pSrc, pSrc->height, pSrc->width,
665
+                       pDest->channels, pDest->maxval);
666
+    bFreeSrc = 1; // source is now a temporary copy that needs to be freed
667
+  }
668
+
669
+  // correct coordinates
670
+  if (destY < 0) {
671
+    height += destY;
672
+    srcY -= destY;
673
+    destY = 0;
674
+  }
675
+  if (destX < 0) {
676
+    width += destX;
677
+    srcX -= destX;
678
+    destX = 0;
679
+  }
680
+  if (srcY < 0) {
681
+    height += srcY;
682
+    destY -= srcY;
683
+    srcY = 0;
684
+  }
685
+  if (srcX < 0) {
686
+    width += srcX;
687
+    destX -= srcX;
688
+    srcX = 0;
689
+  }
690
+  if (height > pDest->height - destY)
691
+    height = pDest->height - destY;
692
+  if (width > pDest->width - destX)
693
+    width = pDest->width - destX;
694
+  if (height > pSrc->height - srcY)
695
+    height = pSrc->height - srcY;
696
+  if (width > pSrc->width - srcX)
697
+    width = pSrc->width - srcX;
698
+  if (height < 0)
699
+    height = 0;
700
+  if (width < 0)
701
+    width = 0;
702
+
703
+  // copy rectangular area
704
+  destI = destX * pDest->channels;
705
+  srcI = srcX * pSrc->channels;
706
+  for (y = 0, dy = destY, sy = srcY; y < height; y++, dy++, sy++)
707
+    for (x = 0, di = destI, si = srcI; x < width; x++)
708
+      for (c = 0; c < pDest->channels; c++, di++, si++)
709
+        pDest->ppData[dy][di] = pSrc->ppData[sy][si];
710
+
711
+  // free source if it is a temporary copy
712
+  if (bFreeSrc)
713
+    BlinkenFrameFree(pSrc);
714
+}
715
+
649 716
 char *BlinkenFrameToString(stBlinkenFrame *pFrame)
650 717
 {
651 718
   int size, y, x, c, i;
... ...
@@ -48,6 +48,9 @@ void BlinkenFrameResize(stBlinkenFrame *pFrame, int height, int width,
48 48
 void BlinkenFrameScale(stBlinkenFrame *pFrame, int height, int width);
49 49
 void BlinkenFrameColorize(stBlinkenFrame *pFrame, int channels, int mode,
50 50
                           int step);
51
+void BlinkenFrameCopyRect(stBlinkenFrame *pDest, int destY, int destX,
52
+                          stBlinkenFrame *pSrc, int srcY, int srcX,
53
+                          int height, int width);
51 54
 
52 55
 char *BlinkenFrameToString(stBlinkenFrame *pFrame);
53 56
 
... ...
@@ -611,6 +611,78 @@ void BlinkenMovieColorize(stBlinkenMovie *pMovie, int channels, int mode)
611 611
   }
612 612
 }
613 613
 
614
+void BlinkenMovieCopyRect(stBlinkenMovie *pDest, int destY, int destX,
615
+                          stBlinkenMovie *pSrc, int srcY, int srcX,
616
+                          int height, int width)
617
+{
618
+  int dcnt, scnt, di, si, dest_dur, src_dur, src_time_ofs;
619
+  stBlinkenFrame *pFrame;
620
+
621
+  if (pDest == NULL || pSrc == NULL)
622
+    return;
623
+
624
+  // exit if both movies empty
625
+  dcnt = pDest->frameCnt;
626
+  scnt = pSrc->frameCnt;
627
+  if (dcnt == 0 || scnt == 0)
628
+    return;
629
+
630
+  // go throuh all source frames
631
+  di = 0;
632
+  si = 0;
633
+  dest_dur = dcnt > 0 ? BlinkenFrameGetDuration(pDest->ppFrames[0]) : 0;
634
+  src_dur = scnt > 0 ? BlinkenFrameGetDuration(pSrc->ppFrames[0]) : 0;
635
+  src_time_ofs = 0;
636
+  while (si < scnt) {
637
+
638
+    // make sure there is a frame in destination movie
639
+    if (di >= dcnt) {
640
+      // append new empty frame that last until end of source frame
641
+      pFrame = BlinkenFrameNew(pDest->height, pDest->width,
642
+                               pDest->channels, pDest->maxval,
643
+                               src_dur - src_time_ofs);
644
+      if (pFrame == NULL)
645
+        return;
646
+      BlinkenFrameClear(pFrame);
647
+      if (BlinkenMovieAppendFrame(pDest, pFrame) != 0)
648
+        return;
649
+      dcnt++;
650
+      dest_dur = src_dur - src_time_ofs;
651
+    }
652
+
653
+    // make sure destination frame does not last longer than source frame
654
+    if (dest_dur > src_dur - src_time_ofs) {
655
+      // split destination frame into two
656
+      pFrame = BlinkenFrameClone(pDest->ppFrames[di]);
657
+      if (pFrame == NULL)
658
+        return;
659
+      if (BlinkenMovieInsertFrame(pDest, di+1, pFrame) != 0)
660
+        return;
661
+      dcnt++;
662
+      BlinkenFrameSetDuration(pDest->ppFrames[di],
663
+                              src_dur - src_time_ofs);
664
+      BlinkenFrameSetDuration(pDest->ppFrames[di+1],
665
+                              dest_dur - (src_dur - src_time_ofs));
666
+      dest_dur = src_dur - src_time_ofs;
667
+    }
668
+
669
+    // copy from source frame to destination frame
670
+    BlinkenFrameCopyRect(pDest->ppFrames[di], destY, destX,
671
+                         pSrc->ppFrames[si], srcY, srcX, height, width);
672
+    src_time_ofs += dest_dur;
673
+    di++;
674
+    dest_dur = di < dcnt ? BlinkenFrameGetDuration(pDest->ppFrames[di]) : 0;
675
+
676
+    // go to next source frame
677
+    if (src_time_ofs >= src_dur) {
678
+      si++;
679
+      src_dur = si < scnt ? BlinkenFrameGetDuration(pSrc->ppFrames[si]) : 0;
680
+      src_time_ofs = 0;
681
+    }
682
+
683
+  } // while (si < scnt)
684
+}
685
+
614 686
 char *BlinkenMovieToString(stBlinkenMovie *pMovie)
615 687
 {
616 688
   char **strs, *str, *ptr;
... ...
@@ -62,6 +62,9 @@ void BlinkenMovieResize(stBlinkenMovie *pMovie, int height, int width,
62 62
                         int channels, int maxval);
63 63
 void BlinkenMovieScale(stBlinkenMovie *pMovie, int height, int width);
64 64
 void BlinkenMovieColorize(stBlinkenMovie *pMovie, int channels, int mode);
65
+void BlinkenMovieCopyRect(stBlinkenMovie *pDest, int destY, int destX,
66
+                          stBlinkenMovie *pSrc, int srcY, int srcX,
67
+                          int height, int width);
65 68
 
66 69
 char *BlinkenMovieToString(stBlinkenMovie *pMovie);
67 70
 
... ...
@@ -1,3 +1,9 @@
1
+0.6.7 2011-10-16
2
+----------------
3
+added copying rectangular section to BlinkenConv
4
+added CopyRect to BlinkenFrame and Movie
5
+changed indenting to be more "standard"
6
+
1 7
 0.6.6 2011-09-10
2 8
 ----------------
3 9
 some Makefile fixes for MAC OS X
... ...
@@ -5,12 +5,9 @@
5 5
 
6 6
 VERSION_MAJOR=0
7 7
 VERSION_MINOR=6
8
-VERSION_REVISION=6
8
+VERSION_REVISION=7
9 9
 VERSION=$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_REVISION)
10 10
 
11
-DATE:=$(shell date +%Y-%m-%d)
12
-YEAR:=$(shell date +%Y)
13
-
14 11
 UPDATE_FILES=Makefile */Makefile */*.c */*.h
15 12
 PACK_FILES=BlinkenLib ChangeLog config examples install Makefile
16 13
 
... ...
@@ -0,0 +1,42 @@
1
+# BlinkenLights Movie 18x8
2
+
3
+@100
4
+110000000000000000
5
+000000000000000000
6
+000000000000000000
7
+000000000000000000
8
+000000000000000000
9
+000000000000000000
10
+000000000000000000
11
+000000000000000000
12
+
13
+@100
14
+111100000000000000
15
+100000000000000000
16
+000000000000000000
17
+000000000000000000
18
+000000000000000000
19
+000000000000000000
20
+000000000000000000
21
+000000000000000000
22
+
23
+@100
24
+111111000000000000
25
+100000000000000000
26
+100000000000000000
27
+000000000000000000
28
+000000000000000000
29
+000000000000000000
30
+000000000000000000
31
+000000000000000000
32
+
33
+@100
34
+111111110000000000
35
+100000000000000000
36
+100000000000000000
37
+100000000000000000
38
+000000000000000000
39
+000000000000000000
40
+000000000000000000
41
+000000000000000000
42
+
... ...
@@ -0,0 +1,42 @@
1
+# BlinkenLights Movie 18x8
2
+
3
+@150
4
+101000000000000000
5
+000000000000000000
6
+000000000000000000
7
+000000000000000000
8
+000000000000000000
9
+000000000000000000
10
+000000000000000000
11
+000000000000000000
12
+
13
+@150
14
+101010100000000000
15
+100000000000000000
16
+000000000000000000
17
+000000000000000000
18
+000000000000000000
19
+000000000000000000
20
+000000000000000000
21
+000000000000000000
22
+
23
+@150
24
+101010101010000000
25
+100000000000000000
26
+100000000000000000
27
+000000000000000000
28
+000000000000000000
29
+000000000000000000
30
+000000000000000000
31
+000000000000000000
32
+
33
+@150
34
+101010101010101000
35
+100000000000000000
36
+100000000000000000
37
+100000000000000000
38
+000000000000000000
39
+000000000000000000
40
+000000000000000000
41
+000000000000000000
42
+
0 43