2

Im reading a printscreen image from a scope that is in .gif format by sending a query to this scope. The returned data is in binary block form. I am communicating to this scope through a socket connection and using tcl. I could read the data fine, but when I try to write the data to a local file, it doesnt seem to write properly, as the created file has no information in it. Objective: to save or write this data to a local file so it can be accessed later.

Here's the piece of code trying to do the task in TCL.

#reading .gif data(binary block form) and writing it to a local file

fconfigure $channelid -encoding binary -translation binary ; #converts the stdin to binary data input
fconfigure $fileId -encoding binary -translation binary ; #converts the stdout to binary data output
set image [getdata $channelid "some query?"] ;# getdata proc reads the query returned data 
puts stderr $image ;#to verify what data I am reading
set filename "C:/test.gif"
set fileId [open $filename "w"]
puts -nonewline $fileId $image
close $fileId

Any thoughts or help will be much appreciated. Thanks.

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
shokii
  • 21
  • 1

1 Answers1

2

GIF data is fundamentally binary; when writing it out, you need to write it as binary or Tcl will apply some transformations to it (e.g., encoding conversion) that are correct for text data but wrong for binary. The easiest way to do that is to open with the wb mode instead of w if the version of Tcl you're using supports that — it was introduced in 8.5 to make things a bit more like C stdio — but otherwise use fconfigure $fileId -translation binary after opening and before writing any data.

Note that Tcl always operates on things immediately as presented; you can't fconfigure a channel before opening it. I'm guessing that your second fconfigure is really a few lines too early. It's probably a good idea for you to turn that code into a procedure so that it doesn't deal with global variables; this helps you detect all sorts of problems with operation ordering much more easily:

proc copy_data {source_channel query_string target_file} {
    # -translation binary implies -encoding binary (and a few other things too)
    fconfigure $source_channel -translation binary
    set image [getdata $source_channel $query_string]
    set fileId [open $target_file "wb"]
    puts -nonewline $fileId $image
    close $fileId
}

# Invoke to do the operation from your example
copy_data $channelid "some query?" "C:/test.gif"
Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • OK, some of Tcl's immediate operations arrange for things to happen later or define things that are used later, but the scheduling/definition _itself_ happens immediately. – Donal Fellows Oct 06 '12 at 07:52