Skip to content

Commit 61125ad

Browse files
committed
Merge pull request #19 from kerim371/add-segy-endian-check
Add segy endian check
2 parents 8777868 + d7b3c77 commit 61125ad

12 files changed

+134
-48
lines changed

src/SegyIO.jl

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ module SegyIO
1919
include("types/SeisCon.jl")
2020

2121
#Reader
22+
include("read/endianness.jl")
2223
include("read/read_fileheader.jl")
2324
include("read/read_traceheader.jl")
2425
include("read/read_trace.jl")

src/read/endianness.jl

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
is_machine_littleendian() = Base.ENDIAN_BOM == 0x04030201
2+
is_machine_bigendian() = Base.ENDIAN_BOM == 0x01020304
3+
4+
function is_segy_littleendian(s::IO)
5+
bfh = BinaryFileHeader()
6+
fh_b2s = fh_byte2sample()
7+
8+
old_pos = position(s)
9+
seek(s, fh_b2s["DataSampleFormat"])
10+
dsf = read(s, typeof(bfh.DataSampleFormat))
11+
dsf_bs = bswap(dsf)
12+
seek(s, old_pos)
13+
14+
if (dsf >= 1 && dsf <= 16 && is_machine_littleendian()) ||
15+
(dsf_bs >= 1 && dsf_bs <= 16 && is_machine_bigendian())
16+
return true
17+
else
18+
return false
19+
end
20+
end
21+
22+
function is_segy_bigendian(s::IO)
23+
bfh = BinaryFileHeader()
24+
fh_b2s = fh_byte2sample()
25+
26+
old_pos = position(s)
27+
seek(s, fh_b2s["DataSampleFormat"])
28+
dsf = read(s, typeof(bfh.DataSampleFormat))
29+
dsf = bswap(read(s, typeof(bfh.DataSampleFormat)))
30+
seek(s, old_pos)
31+
32+
if (dsf >= 1 && dsf <= 16 && is_machine_bigendian()) ||
33+
(dsf_bs >= 1 && dsf_bs <= 16 && is_machine_littleendian())
34+
return true
35+
else
36+
return false
37+
end
38+
end
39+
40+
41+
"""
42+
bswap_needed(s::IO)
43+
44+
Checks whether SEGY and host machine's byte order are same or not.
45+
46+
NOTE: comparison is done based on binary file header value (Data Sample Format)
47+
thus stream (s::IO) must be opened from the begining of the file.
48+
49+
# Examples
50+
51+
s = open("/my/segy.segy", "r")
52+
swap_bytes = bswap_needed(s)
53+
"""
54+
function bswap_needed(s::IO)
55+
bfh = BinaryFileHeader()
56+
fh_b2s = fh_byte2sample()
57+
58+
old_pos = position(s)
59+
seek(s, fh_b2s["DataSampleFormat"])
60+
dsf = read(s, typeof(bfh.DataSampleFormat))
61+
seek(s, old_pos)
62+
63+
if dsf >= 1 && dsf <= 16
64+
return false
65+
else
66+
return true
67+
end
68+
end

src/read/read_block.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ end
77
function read_block!(b::BlockScan, keys::Array{String, 1}, ns::Int, dsf::Int, tmp_data, tmp_headers)
88

