Ignore:
Timestamp:
Jan 31, 2010, 8:39:13 PM (15 years ago)
Author:
gah
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/blt4/gui/scripts/icons.tcl

    r1646 r1649  
    5050    if {"" != $file} {
    5151        switch -- [file extension $file] {
    52             .gif - .jpg - .png {
     52            .gif - .jpg - .png - .xpm - .tif {
    5353                set imh [image create picture -file $file]
    5454            }
     
    7575# ----------------------------------------------------------------------
    7676proc Rappture::icon::data {image {format "gif"}} {
    77     if {[catch {$image data -format $format} result]} {
    78         if {"too many colors" == $result && "" != [auto_execok djpeg]} {
    79             #
    80             # HACK ALERT!  We should use "blt::winop quantize" to
    81             #   reduce the number of colors for GIF format.  But
    82             #   it has a bug right now, so we work around it like this.
    83             #
    84             set tmpfile /tmp/image[pid].dat
    85             $image write $tmpfile -format "jpeg -quality 100"
    86             set fid [open "| djpeg -gif -quantize 250 $tmpfile" r]
    87             fconfigure $fid -encoding binary -translation binary
    88             set result [read $fid]
    89             close $fid
    90             file delete -force $tmpfile
    91         } else {
    92             set result ""
     77    switch -- $format {
     78        "gif" {
     79            $image export gif -data bytes
    9380        }
    94     }
    95     return $result
     81        "jpeg" - "jpg" {
     82            $image export jpg -data bytes -quality 100
     83        }
     84        default {
     85            return ""
     86        }
     87    }       
     88    return $bytes
    9689}
    9790
     
    108101    }
    109102    set delay [expr {round($delay*0.01)}] ;# convert to 1/100s of second
    110 
    111     set imh [lindex $args 0]
    112     set bytes [data $imh gif]
    113     if {[string length $bytes] == 0} {
    114         return ""  ;# can't query image data -- bail out!
    115     }
    116     gif_parse $bytes first
    117 
    118     set final "GIF89a"
    119     gif_put_short final $first(screen-w)
    120     gif_put_short final $first(screen-h)
    121     gif_put_byte final $first(screen-packed)
    122     gif_put_byte final $first(screen-bg)
    123     gif_put_byte final $first(screen-aspect)
    124     gif_put_block final $first(colors)
    125 
    126     gif_put_byte final 0x21  ;# looping block
    127     gif_put_byte final 0xFF
    128     gif_put_byte final 11
    129     gif_put_block final "NETSCAPE2.0"
    130     gif_put_byte final 3     ;# 3 bytes in this block
    131     gif_put_byte final 1     ;# turn looping on
    132     gif_put_short final 0    ;# number of loops (forever)
    133     gif_put_byte final 0     ;# block terminator
    134 
    135     gif_put_byte final 0x21  ;# graphic control block
    136     gif_put_byte final 0xF9
    137     gif_put_byte final 4     ;# 4 bytes in this block
    138     gif_put_byte final 0     ;# packed bits
    139     gif_put_short final [expr {5*$delay}]  ;# delay time *0.01s
    140     gif_put_byte final 0     ;# transparency index
    141     gif_put_byte final 0     ;# block terminator
    142 
    143     gif_put_byte final 0x2C  ;# image block
    144     gif_put_short final $first(im-0-left)
    145     gif_put_short final $first(im-0-top)
    146     gif_put_short final $first(im-0-wd)
    147     gif_put_short final $first(im-0-ht)
    148     gif_put_byte final $first(im-0-packed)
    149     if {($first(im-0-packed) & 0x80) != 0} {
    150         gif_put_block final $first(im-0-colors)
    151     }
    152     gif_put_block final $first(im-0-data)
    153 
    154     foreach imh [lrange $args 1 end] {
    155         catch {unset gif}
    156         gif_parse [data $imh gif] gif
    157 
    158         gif_put_byte final 0x21     ;# graphic control block
    159         gif_put_byte final 0xF9
    160         gif_put_byte final 4        ;# 4 bytes in this block
    161         gif_put_byte final 0        ;# packed bits
    162         gif_put_short final $delay  ;# delay time *0.01s
    163         gif_put_byte final 0        ;# transparency index
    164         gif_put_byte final 0        ;# block terminator
    165 
    166         gif_put_byte final 0x2C     ;# image block
    167         gif_put_short final $gif(im-0-left)
    168         gif_put_short final $gif(im-0-top)
    169         gif_put_short final $gif(im-0-wd)
    170         gif_put_short final $gif(im-0-ht)
    171 
    172         if {[string length $gif(im-0-colors)] > 0} {
    173             gif_put_byte final $gif(im-0-packed)
    174             gif_put_block final $gif(im-0-colors)
    175         } else {
    176             set packed [expr {($gif(im-0-packed) & 0xF8)
    177                 | ($gif(screen-packed) & 0x87)}]
    178             gif_put_byte final $packed
    179             gif_put_block final $gif(colors)
    180         }
    181         gif_put_block final $gif(im-0-data)
    182     }
    183 
    184     gif_put_byte final 0x3B  ;# terminate GIF
    185 
    186     return $final
    187 }
    188 
    189 # ----------------------------------------------------------------------
    190 # USAGE: Rappture::icon::gif_parse <gifImageData> <array>
    191 #
    192 # Takes the data from a GIF image, parses it into various components,
    193 # and returns the information in the <array> in the calling scope.
    194 # ----------------------------------------------------------------------
    195 proc Rappture::icon::gif_parse {gifImageData arrayVar} {
    196     upvar $arrayVar data
    197     if {[string range $gifImageData 0 2] != "GIF"} {
    198         error "not GIF data"
    199     }
    200     set data(version) [string range $gifImageData 0 5]
    201     set pos 6
    202 
    203     set data(screen-w) [gif_get_short $gifImageData pos]
    204     set data(screen-h) [gif_get_short $gifImageData pos]
    205     set data(screen-packed) [gif_get_byte $gifImageData pos]
    206     set data(screen-bg) [gif_get_byte $gifImageData pos]
    207     set data(screen-aspect) [gif_get_byte $gifImageData pos]
    208 
    209     set ctsize [expr {3*(1 << ($data(screen-packed) & 0x07)+1)}]
    210     set data(colors) [gif_get_block $gifImageData pos $ctsize]
    211 
    212     set n 0
    213     while {1} {
    214         set ctrl [gif_get_byte $gifImageData pos]
    215         switch -- [format "0x%02X" $ctrl] {
    216           0x21 {
    217             set ext [gif_get_byte $gifImageData pos]
    218             switch -- [format "0x%02X" $ext] {
    219               0xF9 {
    220                 # graphic control
    221                 set bsize [gif_get_byte $gifImageData pos]
    222                 set data(gc-$n-packed) [gif_get_byte $gifImageData pos]
    223                 set data(gc-$n-delay) [gif_get_short $gifImageData pos]
    224                 set data(gc-$n-transp) [gif_get_byte $gifImageData pos]
    225                 set bterm [gif_get_byte $gifImageData pos]
    226                 if {$bterm != 0} { error "bad magic $bterm" }
    227               }
    228               0xFE {
    229                 # comment extension -- skip and ignore
    230                 while {1} {
    231                     set count [gif_get_byte $gifImageData pos]
    232                     if {$count == 0} {
    233                         break
    234                     }
    235                     incr pos $count
    236                 }
    237               }
    238               0xFF {
    239                 set bsize [gif_get_byte $gifImageData pos]
    240                 set data(app-name) [gif_get_block $gifImageData pos $bsize]
    241                 set data(app-bytes) ""
    242                 while {1} {
    243                     set count [gif_get_byte $gifImageData pos]
    244                     gif_put_byte data(app-bytes) $count
    245                     if {$count == 0} {
    246                         break
    247                     }
    248                     gif_put_block data(app-bytes) \
    249                         [gif_get_block $gifImageData pos $count]
    250                 }
    251               }
    252               default {
    253                 error [format "unknown extension code 0x%02X" $ext]
    254               }
    255             }
    256           }
    257           0x2C {
    258             # image data
    259             set data(im-$n-left) [gif_get_short $gifImageData pos]
    260             set data(im-$n-top) [gif_get_short $gifImageData pos]
    261             set data(im-$n-wd) [gif_get_short $gifImageData pos]
    262             set data(im-$n-ht) [gif_get_short $gifImageData pos]
    263             set data(im-$n-packed) [gif_get_byte $gifImageData pos]
    264             set data(im-$n-colors) ""
    265             if {($data(im-$n-packed) & 0x80) != 0} {
    266                 set ctsize [expr {3*(1 << ($data(im-$n-packed) & 0x07)+1)}]
    267                 set data(im-$n-colors) [gif_get_block $gifImageData pos $ctsize]
    268             }
    269    
    270             set data(im-$n-data) ""
    271             gif_put_byte data(im-$n-data) \
    272                 [gif_get_byte $gifImageData pos] ;# lwz min code size
    273             while {1} {
    274                 set count [gif_get_byte $gifImageData pos]
    275                 gif_put_byte data(im-$n-data) $count
    276                 if {$count == 0} {
    277                     break
    278                 }
    279                 gif_put_block data(im-$n-data) \
    280                     [gif_get_block $gifImageData pos $count]
    281             }
    282             incr n
    283           }
    284           0x3B {
    285             # end of image data
    286             break
    287           }
    288           default {
    289             error [format "unexpected control byte 0x%02X" $ctrl]
    290           }
    291         }
    292     }
    293 }
    294 
    295 # ----------------------------------------------------------------------
    296 # USAGE: Rappture::icon::gif_get_byte <buffer> <posVar>
    297 #
    298 # Extracts one byte of information from the <buffer> at the index
    299 # specified by <posVar> in the calling scope.  Increments <posVar>
    300 # to move past the byte and returns the byte of information.
    301 # ----------------------------------------------------------------------
    302 proc Rappture::icon::gif_get_byte {buffer posVar} {
    303     upvar $posVar pos
    304     set byte [string range $buffer $pos $pos]
    305     incr pos 1
    306 
    307     binary scan $byte c rval
    308     if {$rval < 0} {incr rval 256}
    309     return $rval
    310 }
    311 
    312 # ----------------------------------------------------------------------
    313 # USAGE: Rappture::icon::gif_get_short <buffer> <posVar>
    314 #
    315 # Extracts one short int of information from the <buffer> at the index
    316 # specified by <posVar> in the calling scope.  Increments <posVar>
    317 # to move past the int and returns the information.
    318 # ----------------------------------------------------------------------
    319 proc Rappture::icon::gif_get_short {buffer posVar} {
    320     upvar $posVar pos
    321     set bytes [string range $buffer $pos [expr {$pos+1}]]
    322     incr pos 2
    323 
    324     binary scan $bytes s rval
    325     if {$rval < 0} {incr rval 65536}
    326     return $rval
    327 }
    328 
    329 # ----------------------------------------------------------------------
    330 # USAGE: Rappture::icon::gif_get_block <buffer> <posVar> <size>
    331 #
    332 # Extracts <size> bytes of information from the <buffer> at the index
    333 # specified by <posVar> in the calling scope.  Increments <posVar>
    334 # to move past the byte and returns the byte of information.
    335 # ----------------------------------------------------------------------
    336 proc Rappture::icon::gif_get_block {buffer posVar size} {
    337     upvar $posVar pos
    338     set bytes [string range $buffer $pos [expr {$pos+$size-1}]]
    339     incr pos $size
     103    set img [image create picture]
     104    $img copy [lindex $args 0]
     105    eval $img append [lrange $args 1 end]
     106    $img export gif -animated -data bytes -delay $delay
     107    image delete $img
    340108    return $bytes
    341109}
    342110
    343 # ----------------------------------------------------------------------
    344 # USAGE: Rappture::icon::gif_put_byte <buffer> <charVal>
    345 #
    346 # Appends one byte of information onto the <buffer> in the calling
    347 # scope.  The <charVal> is an integer in the range 0-255.  It is
    348 # formated as a single byte and appended onto the buffer.
    349 # ----------------------------------------------------------------------
    350 proc Rappture::icon::gif_put_byte {bufferVar char} {
    351     upvar $bufferVar buffer
    352     append buffer [binary format c $char]
    353 }
    354 
    355 # ----------------------------------------------------------------------
    356 # USAGE: Rappture::icon::gif_put_short <buffer> <shortVal>
    357 #
    358 # Appends one byte of information onto the <buffer> in the calling
    359 # scope.  The <shortVal> is an integer in the range 0-65535.  It is
    360 # formated as a 2-byte short integer and appended onto the buffer.
    361 # ----------------------------------------------------------------------
    362 proc Rappture::icon::gif_put_short {bufferVar short} {
    363     upvar $bufferVar buffer
    364     append buffer [binary format s $short]
    365 }
    366 
    367 # ----------------------------------------------------------------------
    368 # USAGE: Rappture::icon::gif_put_block <buffer> <val>
    369 #
    370 # Appends a string <val> onto the <buffer> in the calling scope.
    371 # ----------------------------------------------------------------------
    372 proc Rappture::icon::gif_put_block {bufferVar val} {
    373     upvar $bufferVar buffer
    374     append buffer $val
    375 }
Note: See TracChangeset for help on using the changeset viewer.