RFX-GIMP

Check-in [e11499d94c]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Script to transition using jigsaw pieces.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:e11499d94c6a0a01c550e5382cb32e306a445ab0
User & Date: saul 2012-06-09 04:56:23
Context
2012-06-09
08:35
Fixed so both start and end of transition are fully exposed frames. check-in: 4754a5b716 user: saul tags: trunk
04:56
Script to transition using jigsaw pieces. check-in: e11499d94c user: saul tags: trunk
2012-05-03
19:11
Script to simulate a diffusion filter (based on algo by Antoine Tissier). check-in: 98ce1bbf9b user: saul tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added scripts/jigsaw.script.











































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
Script file generated from LiVES

<define>
|1.7
</define>

<name>
jigsaw
</name>

<version>
1
</version>

<author>
saulgoode|http://chiselapp.com/user/saulgoode/repository/RFX-GIMP/home
</author>

<description>
Jigsaw|jigsaw transitioning|1|2|
</description>

<requires>
gimp
</requires>

<params>
horiz_pieces|Horizontal pieces|num0|0|0|1000000|
vert_pieces|Vertical pieces|num0|0|0|1000000|
curvey_edges|Curvey edges|bool|0|
</params>

<param_window>
layout|p0|p1|
layout|p2|
layout|hseparator|
layout|p3|p4|
</param_window>

<properties>
0x0000
</properties>

<language_code>
0xF0
</language_code>

<pre>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 or higher
# as published by the Free Software Foundation.

use IO::Socket; 
use Text::Balanced;

if ($ENV{'RFXGIMP_PORT'}) {
  $rfx_port = $ENV{'RFXGIMP_PORT'};
  }
else {
  $rfx_port = 10008; 
  }

$sock = new IO::Socket::INET ( PeerAddr => 'localhost', 
                               PeerPort => $rfx_port, 
                               Proto => 'tcp' 
                               );
if ( not defined $sock ) {
  my $rfx_pid = fork();
  if (not defined $rfx_pid) {
    &sig_error("UNABLE TO EXECUTE GIMP: Not enough resources");
    } 
  elsif ($rfx_pid == 0) {
    if ( -f $tmpdir . "rfxgimp.pid") {
      open(PIDFILE, $tmpdir . "rfxgimp.pid");
      # should probably do some sanity checking for the off chance that
      # the PID has been recycled or the system has rebooted (e.g, check
      # if process was executed with /usr/bin/perl. But for now...
      kill(15, -<PIDFILE>); # the negative PID means kill all children, too.
      close(PIDFILE);
      }
    setpgid($$,0); # change the pgroup to this forked process, rather than
                   # the original LiVES (so that we don't kill LiVES when 
                   # this prgroup is killed).
    open(PIDFILE, ">" . $tmpdir . "rfxgimp.pid"); # overwrite old file
    print PIDFILE $$;
    close(PIDFILE);
    my $start_gimp = qq{ gimp -i -b "(plug-in-script-fu-server 1 $rfx_port \\\"\\\")" & };
    system ( $start_gimp ); # though started as separate process, GIMP now
                            # is part of this spawned child's pgroup, not the LiVES pgroup
    sleep(); # do nothing, forever
    &sig_error("GIMP killed by external process\n");
    }
  else {
    while (not defined $sock) {
      sleep (1);
      $sock = new IO::Socket::INET ( PeerAddr => 'localhost', 
                                     PeerPort => $rfx_port, 
                                     Proto => 'tcp' 
                                     );
      }
    }
  }

# Define a Perl subroutine for sending messages to the SF server and waiting
# for a response.
#
sub rfx_sendmsg {
  my $message = $_[0];
  my $len = length ($message);
  if ($len > 65535) {
    &sig_error("ERROR: script is too long for one server request: $len > 65535");
    };
  # send script to GIMP
  my $header = pack( 'an', 'G', $len);
  syswrite( $sock, $_ ) for ($header, $message);
  # wait for response
  my $rin = '';
  vec( $rin, fileno($sock), 1 ) = 1;
  select( $rin,  undef, undef, undef );    # wait (forever) for response start
  select( undef, undef, undef, .1 );       # wait a bit for response to finish
                                           #  increase wait if INVALID/INCOMPLETE RESPONSE occurs
  # response
  $len = sysread( $sock, $header, 4 ) or &sig_error("INVALID RESPONSE: empty response");
  ( $len == 4 and $header =~ /^G/ ) or &sig_error("INVALID RESPONSE: bad header");
  my $status;
  ($status, $len) = unpack( 'xCn', $header );
  my $response;
  ( sysread( $sock, $response, $len ) == $len ) or &sig_error("INCOMPLETE RESPONSE: $response");
  # exit if response is not "Success"
  if ( $status and $response =~ /^Error: Success\n/i ) {
    &sig_error("UNSUCCESSFUL EXECUTION: Script-fu error");
    }
  $status; 
  }

