├── Unplugged.Segy
├── icon.ico
├── icon.png
├── packages.config
├── IReadingProgress.cs
├── ITrace.cs
├── IFileHeader.cs
├── ISegyFile.cs
├── Trace.cs
├── SegyFile.cs
├── FileHeader.cs
├── TraceHeader.cs
├── FormatCode.cs
├── ITraceHeader.cs
├── Unplugged.Segy.nuspec
├── ISegyOptions.cs
├── SegyOptions.cs
├── Properties
│ └── AssemblyInfo.cs
├── Unplugged.Segy.csproj
├── ImageWriter.cs
└── SegyReader.cs
├── packages
├── Moq.4.0.10827
│ ├── Moq.chm
│ ├── lib
│ │ ├── NET35
│ │ │ ├── Moq.dll
│ │ │ └── Moq.pdb
│ │ ├── NET40
│ │ │ ├── Moq.dll
│ │ │ └── Moq.pdb
│ │ └── Silverlight4
│ │ │ ├── Castle.Core.dll
│ │ │ ├── Moq.Silverlight.dll
│ │ │ └── Moq.Silverlight.pdb
│ ├── Moq.4.0.10827.nupkg
│ └── License.txt
├── NUnit.2.6.0.12054
│ ├── license.txt
│ └── lib
│ │ └── nunit.framework.dll
├── TestDrivenDesign.0.0.3
│ ├── TestDrivenDesign.0.0.3.nupkg
│ └── lib
│ │ └── net40
│ │ ├── TestDrivenDesign.dll
│ │ └── TestDrivenDesign.dll.CodeAnalysisLog.xml
├── Unplugged.IbmBits.0.0.0.3
│ └── lib
│ │ ├── net40
│ │ └── Unplugged.IbmBits.dll
│ │ └── monotouch
│ │ └── Unplugged.IbmBits.MonoTouch.dll
└── repositories.config
├── Unplugged.Segy.Tests
├── Examples
│ ├── lineE.sgy
│ └── bigEndianIEEEFloat.sgy
├── packages.config
├── SegyOptionsTest.cs
├── Properties
│ └── AssemblyInfo.cs
├── Unplugged.Segy.Tests.csproj
├── ImageWriterTest.cs
└── SegyReaderTest.cs
├── Unplugged.Segy.MonoTouch.Tests
├── Images
│ ├── icon57.png
│ ├── icon72.png
│ ├── icon114.png
│ └── icon144.png
├── Main.cs
├── Info.plist
├── AppDelegate.cs
└── Unplugged.Segy.MonoTouch.Tests.csproj
├── Unplugged.Segy.NUnitTests
├── packages.config
├── Unplugged.Segy.NUnitTests.csproj
└── SegyReading.cs
├── .gitignore
├── CodeAnalysisDictionary.xml
├── UnpluggedSegy.vsmdi
├── Local.testsettings
├── license.txt
├── readme.md
├── TraceAndTestImpact.testsettings
├── Unplugged.Segy.MonoTouch
└── Unplugged.Segy.MonoTouch.csproj
└── UnpluggedSegy.sln
/Unplugged.Segy/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/Unplugged.Segy/icon.ico
--------------------------------------------------------------------------------
/Unplugged.Segy/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/Unplugged.Segy/icon.png
--------------------------------------------------------------------------------
/packages/Moq.4.0.10827/Moq.chm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/packages/Moq.4.0.10827/Moq.chm
--------------------------------------------------------------------------------
/packages/NUnit.2.6.0.12054/license.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/packages/NUnit.2.6.0.12054/license.txt
--------------------------------------------------------------------------------
/Unplugged.Segy.Tests/Examples/lineE.sgy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/Unplugged.Segy.Tests/Examples/lineE.sgy
--------------------------------------------------------------------------------
/packages/Moq.4.0.10827/lib/NET35/Moq.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/packages/Moq.4.0.10827/lib/NET35/Moq.dll
--------------------------------------------------------------------------------
/packages/Moq.4.0.10827/lib/NET35/Moq.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/packages/Moq.4.0.10827/lib/NET35/Moq.pdb
--------------------------------------------------------------------------------
/packages/Moq.4.0.10827/lib/NET40/Moq.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/packages/Moq.4.0.10827/lib/NET40/Moq.dll
--------------------------------------------------------------------------------
/packages/Moq.4.0.10827/lib/NET40/Moq.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/packages/Moq.4.0.10827/lib/NET40/Moq.pdb
--------------------------------------------------------------------------------
/packages/Moq.4.0.10827/Moq.4.0.10827.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/packages/Moq.4.0.10827/Moq.4.0.10827.nupkg
--------------------------------------------------------------------------------
/Unplugged.Segy.MonoTouch.Tests/Images/icon57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/Unplugged.Segy.MonoTouch.Tests/Images/icon57.png
--------------------------------------------------------------------------------
/Unplugged.Segy.MonoTouch.Tests/Images/icon72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/Unplugged.Segy.MonoTouch.Tests/Images/icon72.png
--------------------------------------------------------------------------------
/Unplugged.Segy.MonoTouch.Tests/Images/icon114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/Unplugged.Segy.MonoTouch.Tests/Images/icon114.png
--------------------------------------------------------------------------------
/Unplugged.Segy.MonoTouch.Tests/Images/icon144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/Unplugged.Segy.MonoTouch.Tests/Images/icon144.png
--------------------------------------------------------------------------------
/Unplugged.Segy/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/packages/NUnit.2.6.0.12054/lib/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/packages/NUnit.2.6.0.12054/lib/nunit.framework.dll
--------------------------------------------------------------------------------
/Unplugged.Segy.Tests/Examples/bigEndianIEEEFloat.sgy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/Unplugged.Segy.Tests/Examples/bigEndianIEEEFloat.sgy
--------------------------------------------------------------------------------
/packages/Moq.4.0.10827/lib/Silverlight4/Castle.Core.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/packages/Moq.4.0.10827/lib/Silverlight4/Castle.Core.dll
--------------------------------------------------------------------------------
/packages/Moq.4.0.10827/lib/Silverlight4/Moq.Silverlight.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/packages/Moq.4.0.10827/lib/Silverlight4/Moq.Silverlight.dll
--------------------------------------------------------------------------------
/packages/Moq.4.0.10827/lib/Silverlight4/Moq.Silverlight.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/packages/Moq.4.0.10827/lib/Silverlight4/Moq.Silverlight.pdb
--------------------------------------------------------------------------------
/packages/TestDrivenDesign.0.0.3/TestDrivenDesign.0.0.3.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/packages/TestDrivenDesign.0.0.3/TestDrivenDesign.0.0.3.nupkg
--------------------------------------------------------------------------------
/packages/TestDrivenDesign.0.0.3/lib/net40/TestDrivenDesign.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/packages/TestDrivenDesign.0.0.3/lib/net40/TestDrivenDesign.dll
--------------------------------------------------------------------------------
/Unplugged.Segy.NUnitTests/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/packages/Unplugged.IbmBits.0.0.0.3/lib/net40/Unplugged.IbmBits.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/packages/Unplugged.IbmBits.0.0.0.3/lib/net40/Unplugged.IbmBits.dll
--------------------------------------------------------------------------------
/packages/Unplugged.IbmBits.0.0.0.3/lib/monotouch/Unplugged.IbmBits.MonoTouch.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jfoshee/UnpluggedSegy/HEAD/packages/Unplugged.IbmBits.0.0.0.3/lib/monotouch/Unplugged.IbmBits.MonoTouch.dll
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | [Oo]bj
2 | [Bb]in
3 | TestResults
4 | *.user
5 | *.suo
6 | *.[Cc]ache
7 | *.bak
8 | *.ncb
9 | *.log
10 | *.DS_Store
11 | [Tt]humbs.db
12 | _ReSharper.*
13 | *.resharper
14 | Ankh.NoLoad
15 | *.docstates
16 | *.nupkg
17 |
--------------------------------------------------------------------------------
/Unplugged.Segy/IReadingProgress.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Unplugged.Segy
3 | {
4 | public interface IReadingProgress
5 | {
6 | void ReportProgress(int progressPercentage);
7 | bool CancellationPending { get; }
8 | }
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/Unplugged.Segy/ITrace.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Unplugged.Segy
4 | {
5 | public interface ITrace
6 | {
7 | ITraceHeader Header { get; }
8 | IList Values { get; }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Unplugged.Segy/IFileHeader.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Unplugged.Segy
3 | {
4 | public interface IFileHeader
5 | {
6 | string Text { get; }
7 | FormatCode SampleFormat { get; }
8 | bool IsLittleEndian { get; }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Unplugged.Segy/ISegyFile.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Unplugged.Segy
4 | {
5 | public interface ISegyFile
6 | {
7 | IFileHeader Header { get; }
8 | IList Traces { get; }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Unplugged.Segy.Tests/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Unplugged.Segy/Trace.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Unplugged.Segy
4 | {
5 | class Trace : ITrace
6 | {
7 | public ITraceHeader Header { get; set; }
8 | public IList Values { get; set; }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Unplugged.Segy/SegyFile.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Unplugged.Segy
4 | {
5 | class SegyFile : ISegyFile
6 | {
7 | public IFileHeader Header { get; set; }
8 | public IList Traces { get; set; }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/CodeAnalysisDictionary.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | bpp
6 | Rgba
7 | crossline
8 | segy
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Unplugged.Segy/FileHeader.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Unplugged.Segy
3 | {
4 | class FileHeader : IFileHeader
5 | {
6 | public string Text { get; set; }
7 | public FormatCode SampleFormat { get; set; }
8 | public bool IsLittleEndian { get; set; }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/repositories.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Unplugged.Segy/TraceHeader.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Unplugged.Segy
3 | {
4 | class TraceHeader : ITraceHeader
5 | {
6 | public int SampleCount { get; set; }
7 | public int TraceNumber { get; set; }
8 | public int InlineNumber { get; set; }
9 | public int CrosslineNumber { get; set; }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Unplugged.Segy/FormatCode.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Unplugged.Segy
3 | {
4 | public enum FormatCode
5 | {
6 | None,
7 | IbmFloatingPoint4,
8 | TwosComplementInteger4,
9 | TwosComplementInteger2,
10 | FixedPointWithGain4,
11 | IeeeFloatingPoint4,
12 | Unused1,
13 | Unused2,
14 | TwosComplementInteger1
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Unplugged.Segy/ITraceHeader.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Unplugged.Segy
3 | {
4 | public interface ITraceHeader
5 | {
6 | int SampleCount { get; }
7 | int TraceNumber { get; }
8 | int InlineNumber { get; }
9 | int CrosslineNumber { get; }
10 | //int SampleIntervalInMicroseconds { get; }
11 | //int X { get; }
12 | //int Y { get; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/UnpluggedSegy.vsmdi:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Unplugged.Segy.MonoTouch.Tests/Main.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using MonoTouch.Foundation;
6 | using MonoTouch.UIKit;
7 |
8 | namespace Unplugged.Segy.MonoTouch.Tests
9 | {
10 | public class Application
11 | {
12 | // This is the main entry point of the application.
13 | static void Main (string[] args)
14 | {
15 | // if you want to use a different Application Delegate class from "AppDelegate"
16 | // you can specify it here.
17 | UIApplication.Main (args, null, "AppDelegate");
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Unplugged.Segy/Unplugged.Segy.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $id$
5 | $version$
6 | $title$
7 | $author$
8 | $author$
9 | http://segy.net
10 | https://github.com/jfoshee/UnpluggedSegy/raw/ce8bb8c0182852423afdd1fa254f5de13efbe5c3/Unplugged.Segy/icon.png
11 | false
12 | $description$
13 | Copyright Unplugged Development 2012
14 | SEG-Y, SEGY, SGY, Seismic, IBM
15 |
16 |
--------------------------------------------------------------------------------
/Unplugged.Segy/ISegyOptions.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Unplugged.Segy
3 | {
4 | public interface ISegyOptions
5 | {
6 | bool? IsEbcdic { get; }
7 | //bool? IsLittleEndian { get; }
8 |
9 | int TextHeaderColumnCount { get; }
10 | int TextHeaderRowCount { get; }
11 | bool TextHeaderInsertNewLines { get; }
12 |
13 | //int BinaryHeaderLength { get; }
14 | //int BinaryHeaderLocationForSampleFormat { get; }
15 |
16 | //int TraceHeaderLength { get; }
17 | //int TraceHeaderLocationForInlineNumber { get; }
18 | //int TraceHeaderLocationForCrosslineNumber { get; }
19 | //int TraceHeaderLocationForSampleCount { get; }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Local.testsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 | These are default test settings for a local test run.
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Unplugged.Segy.MonoTouch.Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDisplayName
6 | SEGY Tests
7 | CFBundleIconFiles
8 |
9 | Images/icon57.png
10 | Images/icon114.png
11 | Images/icon72.png
12 | Images/icon144.png
13 |
14 | UIDeviceFamily
15 |
16 | 1
17 | 2
18 |
19 | UISupportedInterfaceOrientations
20 |
21 | UIInterfaceOrientationPortrait
22 | UIInterfaceOrientationPortraitUpsideDown
23 | UIInterfaceOrientationLandscapeLeft
24 | UIInterfaceOrientationLandscapeRight
25 |
26 | UISupportedInterfaceOrientations~ipad
27 |
28 | UIInterfaceOrientationPortrait
29 | UIInterfaceOrientationPortraitUpsideDown
30 | UIInterfaceOrientationLandscapeLeft
31 | UIInterfaceOrientationLandscapeRight
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | Unplugged.Segy is free software distributed under the terms of the
2 | MIT License reproduced below.
3 |
4 | Unplugged.Segy
5 | http://segy.net
6 | Copyright (c) 2011 - 2015 Unplugged Development, Jacob Foshee
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all
16 | copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 | SOFTWARE.
25 |
--------------------------------------------------------------------------------
/Unplugged.Segy/SegyOptions.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Unplugged.Segy
3 | {
4 | public class SegyOptions : ISegyOptions
5 | {
6 | public bool? IsEbcdic { get; set; }
7 | //public bool? IsLittleEndian { get; set; }
8 |
9 | public int TextHeaderColumnCount { get; set; }
10 | public int TextHeaderRowCount { get; set; }
11 | public bool TextHeaderInsertNewLines { get; set; }
12 |
13 | //public int BinaryHeaderLength { get; set; }
14 | //public int BinaryHeaderLocationForSampleFormat { get; set; }
15 |
16 | //public int TraceHeaderLength { get; set; }
17 | //public int TraceHeaderLocationForInlineNumber { get; set; }
18 | //public int TraceHeaderLocationForCrosslineNumber { get; set; }
19 | //public int TraceHeaderLocationForSampleCount { get; set; }
20 |
21 | public SegyOptions()
22 | {
23 | IsEbcdic = true;
24 | //IsLittleEndian = false;
25 | TextHeaderColumnCount = 80;
26 | TextHeaderRowCount = 40;
27 | TextHeaderInsertNewLines = true;
28 | //BinaryHeaderLength = 400;
29 | //BinaryHeaderLocationForSampleFormat = 25;
30 | //TraceHeaderLength = 240;
31 | //TraceHeaderLocationForSampleCount = 115;
32 | //TraceHeaderLocationForInlineNumber = 189;
33 | //TraceHeaderLocationForCrosslineNumber = 193;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Unplugged.Segy.Tests/SegyOptionsTest.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.TestTools.UnitTesting;
2 | using TestDrivenDesign;
3 |
4 | namespace Unplugged.Segy.Tests
5 | {
6 | [TestClass]
7 | public class SegyOptionsTest : TestBase
8 | {
9 | [TestMethod]
10 | public void ImplementsInterface()
11 | {
12 | Assert.IsInstanceOfType(Subject, typeof(ISegyOptions));
13 | }
14 |
15 | [TestMethod]
16 | public void DefaultValues()
17 | {
18 | Assert.AreEqual(true, Subject.IsEbcdic);
19 | //Assert.AreEqual(false, Subject.IsLittleEndian);
20 |
21 | Assert.AreEqual(80, Subject.TextHeaderColumnCount);
22 | Assert.AreEqual(40, Subject.TextHeaderRowCount);
23 | Assert.AreEqual(true, Subject.TextHeaderInsertNewLines);
24 |
25 | //Assert.AreEqual(400, Subject.BinaryHeaderLength);
26 | //Assert.AreEqual(25, Subject.BinaryHeaderLocationForSampleFormat);
27 |
28 | //Assert.AreEqual(240, Subject.TraceHeaderLength);
29 | //Assert.AreEqual(115, Subject.TraceHeaderLocationForSampleCount);
30 | //Assert.AreEqual(189, Subject.TraceHeaderLocationForInlineNumber, "According to SEGY Rev 1, byte 189 - 192 in the trace header should be used for the in-line number");
31 | //Assert.AreEqual(193, Subject.TraceHeaderLocationForCrosslineNumber, "According to SEGY Rev 1, byte 193 - 196 in the trace header should be used for the cross-line number");
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Unplugged.Segy.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Unplugged.Segy.Tests")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Unplugged Development")]
12 | [assembly: AssemblyProduct("Unplugged.Segy.Tests")]
13 | [assembly: AssemblyCopyright("Copyright © Unplugged Development 2011")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("5aeeaf75-62ca-4ecf-9b2c-d71aa0d87c3d")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/Unplugged.Segy.MonoTouch.Tests/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using MonoTouch.Foundation;
6 | using MonoTouch.UIKit;
7 | using MonoTouch.NUnit.UI;
8 |
9 | namespace Unplugged.Segy.MonoTouch.Tests
10 | {
11 | // The UIApplicationDelegate for the application. This class is responsible for launching the
12 | // User Interface of the application, as well as listening (and optionally responding) to
13 | // application events from iOS.
14 | [Register ("AppDelegate")]
15 | public partial class AppDelegate : UIApplicationDelegate
16 | {
17 | // class-level declarations
18 | UIWindow window;
19 | TouchRunner runner;
20 |
21 | //
22 | // This method is invoked when the application has loaded and is ready to run. In this
23 | // method you should instantiate the window, load the UI into it and then make the window
24 | // visible.
25 | //
26 | // You have 17 seconds to return from this method, or iOS will terminate your application.
27 | //
28 | public override bool FinishedLaunching (UIApplication app, NSDictionary options)
29 | {
30 | // create a new window instance based on the screen size
31 | window = new UIWindow (UIScreen.MainScreen.Bounds);
32 | runner = new TouchRunner (window);
33 |
34 | // register every tests included in the main application/assembly
35 | runner.Add (System.Reflection.Assembly.GetExecutingAssembly ());
36 |
37 | window.RootViewController = new UINavigationController (runner.GetViewController ());
38 |
39 | // make the window visible
40 | window.MakeKeyAndVisible ();
41 |
42 | return true;
43 | }
44 | }
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/Unplugged.Segy/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Unplugged.Segy")]
9 | [assembly: AssemblyDescription("Supports reading of seismic images stored in SEG-Y format")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Unplugged Development")]
12 | [assembly: AssemblyProduct("Unplugged.Segy")]
13 | [assembly: AssemblyCopyright("Copyright © Unplugged Development 2012")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("6cec6899-288e-4a02-9d1b-3df1d87fa359")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("0.6.1")]
36 | [assembly: AssemblyFileVersion("0.6.1")]
37 | [assembly: CLSCompliant(true)]
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # SEG-Y Reading Library in C# #
2 |
3 | SEG-Y is a file format for seismic image data. It is also known as SEGY or SGY.
4 |
5 | Issues and sample data welcome.
6 |
7 | ### Example
8 |
9 | ```C#
10 | using System;
11 | using Unplugged.Segy;
12 | ```
13 |
14 | ```C#
15 | var reader = new SegyReader();
16 | ISegyFile line = reader.Read(@"RMOTC Seismic data set\2D_Seismic\NormalizedMigrated_segy\lineA.sgy");
17 | ITrace trace = line.Traces[0];
18 | double mean = 0;
19 | double max = double.MinValue;
20 | double min = double.MaxValue;
21 | foreach (var sampleValue in trace.Values)
22 | {
23 | mean += sampleValue / trace.Values.Count;
24 | if (sampleValue < min) min = sampleValue;
25 | if (sampleValue > max) max = sampleValue;
26 | }
27 | Console.WriteLine(min);
28 | Console.WriteLine(max);
29 | Console.WriteLine(mean);
30 | ```
31 |
32 | ### Supported Sample Formats
33 | - IBM Floating Point 4 (Big Endian)
34 | - IEEE Floating Point 4 (Little Endian)
35 | - Two's Complement Integer 4 (Big and Little Endian)
36 | - Two's Complement Integer 2 (Big and Little Endian)
37 | - Two's Complement Integer 1
38 |
39 | ### Current Known Limitations
40 | - Assumed to be built on Little Endian architecture
41 | - Sample Format not supported: Fixed Point With Gain 4
42 | - Extended Text Headers are not supported
43 | - Writing SEGY files is not supported
44 |
45 | If you have example files of unsupported formats or feature requests, they would be appreciated! Please, send to
46 |
47 | ### Acknowledgements
48 |
49 | Example data is courtesy of the [Rocky Mountian Oilfield Testing Center](http://www.rmotc.doe.gov/) and the U.S. Department of Energy
50 |
51 | Resources on the SEG-Y format:
52 |
53 | - http://walter.kessinger.com/work/segy.html
54 | - http://en.wikipedia.org/wiki/SEG_Y
55 | - http://www.seg.org/documents/10161/77915/seg_y_rev1.pdf
56 |
--------------------------------------------------------------------------------
/packages/Moq.4.0.10827/License.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2007. Clarius Consulting, Manas Technology Solutions, InSTEDD
2 | http://code.google.com/p/moq/
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms,
6 | with or without modification, are permitted provided
7 | that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the
10 | above copyright notice, this list of conditions and
11 | the following disclaimer.
12 |
13 | * Redistributions in binary form must reproduce
14 | the above copyright notice, this list of conditions
15 | and the following disclaimer in the documentation
16 | and/or other materials provided with the distribution.
17 |
18 | * Neither the name of Clarius Consulting, Manas Technology Solutions or InSTEDD nor the
19 | names of its contributors may be used to endorse
20 | or promote products derived from this software
21 | without specific prior written permission.
22 |
23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 | SUCH DAMAGE.
37 |
38 | [This is the BSD license, see
39 | http://www.opensource.org/licenses/bsd-license.php]
--------------------------------------------------------------------------------
/TraceAndTestImpact.testsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 | These are test settings for Trace and Test Impact.
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Unplugged.Segy.NUnitTests/Unplugged.Segy.NUnitTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 10.0.0
7 | 2.0
8 | {5FB4FF59-8350-4596-B3D0-0EF11FA6BCD4}
9 | Library
10 | Unplugged.Segy.NUnitTests
11 | Unplugged.Segy.NUnitTests
12 |
13 |
14 | true
15 | full
16 | false
17 | bin\Debug
18 | DEBUG;
19 | prompt
20 | 4
21 | false
22 |
23 |
24 | none
25 | false
26 | bin\Release
27 | prompt
28 | 4
29 | false
30 |
31 |
32 |
33 | ..\packages\NUnit.2.6.0.12054\lib\nunit.framework.dll
34 |
35 |
36 |
37 |
38 |
39 |
40 | {096016A3-C38E-41C0-9853-4C4AF2DF8782}
41 | Unplugged.Segy
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | Examples\lineE.sgy
51 | PreserveNewest
52 |
53 |
54 |
55 | Examples\bigEndianIEEEFloat.sgy
56 | PreserveNewest
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Unplugged.Segy.NUnitTests/SegyReading.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using NUnit.Framework;
4 |
5 | namespace Unplugged.Segy.MonoTouch.Tests
6 | {
7 | [TestFixture]
8 | public class SegyReading
9 | {
10 | [Test]
11 | public void ShouldReadSegyFile()
12 | {
13 | var subject = new SegyReader();
14 | var segy = subject.Read(@"./Examples/lineE.sgy");
15 | Console.WriteLine(segy.Header.Text);
16 | Assert.That(segy.Traces.Count, Is.EqualTo(111));
17 | }
18 |
19 | [Test]
20 | public void ShouldReadBigEndianIEEEFloatingPoint()
21 | {
22 | var subject = new SegyReader();
23 | var segy = subject.Read(@"./Examples/bigEndianIEEEFloat.sgy");
24 | Console.WriteLine(segy.Header.Text);
25 | Assert.That(segy.Traces.Count, Is.EqualTo(120));
26 | Assert.That(segy.Traces[0].Values[0], Is.EqualTo(0));
27 | Assert.That(segy.Traces[60].Values[159], Is.EqualTo(0.896f).Within(0.001f));
28 | Assert.That(segy.Traces[60].Values[160], Is.EqualTo(1.000f).Within(0.001f));
29 | Assert.That(segy.Traces[60].Values[161], Is.EqualTo(0.896f).Within(0.001f));
30 | }
31 |
32 | [Test]
33 | public void ShouldGetImageBytes()
34 | {
35 | var reader = new SegyReader();
36 | var segy = reader.Read(@"./Examples/lineE.sgy");
37 | var imageWriter = new ImageWriter();
38 | var bytes = imageWriter.GetRaw32BppRgba(segy.Traces);
39 | var expected = 4 * segy.Traces.Count * segy.Traces[0].Values.Count;
40 | Assert.That(bytes.Length, Is.EqualTo(expected));
41 | }
42 |
43 | [Test]
44 | public void ShouldReturnEmptyArrayForNoTraces()
45 | {
46 | var bytes = new ImageWriter().GetRaw32BppRgba(new ITrace[]{});
47 | Assert.That(bytes.Length, Is.EqualTo(0));
48 | }
49 |
50 | class TestProgressReporter : IReadingProgress
51 | {
52 | public void ReportProgress (int progressPercentage)
53 | {
54 | ProgressReported.Add(progressPercentage);
55 | }
56 |
57 | public bool CancellationPending { get; set; }
58 | public List ProgressReported { get; private set; }
59 |
60 | public TestProgressReporter ()
61 | {
62 | ProgressReported = new List();
63 | }
64 | }
65 |
66 | [Test]
67 | public void ShouldReportProgress()
68 | {
69 | var subject = new SegyReader();
70 | var testProgressReporter = new TestProgressReporter();
71 |
72 | subject.Read(@"./Examples/lineE.sgy", testProgressReporter);
73 |
74 | // Assert that message received for each percentage 0 to 100
75 | // (The example has more than 100 traces, so this is reasonable)
76 | var p = testProgressReporter.ProgressReported;
77 | for (int i = 0; i < 101; i++)
78 | Assert.That(p.Contains(i), i.ToString());
79 | }
80 |
81 | class CancelsAtThirty : IReadingProgress
82 | {
83 | public void ReportProgress (int progressPercentage)
84 | {
85 | if (progressPercentage == 30)
86 | CancellationPending = true;
87 | if (progressPercentage > 30)
88 | Assert.Fail("Should not proceed past 30%");
89 | }
90 | public bool CancellationPending { get; set; }
91 | }
92 |
93 | [Test]
94 | public void ShouldStopReadingWhenCancellationPending()
95 | {
96 | var subject = new SegyReader();
97 | var segy = subject.Read(@"./Examples/lineE.sgy", new CancelsAtThirty());
98 | var expected = (int)(.3 * 111);
99 | Assert.That(segy.Traces.Count, Is.EqualTo(expected));
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/Unplugged.Segy/Unplugged.Segy.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {096016A3-C38E-41C0-9853-4C4AF2DF8782}
9 | Library
10 | Properties
11 | Unplugged.Segy
12 | Unplugged.Segy
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 | ExtendedDesignGuidelineRules.ruleset
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 | ExtendedDesignGuidelineRules.ruleset
33 |
34 |
35 | icon.ico
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | ..\packages\Unplugged.IbmBits.0.0.0.3\lib\net40\Unplugged.IbmBits.dll
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | Designer
71 |
72 |
73 |
74 |
75 | Properties\CodeAnalysisDictionary.xml
76 |
77 |
78 |
79 |
80 |
81 |
82 |
89 |
--------------------------------------------------------------------------------
/Unplugged.Segy.Tests/Unplugged.Segy.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 |
7 |
8 | 2.0
9 | {7BE2D039-A482-4792-BBB8-90F68C5B0F57}
10 | Library
11 | Properties
12 | Unplugged.Segy.Tests
13 | Unplugged.Segy.Tests
14 | v4.0
15 | 512
16 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
17 |
18 |
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 |
38 | ..\packages\Moq.4.0.10827\lib\NET40\Moq.dll
39 |
40 |
41 |
42 | 3.5
43 |
44 |
45 |
46 | ..\packages\TestDrivenDesign.0.0.3\lib\net40\TestDrivenDesign.dll
47 |
48 |
49 | False
50 | ..\packages\Unplugged.IbmBits.0.0.0.3\lib\net40\Unplugged.IbmBits.dll
51 |
52 |
53 |
54 |
55 | False
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | {096016A3-C38E-41C0-9853-4C4AF2DF8782}
71 | Unplugged.Segy
72 |
73 |
74 |
75 |
82 |
--------------------------------------------------------------------------------
/Unplugged.Segy.MonoTouch/Unplugged.Segy.MonoTouch.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 10.0.0
7 | 2.0
8 | {4FE7CCB7-A96F-41E7-849E-C6236043BEEF}
9 | {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
10 | Library
11 | Unplugged.Segy.MonoTouch
12 | Unplugged.Segy.MonoTouch
13 |
14 |
15 | true
16 | full
17 | false
18 | bin\Debug
19 | DEBUG;MONO_TOUCH
20 | prompt
21 | 4
22 | false
23 |
24 |
25 | none
26 | false
27 | bin\Release
28 | prompt
29 | 4
30 | false
31 | MONO_TOUCH
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | ..\packages\Unplugged.IbmBits.0.0.0.3\lib\monotouch\Unplugged.IbmBits.MonoTouch.dll
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Unplugged.Segy\FileHeader.cs
49 |
50 |
51 | Unplugged.Segy\FormatCode.cs
52 |
53 |
54 | Unplugged.Segy\IFileHeader.cs
55 |
56 |
57 | Unplugged.Segy\ISegyFile.cs
58 |
59 |
60 | Unplugged.Segy\ISegyOptions.cs
61 |
62 |
63 | Unplugged.Segy\ITrace.cs
64 |
65 |
66 | Unplugged.Segy\ITraceHeader.cs
67 |
68 |
69 | Unplugged.Segy\SegyFile.cs
70 |
71 |
72 | Unplugged.Segy\SegyOptions.cs
73 |
74 |
75 | Unplugged.Segy\SegyReader.cs
76 |
77 |
78 | Unplugged.Segy\Trace.cs
79 |
80 |
81 | Unplugged.Segy\TraceHeader.cs
82 |
83 |
84 | Unplugged.Segy\ImageWriter.cs
85 |
86 |
87 | Unplugged.Segy\IReadingProgress.cs
88 |
89 |
90 |
--------------------------------------------------------------------------------
/Unplugged.Segy.MonoTouch.Tests/Unplugged.Segy.MonoTouch.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | iPhoneSimulator
6 | 10.0.0
7 | 2.0
8 | {884678D1-863C-45C1-BAB1-85BF75E2B3A5}
9 | {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
10 | Exe
11 | Unplugged.Segy.MonoTouch.Tests
12 | UnpluggedSegyMonoTouchTests
13 |
14 |
15 | true
16 | full
17 | false
18 | bin\iPhoneSimulator\Debug
19 | DEBUG;
20 | prompt
21 | 4
22 | false
23 | true
24 | true
25 | None
26 | rare
27 |
28 |
29 | none
30 | false
31 | bin\iPhoneSimulator\Release
32 | prompt
33 | 4
34 | false
35 | None
36 | rare
37 |
38 |
39 | true
40 | full
41 | false
42 | bin\iPhone\Debug
43 | DEBUG;
44 | prompt
45 | 4
46 | false
47 | iPhone Developer
48 | true
49 | true
50 |
51 | rare
52 |
53 |
54 | none
55 | false
56 | bin\iPhone\Release
57 | prompt
58 | 4
59 | false
60 | iPhone Developer
61 | rare
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | SegyReading.cs
78 |
79 |
80 |
81 |
82 |
83 | {4FE7CCB7-A96F-41E7-849E-C6236043BEEF}
84 | Unplugged.Segy.MonoTouch
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | Examples\lineE.sgy
94 |
95 |
96 |
97 |
98 |
99 |
100 | Examples\bigEndianIEEEFloat.sgy
101 |
102 |
103 |
--------------------------------------------------------------------------------
/UnpluggedSegy.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unplugged.Segy.Tests", "Unplugged.Segy.Tests\Unplugged.Segy.Tests.csproj", "{7BE2D039-A482-4792-BBB8-90F68C5B0F57}"
5 | EndProject
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{11DD3C5B-FC93-42FB-8065-3ACE2DDFCADB}"
7 | ProjectSection(SolutionItems) = preProject
8 | CodeAnalysisDictionary.xml = CodeAnalysisDictionary.xml
9 | Local.testsettings = Local.testsettings
10 | readme.md = readme.md
11 | TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings
12 | UnpluggedSegy.vsmdi = UnpluggedSegy.vsmdi
13 | EndProjectSection
14 | EndProject
15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unplugged.Segy", "Unplugged.Segy\Unplugged.Segy.csproj", "{096016A3-C38E-41C0-9853-4C4AF2DF8782}"
16 | EndProject
17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unplugged.Segy.MonoTouch", "Unplugged.Segy.MonoTouch\Unplugged.Segy.MonoTouch.csproj", "{4FE7CCB7-A96F-41E7-849E-C6236043BEEF}"
18 | EndProject
19 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unplugged.Segy.NUnitTests", "Unplugged.Segy.NUnitTests\Unplugged.Segy.NUnitTests.csproj", "{5FB4FF59-8350-4596-B3D0-0EF11FA6BCD4}"
20 | EndProject
21 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unplugged.Segy.MonoTouch.Tests", "Unplugged.Segy.MonoTouch.Tests\Unplugged.Segy.MonoTouch.Tests.csproj", "{884678D1-863C-45C1-BAB1-85BF75E2B3A5}"
22 | EndProject
23 | Global
24 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
25 | Debug|Any CPU = Debug|Any CPU
26 | Release|Any CPU = Release|Any CPU
27 | Debug|iPhoneSimulator = Debug|iPhoneSimulator
28 | Release|iPhoneSimulator = Release|iPhoneSimulator
29 | Debug|iPhone = Debug|iPhone
30 | Release|iPhone = Release|iPhone
31 | EndGlobalSection
32 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
33 | {096016A3-C38E-41C0-9853-4C4AF2DF8782}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 | {096016A3-C38E-41C0-9853-4C4AF2DF8782}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 | {096016A3-C38E-41C0-9853-4C4AF2DF8782}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 | {096016A3-C38E-41C0-9853-4C4AF2DF8782}.Release|Any CPU.Build.0 = Release|Any CPU
37 | {4FE7CCB7-A96F-41E7-849E-C6236043BEEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38 | {4FE7CCB7-A96F-41E7-849E-C6236043BEEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
39 | {4FE7CCB7-A96F-41E7-849E-C6236043BEEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
40 | {4FE7CCB7-A96F-41E7-849E-C6236043BEEF}.Release|Any CPU.Build.0 = Release|Any CPU
41 | {5FB4FF59-8350-4596-B3D0-0EF11FA6BCD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
42 | {5FB4FF59-8350-4596-B3D0-0EF11FA6BCD4}.Debug|Any CPU.Build.0 = Debug|Any CPU
43 | {5FB4FF59-8350-4596-B3D0-0EF11FA6BCD4}.Release|Any CPU.ActiveCfg = Release|Any CPU
44 | {5FB4FF59-8350-4596-B3D0-0EF11FA6BCD4}.Release|Any CPU.Build.0 = Release|Any CPU
45 | {7BE2D039-A482-4792-BBB8-90F68C5B0F57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
46 | {7BE2D039-A482-4792-BBB8-90F68C5B0F57}.Debug|Any CPU.Build.0 = Debug|Any CPU
47 | {7BE2D039-A482-4792-BBB8-90F68C5B0F57}.Release|Any CPU.ActiveCfg = Release|Any CPU
48 | {7BE2D039-A482-4792-BBB8-90F68C5B0F57}.Release|Any CPU.Build.0 = Release|Any CPU
49 | {884678D1-863C-45C1-BAB1-85BF75E2B3A5}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator
50 | {884678D1-863C-45C1-BAB1-85BF75E2B3A5}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator
51 | {884678D1-863C-45C1-BAB1-85BF75E2B3A5}.Debug|iPhone.ActiveCfg = Debug|iPhone
52 | {884678D1-863C-45C1-BAB1-85BF75E2B3A5}.Debug|iPhone.Build.0 = Debug|iPhone
53 | {884678D1-863C-45C1-BAB1-85BF75E2B3A5}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
54 | {884678D1-863C-45C1-BAB1-85BF75E2B3A5}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
55 | {884678D1-863C-45C1-BAB1-85BF75E2B3A5}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator
56 | {884678D1-863C-45C1-BAB1-85BF75E2B3A5}.Release|Any CPU.Build.0 = Release|iPhoneSimulator
57 | {884678D1-863C-45C1-BAB1-85BF75E2B3A5}.Release|iPhone.ActiveCfg = Release|iPhone
58 | {884678D1-863C-45C1-BAB1-85BF75E2B3A5}.Release|iPhone.Build.0 = Release|iPhone
59 | {884678D1-863C-45C1-BAB1-85BF75E2B3A5}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
60 | {884678D1-863C-45C1-BAB1-85BF75E2B3A5}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
61 | EndGlobalSection
62 | GlobalSection(NestedProjects) = preSolution
63 | EndGlobalSection
64 | GlobalSection(MonoDevelopProperties) = preSolution
65 | StartupItem = Unplugged.Segy.MonoTouch.Tests\Unplugged.Segy.MonoTouch.Tests.csproj
66 | EndGlobalSection
67 | GlobalSection(TestCaseManagementSettings) = postSolution
68 | CategoryFile = UnpluggedSegy.vsmdi
69 | EndGlobalSection
70 | GlobalSection(SolutionProperties) = preSolution
71 | HideSolutionNode = FALSE
72 | EndGlobalSection
73 | EndGlobal
74 |
--------------------------------------------------------------------------------
/Unplugged.Segy/ImageWriter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Runtime.InteropServices;
7 | #if !MONO_TOUCH
8 | using System.Drawing.Imaging;
9 | #endif
10 |
11 | namespace Unplugged.Segy
12 | {
13 | ///
14 | /// Responsible for converting SEGY data to a bitmap image
15 | ///
16 | public class ImageWriter
17 | {
18 | ///
19 | /// When true, sample values that are exactly 0.0f will have their alpha component set to 0.
20 | /// Defaults to true.
21 | ///
22 | public bool SetNullValuesToTransparent { get; set; }
23 |
24 | public ImageWriter()
25 | {
26 | SetNullValuesToTransparent = false;
27 | }
28 |
29 | #if !MONO_TOUCH
30 |
31 | ///
32 | /// Writes one or more bitmap for the given SEGY file.
33 | /// If the SEGY has multiple inline numbers, it is assumed to be 3D, and one bitmap is written for each inline.
34 | ///
35 | ///
36 | /// The destination path for the image.
37 | /// If multiple images are written, each inline number is added parenthetically to the file name.
38 | ///
39 | public virtual void Write(ISegyFile segyFile, string path)
40 | {
41 | if (segyFile.Traces == null)
42 | {
43 | using (var bitmap = new Bitmap(1, 1))
44 | bitmap.Save(path);
45 | return;
46 | }
47 | var inlineNumbers = GetInlineNumbers(segyFile);
48 | if (inlineNumbers.Count() == 1)
49 | Write(segyFile.Traces, path);
50 | else
51 | {
52 | dynamic range = FindRange(segyFile.Traces);
53 | WriteBitmapPerInline(segyFile, path, inlineNumbers, range);
54 | }
55 | }
56 |
57 | ///
58 | /// Writes a bitmap image with the given traces to the given destination path.
59 | ///
60 | public virtual void Write(IEnumerable traces, string path)
61 | {
62 | using (var bitmap = GetBitmap(traces))
63 | bitmap.Save(path);
64 | }
65 |
66 | ///
67 | /// Returns a single bitmap image composed from all the trace in the SEGY file.
68 | /// The caller is responsible for disposing of the bitmap. This is highy recommended
69 | /// so that GDI resources will be cleaned up.
70 | ///
71 | /// A disposable bitmap
72 | public virtual Bitmap GetBitmap(ISegyFile segyFile)
73 | {
74 | return GetBitmap(segyFile.Traces);
75 | }
76 |
77 | ///
78 | /// Returns a single bitmap image composed from the given traces.
79 | /// The caller is responsible for disposing of the bitmap. This is highy recommended
80 | /// so that GDI resources will be cleaned up.
81 | ///
82 | /// A disposable bitmap
83 | public virtual Bitmap GetBitmap(IEnumerable traces)
84 | {
85 | dynamic range = FindRange(traces);
86 | return GetBitmap(traces, range);
87 | }
88 | #endif
89 |
90 | ///
91 | /// Returns a bitmap as a one-dimensional byte array. Pixels are layed out as R, G, B, A with one byte per channel.
92 | ///
93 | public virtual byte[] GetRaw32BppRgba(IEnumerable traces)
94 | {
95 | return GetRaw(traces, 4);
96 | }
97 |
98 | ///
99 | /// Returns a bitmap as a one-dimensional byte array. The pixel format is 1 unsigned byte per pixel.
100 | /// Thus, the seismic data is quantized to the range 0...255.
101 | ///
102 | public virtual byte[] GetRaw8Bpp(IEnumerable traces)
103 | {
104 | return GetRaw(traces, 1);
105 | }
106 |
107 | #region Behind the Scenes
108 |
109 | private class ValueRange
110 | {
111 | public float Min { get; set; }
112 | public float Max { get; set; }
113 | public float Delta { get; set; }
114 | }
115 |
116 | private class RawBitmap
117 | {
118 | public int Width { get; set; }
119 | public int Height { get; set; }
120 | public byte[] Bytes { get; set; }
121 | }
122 |
123 | // O(N)
124 | private static ValueRange FindRange(IEnumerable traces)
125 | {
126 | var min = float.MaxValue;
127 | var max = float.MinValue;
128 | foreach (var trace in traces)
129 | foreach (var value in trace.Values)
130 | {
131 | if (value < min) min = value;
132 | if (value > max) max = value;
133 | }
134 | return new ValueRange { Min = min, Max = max, Delta = max - min };
135 | }
136 |
137 | private byte[] GetRaw(IEnumerable traces, int components)
138 | {
139 | var range = FindRange(traces);
140 | return GetRawBytesAndSize(traces, range, components).Bytes;
141 | }
142 |
143 | // O(N)
144 | private RawBitmap GetRawBytesAndSize(IEnumerable traces, ValueRange range, int components)
145 | {
146 | var traceList = traces.ToList();
147 | int width = traceList.Count;
148 | if (width == 0)
149 | return new RawBitmap { Bytes = new byte[] { }, Width = 0, Height = 0 };
150 | int height = traceList.First().Values.Count;
151 | var length = components * width * height;
152 | var bytes = new byte[length];
153 | for (int i = 0; i < width; i++)
154 | for (int j = 0; j < height; j++)
155 | {
156 | var index = components * (j * width + i);
157 | SetColor(bytes, index, range.Min, range.Delta, traceList[i].Values[j], components);
158 | }
159 | return new RawBitmap { Bytes = bytes, Width = width, Height = height };
160 | }
161 |
162 | #if !MONO_TOUCH
163 |
164 | private void WriteBitmapPerInline(ISegyFile segyFile, string path, IEnumerable inlineNumbers, ValueRange range)
165 | {
166 | foreach (var inline in inlineNumbers)
167 | {
168 | var traces = segyFile.Traces.Where(t => t.Header.InlineNumber == inline);
169 | var filename = Path.GetFileNameWithoutExtension(path);
170 | var extenstion = Path.GetExtension(path);
171 | var newPath = filename + " (" + inline + ")" + extenstion;
172 | WriteBitmapForTraces(traces, newPath, range);
173 | }
174 | }
175 |
176 | private void WriteBitmapForTraces(IEnumerable traces, string path, ValueRange range)
177 | {
178 | using (var bitmap = GetBitmap(traces, range))
179 | bitmap.Save(path);
180 | }
181 |
182 | private Bitmap GetBitmap(IEnumerable traces, dynamic range)
183 | {
184 | dynamic raw = GetRawBytesAndSize(traces, range, 4);
185 | return GetBitmap(raw.Bytes, raw.Width, raw.Height);
186 | }
187 |
188 | private static Bitmap GetBitmap(byte[] bytes, int width, int height)
189 | {
190 | var bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
191 | var bitmapData = bitmap.LockBits(Rectangle.FromLTRB(0, 0, width, height), ImageLockMode.WriteOnly, bitmap.PixelFormat);
192 | Marshal.Copy(bytes, 0, bitmapData.Scan0, bytes.Length);
193 | bitmap.UnlockBits(bitmapData);
194 | return bitmap;
195 | }
196 |
197 | #endif
198 |
199 | private void SetColor(byte[] bytes, int offset, float valueMin, float valueRange, float value, int components)
200 | {
201 | var alpha = byte.MaxValue;
202 | if (SetNullValuesToTransparent && value == 0.0f) // Exactly zero is assumed to be a null sample
203 | alpha = byte.MinValue;
204 | var byteValue = (byte)(byte.MaxValue * (value - valueMin) / valueRange);
205 | if (components == 1)
206 | bytes[offset + 0] = byteValue;
207 | else if (components == 4)
208 | {
209 | bytes[offset + 0] = byteValue;
210 | bytes[offset + 1] = byteValue;
211 | bytes[offset + 2] = byteValue;
212 | bytes[offset + 3] = alpha;
213 | }
214 | else
215 | throw new ArgumentException("Unsupported option", "components");
216 | }
217 |
218 | private static IEnumerable GetInlineNumbers(ISegyFile segyFile)
219 | {
220 | return segyFile.Traces.Select(t =>
221 | {
222 | if (t.Header == null)
223 | return 0;
224 | return t.Header.InlineNumber;
225 | }
226 | ).Distinct();
227 | }
228 |
229 | #endregion
230 | }
231 | }
232 |
--------------------------------------------------------------------------------
/Unplugged.Segy/SegyReader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using Unplugged.IbmBits;
7 |
8 | namespace Unplugged.Segy
9 | {
10 | ///
11 | /// Responsible for reading SEGY files given a path or a Stream.
12 | ///
13 | public class SegyReader
14 | {
15 | public ISegyOptions Options { get; set; }
16 | public int InlineNumberLocation { get; set; }
17 | public int CrosslineNumberLocation { get; set; }
18 |
19 | public SegyReader()
20 | {
21 | Options = new SegyOptions();
22 | InlineNumberLocation = 189;
23 | CrosslineNumberLocation = 193;
24 | }
25 |
26 | #region From the Top: Methods that start reading from the beginning of the file
27 |
28 | ///
29 | /// Given a file path, reads entire SEGY file into memory
30 | ///
31 | public virtual ISegyFile Read(string path, IReadingProgress progress = null)
32 | {
33 | using (var stream = File.OpenRead(path))
34 | return Read(stream, progress);
35 | }
36 |
37 | ///
38 | /// Given stream, reads entire SEGY file into memory.
39 | /// Assumes the stream is at the start of the file.
40 | ///
41 | public virtual ISegyFile Read(Stream stream, IReadingProgress progress = null)
42 | {
43 | return Read(stream, int.MaxValue, progress);
44 | }
45 |
46 | ///
47 | /// Given stream and traceCount, reads the requested number
48 | /// of traces into memory. The given traceCount may exceed
49 | /// the number of traces in the file;
50 | /// in that case all the traces in the file are read.
51 | /// Assumes the stream is at the start of the file.
52 | ///
53 | public virtual ISegyFile Read(Stream stream, int traceCount, IReadingProgress progress = null)
54 | {
55 | using (var reader = new BinaryReader(stream))
56 | {
57 | var fileHeader = ReadFileHeader(reader);
58 | var traces = new List();
59 | for (int i = 0; i < traceCount; i++)
60 | {
61 | if (progress != null)
62 | {
63 | // TODO: Check if stream.Length breaks when streaming from web
64 | int percentage = (int)(100 * stream.Position / stream.Length);
65 | progress.ReportProgress(percentage);
66 | if (progress.CancellationPending)
67 | break;
68 | }
69 | var trace = ReadTrace(reader, fileHeader.SampleFormat, fileHeader.IsLittleEndian);
70 | if (trace == null)
71 | break;
72 | traces.Add(trace);
73 | }
74 | return new SegyFile { Header = fileHeader, Traces = traces };
75 | }
76 | }
77 |
78 | ///
79 | /// Given a BinaryReader, reads the SEGY File Header into memory.
80 | /// Asummes the BinaryReader is at the start of the file.
81 | ///
82 | public virtual IFileHeader ReadFileHeader(BinaryReader reader)
83 | {
84 | var text = ReadTextHeader(reader);
85 | FileHeader header = ReadBinaryHeader(reader) as FileHeader;
86 | header.Text = text;
87 | return header;
88 | }
89 |
90 | ///
91 | /// Given a file path reads the text header from the beginning
92 | /// of the SEGY file.
93 | ///
94 | public virtual string ReadTextHeader(string path)
95 | {
96 | using (var stream = File.OpenRead(path))
97 | return ReadTextHeader(stream);
98 | }
99 |
100 | ///
101 | /// Given a stream reads the text header.
102 | /// Assumes the stream is at the start of the file.
103 | ///
104 | public virtual string ReadTextHeader(Stream stream)
105 | {
106 | using (var reader = new BinaryReader(stream))
107 | return ReadTextHeader(reader);
108 | }
109 |
110 | ///
111 | /// Given a BinaryReader reads the text header.
112 | /// Assumes the BinaryReader is at the start of the file.
113 | ///
114 | public virtual string ReadTextHeader(BinaryReader reader)
115 | {
116 | var textHeaderLength = Options.TextHeaderColumnCount * Options.TextHeaderRowCount;
117 | var bytes = reader.ReadBytes(textHeaderLength);
118 | string text = (bytes[0] == 'C') || Options.IsEbcdic == false ?
119 | ASCIIEncoding.Default.GetString(bytes) :
120 | IbmConverter.ToString(bytes);
121 | return Options.TextHeaderInsertNewLines ? InsertNewLines(text) : text;
122 | }
123 |
124 | #endregion
125 |
126 | #region Already in progress: Methods that start reading from the current location in the stream
127 |
128 | ///
129 | /// Given a BinaryReader, reads the binary header.
130 | /// Assumes that the binary header is the next item to be read.
131 | ///
132 | public virtual IFileHeader ReadBinaryHeader(BinaryReader reader)
133 | {
134 | var binaryHeader = reader.ReadBytes(_binaryHeaderSize);
135 | var byte0 = binaryHeader[_sampleFormatIndex];
136 | var byte1 = binaryHeader[_sampleFormatIndex + 1];
137 | bool isLittleEndian = (byte1 == 0);
138 | var sampleFormat = isLittleEndian ?
139 | (FormatCode)byte0 :
140 | (FormatCode)byte1;
141 | return new FileHeader { SampleFormat = sampleFormat, IsLittleEndian = isLittleEndian };
142 | }
143 |
144 | ///
145 | /// Given a BinaryReader, reads the trace header.
146 | /// Assumes that the trace header is the next item to be read.
147 | /// Assumes that the byte order is Big Endian.
148 | ///
149 | public virtual ITraceHeader ReadTraceHeader(BinaryReader reader)
150 | {
151 | return ReadTraceHeader(reader, false);
152 | }
153 |
154 | ///
155 | /// Given a BinaryReader, reads the trace header.
156 | /// Assumes that the trace header is the next item to be read.
157 | ///
158 | public virtual ITraceHeader ReadTraceHeader(BinaryReader reader, bool isLittleEndian)
159 | {
160 | var traceHeader = new TraceHeader();
161 | var headerBytes = reader.ReadBytes(_traceHeaderSize);
162 | if (headerBytes.Length < _traceHeaderSize)
163 | return null;
164 | if (headerBytes.Length >= CrosslineNumberLocation + 3)
165 | traceHeader.CrosslineNumber = traceHeader.TraceNumber =
166 | ToInt32(headerBytes, CrosslineNumberLocation - 1, isLittleEndian);
167 | if (headerBytes.Length >= InlineNumberLocation + 3)
168 | traceHeader.InlineNumber = ToInt32(headerBytes, InlineNumberLocation - 1, isLittleEndian);
169 | if (headerBytes.Length >= _sampleCountIndex + 2)
170 | traceHeader.SampleCount = ToInt16(headerBytes, _sampleCountIndex, isLittleEndian);
171 | return traceHeader;
172 | }
173 |
174 | ///
175 | /// Reads the trace (header and sample values).
176 | /// Assumes that the trace header is the next item to be read.
177 | ///
178 | public virtual ITrace ReadTrace(BinaryReader reader, FormatCode sampleFormat, bool isLittleEndian)
179 | {
180 | var header = ReadTraceHeader(reader, isLittleEndian);
181 | if (header == null)
182 | return null;
183 | var values = ReadTrace(reader, sampleFormat, header.SampleCount, isLittleEndian);
184 | return new Trace { Header = header, Values = values };
185 | }
186 |
187 | ///
188 | /// Assuming the trace header has been read, reads the array of sample values
189 | ///
190 | public virtual IList ReadTrace(BinaryReader reader, FormatCode sampleFormat, int sampleCount, bool isLittleEndian)
191 | {
192 | var trace = new float[sampleCount];
193 | try
194 | {
195 | for (int i = 0; i < sampleCount; i++)
196 | {
197 | switch (sampleFormat)
198 | {
199 | case FormatCode.IbmFloatingPoint4:
200 | trace[i] = reader.ReadSingleIbm();
201 | break;
202 | case FormatCode.IeeeFloatingPoint4:
203 | trace[i] = isLittleEndian ?
204 | reader.ReadSingle() :
205 | ReadReversedSingle(reader);
206 | break;
207 | case FormatCode.TwosComplementInteger1:
208 | trace[i] = ReadSignedByte(reader);
209 | break;
210 | case FormatCode.TwosComplementInteger2:
211 | trace[i] = isLittleEndian ?
212 | reader.ReadInt16() :
213 | reader.ReadInt16BigEndian();
214 | break;
215 | case FormatCode.TwosComplementInteger4:
216 | trace[i] = isLittleEndian ?
217 | reader.ReadInt32() :
218 | reader.ReadInt32BigEndian();
219 | break;
220 | default:
221 | throw new NotSupportedException(
222 | String.Format("Unsupported sample format: {0}. Send an email to dev@segy.net to request support for this format.", sampleFormat));
223 | }
224 | }
225 | }
226 | catch (EndOfStreamException) { /* Encountered end of stream before end of trace. Leave remaining trace samples as zero */ }
227 | return trace;
228 | }
229 |
230 | #endregion
231 |
232 | #region Behind the Scenes
233 |
234 | private const int _binaryHeaderSize = 400;
235 | private const int _traceHeaderSize = 240;
236 | private const int _sampleFormatIndex = 24;
237 | private const int _sampleCountIndex = 114;
238 |
239 | private string InsertNewLines(string text)
240 | {
241 | var rows = Options.TextHeaderRowCount;
242 | var cols = Options.TextHeaderColumnCount;
243 | var result = new StringBuilder(text.Length + rows);
244 | for (int i = 0; i < 1 + text.Length / cols; i++)
245 | {
246 | var line = new string(text.Skip(cols * i).Take(cols).ToArray());
247 | result.AppendLine(line);
248 | }
249 | return result.ToString();
250 | }
251 |
252 | private static int ToInt16(byte[] bytes, int index, bool isLittleEndian)
253 | {
254 | return isLittleEndian ?
255 | BitConverter.ToInt16(bytes, index) :
256 | IbmConverter.ToInt16(bytes, index);
257 | }
258 |
259 | private static int ToInt32(byte[] bytes, int index, bool isLittleEndian)
260 | {
261 | return isLittleEndian ?
262 | BitConverter.ToInt32(bytes, index) :
263 | IbmConverter.ToInt32(bytes, index);
264 | }
265 |
266 | private static float ReadSignedByte(BinaryReader reader)
267 | {
268 | byte b = reader.ReadByte();
269 | return b < 128 ? b : b - 256;
270 | }
271 |
272 | private static float ReadReversedSingle(BinaryReader reader)
273 | {
274 | var b = reader.ReadBytes(4).Reverse().ToArray();
275 | return BitConverter.ToSingle(b, 0);
276 | }
277 |
278 | #endregion
279 | }
280 | }
281 |
--------------------------------------------------------------------------------
/Unplugged.Segy.Tests/ImageWriterTest.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 | using System.Drawing.Imaging;
4 | using System.Runtime.InteropServices;
5 | using Microsoft.VisualStudio.TestTools.UnitTesting;
6 | using Moq;
7 | using TestDrivenDesign;
8 |
9 | namespace Unplugged.Segy.Tests
10 | {
11 | [TestClass]
12 | public class ImageWriterTest : TestBase
13 | {
14 | [TestMethod]
15 | public void ImageWriterOptions()
16 | {
17 | // Arrange
18 | bool setNullValuesToTransparent = Subject.SetNullValuesToTransparent;
19 |
20 | // Assert
21 | Assert.AreEqual(false, setNullValuesToTransparent);
22 | }
23 |
24 | [TestMethod]
25 | public void ShouldCreateImageFile()
26 | {
27 | // Arrange
28 | var path = TestPath() + ".png";
29 | ISegyFile segyFile = new Mock().Object;
30 |
31 | // Act
32 | Subject.Write(segyFile, path);
33 |
34 | // Assert
35 | BinaryFileAssert.Exists(path);
36 | var image = Bitmap.FromFile(path);
37 | Assert.AreEqual(1, image.Width);
38 | Assert.AreEqual(1, image.Height);
39 | }
40 |
41 | [TestMethod]
42 | public void ShouldGetBitmapWithoutWritingIt()
43 | {
44 | // Arrange
45 | var expectedWidth = 5;
46 | var expectedHeight = 21;
47 | var segy = new MockSegyFile(expectedWidth, expectedHeight);
48 |
49 | // Act
50 | Bitmap image = Subject.GetBitmap((ISegyFile)segy);
51 |
52 | // Assert
53 | Assert.AreEqual(expectedWidth, image.Width);
54 | Assert.AreEqual(expectedHeight, image.Height);
55 | image.Dispose();
56 | }
57 |
58 | [TestMethod]
59 | public void ShouldHaveCorrectResolution()
60 | {
61 | // Arrange
62 | var expectedWidth = 7;
63 | var expectedHeight = 11;
64 | var segy = new MockSegyFile(expectedWidth, expectedHeight);
65 | var path = TestPath() + ".png";
66 |
67 | // Act
68 | Subject.Write(segy, path);
69 |
70 | // Assert
71 | using (var image = Bitmap.FromFile(path))
72 | {
73 | Assert.AreEqual(expectedWidth, image.Width);
74 | Assert.AreEqual(expectedHeight, image.Height);
75 | }
76 | }
77 |
78 | [TestMethod]
79 | public void PixelValuesShouldBeBlackToWhite()
80 | {
81 | // Arrange
82 | var traceValues = new float[] { 150, 175, 125, 200, 111, 100, 123 }; // Min: 100, Max: 200
83 | var trace = new MockTrace { Values = traceValues };
84 | var segy = new MockSegyFile { Traces = new ITrace[] { trace } };
85 | var path = TestPath() + ".png";
86 |
87 | // Act
88 | Subject.Write(segy, path);
89 |
90 | // Assert
91 | Bitmap image = new Bitmap(path);
92 | Assert.AreEqual(Color.FromArgb(0, 0, 0), image.GetPixel(0, 5));
93 | Assert.AreEqual(Color.FromArgb(127, 127, 127), image.GetPixel(0, 0));
94 | Assert.AreEqual(Color.FromArgb(255, 255, 255), image.GetPixel(0, 3));
95 | }
96 |
97 | [TestMethod]
98 | public void NullSamplesShouldBeTransparent()
99 | {
100 | // Arrange: A sample value of exactly 0
101 | var traceValues = new float[] { 0.00001f, 0, -0.00001f };
102 | var trace = new MockTrace { Values = traceValues };
103 | var segy = new MockSegyFile { Traces = new ITrace[] { trace } };
104 | var path = TestPath() + ".png";
105 | Subject.SetNullValuesToTransparent = true;
106 |
107 | // Act
108 | Subject.Write(segy, path);
109 |
110 | // Assert
111 | Bitmap image = new Bitmap(path);
112 | Assert.AreEqual(255, image.GetPixel(0, 0).A);
113 | Assert.AreEqual(0, image.GetPixel(0, 1).A);
114 | Assert.AreEqual(255, image.GetPixel(0, 2).A);
115 | }
116 |
117 | [TestMethod]
118 | public void WhenDisabledNullSamplesShouldNotBeTransparent()
119 | {
120 | // Arrange
121 | var trace = new MockTrace { Values = new float[] { 0, 1, -1 } };
122 | var segy = new MockSegyFile { Traces = new ITrace[] { trace } };
123 | var path = TestPath() + ".png";
124 |
125 | // Act
126 | Subject.SetNullValuesToTransparent = false;
127 | Subject.Write(segy, path);
128 |
129 | // Assert
130 | Bitmap image = new Bitmap(path);
131 | Assert.AreEqual(255, image.GetPixel(0, 0).A);
132 | }
133 |
134 | [TestMethod]
135 | public void ShouldCreateImageForEachInline()
136 | {
137 | // Arrange
138 | var values = new float[] { 1, 2, 3 };
139 | var trace12a = new MockTrace { Header = new MockTraceHeader { InlineNumber = 12, CrosslineNumber = 1 }, Values = values };
140 | var trace12b = new MockTrace { Header = new MockTraceHeader { InlineNumber = 12, CrosslineNumber = 2 }, Values = values };
141 | var trace14 = new MockTrace { Header = new MockTraceHeader { InlineNumber = 14 }, Values = values };
142 | var segy = new MockSegyFile { Traces = new ITrace[] { trace12a, trace12b, trace14 } };
143 | var path = TestPath() + ".png";
144 |
145 | // Act
146 | Subject.Write(segy, path);
147 |
148 | // Assert
149 | var image12 = new Bitmap(TestPath() + " (12).png");
150 | Assert.AreEqual(3, image12.Height);
151 | Assert.AreEqual(2, image12.Width);
152 | var image14 = new Bitmap(TestPath() + " (14).png");
153 | Assert.AreEqual(3, image14.Height);
154 | Assert.AreEqual(1, image14.Width);
155 | }
156 |
157 | [TestMethod, DeploymentItem(@"Unplugged.Segy.Tests\Examples\lineE.sgy")]
158 | public void ImageFromExample()
159 | {
160 | // Arrange
161 | var segy = new SegyReader().Read("lineE.sgy");
162 | var path = TestPath() + ".png";
163 |
164 | // Act
165 | Subject.Write(segy, path);
166 |
167 | // Assert
168 | BinaryFileAssert.Exists(path);
169 | TestContext.AddResultFile(path);
170 | }
171 |
172 | [TestMethod]
173 | public void ShouldCreateBlackImageWhenRangeIsZero()
174 | {
175 | // Arrange
176 | var path = TestPath() + ".png";
177 | Subject.SetNullValuesToTransparent = false;
178 |
179 | // Act
180 | Subject.Write(new MockSegyFile(10, 10), path);
181 |
182 | // Assert
183 | TestContext.AddResultFile(path);
184 | Bitmap image = new Bitmap(path);
185 | Assert.AreEqual(0, image.GetPixel(0, 0).R);
186 | Assert.AreEqual(255, image.GetPixel(0, 0).A);
187 | }
188 |
189 | [TestMethod]
190 | public void ShouldCreateImageWithGivenTraces()
191 | {
192 | // Arrange
193 | IEnumerable traces = MockTraces2x3();
194 | var path = TestPath() + ".jpg";
195 |
196 | // Act
197 | Subject.Write(traces, path);
198 |
199 | // Assert
200 | BinaryFileAssert.Exists(path);
201 | TestContext.AddResultFile(path);
202 | var image = new Bitmap(path);
203 | VerifyBitmapFromMockTraces2x3(image);
204 | }
205 |
206 | [TestMethod]
207 | public void ShouldGetBitmapWithGivenTraces()
208 | {
209 | // Arrange
210 | IEnumerable traces = MockTraces2x3();
211 |
212 | // Act
213 | Bitmap image = Subject.GetBitmap(traces);
214 |
215 | // Assert
216 | VerifyBitmapFromMockTraces2x3(image);
217 | }
218 |
219 | [TestMethod]
220 | public void ShouldGetFourComponentByteArray()
221 | {
222 | // Arrange
223 | IEnumerable traces = MockTraces2x3();
224 |
225 | // Act
226 | byte[] bytes = Subject.GetRaw32BppRgba(traces);
227 |
228 | // Assert
229 | Assert.AreEqual(2 * 3 * 4, bytes.Length);
230 | Assert.AreEqual(127, bytes[0], "r");
231 | Assert.AreEqual(255, bytes[3], "a");
232 | using (var bmp = Subject.GetBitmap(traces))
233 | {
234 | var bmpData = bmp.LockBits(Rectangle.FromLTRB(0, 0, 2, 3), ImageLockMode.ReadOnly, bmp.PixelFormat);
235 | int length = bmpData.Stride * bmp.Height;
236 | byte[] expected = new byte[length];
237 | Marshal.Copy(bmpData.Scan0, expected, 0, length);
238 | CollectionAssert.AreEqual(expected, bytes);
239 | }
240 | }
241 |
242 | [TestMethod]
243 | public void ShouldGetSingleComponentByteArray()
244 | {
245 | // Arrange
246 | IEnumerable traces = MockTraces2x3();
247 |
248 | // Act
249 | byte[] bytes = Subject.GetRaw8Bpp(traces);
250 |
251 | // Assert
252 | var expected = new byte[]
253 | {
254 | 127, 63, // 20, 15
255 | 0, 255, // 10, 30
256 | 191, 191 // 25, 25
257 | };
258 | CollectionAssert.AreEqual(expected, bytes);
259 | }
260 |
261 | private static IEnumerable MockTraces2x3()
262 | {
263 | var trace1 = new MockTrace { Values = new float[] { 20, 10, 25 } };
264 | var trace2 = new MockTrace { Values = new float[] { 15, 30, 25 } };
265 | return new ITrace[] { trace1, trace2 };
266 | }
267 |
268 | private static void VerifyBitmapFromMockTraces2x3(Bitmap image)
269 | {
270 | Assert.AreEqual(2, image.Width);
271 | Assert.AreEqual(3, image.Height);
272 | Assert.AreEqual(Color.FromArgb(127, 127, 127), image.GetPixel(0, 0));
273 | image.Dispose();
274 | }
275 |
276 | [TestMethod]
277 | public void GivenTracesForCrosslineShouldCreateOneImage()
278 | {
279 | // Arrange
280 | var trace1 = new MockTrace { Values = new float[] { 99 }, Header = new MockTraceHeader { CrosslineNumber = 1, InlineNumber = 10 } };
281 | var trace2 = new MockTrace { Values = new float[] { 77 }, Header = new MockTraceHeader { CrosslineNumber = 1, InlineNumber = 20 } };
282 | IEnumerable traces = new ITrace[] { trace1, trace2 };
283 | var path = TestPath() + ".jpg";
284 |
285 | // Act
286 | Subject.Write(traces, path);
287 |
288 | // Assert
289 | BinaryFileAssert.Exists(path);
290 | TestContext.AddResultFile(path);
291 | var image = new Bitmap(path);
292 | Assert.AreEqual(2, image.Width);
293 | Assert.AreEqual(1, image.Height);
294 | }
295 |
296 | //[TestMethod]
297 | //public void ImageFromExample3D()
298 | //{
299 | // // Arrange
300 | // var reader = new SegyReader { InlineNumberLocation = 17 };
301 | // var userprofile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
302 | // var segy = reader.Read(userprofile + @"\Desktop\RMOTC Data\RMOTC Seismic data set\3D_Seismic\filt_mig.sgy");
303 | // var path = TestPath() + ".png";
304 |
305 | // // Act
306 | // Subject.Write(segy, path);
307 |
308 | // // Assert
309 | // TestContext.AddResultFile(path);
310 | //}
311 |
312 | // TODO: Should verify trace range normalized over whole volume
313 | // TODO: Handle variable length traces
314 | }
315 |
316 | class MockTraceHeader : ITraceHeader
317 | {
318 | public int SampleCount { get; set; }
319 | public int TraceNumber { get; set; }
320 | public int InlineNumber { get; set; }
321 | public int CrosslineNumber { get; set; }
322 | }
323 |
324 | class MockTrace : ITrace
325 | {
326 | public ITraceHeader Header { get; set; }
327 | public IList Values { get; set; }
328 | }
329 |
330 | class MockSegyFile : ISegyFile
331 | {
332 | public IFileHeader Header { get; set; }
333 | public IList Traces { get; set; }
334 |
335 | public MockSegyFile()
336 | {
337 | }
338 |
339 | public MockSegyFile(int traces, int samplesPerTrace)
340 | {
341 | var trace = new MockTrace { Values = new float[samplesPerTrace] };
342 | Traces = new ITrace[traces];
343 | for (int i = 0; i < traces; i++)
344 | Traces[i] = trace;
345 | }
346 | }
347 |
348 | }
349 |
--------------------------------------------------------------------------------
/packages/TestDrivenDesign.0.0.3/lib/net40/TestDrivenDesign.dll.CodeAnalysisLog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Consider replacing the language-specific data type identifier 'Bool' in member name 'TestBase.DataValueAsBool(string)' with either a language-independent equivalent or a more generic term, such as 'value'.
17 |
18 |
19 | Because the behavior of 'Convert.ToBoolean(object)' could vary based on the current user's locale settings, replace this call in 'TestBase.DataValueAsBool(string)' with a call to 'Convert.ToBoolean(object, IFormatProvider)'. If the result of 'Convert.ToBoolean(object, IFormatProvider)' will be based on input from the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter. Otherwise, if the result will based on input stored and accessed by software, such as when it is loaded from disk or from a database, specify 'CultureInfo.InvariantCulture'.
20 |
21 |
22 |
23 |
24 |
25 |
26 | Consider replacing the language-specific data type identifier 'Float' in member name 'TestBase.DataValueAsFloat(string)' with either a language-independent equivalent or a more generic term, such as 'value'.
27 |
28 |
29 | Because the behavior of 'Convert.ToSingle(object)' could vary based on the current user's locale settings, replace this call in 'TestBase.DataValueAsFloat(string)' with a call to 'Convert.ToSingle(object, IFormatProvider)'. If the result of 'Convert.ToSingle(object, IFormatProvider)' will be based on input from the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter. Otherwise, if the result will based on input stored and accessed by software, such as when it is loaded from disk or from a database, specify 'CultureInfo.InvariantCulture'.
30 |
31 |
32 |
33 |
34 |
35 |
36 | Consider replacing the language-specific data type identifier 'Int' in member name 'TestBase.DataValueAsInt(string)' with either a language-independent equivalent or a more generic term, such as 'value'.
37 |
38 |
39 | Because the behavior of 'Convert.ToInt32(object)' could vary based on the current user's locale settings, replace this call in 'TestBase.DataValueAsInt(string)' with a call to 'Convert.ToInt32(object, IFormatProvider)'. If the result of 'Convert.ToInt32(object, IFormatProvider)' will be based on input from the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter. Otherwise, if the result will based on input stored and accessed by software, such as when it is loaded from disk or from a database, specify 'CultureInfo.InvariantCulture'.
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | Consider a design where 'TestBase<T>.Verify(Expression<Action<T>>)' doesn't nest generic type 'Expression<Action<T>>'.
51 |
52 |
53 | In externally visible method 'TestBase<T>.Verify(Expression<Action<T>>)', validate parameter 'expression' before using it.
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | Do not nest generic types in member signatures
69 | Avoid API that require users to instantiate a generic type with another generic type as type argument. The syntax gets too complex.
70 | Consider a design where {0} doesn't nest generic type {1}.
71 |
72 | http://msdn.microsoft.com/library/ms182144(VS.100).aspx
73 | [none]
74 | CriticalError
75 |
76 |
77 |
78 | Identifiers should not contain type names
79 | Avoid using language-specific types name in parameters and members and data type identifiers in parameters. Types names might not be intuitive for all developers. It is recommended that you select a generic name, such as 'value', instead. If this is not sufficient, be sure to use the type name as it is defined in the .NET Framework Library and avoid language-specific type names completely. Some examples of C#-specific type names are 'float' (use 'Single' if a generic name is not sufficient), and 'ulong' (use 'UInt64' if a generic name is not sufficient).
80 | In member {0}, consider replacing the data type identifier '{1}' in parameter name {2} with a more generic term, such as 'value'.
81 | Consider replacing the language-specific data type identifier '{0}' in member name {1} with either a language-independent equivalent or a more generic term, such as 'value'.
82 |
83 | http://msdn.microsoft.com/library/bb531486(VS.100).aspx
84 | [none]
85 | Error
86 |
87 |
88 |
89 | Specify IFormatProvider
90 | If an overload exists that takes an IFormatProvider argument, it should always be called in favor of an overload that does not. Some methods in the runtime convert a value to or from a string representation and take a string parameter that contains one or more characters, called format specifiers, which indicate how the value is to be converted. If the meaning of the format specifier varies by culture, a formatting object supplies the actual characters used in the string representation. In scenarios where sorting and comparison behavior should never change between cultures, specify CultureInfo.InvariantCulture, otherwise, specify CultureInfo.CurrentCulture.
91 | Because the behavior of {0} could vary based on the current user's locale settings, replace this call in {1} with a call to {2}. If the result of {2} will be based on input from the user, specify {3} as the 'IFormatProvider' parameter. Otherwise, if the result will based on input stored and accessed by software, such as when it is loaded from disk or from a database, specify {4}.
92 |
93 | http://msdn.microsoft.com/library/ms182190(VS.100).aspx
94 | [none]
95 | Error
96 |
97 |
98 |
99 | Validate arguments of public methods
100 | All reference arguments passed to externally visible methods should be checked against null (Nothing in VB). If appropriate, throw a System.ArgumentNullException when the argument is null.
101 | In externally visible method {0}, validate parameter '{1}' before using it.
102 | RuleOwner
103 | http://msdn.microsoft.com/library/ms182182(VS.100).aspx
104 |
105 | Warning
106 |
107 |
108 |
109 |
110 | Category
111 | Certainty
112 | Collapse All
113 | Check Id
114 | Error
115 | error(s)
116 | Expand All
117 | Help
118 | Line
119 | message(s)
120 | [Location not stored in Pdb]
121 | Project
122 | Resolution
123 | Rule
124 | Rule File
125 | Rule Description
126 | Source
127 | Status
128 | Target
129 | Warning
130 | warning(s)
131 | Code Analysis Report
132 |
133 |
134 |
--------------------------------------------------------------------------------
/Unplugged.Segy.Tests/SegyReaderTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Text;
7 | using Microsoft.VisualStudio.TestTools.UnitTesting;
8 | using TestDrivenDesign;
9 | using Unplugged.IbmBits;
10 |
11 | namespace Unplugged.Segy.Tests
12 | {
13 | [TestClass]
14 | public class SegyReaderTest : TestBase
15 | {
16 | #region Loading Options
17 |
18 | [TestMethod]
19 | public void ShouldHaveDefaultOptions()
20 | {
21 | // Arrange
22 | ISegyOptions options = Subject.Options;
23 |
24 | // Assert
25 | Assert.IsInstanceOfType(options, typeof(SegyOptions));
26 | }
27 |
28 | [TestMethod]
29 | public void InlineNumberLocation()
30 | {
31 | // Arrange
32 | int inlineNumberLocation = Subject.InlineNumberLocation;
33 | int crosslineNumberLocation = Subject.CrosslineNumberLocation;
34 |
35 | // Assert
36 | Assert.AreEqual(189, inlineNumberLocation, "According to SEGY Rev 1, byte 189 - 192 in the trace header should be used for the in-line number");
37 | Assert.AreEqual(193, crosslineNumberLocation, "According to SEGY Rev 1, byte 193 - 196 in the trace header should be used for the cross-line number");
38 | }
39 |
40 | #endregion
41 |
42 | /// The text header is typically 3200 EBCDIC encoded character bytes. That is, 80 columns by 40 lines (formerly punch cards).
43 | #region Textual Header
44 |
45 | [TestMethod]
46 | public void ShouldReadHeaderFromEbcdicEncoding()
47 | {
48 | // Arrange some Ebcdic characters at the beginning of the file
49 | var expected = "Once upon a time...";
50 | var ebcdicBytes = ConvertToEbcdic(expected);
51 | var path = TestPath();
52 | File.WriteAllBytes(path, ebcdicBytes);
53 |
54 | // Act
55 | string header = Subject.ReadTextHeader(path);
56 |
57 | // Assert
58 | StringAssert.StartsWith(header, expected);
59 | }
60 |
61 | [TestMethod]
62 | public void ShouldRead3200BytesForTextHeader()
63 | {
64 | // Arrange some Ebcdic characters at the beginning of the file
65 | var expected = "TheEnd";
66 | var ebcdicBytes = ConvertToEbcdic(new string('c', 3200 - 6) + expected + "notExpected");
67 | File.WriteAllBytes(TestPath(), ebcdicBytes);
68 |
69 | // Act
70 | var header = Subject.ReadTextHeader(TestPath());
71 |
72 | // Assert
73 | StringAssert.EndsWith(header.TrimEnd(), expected);
74 | }
75 |
76 | [TestMethod, DeploymentItem(@"Unplugged.Segy.Tests\Examples\lineE.sgy")]
77 | public void ShouldReadExampleTextHeader()
78 | {
79 | // Act
80 | var header = Subject.ReadTextHeader(_example);
81 |
82 | // Assert
83 | Console.WriteLine(header);
84 | StringAssert.StartsWith(header, "C 1");
85 | StringAssert.Contains(header, "CLIENT");
86 | StringAssert.EndsWith(header.TrimEnd(), "END EBCDIC");
87 | }
88 |
89 | [TestMethod, DeploymentItem(@"Unplugged.Segy.Tests\Examples\lineE.sgy")]
90 | public void ShouldReadTextHeaderGivenStream()
91 | {
92 | // Arrange
93 | using (Stream stream = File.OpenRead(_example))
94 | {
95 | // Act
96 | string header = Subject.ReadTextHeader(stream);
97 |
98 | // Arrange
99 | StringAssert.EndsWith(header.TrimEnd(), "END EBCDIC");
100 | }
101 | }
102 |
103 | [TestMethod]
104 | public void ShouldInsertNewlinesEvery80Characters()
105 | {
106 | // Arrange
107 | var line1 = new string('a', 80);
108 | var line2 = new string('b', 80);
109 | var line3 = new string('c', 80);
110 | var bytes = ConvertToEbcdic(line1 + line2 + line3);
111 | File.WriteAllBytes(TestPath(), bytes);
112 |
113 | // Act
114 | var header = Subject.ReadTextHeader(TestPath());
115 |
116 | // Assert
117 | var lines = SplitLines(header);
118 | Assert.AreEqual(line1, lines[0]);
119 | Assert.AreEqual(line2, lines[1]);
120 | Assert.AreEqual(line3, lines[2]);
121 | }
122 |
123 | [TestMethod]
124 | public void ShouldDetectAsciiHeaderByFirstCharacter()
125 | {
126 | // Arrange
127 | var expected = "C 1 This is expected";
128 | var extra = new string('z', 80);
129 | File.WriteAllText(TestPath(), expected + extra, Encoding.ASCII);
130 |
131 | // Act
132 | var header = Subject.ReadTextHeader(TestPath());
133 |
134 | // Assert
135 | StringAssert.StartsWith(header, expected);
136 | Assert.AreEqual(2, SplitLines(header).Count(), "Should split lines for ascii header");
137 | }
138 |
139 | [TestMethod]
140 | public void ShouldObserveOptionsForTextHeader()
141 | {
142 | // Arrange
143 | Subject.Options = new SegyOptions { TextHeaderColumnCount = 3, TextHeaderRowCount = 7, IsEbcdic = false };
144 | var text = new string('e', 21) + "n";
145 | File.WriteAllText(TestPath(), text);
146 |
147 | // Act
148 | var result = Subject.ReadTextHeader(TestPath());
149 |
150 | // Assert
151 | StringAssert.StartsWith(result, "eee" + Environment.NewLine);
152 | CollectionAssert.DoesNotContain(result.ToCharArray(), 'n');
153 | }
154 |
155 | [TestMethod]
156 | public void ShouldObserveNewLinesOption()
157 | {
158 | // Arrange
159 | Subject.Options = new SegyOptions { TextHeaderInsertNewLines = false };
160 | var expected = new string('x', 3200);
161 | File.WriteAllBytes(TestPath(), ConvertToEbcdic(expected));
162 |
163 | // Act
164 | var actual = Subject.ReadTextHeader(TestPath());
165 |
166 | // Assert
167 | Assert.AreEqual(expected, actual);
168 | }
169 |
170 | #endregion
171 |
172 | /// 400-byte Binary File Header follows 3200 byte textual header
173 | /// Bytes 3225-3226: Data sample format code
174 | #region Binary File Header
175 |
176 | [TestMethod]
177 | public void ShouldReadSampleFormatFromByte25()
178 | {
179 | // Arrange
180 | var expected = FormatCode.IeeeFloatingPoint4;
181 | bool isLittleEndian = false;
182 |
183 | // Act
184 | IFileHeader result = Set16BitValueInBinaryStreamAndRead((sr, br) => sr.ReadBinaryHeader(br), 25, (Int16)expected, isLittleEndian);
185 |
186 | // Assert
187 | Assert.AreEqual(expected, result.SampleFormat);
188 | Assert.AreEqual(isLittleEndian, result.IsLittleEndian);
189 | }
190 |
191 | [TestMethod]
192 | public void ShouldDetectLittleEndiannessFromSampleFormat()
193 | {
194 | // Arrange
195 | var expected = FormatCode.TwosComplementInteger1;
196 | bool isLittleEndian = true;
197 |
198 | // Act
199 | IFileHeader result = Set16BitValueInBinaryStreamAndRead((sr, br) => sr.ReadBinaryHeader(br), 25, (Int16)expected, isLittleEndian);
200 |
201 | // Assert
202 | Assert.AreEqual(expected, result.SampleFormat);
203 | Assert.AreEqual(isLittleEndian, result.IsLittleEndian);
204 | }
205 |
206 | [TestMethod]
207 | public void ShouldConsume400Bytes()
208 | {
209 | AssertBytesConsumed((r) => Subject.ReadBinaryHeader(r), 400);
210 | }
211 |
212 | [TestMethod, DeploymentItem(@"Unplugged.Segy.Tests\Examples\lineE.sgy")]
213 | public void ShouldReadTextAndBinaryHeaderGivenBinaryReader()
214 | {
215 | // Arrange
216 | using (var stream = File.OpenRead(_example))
217 | using (var reader = new BinaryReader(stream))
218 | {
219 | // Act
220 | IFileHeader fileHeader = Subject.ReadFileHeader(reader);
221 |
222 | // Assert
223 | Assert.AreEqual(Subject.ReadTextHeader(_example), fileHeader.Text);
224 | Assert.AreEqual(FormatCode.IbmFloatingPoint4, fileHeader.SampleFormat);
225 | }
226 | }
227 |
228 | #endregion
229 |
230 | /// The Trace Header is typically 240 bytes with Big Endian values
231 | /// Info from the standard:
232 | /// 115-116 Number of samples in this trace
233 | /// 117-118 Sample Interval in Micro-Seconds
234 | /// 181-194 X CDP
235 | /// 185-188 Y CDP
236 | /// 189-192 Inline number (for 3D)
237 | /// 193-196 Cross-line number (for 3D)
238 | ///
239 | /// Header Information from Teapot load sheet
240 | /// Inline (line) bytes: 17- 20 and 181-184
241 | /// Crossline (trace) bytes: 13- 16 and 185-188
242 | /// CDP X_COORD bytes: 81- 84 and 189-193
243 | /// CDP Y_COORD bytes: 85- 88 and 193-196
244 | #region Trace Header
245 |
246 | [TestMethod]
247 | public void SystemShouldBeLittleEndian()
248 | {
249 | Assert.IsTrue(BitConverter.IsLittleEndian, "These tests assume the system is little endian");
250 | }
251 |
252 | [TestMethod]
253 | public void ShouldReadTraceNumberFromSpecifiedByteLocation()
254 | {
255 | // Arrange
256 | Int32 expectedValue = Int16.MaxValue + 100;
257 | Subject.CrosslineNumberLocation = 113;
258 |
259 | // Act
260 | ITraceHeader result = Set32BitValueInBinaryStreamAndRead((sr, br) => sr.ReadTraceHeader(br), Subject.CrosslineNumberLocation, expectedValue);
261 |
262 | // Assert
263 | Assert.AreEqual(expectedValue, result.TraceNumber);
264 | Assert.AreEqual(expectedValue, result.CrosslineNumber);
265 | }
266 |
267 | [TestMethod]
268 | public void ShouldReadInlineNumberFromSpecifiedByteLocation()
269 | {
270 | // Arrange
271 | Int32 expectedValue = Int16.MaxValue + 100;
272 | Subject.InlineNumberLocation = 123;
273 |
274 | // Act
275 | ITraceHeader result = Set32BitValueInBinaryStreamAndRead((sr, br) => sr.ReadTraceHeader(br), Subject.InlineNumberLocation, expectedValue);
276 |
277 | // Assert
278 | Assert.AreEqual(expectedValue, result.InlineNumber);
279 | }
280 |
281 | [TestMethod]
282 | public void ShouldReadNumberOfSamplesFromByte115()
283 | {
284 | // Arrange
285 | Int16 expectedValue = 2345;
286 |
287 | // Act
288 | ITraceHeader result = Set16BitValueInBinaryStreamAndRead((sr, br) => sr.ReadTraceHeader(br), 115, expectedValue, false);
289 |
290 | // Assert
291 | Assert.AreEqual(expectedValue, result.SampleCount);
292 | }
293 |
294 | [TestMethod]
295 | public void ShouldConsume240Bytes()
296 | {
297 | AssertBytesConsumed(r => Subject.ReadTraceHeader(r), 240);
298 | }
299 |
300 | [TestMethod, DeploymentItem(@"Unplugged.Segy.Tests\Examples\lineE.sgy")]
301 | public void ShouldReadTraceHeaderFromExample()
302 | {
303 | // Arrange
304 | using (var stream = File.OpenRead(_example))
305 | using (var reader = new BinaryReader(stream))
306 | {
307 | var header = Subject.ReadFileHeader(reader);
308 |
309 | // Act
310 | var traceHeader = Subject.ReadTraceHeader(reader);
311 |
312 | // Assert
313 | Assert.AreEqual(1001, traceHeader.SampleCount);
314 | for (int i = 0; i < traceHeader.SampleCount; i++)
315 | {
316 | var value = reader.ReadSingleIbm();
317 | Console.WriteLine(value);
318 | Assert.IsTrue(value < 10 && value > -10);
319 | }
320 | Assert.AreEqual(1001, Subject.ReadTraceHeader(reader).SampleCount);
321 | }
322 | }
323 |
324 | #endregion
325 |
326 | #region Trace Data
327 |
328 | [TestMethod]
329 | public void ShouldConsumeAllBytesInTrace()
330 | {
331 | // Arrange
332 | FormatCode sampleFormat = FormatCode.IeeeFloatingPoint4;
333 | int sampleCount = 200;
334 | var expected = 800;
335 | IList result = null;
336 |
337 | // Act
338 | AssertBytesConsumed(r => result = Subject.ReadTrace(r, sampleFormat, sampleCount, false), expected);
339 |
340 | // Assert
341 | Assert.AreEqual(sampleCount, result.Count);
342 | }
343 |
344 | [TestMethod]
345 | public void ShouldReadSinglesForIeeeFormat()
346 | {
347 | var expected = new float[] { 10, 20, 30 };
348 | var bytes = BitConverter.GetBytes(10f).Concat(BitConverter.GetBytes(20f)).Concat(BitConverter.GetBytes(30f)).ToArray();
349 | VerifyReadsSamplesOfGivenFormat(FormatCode.IeeeFloatingPoint4, expected, bytes, true);
350 | }
351 |
352 | [TestMethod]
353 | public void ShouldReadSingleIbmForIbmFormat()
354 | {
355 | // TODO: This test would be clearer if I had code to convert TO IBM Float
356 | var bytes = BitConverter.GetBytes(96795456).Concat(BitConverter.GetBytes(2136281153)).Concat(BitConverter.GetBytes(1025579328)).ToArray();
357 | var expected = new float[] { 0.9834598f, 1.020873f, 0.09816343f };
358 | VerifyReadsSamplesOfGivenFormat(FormatCode.IbmFloatingPoint4, expected, bytes, false);
359 | }
360 |
361 | [TestMethod]
362 | public void ShouldReadTwosComplementInteger2BigEndian()
363 | {
364 | var expected = new float[] { -777, 888 };
365 | var bytes = BitConverter.GetBytes((Int16)(-777)).Reverse().Concat(BitConverter.GetBytes((Int16)888).Reverse()).ToArray();
366 | VerifyReadsSamplesOfGivenFormat(FormatCode.TwosComplementInteger2, expected, bytes, false);
367 | }
368 |
369 | [TestMethod]
370 | public void ShouldReadTwosComplementInteger2LittleEndian()
371 | {
372 | VerifyReadsSamplesOfGivenFormat(FormatCode.TwosComplementInteger2, new float[] { 513 }, new byte[] { 1, 2 }, true);
373 | }
374 |
375 | [TestMethod]
376 | public void ShouldReadTwosComplementInteger4BigEndian()
377 | {
378 | var expected = new float[] { -777, 888 };
379 | var bytes = BitConverter.GetBytes((Int32)(-777)).Reverse().Concat(BitConverter.GetBytes((Int32)888).Reverse()).ToArray();
380 | VerifyReadsSamplesOfGivenFormat(FormatCode.TwosComplementInteger4, expected, bytes, false);
381 | }
382 |
383 | [TestMethod]
384 | public void ShouldReadTwosComplementInteger4LittleEndian()
385 | {
386 | var expected = new float[] { -777, 888 };
387 | var bytes = BitConverter.GetBytes((Int32)(-777)).Concat(BitConverter.GetBytes((Int32)888)).ToArray();
388 | VerifyReadsSamplesOfGivenFormat(FormatCode.TwosComplementInteger4, expected, bytes, true);
389 | }
390 |
391 | [TestMethod]
392 | public void ShouldReadTwosComplementInteger1()
393 | {
394 | VerifyReadsSamplesOfGivenFormat(FormatCode.TwosComplementInteger1, new float[] { -126, -128, 88 }, new byte[] { 130, 128, 88}, true);
395 | }
396 |
397 | [TestMethod]
398 | public void ShouldHandleEndOfStreamBeforeEndOfTrace()
399 | {
400 | // Arrange
401 | var bytes = new byte[] { 1, 0, 2, 0 };
402 | var expected = new float[] { 1, 2, 0 };
403 |
404 | // Act
405 | VerifyReadsSamplesOfGivenFormat(FormatCode.TwosComplementInteger2, expected, bytes, true);
406 | }
407 |
408 | private void VerifyReadsSamplesOfGivenFormat(FormatCode sampleFormat, float[] expected, byte[] bytes, bool isLittleEndian)
409 | {
410 | // Arrange
411 | var sampleCount = expected.Length;
412 | IList result = null;
413 |
414 | // Act
415 | using (var stream = new MemoryStream(bytes))
416 | using (var reader = new BinaryReader(stream))
417 | result = Subject.ReadTrace(reader, sampleFormat, sampleCount, isLittleEndian);
418 |
419 | // Assert
420 | for (int i = 0; i < sampleCount; i++)
421 | Assert.AreEqual(expected[i], result[i], 0.00001);
422 | }
423 |
424 | [TestMethod]
425 | public void ShouldReadTraceHeaderAndValuesGivenSampleFormat()
426 | {
427 | // Arrange
428 | var sampleFormat = FormatCode.IeeeFloatingPoint4;
429 | var expected = new float[] { 11, 111 };
430 | var bytes = new byte[240]; // trace header
431 | SetBigIndianValue((Int16)expected.Length, bytes, 115);
432 | bytes = bytes.Concat(BitConverter.GetBytes(expected[0]).Reverse()).Concat(BitConverter.GetBytes(expected[1]).Reverse()).ToArray();
433 | ITrace trace = null;
434 |
435 | // Act
436 | using (var stream = new MemoryStream(bytes))
437 | using (var reader = new BinaryReader(stream))
438 | trace = Subject.ReadTrace(reader, sampleFormat, false);
439 |
440 | // Assert
441 | Assert.AreEqual(expected.Length, trace.Header.SampleCount);
442 | CollectionAssert.AreEqual(expected, trace.Values.ToList());
443 | }
444 |
445 | #endregion
446 |
447 | #region Reading Entire File
448 |
449 | [TestMethod, DeploymentItem(@"Unplugged.Segy.Tests\Examples\lineE.sgy")]
450 | public void ShouldReadFileHeadersAndAllTraces()
451 | {
452 | // Arrange
453 | var path = _example;
454 |
455 | // Act
456 | ISegyFile segy = Subject.Read(path);
457 |
458 | // Assert
459 | VerifyExampleValuesAndTraceCount(segy);
460 | }
461 |
462 | [TestMethod, DeploymentItem(@"Unplugged.Segy.Tests\Examples\lineE.sgy")]
463 | public void ShouldReadStreamHeadersAndAllTraces()
464 | {
465 | // Arrange
466 | var path = _example;
467 | ISegyFile segy = null;
468 |
469 | // Act
470 | using (Stream stream = File.OpenRead(path))
471 | segy = Subject.Read(stream);
472 |
473 | // Assert
474 | VerifyExampleValuesAndTraceCount(segy);
475 | }
476 |
477 | [TestMethod, DeploymentItem(@"Unplugged.Segy.Tests\Examples\lineE.sgy")]
478 | public void ShouldBeAbleToReadSegyFromNetworkStream()
479 | {
480 | // Arrange
481 | var webclient = new WebClient();
482 | using (var stream = webclient.OpenRead("https://github.com/jfoshee/UnpluggedSegy/raw/c44f0f65c4c80671964531cf5d45170fcb585d15/Unplugged.Segy.Tests/Examples/lineE.sgy"))
483 | {
484 | // Act
485 | var segy = Subject.Read(stream);
486 |
487 | // Assert
488 | VerifyExampleValuesAndTraceCount(segy);
489 | }
490 | }
491 |
492 | [TestMethod, DeploymentItem(@"Unplugged.Segy.Tests\Examples\lineE.sgy")]
493 | public void ShouldReadNoMoreThanRequestedNumberOfTraces()
494 | {
495 | // Arrange
496 | int traceCount = 5;
497 | using (Stream stream = File.OpenRead(_example))
498 | {
499 | // Act
500 | ISegyFile segy = Subject.Read(stream, traceCount);
501 |
502 | // Assert
503 | VerifyExampleValues(segy);
504 | Assert.AreEqual(traceCount, segy.Traces.Count);
505 | }
506 | }
507 |
508 | [TestMethod, DeploymentItem(@"Unplugged.Segy.Tests\Examples\lineE.sgy")]
509 | public void ShouldReadAllTracesIfRequestedTraceCountIsGreater()
510 | {
511 | // Arrange
512 | using (Stream stream = File.OpenRead(_example))
513 | {
514 | // Act
515 | ISegyFile segy = Subject.Read(stream, 9999);
516 |
517 | // Assert
518 | VerifyExampleValuesAndTraceCount(segy);
519 | }
520 | }
521 |
522 | private const string _example = "lineE.sgy";
523 |
524 | private static void VerifyExampleValues(ISegyFile result)
525 | {
526 | StringAssert.StartsWith(result.Header.Text, "C 1");
527 | StringAssert.Contains(result.Header.Text, "C16 GEOPHONES");
528 | Assert.AreEqual(FormatCode.IbmFloatingPoint4, result.Header.SampleFormat);
529 | Assert.AreEqual(1001, result.Traces.First().Header.SampleCount);
530 | var traceValues = result.Traces.First().Values.ToList();
531 | Assert.AreEqual(1001, traceValues.Count);
532 | CollectionAssert.Contains(traceValues, 0f);
533 | CollectionAssert.Contains(traceValues, 0.9834598f);
534 | CollectionAssert.DoesNotContain(traceValues, float.PositiveInfinity);
535 | }
536 |
537 | private static void VerifyExampleValuesAndTraceCount(ISegyFile result)
538 | {
539 | VerifyExampleValues(result);
540 | var fileLength = new FileInfo(_example).Length;
541 | Assert.AreEqual((fileLength - 3200 - 400) / (240 + 1001 * 4), result.Traces.Count);
542 | }
543 |
544 | [TestMethod]
545 | public void AllReadMethodsShouldBeMockable()
546 | {
547 | // Act
548 | var readMethods = typeof(SegyReader).GetMethods().Where(m => m.Name == "Read");
549 |
550 | // Assert
551 | foreach (var method in readMethods)
552 | Assert.IsTrue(method.IsVirtual);
553 | }
554 |
555 | #endregion
556 |
557 | #region Reading Little Endian
558 |
559 | [TestMethod]
560 | public void ShouldReadLittleEndianTraceHeader()
561 | {
562 | // Arrange
563 | var bytes = new byte[240];
564 | bytes[114] = 1; // 1
565 | bytes[115] = 2; // 512
566 | Subject.InlineNumberLocation = 101;
567 | bytes[100] = 1; // 1
568 | bytes[103] = 2; // 33,554,432
569 | Subject.CrosslineNumberLocation = 201;
570 | bytes[200] = 2; // 2
571 | bytes[203] = 2; // 33,554,432
572 | ITraceHeader traceHeader = null;
573 |
574 | // Act
575 | using (var stream = new MemoryStream(bytes))
576 | using (var reader = new BinaryReader(stream))
577 | traceHeader = Subject.ReadTraceHeader(reader, true);
578 |
579 | // Assert
580 | Assert.AreEqual(513, traceHeader.SampleCount);
581 | Assert.AreEqual(33554433, traceHeader.InlineNumber);
582 | Assert.AreEqual(33554434, traceHeader.CrosslineNumber);
583 | Assert.AreEqual(33554434, traceHeader.TraceNumber);
584 | }
585 |
586 | // TODO: LittleEndianIntegrationTest
587 |
588 | #endregion
589 |
590 | #region Behind the scenes
591 |
592 | private static byte[] ConvertToEbcdic(string expected)
593 | {
594 | var unicode = Encoding.Unicode;
595 | var ebcdic = Encoding.GetEncoding("IBM037");
596 | var unicodeBytes = unicode.GetBytes(expected);
597 | var ebcdicBytes = Encoding.Convert(unicode, ebcdic, unicodeBytes);
598 | return ebcdicBytes;
599 | }
600 |
601 | private static string[] SplitLines(string header)
602 | {
603 | return header.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
604 | }
605 |
606 | private TResult Set16BitValueInBinaryStreamAndRead(Func act, int byteNumber, Int16 value, bool isLittleEndian)
607 | {
608 | // Arrange
609 | var bytes = new byte[400];
610 | if (isLittleEndian)
611 | BitConverter.GetBytes(value).CopyTo(bytes, byteNumber - 1);
612 | else
613 | SetBigIndianValue(value, bytes, byteNumber);
614 |
615 | // Act
616 | using (var stream = new MemoryStream(bytes))
617 | using (var reader = new BinaryReader(stream))
618 | return act(Subject, reader);
619 | }
620 |
621 | private TResult Set32BitValueInBinaryStreamAndRead(Func act, int byteNumber, Int32 value)
622 | {
623 | // Arrange
624 | var bytes = new byte[400];
625 | SetBigIndianValue(value, bytes, byteNumber);
626 |
627 | // Act
628 | using (var stream = new MemoryStream(bytes))
629 | using (var reader = new BinaryReader(stream))
630 | return act(Subject, reader);
631 | }
632 |
633 | private static void SetBigIndianValue(Int16 value, byte[] bytes, int byteNumber)
634 | {
635 | var samplesBytes = BitConverter.GetBytes(value);
636 | bytes[byteNumber - 1] = samplesBytes[1];
637 | bytes[byteNumber] = samplesBytes[0];
638 | }
639 |
640 | private static void SetBigIndianValue(Int32 value, byte[] bytes, int byteNumber)
641 | {
642 | var samplesBytes = BitConverter.GetBytes(value);
643 | bytes[byteNumber - 1] = samplesBytes[3];
644 | bytes[byteNumber + 0] = samplesBytes[2];
645 | bytes[byteNumber + 1] = samplesBytes[1];
646 | bytes[byteNumber + 2] = samplesBytes[0];
647 | }
648 |
649 | // TODO: Move AssertBytesConsumed to TDD lib
650 | public static void AssertBytesConsumed(Action act, int expectedNumberOfBytes)
651 | {
652 | var bytes = new byte[2 * expectedNumberOfBytes];
653 | using (var stream = new MemoryStream(bytes))
654 | using (var reader = new BinaryReader(stream))
655 | {
656 | // Act
657 | act(reader);
658 |
659 | // Assert
660 | Assert.AreEqual(expectedNumberOfBytes, stream.Position, "Wrong number of bytes were consumed.");
661 | }
662 | }
663 | #endregion
664 | }
665 | }
666 |
--------------------------------------------------------------------------------