1############################################################################# 2# Author: # 3# ------ # 4# Anton Kokalj Email: Tone.Kokalj@ijs.si # 5# Department of Physical and Organic Chemistry Phone: x 386 1 477 3523 # 6# Jozef Stefan Institute Fax: x 386 1 477 3811 # 7# Jamova 39, SI-1000 Ljubljana # 8# SLOVENIA # 9# # 10# Source: $XCRYSDEN_TOPDIR/Tcl/__file__ 11# ------ # 12# Copyright (c) 2008 by Anton Kokalj # 13############################################################################# 14 15proc determine_movie_encoders {} { 16 global xcMisc 17 18 set gif_encoder_priority_list {convert gifsicle whirlgif} 19 set movie_encoder_priority_list {mencoder ppmtompeg} 20 21 if { [info exists xcMisc(gif_encoder)] } { 22 set gif_encoder_priority_list [linsert $gif_encoder_priority_list 0 [file tail $xcMisc(gif_encoder)]] 23 } 24 if { [info exists xcMisc(movie_encoder)] } { 25 set movie_encoder_priority_list [linsert $movie_encoder_priority_list 0 [file tail $xcMisc(movie_encoder)]] 26 } 27 28 foreach enc $gif_encoder_priority_list { 29 if { [info exists xcMisc($enc)] } { 30 set xcMisc(gif_encoder) $enc 31 break 32 } 33 } 34 35 foreach enc $movie_encoder_priority_list { 36 if { [info exists xcMisc($enc)] } { 37 set xcMisc(movie_encoder) $enc 38 break 39 } 40 } 41} 42 43 44# ------------------------------------------------------------------------ 45# 46# AVI/MPEG movies 47# 48# ------------------------------------------------------------------------ 49 50proc encode_movie {filelist outfile} { 51 global gifAnim xcMisc system 52 53 if { $gifAnim(temp_files_dir) == "pwd" } { 54 set dir $system(PWD) 55 cd $system(PWD) 56 } else { 57 set dir $system(SCRDIR) 58 cd $system(SCRDIR) 59 } 60 61 set cmdLine [cmdLine_$xcMisc(movie_encoder) $filelist $outfile $dir] 62 63 set cw [DisplayUpdateWidget "Encoding" "Encoding the movie"] 64 eval xcCatchExecReturnRedirectStdErr $cmdLine 65 destroy $cw 66} 67 68 69proc cmdLine_ppmtompeg {filelist outfile input_dir} { 70 global xcMisc 71 return "$xcMisc(ppmtompeg) [mpegCreateParamFile $outfile $input_dir [join $filelist\n]]" 72} 73 74 75proc cmdLine_mencoder {filelist outfile input_dir} { 76 global gifAnim xcMisc 77 78 if { [regexp {\.ppm[ \n\r,]|\.ppm$} $filelist] } { 79 # we need to convert all *.PPM files to *.PNG files 80 set cw [DisplayUpdateWidget "Converting" "Converting frame files to PNG format"] 81 foreach image $gifAnim(filelist) { 82 set newfile [file rootname $image].png 83 scripting::_printToFile_imageConvert $image $newfile 84 } 85 set tmplist $filelist 86 regsub -all -- {\.ppm} $tmplist .png filelist 87 destroy $cw 88 } 89 90 set delay [expr {$gifAnim(delay) <= 0.0 ? 1 : $gifAnim(delay)}] 91 set fps [expr 100.0 / $delay] 92 93 set cmdLine "$xcMisc(mencoder) mf://[join $filelist ,]" 94 95 if { [string toupper [file extension $outfile]] == ".AVI" } { 96 # create AVI file 97 append cmdLine " -mf fps=$fps -o $outfile -ovc lavc -lavcopts vcodec=mpeg4" 98 } else { 99 # create MPEG file 100 append cmdLine " -of mpeg -mf fps=$fps -o $outfile -ovc lavc -lavcopts vcodec=mpeg2video" 101 } 102 103 if { $gifAnim(edit_param) } { 104 set cmdLine [gifAnim:editParam $cmdLine] 105 } 106 return $cmdLine 107} 108 109 110# ------------------------------------------------------------------------ 111# 112# Animated GIF 113# 114# ------------------------------------------------------------------------ 115 116proc encode_gif {filelist outfile} { 117 global gifAnim xcMisc mesa_bg system 118 119 # determine the background color 120 121 if { $gifAnim(gif_transp) } { 122 if { ! [info exists mesa_bg(current)] } { 123 set mesa_bg(current) \#000000 124 } 125 if { [string index $mesa_bg(current) 0] == "#" } { 126 set bg_color $mesa_bg(current) 127 } else { 128 set bg_color [rgb_f2h $mesa_bg(current)] 129 } 130 set gifAnim(bg_color) $bg_color 131 } 132 133 # construct the execution command-line for encoding 134 135 set cmdLine [cmdLine_$xcMisc(gif_encoder) $filelist $outfile] 136 137 # encode ... 138 139 if { $gifAnim(temp_files_dir) == "pwd" } { 140 cd $system(PWD) 141 } else { 142 cd $system(SCRDIR) 143 } 144 if { $gifAnim(edit_param) } { 145 set cmdLine [gifAnim:editParam $cmdLine] 146 } 147 148 puts stderr "cmdLine=$cmdLine" 149 flush stderr 150 151 set cw [DisplayUpdateWidget "Encoding" "Encoding the Animated-GIF movie"] 152 if { $xcMisc(gif_encoder) != "gifsicle" } { 153 eval xcCatchExecReturnRedirectStdErr $cmdLine 154 } else { 155 eval exec_gifsicle $cmdLine 156 } 157 destroy $cw 158} 159 160 161proc cmdLine_convert {filelist outfile} { 162 global gifAnim xcMisc 163 164 if { $gifAnim(gif_transp) } { 165 append comlin " -dispose Previous" 166 } 167 168 append comlin " $filelist -set delay $gifAnim(delay) -loop $gifAnim(loop)" 169 170 if { $gifAnim(gif_global_colormap) && !$gifAnim(gif_transp) } { 171 append comlin " +map" 172 } 173 if { $gifAnim(gif_transp) } { 174 append comlin " -transparent $gifAnim(bg_color)" 175 } 176 if { $gifAnim(gif_minimize) } { 177 append comlin " -layers optimize" 178 } 179 return [format "%s %s %s" $xcMisc(convert) $comlin $outfile] 180} 181 182 183proc cmdLine_gifsicle {filelist outfile} { 184 global gifAnim xcMisc 185 186 set flags "--no-warnings --delay $gifAnim(delay) --loopcount=$gifAnim(loop)" 187 if { $gifAnim(gif_transp) } { 188 append flags " --disposal background --transparent=$gifAnim(bg_color)" 189 } 190 if { $gifAnim(gif_minimize) } { 191 append flags " -O2" 192 } 193 if { $gifAnim(gif_global_colormap) } { 194 # ignored 195 } 196 return [format "%s %s %s > %s" $xcMisc(gifsicle) $flags $filelist $outfile] 197} 198 199 200proc cmdLine_whirlgif {filelist outfile} { 201 global gifAnim xcMisc 202 203 set flags " -time $gifAnim(delay) -loop $gifAnim(loop)" 204 if { $gifAnim(gif_minimize) } { 205 append flags " -minimize" 206 } 207 if { $gifAnim(gif_global_colormap) } { 208 append flags " -globalmap" 209 } 210 if { $gifAnim(gif_transp) } { 211 append flags " -disp prev -trans $gifAnim(bg_color)" 212 } 213 214 return [format "%s %s %s %s %s" $xcMisc(whirlgif) $flags -o $outfile $filelist] 215} 216 217 218proc exec_gifsicle {args} { 219 xcDebug -stderr "Executing: $args" 220 if { [catch {eval exec $args 2> gifsicle.stderr} errMsg] } { 221 # gifsicle returns wrong status of 1 when -transparent option 222 # is used 223 set msg [ReadFile gifsicle.stderr] 224 if { [string match {*Usage: gifsicle*} $msg] } { 225 ErrorDialogInfo "while executing\nexec $args" $msg\n$errMsg 226 uplevel 1 { 227 return 1 228 } 229 } 230 } 231 return 0 232}