# convert6432.py
#
# Program to modify the header in grd type 1 GMT files
# If these files are generated in Linux, the size of the header is 892;
# if they are created in Cygwin or by the Microsoft C binaries, the size
# is 896.
# This program modifies the header, thus converting files from one
# implementation to the other.
# From Linux to Cygwin, it inserts 4 bytes in the header
# From Cygwin to Linux, it removes 4 bytes in the header
# The original file is not modified; a new converted file is created.
# 
# convert6432 <input grd=1 file> <output grd=1 file> ishift
# 
# ishift = 4 to add 4 bytes  (linux to cygwin)
# ishift = -4 to remove 4 bytes (cygwin to linux)
#
# Marta, August 3, 2003
#
# mghidella@dna.gov.ar
#
# Translated into Python by David Finlayson (dfinlays@u.washington.edu)

import sys
import struct

# Get Command line Arguments
if len(sys.argv) != 4:
    print """
     USAGE: python convert6432.py <input grd=1 file> <output grd=1 file> ishift
        
     Needed arguments:
     1) Input grd file (grd format =1)
     2) Output grd file (grd format = 1)
     3) Number of bytes to shift in the header:
        4 (adds 4 bytes, linux to cygwin conversion)
       -4 (removes 4 bytes, cygwin to linux conversion)
    """
    sys.exit(-1)

infile = sys.argv[1]
outfile = sys.argv[2]
ishift = int(sys.argv[3])
print "infile: %s; outfile: %s; shift= %d" % (infile, outfile, ishift)

if (ishift != 4 and ishift != -4):
    print "third argument has to be either 4 or -4"
    sys.exit(-1)

try:
    fin = file(infile, 'rb')
except:
    print "error opening: %s" % (infile)
    sys.exit(-1)

try:
    fout = file(outfile, 'wb')
except:
    print "error opening: %s" % (outfile)
    sys.exit(-1)

# Reads the first 4 bytes in the file to check that it is not a netCDF file
aux = fin.read(4)
auxstr = []
auxstr.append(struct.unpack("c", aux[0])[0])
auxstr.append(struct.unpack("c", aux[1])[0])
auxstr.append(struct.unpack("c", aux[2])[0])
auxstr.append(str(struct.unpack("b", aux[3])[0]))
auxstr = "".join(auxstr)

if auxstr == "CDF1":
    print "seems to be a netCDF file: auxstr= %s" % (auxstr)
    sys.exit(-1)

# gets nx from auxilary char
nx = struct.unpack("i", aux)[0]

# Reads ny and node_offset
ny = fin.read(4)
ny = struct.unpack("i", ny)[0]
node_offset = fin.read(4)
node_offset = struct.unpack("i", node_offset)[0]

# writes nx, ny and node_offset in the output file
fout.write(struct.pack("i", nx))
fout.write(struct.pack("i", ny))
fout.write(struct.pack("i", node_offset))

print "nx= %d; ny= %d, node_offset=%d" % (nx, ny, node_offset)

# only reads in this case
if ishift == -4:
    npad = fin.read(4)

# only writes in this case
if ishift == 4:
    fout.write(struct.pack("i", 0))

# reads and writes the rest of the file
fout.write(fin.read())

fin.close()
fout.close()


