Skip to content

Commit

Permalink
Merge pull request #6 from opensatelliteproject/Charts
Browse files Browse the repository at this point in the history
Charts
  • Loading branch information
racerxdl authored Feb 14, 2017
2 parents a0f1af9 + 5081f85 commit e7e1382
Show file tree
Hide file tree
Showing 60 changed files with 905 additions and 295 deletions.
4 changes: 4 additions & 0 deletions XRIT/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
bin/*
obj/*
Content/bin
Content/obj
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
12 changes: 10 additions & 2 deletions goesdump/ChannelDecoder/MSDU.cs → XRIT/PacketData/MSDU.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System;
using System.Linq;
using OpenSatelliteProject.Tools;

namespace OpenSatelliteProject {
namespace OpenSatelliteProject.PacketData {
public class MSDU {
#region Properties

public int Version { get; set; }

public int SHF { get; set; }
Expand Down Expand Up @@ -53,18 +55,21 @@ public bool FillPacket {
return APID == 2047;
}
}

#endregion

#region Constructor / Destructor

private MSDU() {
}

#endregion

#region Methods

public void addDataBytes(byte[] data) {
if (data.Length + Data.Length > PacketLength + 2) {
UIConsole.GlobalConsole.Warn("Overflow in MSDU!");
Console.WriteLine("(MSDU) Overflow in MSDU!");
}
byte[] newData = new byte[Data.Length + data.Length];
Array.Copy(Data, newData, Data.Length);
Expand All @@ -76,10 +81,12 @@ public void addDataBytes(byte[] data) {
}

}

#endregion


#region Builders / Parsers

public static MSDU parseMSDU(byte[] data) {
MSDU msdu = new MSDU();

Expand Down Expand Up @@ -126,6 +133,7 @@ public static MSDU parseMSDU(byte[] data) {

return msdu;
}

#endregion
}
}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;

namespace OpenSatelliteProject {
namespace OpenSatelliteProject.PacketData {
public enum SequenceType {
CONTINUED_SEGMENT = 0,
FIRST_SEGMENT = 1,
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
27 changes: 27 additions & 0 deletions XRIT/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;

// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.

[assembly: AssemblyTitle("XRIT")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("Lucas Teske @ 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.

[assembly: AssemblyVersion("1.0.*")]

// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.

//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

134 changes: 134 additions & 0 deletions XRIT/Tools/FileParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenSatelliteProject.PacketData;
using OpenSatelliteProject.PacketData.Enums;
using OpenSatelliteProject.PacketData.Structs;

namespace OpenSatelliteProject.Tools {
public static class FileParser {
public static XRITHeader GetHeader(byte[] data) {
List<XRITBaseHeader> headers = GetHeaderData(data);
return new XRITHeader(headers);
}

public static List<XRITBaseHeader> GetHeaderData(byte[] data) {
List<XRITBaseHeader> headers = new List<XRITBaseHeader>();
int maxLength = data.Length; // Initial Guess
int c = 0;

while (c < maxLength) {
int type = data[0];
byte[] tmp = data.Skip(1).Take(2).ToArray();

if (BitConverter.IsLittleEndian) {
Array.Reverse(tmp);
}

int size = BitConverter.ToUInt16(tmp, 0);
tmp = data.Take(size).ToArray();

if (tmp.Length < size) {
Console.WriteLine("Not enough data for unpack header: Expected {0} got {1}", size, tmp.Length);
break;
}

XRITBaseHeader h;
switch (type) {
case (int)HeaderType.PrimaryHeader:
PrimaryRecord fh = LLTools.ByteArrayToStruct<PrimaryRecord>(tmp);
fh = LLTools.StructToSystemEndian(fh);
h = new PrimaryHeader(fh);
maxLength = (int)fh.HeaderLength; // Set the correct size
break;
case (int)HeaderType.ImageStructureRecord:
ImageStructureRecord isr = LLTools.ByteArrayToStruct<ImageStructureRecord>(tmp);
isr = LLTools.StructToSystemEndian(isr);
h = new ImageStructureHeader(isr);
break;
case (int)HeaderType.ImageNavigationRecord:
ImageNavigationRecord inr = LLTools.ByteArrayToStruct<ImageNavigationRecord>(tmp);
inr = LLTools.StructToSystemEndian(inr);
h = new ImageNavigationHeader(inr);
break;
case (int)HeaderType.ImageDataFunctionRecord:
// Cannot marshable due variable length
//ImageDataFunctionRecord idfr = LLTools.ByteArrayToStruct<ImageDataFunctionRecord>(tmp);
//idfr = LLTools.StructToSystemEndian(idfr);
ImageDataFunctionRecord idfr = new ImageDataFunctionRecord();
idfr.Data = System.Text.Encoding.UTF8.GetString(tmp.Skip(3).ToArray());
h = new ImageDataFunctionHeader(idfr);
break;
case (int)HeaderType.AnnotationRecord:
// Cannot be marshalled due variable length
//AnnotationRecord ar = LLTools.ByteArrayToStruct<AnnotationRecord>(tmp);
//ar = LLTools.StructToSystemEndian(ar);
AnnotationRecord ar = new AnnotationRecord();
ar.Filename = System.Text.Encoding.UTF8.GetString(tmp.Skip(3).ToArray());
h = new AnnotationHeader(ar);
break;
case (int)HeaderType.TimestampRecord:
TimestampRecord tr = LLTools.ByteArrayToStruct<TimestampRecord>(tmp);
tr = LLTools.StructToSystemEndian(tr);
h = new TimestampHeader(tr);
break;
case (int)HeaderType.AncillaryTextRecord:
// Cannot be marshalled due variable length.
// AncillaryText at = LLTools.ByteArrayToStruct<AncillaryText>(tmp);
//at = LLTools.StructToSystemEndian(at);
AncillaryText at = new AncillaryText();
at.Data = System.Text.Encoding.UTF8.GetString(tmp.Skip(3).ToArray());
h = new AncillaryHeader(at);
break;
case (int)HeaderType.KeyRecord:
h = new XRITBaseHeader(HeaderType.KeyRecord, tmp);
break;
case (int)HeaderType.SegmentIdentificationRecord:
SegmentIdentificationRecord sir = LLTools.ByteArrayToStruct<SegmentIdentificationRecord>(tmp);
sir = LLTools.StructToSystemEndian(sir);
h = new SegmentIdentificationHeader(sir);
break;
case (int)HeaderType.NOAASpecificHeader:
NOAASpecificRecord nsr = LLTools.ByteArrayToStruct<NOAASpecificRecord>(tmp);
nsr = LLTools.StructToSystemEndian(nsr);
h = new NOAASpecificHeader(nsr);
break;
case (int)HeaderType.HeaderStructuredRecord:
// Cannot be marshalled due variable length
//HeaderStructuredRecord hsr = LLTools.ByteArrayToStruct<HeaderStructuredRecord>(tmp);
//hsr = LLTools.StructToSystemEndian(hsr); // Header Structured Record doesn't have endianess dependant fields
HeaderStructuredRecord hsr = new HeaderStructuredRecord();
hsr.Data = System.Text.Encoding.UTF8.GetString(tmp.Skip(3).ToArray());
h = new HeaderStructuredHeader(hsr);
break;
case (int)HeaderType.RiceCompressionRecord:
RiceCompressionRecord rcr = LLTools.ByteArrayToStruct<RiceCompressionRecord>(tmp);
rcr = LLTools.StructToSystemEndian(rcr);
h = new RiceCompressionHeader(rcr);
break;
case (int)HeaderType.DCSFileNameRecord:
// Cannot be marshalled due variable length
//DCSFilenameRecord dfr = LLTools.ByteArrayToStruct<DCSFilenameRecord>(tmp);
//dfr = LLTools.StructToSystemEndian(dfr); // DCS Filename Record doesn't have endianess dependant fields
DCSFilenameRecord dfr = new DCSFilenameRecord();
dfr.Filename = System.Text.Encoding.UTF8.GetString(tmp.Skip(3).ToArray());
h = new DCSFilenameHeader(dfr);
break;
default:
h = new XRITBaseHeader();
h.Type = HeaderType.Unknown;
break;
}

h.RawData = tmp;
headers.Add(h);
c += size;
data = data.Skip(size).ToArray();
}

return headers;
}

}
}

155 changes: 155 additions & 0 deletions XRIT/Tools/ImageHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
using System;
using System.IO;
using System.Linq;
using OpenSatelliteProject.PacketData.Structs;
using OpenSatelliteProject.PacketData;
using System.Drawing;
using System.Drawing.Imaging;
using OpenSatelliteProject.Tools;
using System.Runtime.InteropServices;

namespace OpenSatelliteProject.Tools {
public class ImageHandler {

public static ImageHandler Handler { get; private set; }

static ImageHandler() {
ImageHandler.Handler = new ImageHandler();
}

private ImageHandler() {

}

public void HandleFile(string filename, string outputFolder) {
var f = File.Open(filename, FileMode.Open);
var firstHeader = new byte[3];
f.Read(firstHeader, 0, 3);
if (firstHeader[0] == 0) {
var tmp = firstHeader.Skip(1).Take(2).ToArray();
if (BitConverter.IsLittleEndian) {
Array.Reverse(tmp);
}

int size = BitConverter.ToUInt16(tmp, 0);
firstHeader = new byte[size - 3];
f.Seek(0, SeekOrigin.Begin);
f.Read(firstHeader, 0, size - 3);

PrimaryRecord fh = LLTools.ByteArrayToStruct<PrimaryRecord>(firstHeader);
fh = LLTools.StructToSystemEndian(fh);

f.Seek(0, SeekOrigin.Begin);
tmp = new byte[fh.HeaderLength];
f.Read(tmp, 0, (int)fh.HeaderLength);
var header = FileParser.GetHeader(tmp);
ProcessFile(f, header, outputFolder);
f.Close();
} else {
Console.WriteLine("Expected header type 0 for first header. Got {0}.", (int)firstHeader[0]);
}
}

private void ProcessCompressedFile(FileStream file, XRITHeader header, string outputFolder) {
if (header.NOAASpecificHeader.Compression == CompressionType.GIF) {
string outName = header.Filename.Replace(".lrit", ".gif");
outName = Path.Combine(outputFolder, outName);
var file2 = File.OpenWrite(outName);

byte[] buffer = new Byte[1024];
int bytesRead;

while ((bytesRead = file.Read(buffer, 0, 1024)) > 0) {
file2.Write(buffer, 0, bytesRead);
}

file2.Close();
} else if (header.NOAASpecificHeader.Compression == CompressionType.JPEG) {
string outName = header.Filename.Replace(".lrit", ".jpg");
outName = Path.Combine(outputFolder, outName);
var file2 = File.OpenWrite(outName);

byte[] buffer = new Byte[1024];
int bytesRead;

while ((bytesRead = file.Read(buffer, 0, 1024)) > 0) {
file2.Write(buffer, 0, bytesRead);
}

file2.Close();
} else {
throw new Exception(string.Format("Unknown Compression type: {0}", header.NOAASpecificHeader.Compression.ToString()));
}
}

private void ProcessFile(FileStream file, XRITHeader header, string outputFolder) {
var width = header.ImageStructureHeader.Columns;
var height = header.ImageStructureHeader.Lines;
var bitsPerPixel = header.ImageStructureHeader.BitsPerPixel;

if (header.NOAASpecificHeader.Compression != CompressionType.NO_COMPRESSION && header.NOAASpecificHeader.Compression != CompressionType.LRIT_RICE) {
ProcessCompressedFile(file, header, outputFolder);
return;
}

if (bitsPerPixel != 8 && bitsPerPixel != 1) {
throw new Exception(string.Format("Unsupported bits per pixel {0}", bitsPerPixel));
}

var format = bitsPerPixel == 8 ? PixelFormat.Format8bppIndexed : PixelFormat.Format1bppIndexed;
var b = new Bitmap(width, height, format);
var bytesToRead = (width * height);

if (bitsPerPixel == 1) {
bytesToRead = (8 * (bytesToRead + 7)) / 8;
bytesToRead /= 8;
} else {
// Create grayscale palette
ColorPalette pal = b.Palette;
for(int i=0;i<=255;i++) {
pal.Entries[i] = Color.FromArgb(i, i, i);
}
b.Palette = pal;
}

var buffer = new byte[bytesToRead];
file.Read(buffer, 0, bytesToRead);

if (width % 8 == 0 || bitsPerPixel != 1) {
var data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.WriteOnly, format);
if (data.Stride == width * bitsPerPixel / 8) {
Marshal.Copy(buffer, 0, data.Scan0, buffer.Length);
} else {
// So our stride is bigger than our width (alignment issues). So let's copy line by line.
var strideBuffer = new byte[data.Stride * height];
int nwidth = width * bitsPerPixel / 8;
for (int i = 0; i < height; i++) {
Buffer.BlockCopy(buffer, nwidth * i, strideBuffer, data.Stride * i, nwidth);
}
Marshal.Copy(strideBuffer, 0, data.Scan0, strideBuffer.Length);
}
b.UnlockBits(data);
} else {
// Hard mode, let's optimize this in the future.
b = new Bitmap(width, height, PixelFormat.Format24bppRgb);
var z = 0;
for (int i = 0; i < bytesToRead; i++) {
for (int k = 7; k >= 0; k--) {
var x = z % width;
var y = z / width;
bool bitset = ((buffer[i] >> k) & 1) == 1;
if (x < width && y < height) {
b.SetPixel(x, y, Color.FromArgb((int)(bitset ? 0xFFFFFFFF : 0x0)));
}
z++;
}
}
}

string outName = header.Filename.Replace(".lrit", ".gif");
outName = Path.Combine(outputFolder, outName);
b.Save(outName, ImageFormat.Gif);
}
}
}

Loading

0 comments on commit e7e1382

Please sign in to comment.