RFX-GIMP

Check-in [10e9ed69cf]
Login

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

Overview
Comment:New script (transition actually)
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:10e9ed69cf6bcc6bbeffd3000bbdeb5749efb6d0
User & Date: saul 2012-04-10 06:48:14
Context
2012-04-15
06:36
New script using GIMP's 'waves' plug-in that makes pond ripples. check-in: 9feb27b2d2 user: saul tags: trunk
2012-04-10
06:48
New script (transition actually) check-in: 10e9ed69cf user: saul tags: trunk
2012-04-05
14:00
Forgot .script file check-in: e765fa2557 user: saul tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added scripts/color-match.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
Script file generated from LiVES

<define>
|1.7
</define>

<name>
color-match
</name>

<version>
1
</version>

<author>
saulgoode|
</author>

<description>
Color match|Matching colors|1|2|
</description>

<requires>
gimp
</requires>

<params>

</params>

<param_window>
</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>
&rfx_sendmsg (
  qq{
    (begin
      (when (= $start $frame)
        (define color-match-image (car (gimp-file-load RUN-NONINTERACTIVE "$in2" "$in2")))
        (gimp-image-undo-disable color-match-image)
        (gimp-image-scale-full color-match-image $width $height INTERPOLATION-CUBIC)
        (gimp-convert-indexed color-match-image NO-DITHER MAKE-PALETTE 256 FALSE TRUE "") )
        
      (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)))
             (decomp-mode "LAB") 
               ; (decomp-mode "YCbCr_ITU_R709")
               ; (decomp-mode "YCbCr_ITU_R470")
             (cb-image (car (gimp-image-duplicate color-match-image)))
             (decomp-layer 0)
             (y-images '())
             (uv-images '()) )
        (gimp-image-undo-disable image)
        (gimp-image-undo-disable cb-image)
        (set! decomp-layer (car (gimp-layer-new-from-drawable layer cb-image)))
        (gimp-image-add-layer cb-image decomp-layer 0)
        (gimp-convert-rgb cb-image)
        (let ((y-images (plug-in-decompose RUN-NONINTERACTIVE 
                                           image 
                                           layer
                                           decomp-mode 
                                           FALSE ))
              (uv-images (plug-in-decompose RUN-NONINTERACTIVE 
                                            cb-image 
                                            decomp-layer
                                            decomp-mode 
                                            FALSE )) )
          (gimp-image-delete cb-image)
          (set! cb-image (car (plug-in-compose RUN-NONINTERACTIVE
                                               (car y-images)
                                               0
                                               (cadr uv-images)
                                               (caddr uv-images)
                                               (cadddr y-images)
                                               decomp-mode  )))
          (map (lambda (x) (unless (< x 1) (gimp-image-delete x))) y-images)
          (map (lambda (x) (unless (< x 1) (gimp-image-delete x))) uv-images) )
        (gimp-image-delete image)

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

<post>
&rfx_sendmsg (
  qq{
    (gimp-image-delete color-match-image))
    }
  );
</post>

<onchange>
</onchange>

Added transitions/color-match.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
&rfx_sendmsg (
  qq{
    (begin
      (when (= $start $frame)
        (define color-match-image (car (gimp-file-load RUN-NONINTERACTIVE "$in2" "$in2")))
        (gimp-image-undo-disable color-match-image)
        (gimp-image-scale-full color-match-image $width $height INTERPOLATION-CUBIC)
        (gimp-convert-indexed color-match-image NO-DITHER MAKE-PALETTE 256 FALSE TRUE "") )
        
      (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)))
             (decomp-mode "LAB") 
               ; (decomp-mode "YCbCr_ITU_R709")
               ; (decomp-mode "YCbCr_ITU_R470")
             (cb-image (car (gimp-image-duplicate color-match-image)))
             (decomp-layer 0)
             (y-images '())
             (uv-images '()) )
        (gimp-image-undo-disable image)
        (gimp-image-undo-disable cb-image)
        (set! decomp-layer (car (gimp-layer-new-from-drawable layer cb-image)))
        (gimp-image-add-layer cb-image decomp-layer 0)
        (gimp-convert-rgb cb-image)
        (let ((y-images (plug-in-decompose RUN-NONINTERACTIVE 
                                           image 
                                           layer
                                           decomp-mode 
                                           FALSE ))
              (uv-images (plug-in-decompose RUN-NONINTERACTIVE 
                                            cb-image 
                                            decomp-layer
                                            decomp-mode 
                                            FALSE )) )
          (gimp-image-delete cb-image)
          (set! cb-image (car (plug-in-compose RUN-NONINTERACTIVE
                                               (car y-images)
                                               0
                                               (cadr uv-images)
                                               (caddr uv-images)
                                               (cadddr y-images)
                                               decomp-mode  )))
          (map (lambda (x) (unless (< x 1) (gimp-image-delete x))) y-images)
          (map (lambda (x) (unless (< x 1) (gimp-image-delete x))) uv-images) )
        (gimp-image-delete image)

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

Added transitions/color-match.post.











>
>
>
>
>
1
2
3
4
5
&rfx_sendmsg (
  qq{
    (gimp-image-delete color-match-image)
    }
  );