# define a Script-fu utility function to save frames using the PNG or JPG
# compression levels specified in 'gimprc'. 
# To specify a PNG compression level of 5, include the following line
# in gimprc:
#   (rfx-png-compression "5") 
# If not specified then a default level of "3" is assumed.
# "3" is a good choice for PNGs because higher levels double the write
# times while only offering about 15% reduction in file size.
# To specify a JPG compression level of 85, include the following line
# in gimprc:
#   (rfx-jpg-compression "85") 
# If not specified then a default level of "93" is assumed.

# NOTE: 'rfx-save-frame' DELETES the image.  
&rfx_sendmsg( qq{
  (begin
    (define rfx-curtmpdir "$curtmpdir")
    (define rfx-imgext "$img_ext")
    (unless (defined? 'rfx-save-frame)
      (define rfx-png-compression (catch #f (gimp-gimprc-query "rfx-png-compression")))
      (set! rfx-png-compression (if rfx-png-compression
                                  (string->number (car rfx-png-compression))
                                  3 ))
      (define rfx-jpg-compression (catch #f (gimp-gimprc-query "rfx-jpg-compression")))
      (set! rfx-jpg-compression (if rfx-jpg-compression
                                  (string->number (car rfx-jpg-compression))
                                  93 ))
      (define (rfx-save-frame image basename)
        (let ((filename (string-append rfx-curtmpdir DIR-SEPARATOR basename))
              (layer (car (gimp-image-get-active-layer image))) )
          (if (string-ci=? rfx-imgext ".jpg")
            (begin
              (gimp-context-push)
              (gimp-context-set-background '(6 6 6))
              (let loop ((layers (vector->list (cadr (gimp-image-get-layers image)))))
                (unless (null? layers)
                  (if (= (car layers) layer)
                    (gimp-drawable-set-visible layer TRUE)
                    (gimp-drawable-set-visible (car layers) FALSE) )
                  (loop (cdr layers)) ))
              (set! layer (car (gimp-image-flatten image)))
              (file-jpeg-save RUN-NONINTERACTIVE 
                              image 
                              layer
                              filename 
                              filename 
                              (/ rfx-jpg-compression 100)
                              0 ; smoothing 
                              1 ; optimize 
                              1 ; progressive 
                              "" ; comment 
                              0 ; subsmp (0-4)
                              1 ; baseline 
                              0 ; restart 
                              0 ;dct 
                              )
              (gimp-context-pop) )
            (begin
              (unless (zero? (car (gimp-image-base-type image)))
                (gimp-image-convert-rgb image) )
              (file-png-save2 RUN-NONINTERACTIVE 
                              image 
                              layer
                              filename 
                              filename 
                              FALSE ; interlace
                              rfx-png-compression
                              FALSE ; bkgd
                              (car (gimp-drawable-has-alpha layer))
                              FALSE ; offs
                              FALSE ; phys
                              FALSE ; time
                              TRUE  ; comment
                              FALSE ; svtrans
                              )))
          (gimp-image-delete image) )))
    (define (make-progressor start delta . period)
      (let ((start start)
            (value start)
            (delta delta)
            (period (if (null? period)
                        #f
                        (car period)) ))
        (lambda ()
          (let ((temp value))
            (set! value (if (and period (>= (+ value delta) (+ start period)))
                          (- (+ value delta) period)
                          (+ value delta) ))
            temp ))))
    )
  }
  );
</pre>

<loop>
# $p0 - Horizontal pieces
# $p1 - Vertical pieces
# $p2 - Curved edges (boolean)

&rfx_sendmsg (
  qq{
    (begin
      (when (= $frame $start)
        (define rfx-jigsaw-pieces '())
        (define rfx-jigsaw-keyframes '())
        (let* ((jigsaw-image (car (gimp-image-new $width $height RGB)))
               (layer (car (gimp-layer-new jigsaw-image 
                                           $width 
                                           $height 
                                           RGBA-IMAGE
                                           "jigsaw"
                                           100
                                           NORMAL-MODE ))))
          (gimp-image-add-layer jigsaw-image layer 0)
          (gimp-drawable-fill layer WHITE-FILL)
          (plug-in-jigsaw RUN-NONINTERACTIVE jigsaw-image layer $p0 $p1 $p2 0 0)
          (let row-loop ((row $p1))
            (unless (zero? row)
              (let col-loop ((col $p0))
                (if (zero? col)
                  (row-loop (pred row))
                  (begin
                    (gimp-fuzzy-select layer 
                                       (- (* (/ $width $p0) col) (/ $width $p0 2))
                                       (- (* (/ $height $p1) row) (/ $height $p1 2))
                                       128 
                                       CHANNEL-OP-REPLACE
                                       FALSE
                                       FALSE
                                       0
                                       FALSE )
                    (plug-in-sel2path RUN-NONINTERACTIVE jigsaw-image layer)
                    (set! rfx-jigsaw-pieces 
                          (cons (car (gimp-vectors-export-to-string 
                                         jigsaw-image 
                                         (car (gimp-image-get-active-vectors jigsaw-image)) ))
                                rfx-jigsaw-pieces ))
                    (col-loop (pred col)) )))))
          (gimp-image-delete jigsaw-image) 
          )
        ;; randomize the list of pieces
        (let ((number-of-pieces (length rfx-jigsaw-pieces)))
          (set! rfx-jigsaw-pieces 
                (let loop ((lis rfx-jigsaw-pieces)
                           (k number-of-pieces) )
                  (if (zero? k)
                    lis
                    (let ((index (random number-of-pieces)))
                      (loop (append (list-tail lis index)
                                    (list-tail (reverse lis) (- (length lis)  index)) )
                            (pred k) ))))))
        (let ((next-keyframe (make-progressor $start (/ (- $end $start) (* $p0 $p1)))))
          (set! rfx-jigsaw-keyframes (map next-keyframe rfx-jigsaw-pieces))
          )
        )
      (let* ((input-file (string-append "$curtmpdir" DIR-SEPARATOR "$in"))
             (image (car (gimp-file-load RUN-NONINTERACTIVE input-file input-file)))
             (layer (car (gimp-image-get-active-layer image)))
             (input-file2 (string-append "$in2"))
             (image2 (car (gimp-file-load RUN-NONINTERACTIVE input-file2 input-file2)))
             (b-layer (car (gimp-layer-new-from-drawable 
                                (car (gimp-image-get-active-layer image2)) 
                                image ))) )
        (gimp-image-undo-disable image)
        (gimp-image-add-layer image b-layer 1)
        (gimp-image-delete image2)

        (gimp-layer-add-alpha layer)
        (gimp-selection-none image)

        (let loop ((keyframes rfx-jigsaw-keyframes)
                   (pieces rfx-jigsaw-pieces) )
          (unless (null? keyframes)
            (let ((path (vector-ref (cadr (gimp-vectors-import-from-string image 
                                                              (car pieces)
                                                              -1
                                                              TRUE
                                                              FALSE ))
                                    0 )))
              (gimp-vectors-to-selection path CHANNEL-OP-ADD TRUE FALSE 0 0)
              (loop (cdr keyframes)
                    (cdr pieces) ))))
        (gimp-selection-grow image 1)
        (gimp-edit-clear layer)
        (when (and (pair? (cdr rfx-jigsaw-keyframes))
                   (>= $frame (cadr rfx-jigsaw-keyframes)) )
          (set! rfx-jigsaw-keyframes (cdr rfx-jigsaw-keyframes)) )

        (gimp-image-merge-visible-layers image CLIP-TO-IMAGE)
        (rfx-save-frame image "$out") 
        )
      )
    }
  );
</loop>

<post>
</post>

<onchange>
init|$p0_max = 50;
init|$p1_max = 50;
init|$p0 = 3;
init|$p1 = 3;
</onchange>

Added transitions/jigsaw.loop.







































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# $p0 - Horizontal pieces
# $p1 - Vertical pieces
# $p2 - Curved edges (boolean)

&rfx_sendmsg (
  qq{
    (begin
      (when (= $frame $start)
        (define rfx-jigsaw-pieces '())
        (define rfx-jigsaw-keyframes '())
        (let* ((jigsaw-image (car (gimp-image-new $width $height RGB)))
               (layer (car (gimp-layer-new jigsaw-image 
                                           $width 
                                           $height 
                                           RGBA-IMAGE
                                           "jigsaw"
                                           100
                                           NORMAL-MODE ))))
          (gimp-image-add-layer jigsaw-image layer 0)
          (gimp-drawable-fill layer WHITE-FILL)
          (plug-in-jigsaw RUN-NONINTERACTIVE jigsaw-image layer $p0 $p1 $p2 0 0)
          (let row-loop ((row $p1))
            (unless (zero? row)
              (let col-loop ((col $p0))
                (if (zero? col)
                  (row-loop (pred row))
                  (begin
                    (gimp-fuzzy-select layer 
                                       (- (* (/ $width $p0) col) (/ $width $p0 2))
                                       (- (* (/ $height $p1) row) (/ $height $p1 2))
                                       128 
                                       CHANNEL-OP-REPLACE
                                       FALSE
                                       FALSE
                                       0
                                       FALSE )
                    (plug-in-sel2path RUN-NONINTERACTIVE jigsaw-image layer)
                    (set! rfx-jigsaw-pieces 
                          (cons (car (gimp-vectors-export-to-string 
                                         jigsaw-image 
                                         (car (gimp-image-get-active-vectors jigsaw-image)) ))
                                rfx-jigsaw-pieces ))
                    (col-loop (pred col)) )))))
          (gimp-image-delete jigsaw-image) 
          )
        ;; randomize the list of pieces
        (let ((number-of-pieces (length rfx-jigsaw-pieces)))
          (set! rfx-jigsaw-pieces 
                (let loop ((lis rfx-jigsaw-pieces)
                           (k number-of-pieces) )
                  (if (zero? k)
                    lis
                    (let ((index (random number-of-pieces)))
                      (loop (append (list-tail lis index)
                                    (list-tail (reverse lis) (- (length lis)  index)) )
                            (pred k) ))))))
        (let ((next-keyframe (make-progressor $start (/ (- $end $start) (* $p0 $p1)))))
          (set! rfx-jigsaw-keyframes (map next-keyframe rfx-jigsaw-pieces))
          )
        )
      (let* ((input-file (string-append "$curtmpdir" DIR-SEPARATOR "$in"))
             (image (car (gimp-file-load RUN-NONINTERACTIVE input-file input-file)))
             (layer (car (gimp-image-get-active-layer image)))
             (input-file2 (string-append "$in2"))
             (image2 (car (gimp-file-load RUN-NONINTERACTIVE input-file2 input-file2)))
             (b-layer (car (gimp-layer-new-from-drawable 
                                (car (gimp-image-get-active-layer image2)) 
                                image ))) )
        (gimp-image-undo-disable image)
        (gimp-image-add-layer image b-layer 1)
        (gimp-image-delete image2)

        (gimp-layer-add-alpha layer)
        (gimp-selection-none image)

        (let loop ((keyframes rfx-jigsaw-keyframes)
                   (pieces rfx-jigsaw-pieces) )
          (unless (null? keyframes)
            (let ((path (vector-ref (cadr (gimp-vectors-import-from-string image 
                                                              (car pieces)
                                                              -1
                                                              TRUE
                                                              FALSE ))
                                    0 )))
              (gimp-vectors-to-selection path CHANNEL-OP-ADD TRUE FALSE 0 0)
              (loop (cdr keyframes)
                    (cdr pieces) ))))
        (gimp-selection-grow image 1)
        (gimp-edit-clear layer)
        (when (and (pair? (cdr rfx-jigsaw-keyframes))
                   (>= $frame (cadr rfx-jigsaw-keyframes)) )
          (set! rfx-jigsaw-keyframes (cdr rfx-jigsaw-keyframes)) )

        (gimp-image-merge-visible-layers image CLIP-TO-IMAGE)
        (rfx-save-frame image "$out") 
        )
      )
    }
  );