99
f = open(b.file)
10+
swap_bytes = bswap_needed(f)
1011
seek(f, b.startbyte)
1112
brange = b.endbyte - b.startbyte
1213
s = IOBuffer(read(f, brange))
@@ -29,6 +30,6 @@ function read_block!(b::BlockScan, keys::Array{String, 1}, ns::Int, dsf::Int, tm
2930
tracee = min(trace + TRACE_CHUNKSIZE - 1, ntraces)
3031
chunk = length(trace:tracee)*trace_size
3132
sloc = IOBuffer(read(s, chunk))
32-
read_traces!(sloc, view(tmp_headers, trace:tracee), view(tmp_data, :, trace:tracee), keys, th_b2s)
33+
read_traces!(sloc, view(tmp_headers, trace:tracee), view(tmp_data, :, trace:tracee), keys, th_b2s; swap_bytes=swap_bytes)
3334
end
3435
end

src/read/read_block_headers.jl

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export read_block_headers!
33
function read_block_headers!(b::BlockScan, keys::Array{String, 1}, ns::Int, dsf::Int, headers)
44

55
f = open(b.file)
6+
swap_bytes = bswap_needed(f)
67
seek(f, b.startbyte)
78
brange = b.endbyte - b.startbyte
89
s = IOBuffer(read(f, brange))
@@ -23,7 +24,7 @@ function read_block_headers!(b::BlockScan, keys::Array{String, 1}, ns::Int, dsf:
2324
tmph = zeros(UInt8, 240)
2425
# Read each traceheader
2526
for trace in 1:ntraces
26-
read_traceheader!(s, keys, th_b2s, headers[trace]; th=tmph)
27+
read_traceheader!(s, keys, th_b2s, headers[trace]; swap_bytes=swap_bytes, th=tmph)
2728
skip(s, ns*4)
2829
end
2930

@@ -32,6 +33,7 @@ end
3233
function read_block_headers!(b::BlockScan, ns::Int, dsf::Int, headers)
3334

3435
f = open(b.file)
36+
swap_bytes = bswap_needed(f)
3537
seek(f, b.startbyte)
3638
brange = b.endbyte - b.startbyte
3739
s = IOBuffer(read(f, brange))
@@ -50,7 +52,7 @@ function read_block_headers!(b::BlockScan, ns::Int, dsf::Int, headers)
5052
th_b2s = th_byte2sample()
5153
# Read each traceheader
5254
for trace in 1:ntraces
53-
read_traceheader!(s, th_b2s, headers[trace])
55+
read_traceheader!(s, th_b2s, headers[trace]; swap_bytes=swap_bytes)
5456
skip(s, ns*4)
5557
end
5658

src/read/read_file.jl

+5-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ Read entire SEGY file from stream 's', only reading the header values in 'keys'.
1818
"""
1919
function read_file(s::IO, keys::Array{String, 1}, warn_user::Bool;
2020
start_byte::Int = 3600, end_byte::Int = position(seekend(s)))
21+
22+
swap_bytes = bswap_needed(s)
23+
2124
# Read File Header
22-
fh = read_fileheader(s)
25+
fh = read_fileheader(s; swap_bytes=swap_bytes)
2326

2427
# Move to start of block
2528
seek(s, start_byte)
@@ -53,7 +56,7 @@ function read_file(s::IO, keys::Array{String, 1}, warn_user::Bool;
5356
tracee = min(trace + TRACE_CHUNKSIZE - 1, ntraces)
5457
chunk = length(trace:tracee)*trace_size
5558
sloc = IOBuffer(read(s, chunk))
56-
read_traces!(sloc, view(headers, trace:tracee), view(data, :, trace:tracee), keys, th_b2s)
59+
read_traces!(sloc, view(headers, trace:tracee), view(data, :, trace:tracee), keys, th_b2s; swap_bytes=swap_bytes)
5760
end
5861

5962
return SeisBlock(fh, headers, data)

src/read/read_fileheader.jl

+6-6
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ export read_fileheader
44
"""
55
# Info
66
7-
Use: fileheader = read_fileheader(s::IO; bigendian::Bool = true)
7+
Use: fileheader = read_fileheader(s::IO; swap_bytes::Bool = bswap_needed(s))
88
99
Returns a binary file header formed using bytes 3200-3600 from the stream 's'.
1010
"""
11-
function read_fileheader(s::IO; bigendian::Bool = true)
12-
return read_fileheader(s, fh_keys(); bigendian=bigendian)
11+
function read_fileheader(s::IO; swap_bytes::Bool = bswap_needed(s))
12+
return read_fileheader(s, fh_keys(); swap_bytes=swap_bytes)
1313
end
1414

1515

1616
"""
17-
Use: fileheader = read_fileheader(s::IO, keys::Array{String,1}; bigendian::Bool = true)
17+
Use: fileheader = read_fileheader(s::IO, keys::Array{String,1}; swap_bytes::Bool = bswap_needed(s))
1818
1919
Return a fileheader from stream 's' with the fields defined in 'keys'.
2020
@@ -41,7 +41,7 @@ Read only the sample interval and number of traces from the file header.
4141
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Dict("expf"=>3226,"sfe"=>3234,"rgc"=>3250,"jobid"=>3200,
4242
"dt"=>3216,"nsfr"=>3222,"slen"=>3236,"vpol"=>3258,"renum"=>3208,"dsf"=>3224…))
4343
"""
44-
function read_fileheader(s::IO, keys::Array{String,1}; bigendian::Bool = true)
44+
function read_fileheader(s::IO, keys::Array{String,1}; swap_bytes::Bool = bswap_needed(s))
4545

4646
# Return to start of stream
4747
seekstart(s)
@@ -52,7 +52,7 @@ function read_fileheader(s::IO, keys::Array{String,1}; bigendian::Bool = true)
5252
# Initialize binary file header
5353
bfh = BinaryFileHeader()
5454
fh_b2s = fh_byte2sample()
55-
swp(x) = bigendian ? bswap(x) : x
55+
swp(x) = swap_bytes ? bswap(x) : x
5656

5757
for k in keys
5858

src/read/read_trace.jl

+13-14
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,53 @@
1-
export read_trace
1+
export read_traces
22

33
"""
4-
Use: read_trace!(s::IO,
4+
Use: read_traces!(s::IO,
55
fh::BinaryFileHeader,
66
datatype::Type,
77
headers::AbstractArray{BinaryTraceHeader,1},
88
data::AbstractArray{<:Union{IBMFloat32, Float32}, 2},
99
trace::Int,
10-
th_byte2sample::Dict{String,Int32})
10+
th_byte2sample::Dict{String,Int32};
11+
swap_bytes::Bool)
1112
1213
Reads 'trace' from the current position of stream 's' into 'headers' and
1314
'data'.
1415
"""
1516
function read_traces!(s::IO, headers::AbstractVector{BinaryTraceHeader},
1617
data::AbstractMatrix{<:Union{IBMFloat32, Float32}},
17-
th_byte2sample::Dict{String,Int32})
18+
th_byte2sample::Dict{String,Int32};
19+
swap_bytes::Bool)
1820

19-
return read_traces!(s, headers, data, collect(keys(th_byte2sample)), th_byte2sample)
21+
return read_traces!(s, headers, data, collect(keys(th_byte2sample)), th_byte2sample; swap_bytes=swap_bytes)
2022
end
2123

2224
"""
23-
Use: read_trace!(s::IO,
25+
Use: read_traces!(s::IO,
2426
fh::BinaryFileHeader,
2527
datatype::Type,
2628
headers::AbstractArray{BinaryTraceHeader,1},
2729
data::AbstractArray{<:Union{IBMFloat32, Float32}, 2},
2830
trace::Int,
2931
keys::Array{String,1},
30-
th_byte2sample::Dict{String,Int32})
32+
th_byte2sample::Dict{String,Int32};
33+
swap_bytes::Bool)
3134
3235
Reads 'trace' from the current position of stream 's' into 'headers' and
3336
'data'. Only the header values in 'keys' and read.
3437
"""
3538
function read_traces!(s::IO, headers::AbstractVector{BinaryTraceHeader},
3639
data::AbstractMatrix{DT}, keys::Array{String,1},
37-
th_byte2sample::Dict{String,Int32}) where {DT<:Union{IBMFloat32, Float32}}
40+
th_byte2sample::Dict{String,Int32}; swap_bytes::Bool) where {DT<:Union{IBMFloat32, Float32}}
3841

3942
ntrace = size(data, 2)
4043
ntrace == 0 && return
41-
swp = swp_func(DT)
4244
tmph = zeros(UInt8, 240)
4345
for trace_loc=0:ntrace-1
4446
# Read trace header
45-
read_traceheader!(s, keys, th_byte2sample, headers[trace_loc+1]; th=tmph)
47+
read_traceheader!(s, keys, th_byte2sample, headers[trace_loc+1]; swap_bytes=swap_bytes, th=tmph)
4648
# Read trace
4749
read!(s, view(data, :, trace_loc+1))
4850
end
49-
map!(swp, data, data)
51+
(swap_bytes) && (data = bswap.(data))
5052
nothing
5153
end
52-
53-
swp_func(::Type{Float32}) = bswap
54-
swp_func(::Any) = x -> x

src/read/read_traceheader.jl

+11-11
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,34 @@ export read_traceheader
33
"""
44
# Info
55
6-
Use: fileheader = read_fileheader(s::IO; bigendian::Bool = true)
6+
Use: fileheader = read_fileheader(s::IO; swap_bytes::Bool)
77
88
99
Returns a binary trace header formed from the current position in the stream 's'.
1010
"""
11-
function read_traceheader(s::IO, th_byte2sample::Dict{String,Int32}; bigendian::Bool=true, th=zeros(UInt8, 240))
12-
return read_traceheader(s, collect(keys(th_byte2sample)), th_byte2sample; bigendian=bigendian, th=th)
11+
function read_traceheader(s::IO, th_byte2sample::Dict{String,Int32}; swap_bytes::Bool, th=zeros(UInt8, 240))
12+
return read_traceheader(s, collect(keys(th_byte2sample)), th_byte2sample; swap_bytes=swap_bytes, th=th)
1313
end
1414

1515
"""
16-
Use: fileheader = read_traceheader(s::IO, keys = Array{String,1}; bigendian::Bool = true)
16+
Use: fileheader = read_traceheader(s::IO, keys = Array{String,1}; swap_bytes::Bool)
1717
1818
Returns a binary trace header formed from the current position in the stream 's', only reading
1919
header values denoted in 'keys'.
2020
"""
2121
function read_traceheader(s::IO, keys::Array{String,1}, th_byte2sample::Dict{String, Int32};
22-
bigendian::Bool = true, th=zeros(UInt8, 240))
22+
swap_bytes::Bool, th=zeros(UInt8, 240))
2323

2424
# Initialize binary file header
2525
traceheader = BinaryTraceHeader()
2626

27-
read_traceheader!(s, keys, th_byte2sample, traceheader; bigendian=bigendian, th=th)
27+
read_traceheader!(s, keys, th_byte2sample, traceheader; swap_bytes=swap_bytes, th=th)
2828
return traceheader
2929
end
3030

3131
function read_traceheader!(s::IO, keys::Array{String,1}, th_byte2sample::Dict{String, Int32}, hdr::BinaryTraceHeader;
32-
bigendian::Bool = true, th=zeros(UInt8, 240))
33-
32+
swap_bytes::Bool, th=zeros(UInt8, 240))
33+
3434
# read full trace header then split
3535
read!(s, th)
3636

@@ -40,11 +40,11 @@ function read_traceheader!(s::IO, keys::Array{String,1}, th_byte2sample::Dict{St
4040
nb = sizeof(getfield(hdr, sym)) - 1
4141
bst = th_byte2sample[k]+1
4242
val = reinterpret(typeof(getfield(hdr, sym)), th[bst:bst+nb])[1]
43-
bigendian && (val = bswap(val))
43+
swap_bytes && (val = bswap(val))
4444
setfield!(hdr, sym, val)
4545
end
4646
nothing
4747
end
4848

49-
read_traceheader!(s::IO, thb::Dict{String, Int32}, hdr::BinaryTraceHeader; be::Bool = true, th=zeros(UInt8, 240)) =
50-
read_traceheader!(s, collect(keys(thb)), thb, hdr; be=be, th=th)
49+
read_traceheader!(s::IO, thb::Dict{String, Int32}, hdr::BinaryTraceHeader; swap_bytes::Bool, th=zeros(UInt8, 240)) =
50+
read_traceheader!(s, collect(keys(thb)), thb, hdr; swap_bytes=swap_bytes, th=th)

src/scan/scan_block.jl

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ export scan_block
22

33
function scan_block(buf::IO, mem_block::Int, mem_trace::Int, keys::Array{String,1},
44
chunk_start::Int, file::String, th_byte2sample::Dict{String, Int32})
5-
5+
6+
f = open(file)
7+
swap_bytes = bswap_needed(f)
8+
close(f)
9+
610
# Calc info about this block
711
startbyte = position(buf) + chunk_start
812
ntraces_block = Int(mem_block/mem_trace)
@@ -12,7 +16,7 @@ function scan_block(buf::IO, mem_block::Int, mem_trace::Int, keys::Array{String,
1216
# Read all headers and record end byte
1317
while !eof(buf) && count<ntraces_block
1418
count += 1
15-
read_traceheader!(buf, keys, th_byte2sample, headers[count] )
19+
read_traceheader!(buf, keys, th_byte2sample, headers[count]; swap_bytes=swap_bytes)
1620
skip(buf, mem_trace-240)
1721
end
1822
endbyte = position(buf) + chunk_start

src/scan/scan_shots.jl

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ export scan_shots
33
function scan_shots!(s::IO, mem_chunk::Int, mem_trace::Int,
44
keys::Array{String,1}, file::AbstractString, scan::Array{BlockScan,1}, fl_eof::Bool)
55

6+
f = open(file)
7+
swap_bytes = bswap_needed(f)
8+
close(f)
9+
610
# Load chunk into memory
711
chunk_start = position(s)
812
buf = IOBuffer(read(s, mem_chunk))
@@ -14,7 +18,7 @@ function scan_shots!(s::IO, mem_chunk::Int, mem_trace::Int,
1418
# Get headers from chunk
1519
th = zeros(UInt8, 240)
1620
for i in 1:ntraces
17-
read_traceheader!(buf, keys, SegyIO.th_b2s, headers[i]; th=th)
21+
read_traceheader!(buf, keys, SegyIO.th_b2s, headers[i]; swap_bytes=swap_bytes, th=th)
1822
skip(buf, mem_trace-240)
1923
end
2024

src/types/IBMFloat32.jl

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ primitive type IBMFloat32 32 end
44
ieeeOfPieces(fr::UInt32, exp::Int32, sgn::UInt32) =
55
reinterpret(Float32, convert(UInt32,fr >>> 9) | convert(UInt32,exp << 23) | sgn) :: Float32
66

7-
import Base.convert, Base.Float32
7+
import Base.convert, Base.Float32, Base.bswap
88

99
function convert(::Type{Float32}, ibm::IBMFloat32)
1010
local fr::UInt32 = ntoh(reinterpret(UInt32, ibm))
@@ -29,3 +29,7 @@ function convert(::Type{Float32}, ibm::IBMFloat32)
2929
end
3030
Float32(ibm::IBMFloat32) = convert(Float32,ibm)
3131
## From JuliaSeis
32+
33+
function bswap(ibm::IBMFloat32)
34+
return reinterpret(IBMFloat32, bswap(reinterpret(UInt32, ibm)))
35+
end

0 commit comments

Comments
 (0)