#------------------------------------------------------------------------
#
# Copyright (c) 1997-1998 by Cornell University.
# 
# See the file "license.txt" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
#------------------------------------------------------------------------
# giftoppm.vm
# Convert a GIF to one or more PPMs

package require DvmBasic
package require DvmImap
package require DvmPnm
package require DvmGif

source ../lib/pnmlib.tcl

if {$argc < 2} {
    puts "Enter input GIF file :"
    set infile [gets stdin]
    puts "Enter output PPM filename prefix (eg. prefix foo will generate foo0.pgm) :"
    set outfile [gets stdin]
} else {
    set infile [lindex $argv 0]
    set outfile [lindex $argv 1]
}

set hdr [gif_seq_hdr_new]

set bp   [bitparser_new]
set bs   [bitstream_new [file size $infile]]
set file [open $infile r]
fconfigure $file -translation binary -buffersize 65535
bitstream_channel_read $bs $file 0
bitparser_wrap $bp $bs

#Parse the sequence header
gif_seq_hdr_parse $bp $hdr


set rmap [imagemap_new]
set gmap [imagemap_new]
set bmap [imagemap_new]

#Parse the global color table, if present
if {[gif_seq_hdr_get_ct_flag $hdr] == 1} then {
    set ctsize [ gif_seq_hdr_get_ct_size $hdr ]
    gif_ct_parse $bp $ctsize $rmap $gmap $bmap
}


# Find the number of images
set currPos [ bitparser_tell $bp ]
set num 0
while {[gif_img_find $bp] == 0} {
    gif_img_skip $bp
    incr num
}
bitparser_seek $bp $currPos

set imgHdr [gif_img_hdr_new]
set pnmhdr [pnm_hdr_new]

for {set i 0} {$i < $num} {incr i} {

    #Find the next image and parse its header
    gif_img_find $bp
    gif_img_hdr_parse $bp $imgHdr

    # Allocate a new byte image for each image read, in case some have 
    # different dimensions
    set w [gif_img_hdr_get_width $imgHdr]
    set h [gif_img_hdr_get_height $imgHdr]
    set red [byte_new $w $h]
    set green [byte_new $w $h]
    set blue [byte_new $w $h]
    set indices [byte_new $w $h]

    #Parse the local color table, if present
    if {[gif_img_hdr_get_ct_flag $imgHdr] == 1} then {
        set lrmap [imagemap_new]
        set lgmap [imagemap_new]
        set lbmap [imagemap_new]
	set ctsize [gif_img_hdr_get_ct_size $imgHdr]

        gif_ct_parse $bp $ctsize $lrmap $lgmap $lbmap
    }

    #Parse the index image
    if {[gif_img_hdr_get_interlaced $imgHdr]} {
	gif_img_interlaced_parse $bp $hdr $imgHdr $indices
    } else {
	gif_img_non_interlaced_parse $bp $hdr $imgHdr $indices
    }

    #Create the RGB image by applying the appropriate image map
    if {[gif_img_hdr_get_ct_flag $imgHdr] == 1} then {
        imagemap_apply $lrmap $indices $red
        imagemap_apply $lgmap $indices $green
        imagemap_apply $lbmap $indices $blue

        imagemap_free $lrmap
        imagemap_free $lgmap
        imagemap_free $lbmap
    } else {
        imagemap_apply $rmap $indices $red
        imagemap_apply $gmap $indices $green
        imagemap_apply $bmap $indices $blue
    }

    # Write the RGB image to disk
    write_ppm $pnmhdr $red $green $blue ${outfile}${i}.ppm

    byte_free $red
    byte_free $green
    byte_free $blue
    byte_free $indices
}