static LibInfo() { var assembly = Assembly.GetExecutingAssembly(); try { using (Stream stream = assembly.GetManifestResourceStream("OpenSatelliteProject.git-hash.txt")) using (StreamReader reader = new StreamReader(stream)) { string result = reader.ReadToEnd(); _commitId = result; } } catch (Exception) { UIConsole.Warn("Cannot load git-hash from library."); } try { using (Stream stream = assembly.GetManifestResourceStream("OpenSatelliteProject.git-log.txt")) using (StreamReader reader = new StreamReader(stream)) { string result = reader.ReadToEnd(); _gitlog = result; } } catch (Exception) { UIConsole.Warn("Cannot load git-log from library."); } }
private static byte[] ReadFileFromAssembly(string filename) { byte[] data = null; var assembly = Assembly.GetExecutingAssembly(); try { Stream stream = assembly.GetManifestResourceStream($"OpenSatelliteProject.ShapeFiles.{filename}"); if (stream == null) { stream = assembly.GetManifestResourceStream($"OpenSatelliteProject.{filename}"); } using (stream) { data = new byte[stream.Length]; int position = 0; while (position < stream.Length) { int chunkSize = stream.Length - position > 4096 ? 4096 : (int)(stream.Length - position); stream.Read(data, position, chunkSize); position += chunkSize; } } } catch (Exception e) { UIConsole.Warn($"ShapeFiles -- Cannot load {filename} from library."); UIConsole.Error($"ShapeFiles -- {e.Message}"); } return(data); }
void SetConfigVars() { UIConsole.Log("Setting Configuration"); FileHandler.SkipEMWIN = !ProgConfig.EnableEMWIN; FileHandler.SkipDCS = !ProgConfig.EnableDCS; FileHandler.SkipWeatherData = !ProgConfig.EnableWeatherData; if (ProgConfig.TemporaryFileFolder != null) { if (!LLTools.TestFolderAccess(ProgConfig.TemporaryFileFolder)) { UIConsole.Error($"Cannot write file to Temporary Folder {ProgConfig.TemporaryFileFolder}"); throw new ApplicationException($"Cannot write file to Temporary Folder {ProgConfig.TemporaryFileFolder}"); } FileHandler.TemporaryFileFolder = ProgConfig.TemporaryFileFolder; } if (ProgConfig.FinalFileFolder != null) { if (!LLTools.TestFolderAccess(ProgConfig.FinalFileFolder)) { UIConsole.Error($"Cannot write file to Final Folder {ProgConfig.FinalFileFolder}"); throw new ApplicationException($"Cannot write file to Final Folder {ProgConfig.FinalFileFolder}"); } FileHandler.FinalFileFolder = ProgConfig.FinalFileFolder; } ImageManager.EraseFiles = ProgConfig.EraseFilesAfterGeneratingFalseColor; ImageManager.GenerateInfrared = ProgConfig.GenerateInfraredImages; ImageManager.GenerateVisible = ProgConfig.GenerateVisibleImages; ImageManager.GenerateWaterVapour = ProgConfig.GenerateWaterVapourImages; ImageManager.MaxRetryCount = ProgConfig.MaxGenerateRetry; ImageManager.UseNOAAFileFormat = ProgConfig.UseNOAAFormat; ImageManager.GenerateLabels = ProgConfig.GenerateLabels; ImageManager.GenerateLatLonOverlays = ProgConfig.GenerateLatLonOverlays; ImageManager.GenerateMapOverlays = ProgConfig.GenerateMapOverlays; ImageManager.GenerateLatLonLabel = ProgConfig.GenerateLatLonLabel; Connector.ChannelDataServerName = ProgConfig.ChannelDataServerName; Connector.StatisticsServerName = ProgConfig.StatisticsServerName; Connector.ConstellationServerName = ProgConfig.ConstellationServerName; Connector.ChannelDataServerPort = ProgConfig.ChannelDataServerPort; Connector.StatisticsServerPort = ProgConfig.StatisticsServerPort; Connector.ConstellationServerPort = ProgConfig.ConstellationServerPort; if (LLTools.IsLinux) { SyslogClient.SysLogServerIp = ProgConfig.SysLogServer; try { SyslogClient.Send(ProgConfig.SysLogFacility, Level.Information, "Your syslog connection is working! OpenSatelliteProject is enabled to send logs."); } catch (SocketException) { UIConsole.Warn("Your syslog is not enabled to receive UDP request. Please refer to https://opensatelliteproject.github.io/OpenSatelliteProject/"); } } }
public static void HandleTextData(string filename, XRITHeader header) { if (header.PrimaryHeader.FileType == FileTypeCode.TEXT) { string basedir = FileHandler.FinalFileFolder; basedir = Path.Combine(basedir, TextFolder); try { UIConsole.Log($"New {header.ToNameString()}"); if (!Directory.Exists(basedir)) { Directory.CreateDirectory(basedir); } TextHandler.Handler.HandleFile(filename, basedir); File.Delete(filename); } catch (Exception e) { UIConsole.Warn($"Failed to parse Weather Data Image at {Path.GetFileName(filename)}: {e}"); } } else { FileHandler.DefaultHandler(filename, header); } }
public void ParseBytes(byte[] data) { uint counter; bool replayFlag; bool ovfVcnt; bool ovfVcntProblem; bool frameJump; if (data.Length < FRAMESIZE) { throw new Exception(String.Format("Not enough data. Expected {0} and got {1}", FRAMESIZE, data.Length)); } channelId = (data[1] & 0x3F); byte[] cb = data.Skip(2).Take(4).ToArray(); if (BitConverter.IsLittleEndian) { Array.Reverse(cb); } cb[0] = 0x00; counter = BitConverter.ToUInt32(cb, 0); //counter &= 0xFFFFFF00; counter >>= 8; replayFlag = (data[5] & 0x80) > 0; if (replayFlag) { UIConsole.Debug("Replay Flag set. Skipping packet."); return; } if (counter - lastFrame - 1 == -1) { UIConsole.Warn("Last packet same ID as the current one but no replay bit set! Skipping packet."); return; } frameJump = lastFrame > counter; ovfVcnt = frameJump && counter == 0; ovfVcntProblem = ovfVcnt && (0xFFFFFF - lastFrame) + counter - 1 > 0; if (frameJump && !ovfVcnt) { UIConsole.Warn($"Frame Jump occured. Current Frame: {counter} Last Frame: {lastFrame}"); if (lastAPID != -1) { temporaryStorage[lastAPID].FrameLost = true; } } else if (lastFrame != -1 && lastFrame + 1 != counter && !ovfVcnt) { UIConsole.Error(String.Format("Lost {0} frames. Last Frame #{1} - Current Frame #{2} on VCID {3}", counter - lastFrame - 1, lastFrame, counter, channelId)); if (lastAPID != -1) { temporaryStorage[lastAPID].FrameLost = true; } } else if (!IgnoreCounterJump && lastFrame != -1 && ovfVcntProblem) { UIConsole.Error(String.Format("Lost {0} frames. Last Frame #{1} - Current Frame #{2} on VCID {3}", (0xFFFFFF - lastFrame) + counter - 1, lastFrame, counter, channelId)); if (lastAPID != -1) { temporaryStorage[lastAPID].FrameLost = true; } } if (ovfVcntProblem && IgnoreCounterJump || frameJump && IgnoreCounterJump) { UIConsole.Warn($"Frame Jump detected from {lastFrame} to {counter} on VCID {channelId} but IgnoreCounterJump is set to true. Ignoring..."); } if (lastFrame != -1) { if (frameJump && !ovfVcnt) { manager.FrameLoss++; } else if (!IgnoreCounterJump && ovfVcnt) { int losses = (int)Math.Abs((0xFFFFFF - lastFrame) + counter - 1); if (losses < MAX_ACCOUTABLE_LOSSES) { FrameLoss += losses; if (manager != null) { manager.FrameLoss += losses; } } else { UIConsole.Warn($"Frame Lost ({losses}) in this section is higher than max accountable losses. Not accounting for it (probably corrupt frame)."); } } else if (!ovfVcnt) { int losses = (int)Math.Abs(counter - lastFrame - 1); if (losses < MAX_ACCOUTABLE_LOSSES) { FrameLoss += losses; if (manager != null) { manager.FrameLoss += losses; } } else { UIConsole.Warn($"Frame Lost ({losses}) in this section is higher than max accountable losses. Not accounting for it (probably corrupt frame)."); } } } if (frameJump && !ovfVcnt) { FrameJumps++; if (manager != null) { manager.FrameJumps++; } } if (lastFrame < counter || ovfVcnt || frameJump) { lastFrame = (int)counter; } else { UIConsole.Warn($"LastFrame is bigger than currentFrame ({lastFrame} > {counter}). Not changing current number..."); } cb = data.Skip(6).Take(2).ToArray(); if (BitConverter.IsLittleEndian) { Array.Reverse(cb); } int fhp = BitConverter.ToUInt16(cb, 0) & 0x7FF; data = data.Skip(8).ToArray(); // Data is now TP_PDU var p = Tuple.Create(0, new byte[0]); if (fhp != 2047) // Has a packet start { if (lastAPID == -1 && buffer.Length > 0) { // There was not enough data to packetize last time. So lets fill the buffer until the fhp and create packet. if (fhp > 0) { buffer = buffer.Concat(data.Take(fhp)).ToArray(); data = data.Skip(fhp).ToArray(); fhp = 0; } p = CreatePacket(buffer); lastAPID = p.Item1; buffer = p.Item2; } if (lastAPID != -1) { if (fhp > 0) { temporaryStorage[lastAPID].addDataBytes(buffer.Concat(data.Take(fhp)).ToArray()); data = data.Skip(fhp).ToArray(); fhp = 0; } if (!temporaryStorage[lastAPID].Full && !temporaryStorage[lastAPID].FrameLost && lastAPID != 2047) { Bugs++; if (manager != null) { manager.Bugs++; } StackFrame callStack = new StackFrame(0, true); UIConsole.Debug(String.Format("Problem at line {0} in file {1}! Not full! Check code for bugs!", callStack.GetFileLineNumber(), callStack.GetFileName())); } FinishMSDU(temporaryStorage[lastAPID]); temporaryStorage.Remove(lastAPID); lastAPID = -1; } buffer = buffer.Concat(data.Skip(fhp)).ToArray(); p = CreatePacket(buffer); lastAPID = p.Item1; buffer = p.Item2; } else { if (buffer.Length > 0 && lastAPID != -1) { buffer = buffer.Concat(data).ToArray(); p = CreatePacket(buffer); lastAPID = p.Item1; buffer = p.Item2; } else if (lastAPID == -1) { buffer = buffer.Concat(data).ToArray(); p = CreatePacket(buffer); lastAPID = p.Item1; buffer = p.Item2; } else if (buffer.Length > 0) { Console.WriteLine("EDGE CASE!"); } else { temporaryStorage[lastAPID].addDataBytes(data); } } }
public void FinishMSDU(MSDU msdu) { try { if (msdu.APID == 2047) { // Skip fill packet return; } bool firstOrSinglePacket = msdu.Sequence == SequenceType.FIRST_SEGMENT || msdu.Sequence == SequenceType.SINGLE_DATA; Packets++; if (manager != null) { manager.Packets++; } if (!msdu.Valid) { CRCFails++; if (manager != null) { manager.CRCFails++; } } if (manager != null) { LengthFails++; if (!msdu.Full) { manager.LengthFails++; } } if (!msdu.Valid || !msdu.Full) { if (msdu.FrameLost) { UIConsole.Error($"Lost some frames on MSDU, the file will be corrupted. CRC Match: {msdu.Valid} - Size Match: {msdu.Full}"); } else { UIConsole.Error($"Corrupted MSDU. CRC Match: {msdu.Valid} - Size Match: {msdu.Full}"); } } if (msdu.Sequence == SequenceType.FIRST_SEGMENT || msdu.Sequence == SequenceType.SINGLE_DATA) { if (startnum != -1) { UIConsole.Warn("Received First Segment but last data wasn't finished! Forcing dump."); // This can only happen for multi-segment file. filename = Path.Combine(FileHandler.TemporaryFileFolder, channelId.ToString()); filename = Path.Combine(filename, $"{lastMSDU.APID}_{lastMSDU.Version}.lrit"); FileHandler.HandleFile(filename, fileHeader, manager); startnum = -1; endnum = -1; } fileHeader = FileParser.GetHeader(msdu.Data.Skip(10).ToArray()); if (msdu.Sequence == SequenceType.FIRST_SEGMENT) { startnum = msdu.PacketNumber; } } else if (msdu.Sequence == SequenceType.LAST_SEGMENT) { endnum = msdu.PacketNumber; if (startnum == -1) { // Orphan Packet endnum = -1; return; } } else if (msdu.Sequence != SequenceType.SINGLE_DATA && startnum == -1) { // Orphan Packet return; } // LRIT EMWIN /* Uncomment to enable EMWIN Ingestor * Its broken right now * if (fileHeader.PrimaryHeader.FileType == FileTypeCode.EMWIN) { * //Ingestor * int offset = 10 + (int)fileHeader.PrimaryHeader.HeaderLength; * EMWIN.Ingestor.Process(msdu.Data.Skip(offset).ToArray()); * return; * } */ string path = Path.Combine(FileHandler.TemporaryFileFolder, channelId.ToString()); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } filename = Path.Combine(path, $"{msdu.APID}_{msdu.Version}.lrit"); byte[] dataToSave = msdu.Data.Skip(firstOrSinglePacket ? 10 : 0).Take(firstOrSinglePacket ? msdu.PacketLength - 10 : msdu.PacketLength).ToArray(); if (fileHeader.Compression == CompressionType.LRIT_RICE && !firstOrSinglePacket) { int missedPackets = lastMSDU.PacketNumber - msdu.PacketNumber - 1; if (lastMSDU.PacketNumber == 16383 && msdu.PacketNumber == 0) { missedPackets = 0; } if (missedPackets > 0) { UIConsole.Warn(String.Format("Missed {0} packets on image. Filling with null bytes. Last Packet Number: {1} Current: {2}", missedPackets, lastMSDU.PacketNumber, msdu.PacketNumber)); byte[] fill = Decompress.GenerateFillData(fileHeader.ImageStructureHeader.Columns); using (FileStream fs = new FileStream(filename, FileMode.Append, FileAccess.Write)) { using (BinaryWriter sw = new BinaryWriter(fs)) { while (missedPackets > 0) { sw.Write(fill); missedPackets--; } sw.Flush(); } } } dataToSave = Decompress.InMemoryDecompress(dataToSave, fileHeader.ImageStructureHeader.Columns, fileHeader.RiceCompressionHeader.Pixel, fileHeader.RiceCompressionHeader.Flags); } lastMSDU = msdu; using (FileStream fs = new FileStream(filename, firstOrSinglePacket ? FileMode.Create : FileMode.Append, FileAccess.Write)) { using (BinaryWriter sw = new BinaryWriter(fs)) { sw.Write(dataToSave); sw.Flush(); } } if (msdu.Sequence == SequenceType.LAST_SEGMENT || msdu.Sequence == SequenceType.SINGLE_DATA) { FileHandler.HandleFile(filename, fileHeader, manager); startnum = -1; endnum = -1; } } catch (Exception e) { UIConsole.Error(String.Format("Exception on FinishMSDU: {0}", e)); } }
public void FinishMSDU(MSDU msdu) { try { if (msdu.APID == 2047) { // Skip fill packet return; } bool firstOrSinglePacket = msdu.Sequence == SequenceType.FIRST_SEGMENT || msdu.Sequence == SequenceType.SINGLE_DATA; Packets++; if (manager != null) { manager.Packets++; } if (!msdu.Valid) { CRCFails++; if (manager != null) { manager.CRCFails++; } } if (manager != null) { LengthFails++; if (!msdu.Full) { manager.LengthFails++; } } if (!msdu.Valid || !msdu.Full) { if (msdu.FrameLost) { UIConsole.Error($"Lost some frames on MSDU, the file will be corrupted. CRC Match: {msdu.Valid} - Size Match: {msdu.Full}"); } else { UIConsole.Error($"Corrupted MSDU. CRC Match: {msdu.Valid} - Size Match: {msdu.Full}"); } } if (msdu.Sequence == SequenceType.FIRST_SEGMENT || msdu.Sequence == SequenceType.SINGLE_DATA) { if (msduCache.ContainsKey(msdu.APID)) { var minfo = msduCache[msdu.APID]; UIConsole.Warn($"Received First Segment for {msdu.APID:X3} but last data wasn't saved to disk yet! Forcing dump."); string ofilename = Path.Combine(FileHandler.TemporaryFileFolder, channelId.ToString()); ofilename = Path.Combine(ofilename, minfo.FileName); FileHandler.HandleFile(ofilename, minfo.Header, manager); msduCache.Remove(msdu.APID); } var msInfo = new MSDUInfo() { APID = msdu.APID, FileName = msdu.TemporaryFilename, Header = FileParser.GetHeader(msdu.Data.Skip(10).ToArray()), LastPacketNumber = msdu.PacketNumber, }; msduCache.Add(msdu.APID, msInfo); } else if (msdu.Sequence == SequenceType.LAST_SEGMENT || msdu.Sequence == SequenceType.CONTINUED_SEGMENT) { if (!msduCache.ContainsKey(msdu.APID)) { UIConsole.Debug($"Orphan Packet for APID {msdu.APID}!"); return; } } var msduInfo = msduCache[msdu.APID]; msduInfo.Refresh(); // LRIT EMWIN /* Uncomment to enable EMWIN Ingestor * Its broken right now * if (fileHeader.PrimaryHeader.FileType == FileTypeCode.EMWIN) { * //Ingestor * int offset = 10 + (int)fileHeader.PrimaryHeader.HeaderLength; * EMWIN.Ingestor.Process(msdu.Data.Skip(offset).ToArray()); * return; * } */ string path = Path.Combine(FileHandler.TemporaryFileFolder, channelId.ToString()); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } string filename = Path.Combine(path, msduInfo.FileName); byte[] dataToSave = msdu.Data.Skip(firstOrSinglePacket ? 10 : 0).Take(firstOrSinglePacket ? msdu.PacketLength - 10 : msdu.PacketLength).ToArray(); if (msduInfo.Header.Compression == CompressionType.LRIT_RICE && !firstOrSinglePacket) { int missedPackets = msduInfo.LastPacketNumber - msdu.PacketNumber - 1; if (msduInfo.LastPacketNumber == 16383 && msdu.PacketNumber == 0) { missedPackets = 0; } if (missedPackets > 0) { UIConsole.Warn(String.Format("Missed {0} packets on image. Filling with null bytes. Last Packet Number: {1} Current: {2}", missedPackets, msduInfo.LastPacketNumber, msdu.PacketNumber)); byte[] fill = Decompress.GenerateFillData(msduInfo.Header.ImageStructureHeader.Columns); using (FileStream fs = new FileStream(filename, FileMode.Append, FileAccess.Write)) { using (BinaryWriter sw = new BinaryWriter(fs)) { while (missedPackets > 0) { sw.Write(fill); missedPackets--; } sw.Flush(); } } } if (msduInfo.Header.RiceCompressionHeader == null) // Fix bug for GOES-15 TX after GOES-16 switch. Weird, but let's try defaults { dataToSave = Decompress.InMemoryDecompress(dataToSave, msduInfo.Header.ImageStructureHeader.Columns, 16, AEC.ALLOW_K13_OPTION_MASK | AEC.MSB_OPTION_MASK | AEC.NN_OPTION_MASK); // 49 } else { dataToSave = Decompress.InMemoryDecompress(dataToSave, msduInfo.Header.ImageStructureHeader.Columns, msduInfo.Header.RiceCompressionHeader.Pixel, msduInfo.Header.RiceCompressionHeader.Flags); } } msduInfo.LastPacketNumber = msdu.PacketNumber; using (FileStream fs = new FileStream(filename, firstOrSinglePacket ? FileMode.Create : FileMode.Append, FileAccess.Write)) { using (BinaryWriter sw = new BinaryWriter(fs)) { sw.Write(dataToSave); sw.Flush(); } } if (msdu.Sequence == SequenceType.LAST_SEGMENT || msdu.Sequence == SequenceType.SINGLE_DATA) { FileHandler.HandleFile(filename, msduInfo.Header, manager); msduCache.Remove(msdu.APID); } } catch (Exception e) { UIConsole.Error(String.Format("Exception on FinishMSDU: {0}", e)); } }
private void channelDataLoop() { try { UIConsole.Log("Channel Data Loop started"); byte[] buffer = new byte[892]; IPHostEntry ipHostInfo = Dns.GetHostEntry(ChannelDataServerName); IPAddress ipAddress = new IPAddress(new byte[] { 127, 0, 0, 1 }); foreach (IPAddress ip in ipHostInfo.AddressList) { if (ip.AddressFamily != AddressFamily.InterNetworkV6) { ipAddress = ip; break; } } IPEndPoint remoteEP = new IPEndPoint(ipAddress, ChannelDataServerPort); Socket sender = null; while (channelDataThreadRunning) { bool isConnected = true; UIConsole.Log("Channel Data Thread connect"); try { sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sender.ReceiveTimeout = 3000; sender.Connect(remoteEP); isConnected = true; UIConsole.Log(String.Format("Socket connected to {0}", sender.RemoteEndPoint.ToString())); int nullReceive = 0; while (isConnected) { try { var receivedBytes = sender.Receive(buffer); if (receivedBytes < buffer.Length && receivedBytes != 0) { UIConsole.Error("Received less bytes than channel data!"); Thread.Sleep(200); nullReceive = 0; } else if (receivedBytes == 0) { nullReceive++; if (nullReceive == 5) { UIConsole.Error("Cannot reach server. Dropping connection!"); isConnected = false; sender.Shutdown(SocketShutdown.Both); sender.Disconnect(false); sender.Close(); } } else { nullReceive = 0; this.postChannelData(buffer); } } catch (ArgumentNullException ane) { UIConsole.Error(String.Format("ArgumentNullException : {0}", ane.ToString())); isConnected = false; } catch (SocketException se) { // That's usually timeout. I would say that is best to handle and show some message // But for now, that would make it confusing for the users. So let's keep without a notice. //UIConsole.GlobalConsole.Error(String.Format("SocketException : {0}", se.ToString())); isConnected = false; } catch (Exception e) { UIConsole.Error(String.Format("Unexpected exception : {0}", e.ToString())); isConnected = false; } DataConnected = isConnected; if (!channelDataThreadRunning) { break; } } sender.Shutdown(SocketShutdown.Both); sender.Disconnect(false); sender.Close(); } catch (ArgumentNullException ane) { UIConsole.Error(String.Format("ArgumentNullException : {0}", ane.ToString())); } catch (SocketException se) { UIConsole.Error(String.Format("SocketException : {0}", se.ToString())); } catch (Exception e) { UIConsole.Error(String.Format("Unexpected exception : {0}", e.ToString())); } if (channelDataThreadRunning) { UIConsole.Warn("Socket closed. Waiting 1s before trying again."); Thread.Sleep(1000); } } UIConsole.Debug("Requested to close Channel Data Thread!"); try { if (sender != null) { sender.Shutdown(SocketShutdown.Both); sender.Disconnect(false); sender.Close(); } } catch (Exception e) { UIConsole.Debug(String.Format("Exception thrown when closing socket: {0} Ignoring.", e.ToString())); } UIConsole.Log("Channel Data Thread closed."); } catch (Exception e) { CrashReport.Report(e); } }
/// <summary> /// Applies a LUT using Lookup function using visible and infrared bitmaps. Output to visible. /// visible bitmap needs to be 24bpp RGB or 32bpp ARGB /// This also assumes Grayscale images as RGB /// </summary> /// <param name="lookup">Lookup function(int visible, int infrared)</param> /// <param name="visible">Visible.</param> /// <param name="infrared">Infrared.</param> public static void Apply2DLut(Func <byte, byte, int> lookup, ref Bitmap visible, Bitmap infrared) { // FalseColorLUTVal(int thermal, int visible) if (visible.PixelFormat != PixelFormat.Format24bppRgb && visible.PixelFormat != PixelFormat.Format32bppArgb) { throw new ArgumentException("Visible bitmap needs to be RGB24 or ARGB32"); } if (infrared.PixelFormat != visible.PixelFormat) { infrared = ToFormat(infrared, visible.PixelFormat); } if (visible.Height != infrared.Height || visible.Width != infrared.Width) { UIConsole.Warn("The Infrared and Visible channels size doesn't match, the false might look weird.\n" + $"Visible({visible.Width}, {visible.Height}) vs Infrared({infrared.Width}, {infrared.Height})"); } var vdata = visible.LockBits(new Rectangle(0, 0, visible.Width, visible.Height), ImageLockMode.ReadWrite, visible.PixelFormat); var idata = infrared.LockBits(new Rectangle(0, 0, infrared.Width, infrared.Height), ImageLockMode.ReadOnly, visible.PixelFormat); var totalPoints = Math.Min(vdata.Stride * visible.Height, idata.Stride * infrared.Height); // Avoids crash on corrupted images switch (visible.PixelFormat) { case PixelFormat.Format24bppRgb: unsafe { var vPtr = (byte *)vdata.Scan0.ToPointer(); var iPtr = (byte *)idata.Scan0.ToPointer(); for (var stridePos = 0; stridePos < totalPoints; stridePos += 3) { // Assume Grayscale in RGB var visVal = vPtr[stridePos]; var irVal = iPtr[stridePos]; var color = lookup(irVal, visVal); vPtr [stridePos + 0] = (byte)((color >> 0) & 0xFF); vPtr [stridePos + 1] = (byte)((color >> 8) & 0xFF); vPtr [stridePos + 2] = (byte)((color >> 16) & 0xFF); } } break; case PixelFormat.Format32bppArgb: unsafe { var vPtr = (byte *)vdata.Scan0.ToPointer(); var iPtr = (byte *)idata.Scan0.ToPointer(); for (var stridePos = 0; stridePos < totalPoints; stridePos += 4) { // Assume Grayscale in ARGB var visVal = vPtr[stridePos]; var irVal = iPtr [stridePos]; var color = lookup(irVal, visVal); vPtr [stridePos + 0] = (byte)((color >> 0) & 0xFF); vPtr [stridePos + 1] = (byte)((color >> 8) & 0xFF); vPtr [stridePos + 2] = (byte)((color >> 16) & 0xFF); vPtr [stridePos + 3] = (byte)((color >> 24) & 0xFF); } } break; default: UIConsole.Error($"ImageTools received an unsuported image type: {visible.PixelFormat}"); break; } visible.UnlockBits(vdata); infrared.UnlockBits(idata); }
public static string Decompressor(string prefix, int pixels, int startnum, int endnum, int pixelsPerBlock, int mask) { /** * Temporary Workarround. Needs to change directly on Demuxer */ string outputFile = String.Format("{0}_decomp{1}.lrit", prefix, startnum); string ifile; FileStream f = null; try { ifile = string.Format("{0}{1}.lrit", prefix, startnum); byte[] input = File.ReadAllBytes(ifile); byte[] outputData = new byte[pixels]; try { File.Delete(ifile); } catch (IOException e) { UIConsole.Warn(String.Format("Cannot delete file {0}: {1}", Path.GetFileName(ifile), e)); } f = File.OpenWrite(outputFile); startnum++; // First file only contains header f.Write(input, 0, input.Length); int overflowCaseLast = -1; // Check for overflow in file number if (endnum < startnum) { overflowCaseLast = endnum; endnum = 16383; } for (int i = startnum; i <= endnum; i++) { ifile = string.Format("{0}{1}.lrit", prefix, i); for (int z = 0; z < outputData.Length; z++) { outputData[z] = 0x00; } try { input = File.ReadAllBytes(ifile); File.Delete(ifile); AEC.LritRiceDecompress(ref outputData, input, 8, pixelsPerBlock, pixels, mask); } catch (FileNotFoundException) { UIConsole.Error(String.Format("Decompressor cannot find file {0}", Path.GetFileName(ifile))); } catch (AECException e) { UIConsole.Error($"AEC Decompress problem decompressing file {Path.GetFileName(ifile)}: {e.status.ToString()}"); UIConsole.Debug($"AEC Params: 8 - {pixelsPerBlock} - {pixels} - {mask}"); } catch (IOException e) { UIConsole.Error($"AEC Decompress problem decompressing file {Path.GetFileName(ifile)}: {e}"); } f.Write(outputData, 0, outputData.Length); } if (overflowCaseLast != -1) { for (int i = 0; i < overflowCaseLast; i++) { ifile = string.Format("{0}{1}.lrit", prefix, i); for (int z = 0; z < outputData.Length; z++) { outputData[z] = 0x00; } try { input = File.ReadAllBytes(ifile); File.Delete(ifile); AEC.LritRiceDecompress(ref outputData, input, 8, pixelsPerBlock, pixels, mask); } catch (FileNotFoundException) { UIConsole.Error(String.Format("Decompressor cannot find file {0}", Path.GetFileName(ifile))); } catch (AECException e) { UIConsole.Error($"AEC Decompress problem decompressing file {Path.GetFileName(ifile)}: {e.status.ToString()}"); UIConsole.Debug($"AEC Params: 8 - {pixelsPerBlock} - {pixels} - {mask}"); } catch (IOException e) { Console.WriteLine("Error deleting file {0}: {1}", Path.GetFileName(ifile), e); } f.Write(outputData, 0, outputData.Length); } } } catch (Exception e) { UIConsole.Error(string.Format("There was an error decompressing data: {0}", e)); } try { if (f != null) { f.Close(); } } catch (Exception) { // Do nothing } return(outputFile); }
public void Update() { try { var files = Directory.GetFiles(Folder).Where(f => f.EndsWith(".lrit")).ToList(); foreach (var file in files) { if (alreadyProcessed.Contains(file)) { continue; } try { var header = FileParser.GetHeaderFromFile(file); var anciliary = header.AncillaryHeader != null ? header.AncillaryHeader.Values : null; var satellite = "Unknown"; var region = "Unknown"; var satLon = 0f; var datetime = header.TimestampHeader == null ? DateTime.Now : header.TimestampHeader.DateTime; // Defaults to capture time if (header.TimestampHeader == null) { UIConsole.Warn("Image didn't come with Capture Time. Using Local Time"); } var channel = 99; var segmentId = header.SegmentIdentificationHeader != null ? header.SegmentIdentificationHeader.Sequence : 0; var imageKey = header.SegmentIdentificationHeader != null ? header.SegmentIdentificationHeader.ImageID : -1; if (header.Product.ID == (int)NOAAProductID.HIMAWARI8_ABI) { channel = header.SubProduct.ID; satellite = "HIMAWARI8"; region = "Full Disk"; } var rgx = new Regex(@".*\((.*)\)", RegexOptions.IgnoreCase); var regMatch = rgx.Match(header.ImageNavigationHeader.ProjectionName); satLon = float.Parse(regMatch.Groups[1].Captures[0].Value, CultureInfo.InvariantCulture); if (anciliary != null) { if (anciliary.ContainsKey("Satellite")) { satellite = anciliary["Satellite"]; } if (anciliary.ContainsKey("Region")) { region = anciliary["Region"]; } if (anciliary.ContainsKey("Channel")) { channel = int.Parse(anciliary["Channel"]); } if (anciliary.ContainsKey("Time of frame start")) { var dtstring = anciliary["Time of frame start"]; // 2017/055/05:45:18 // or // 2017-03-27T15:45:38.2Z if (dtstring[4] == '/') { var year = dtstring.Substring(0, 4); var dayOfYear = dtstring.Substring(5, 3); var hours = dtstring.Substring(9, 2); var minutes = dtstring.Substring(12, 2); var seconds = dtstring.Substring(15, 2); //Console.WriteLine("Year: {0}\nDay Of Year: {1}\nHours: {2}\nMinutes: {3}\nSeconds: {4}", year, dayOfYear, hours, minutes, seconds); datetime = new DateTime(int.Parse(year), 1, 1, int.Parse(hours), int.Parse(minutes), int.Parse(seconds)); datetime = datetime.AddDays(int.Parse(dayOfYear) - 1); } else { datetime = DateTime.Parse(dtstring, null, DateTimeStyles.RoundtripKind); } } else { UIConsole.Debug("No Frame Time of Start found! Using capture time."); } } var cropSection = region.ToLower().Contains("full disk") || header.IsFullDisk; int timestamp = 0; if (datetime.Year < 2005 && file.Contains("OR_ABI")) { // Timestamp bug on G16 imageKey = header.SegmentIdentificationHeader != null ? header.SegmentIdentificationHeader.ImageID : (int)Math.Floor((datetime - UnixEpoch).TotalSeconds); timestamp = (int)Math.Floor((datetime - UnixEpoch).TotalSeconds); } else if (datetime.Year < 2005 && file.Contains("IMG_DK")) { // Himawari-8 relay BUG //IMG_DK01VIS_201704161550 string bfile = Path.GetFileName(file); string hdt = bfile.Substring(12, 12); var year = hdt.Substring(0, 4); var month = hdt.Substring(4, 2); var day = hdt.Substring(6, 2); var hour = hdt.Substring(8, 2); var minute = hdt.Substring(10, 2); datetime = new DateTime(int.Parse(year), int.Parse(month), int.Parse(day), int.Parse(hour), int.Parse(minute), 0); imageKey = timestamp = (int)Math.Floor((datetime - UnixEpoch).TotalSeconds); } else { imageKey = timestamp = (int)Math.Floor((datetime - UnixEpoch).TotalSeconds); } if (!groupData.ContainsKey(imageKey)) { groupData[imageKey] = new GroupData(); } var grp = groupData[imageKey]; grp.SatelliteName = satellite; grp.RegionName = region; grp.FrameTime = datetime; if (segmentId == 0) { grp.CropImage = cropSection; grp.SatelliteLongitude = satLon; if ( header.ImageNavigationHeader != null && header.ImageNavigationHeader.ColumnScalingFactor != 0 && header.ImageNavigationHeader.LineScalingFactor != 0 ) { grp.HasNavigationData = true; grp.FallBackColumnScalingFactor = header.ImageNavigationHeader.ColumnScalingFactor; grp.FallBackLineScalingFactor = header.ImageNavigationHeader.LineScalingFactor; grp.FallBackColumnOffset = grp.FallBackColumnOffset == -1 ? header.ImageNavigationHeader.ColumnOffset : grp.FallBackColumnOffset; grp.FallBackLineOffset = grp.FallBackLineOffset == -1 ? header.ImageNavigationHeader.LineOffset : grp.FallBackLineOffset; } } grp.Code = header.SegmentIdentificationHeader != null ? header.SegmentIdentificationHeader.ImageID + "_" + header.SubProduct.Name : header.Product.Name + "_" + header.SubProduct.Name; var od = new OrganizerData(); string z; switch (channel) { case 1: // Visible od = grp.Visible; break; case 2: // Visible for G16 if (satellite == "G16" || satellite == "G17") { od = grp.Visible; } else { string p = $"{timestamp%1000}-{((NOAAProductID)header.Product.ID).ToString()}-{header.SubProduct.Name}"; if (!grp.OtherData.ContainsKey(p)) { grp.OtherData.Add(p, new OrganizerData()); } od = grp.OtherData[p]; } break; case 3: // Water Vapour od = satellite == "HIMAWARI8" ? grp.Infrared : grp.WaterVapour; break; case 4: // Infrared od = grp.Infrared; break; case 7: if (satellite == "HIMAWARI8") { od = grp.WaterVapour; break; } z = $"{timestamp%1000}-{((NOAAProductID)header.Product.ID).ToString()}-{header.SubProduct.Name}"; if (!grp.OtherData.ContainsKey(z)) { grp.OtherData.Add(z, new OrganizerData()); } od = grp.OtherData[z]; break; case 8: if (satellite == "G16") { od = grp.WaterVapour; break; } z = $"{timestamp%1000}-{((NOAAProductID)header.Product.ID).ToString()}-{header.SubProduct.Name}"; if (!grp.OtherData.ContainsKey(z)) { grp.OtherData.Add(z, new OrganizerData()); } od = grp.OtherData[z]; break; case 13: // Infrared for G16 if (satellite == "G16") { od = grp.Infrared; break; } z = $"{timestamp%1000}-{((NOAAProductID)header.Product.ID).ToString()}-{header.SubProduct.Name}"; if (!grp.OtherData.ContainsKey(z)) { grp.OtherData.Add(z, new OrganizerData()); } od = grp.OtherData[z]; break; default: z = $"{timestamp%1000}-{((NOAAProductID)header.Product.ID).ToString()}-{header.SubProduct.Name}"; if (!grp.OtherData.ContainsKey(z)) { grp.OtherData.Add(z, new OrganizerData()); } od = grp.OtherData[z]; break; } od.Code = grp.Code; od.Timestamp = timestamp; od.Segments[segmentId] = file; od.FirstSegment = Math.Min(od.FirstSegment, segmentId); od.FileHeader = header; if (od.Columns == -1) { od.Columns = header.ImageStructureHeader.Columns; od.Lines = header.ImageStructureHeader.Lines; od.PixelAspect = header.ImageNavigationHeader.ColumnScalingFactor / (float)header.ImageNavigationHeader.LineScalingFactor; od.ColumnOffset = header.ImageNavigationHeader.ColumnOffset; od.MaxSegments = header.SegmentIdentificationHeader != null ? header.SegmentIdentificationHeader.MaxSegments : 1; if (segmentId == 0) { od.ColumnScalingFactor = header.ImageNavigationHeader.ColumnScalingFactor; od.LineScalingFactor = header.ImageNavigationHeader.LineScalingFactor; od.ColumnOffset = od.ColumnOffset == -1 ? header.ImageNavigationHeader.ColumnOffset : od.ColumnOffset; od.LineOffset = od.LineOffset == -1 ? header.ImageNavigationHeader.LineOffset : od.LineOffset; } else { od.ColumnScalingFactor = grp.FallBackColumnScalingFactor; od.LineScalingFactor = grp.FallBackLineScalingFactor; od.ColumnOffset = grp.FallBackColumnOffset; od.LineOffset = grp.FallBackLineOffset; } } else { od.Lines += header.ImageStructureHeader.Lines; } alreadyProcessed.Add(file); } catch (Exception e) { UIConsole.Error($"Error reading file {Path.GetFileName(file)}: {e}"); alreadyProcessed.Add(file); } } } catch (Exception e) { UIConsole.Error($"Error checking folders: {e}"); } }
public static void HandleWeatherData(string filename, XRITHeader header) { if (header.Filename.Contains("KWIN")) { // HRIT EMWIN wrongly has product id of weather data if (FileHandler.SkipEMWIN) { try { File.Delete(filename); } catch (Exception) { // Do nothing, file doesn't exists } return; } string fz = null; switch (header.Compression) { case CompressionType.ZIP: fz = DumpFile(filename, header, "zip"); break; case CompressionType.GIF: fz = DumpFile(filename, header, "gif"); break; case CompressionType.JPEG: fz = DumpFile(filename, header, "jpg"); break; case CompressionType.NO_COMPRESSION: fz = DumpFile(filename, header, "txt"); break; default: fz = DumpFile(filename, header, "bin"); break; } if (fz != null) { try { File.Delete(fz); } catch (Exception) { // Do nothing, file doesn't exists } } } else if (header.PrimaryHeader.FileType == FileTypeCode.IMAGE) { string basedir = FileHandler.FinalFileFolder; if (header.Product.ID == (int)NOAAProductID.OTHER_SATELLITES_1 || header.Product.ID == (int)NOAAProductID.OTHER_SATELLITES_2) { basedir = Path.Combine(basedir, OtherSatellitesFolder); } else { basedir = Path.Combine(basedir, WeatherDataFolder); } try { UIConsole.Log($"New {header.ToNameString()}"); //UIConsole.Log($"New Weather Data - {header.SubProduct.Name}"); if (!Directory.Exists(basedir)) { Directory.CreateDirectory(basedir); } ImageHandler.Handler.HandleFile(filename, basedir); File.Delete(filename); } catch (Exception e) { UIConsole.Warn($"Failed to parse Weather Data Image at {Path.GetFileName(filename)}: {e}"); } } else if (header.PrimaryHeader.FileType == FileTypeCode.TEXT) { string fz = DumpFile(filename, header, "txt"); if (fz != null) { try { File.Delete(fz); } catch (Exception) { // Do nothing, file doesn't exists } } } else { FileHandler.DefaultHandler(filename, header); } }
private void statisticsLoop() { try { UIConsole.Log("Statistics Thread Started"); var buffer = new byte[4167]; var ipHostInfo = Dns.GetHostEntry(StatisticsServerName); var ipAddress = new IPAddress(new byte[] { 127, 0, 0, 1 }); foreach (var ip in ipHostInfo.AddressList) { if (ip.AddressFamily == AddressFamily.InterNetworkV6) { continue; } ipAddress = ip; break; } var remoteEP = new IPEndPoint(ipAddress, StatisticsServerPort); Socket sender = null; while (statisticsThreadRunning) { try { UIConsole.Log("Statistics Thread connect"); sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { ReceiveTimeout = 5000 }; sender.Connect(remoteEP); var isConnected = true; UIConsole.Log($"Socket connected to {sender.RemoteEndPoint}"); var nullReceive = 0; while (isConnected) { try { var receivedBytes = sender.Receive(buffer); if (receivedBytes < buffer.Length && receivedBytes != 0) { nullReceive = 0; UIConsole.Error("Received less than Statistics Packet size!"); Thread.Sleep(200); } else if (receivedBytes == 0) { nullReceive++; if (nullReceive == 5) { UIConsole.Error("Cannot reach server. Dropping connection!"); isConnected = false; sender.Shutdown(SocketShutdown.Both); sender.Disconnect(false); sender.Close(); } } else { nullReceive = 0; var sst = Statistics_st.fromByteArray(buffer); this.postStatistics(sst); } } catch (ArgumentNullException ane) { UIConsole.Error($"ArgumentNullException : {ane}"); isConnected = false; } catch (SocketException se) { // That's usually timeout. I would say that is best to handle and show some message // But for now, that would make it confusing for the users. So let's keep without a notice. //UIConsole.GlobalConsole.Error(String.Format("SocketException : {0}", se.ToString())); isConnected = false; } catch (Exception e) { UIConsole.Error($"Unexpected exception : {e}"); isConnected = false; } StatisticsConnected = isConnected; if (!statisticsThreadRunning) { break; } Thread.Sleep(1); } sender.Shutdown(SocketShutdown.Both); sender.Disconnect(false); sender.Close(); } catch (ArgumentNullException ane) { UIConsole.Error($"ArgumentNullException : {ane}"); } catch (SocketException se) { UIConsole.Error($"SocketException : {se}"); } catch (Exception e) { UIConsole.Error($"Unexpected exception : {e}"); } if (!statisticsThreadRunning) { continue; } UIConsole.Warn("Socket closed. Waiting 1s before trying again."); Thread.Sleep(1000); } Console.WriteLine("Requested to close Statistics Thread!"); try { if (sender != null) { sender.Shutdown(SocketShutdown.Both); sender.Disconnect(false); sender.Close(); } } catch (Exception e) { UIConsole.Debug($"Exception thrown when closing socket: {e} Ignoring."); } UIConsole.Log("Statistics Thread closed"); } catch (Exception e) { CrashReport.Report(e); } }
public void Process(byte[] inData) { buffer = buffer.Concat(inData).ToArray(); var pos = FindSyncMarker(buffer); if (pos == -1) { if (buffer.Length > MAX_FRAME_SIZE * 3) { UIConsole.Warn($"EMWIN Buffer grown beyond {MAX_FRAME_SIZE * 3}! This should happen. Clearing buffer."); buffer = new byte[0]; } return; } var data = buffer.Skip(pos + 6).Take(MAX_FRAME_SIZE - 6).ToArray(); // 12 for the syncMark if (data.Length != MAX_FRAME_SIZE - 6) { // Not Enough Data return; } buffer = buffer.Skip(pos + MAX_FRAME_SIZE).ToArray(); if (data.Length > 0) { var headerData = Encoding.GetEncoding("ISO-8859-1").GetString(data.Take(80).ToArray()); data = data.Skip(80).ToArray(); try { var header = new EMWINHeader(headerData); if (header.Filename.Equals(FILLFILENAME)) { return; } //UIConsole.GlobalConsole.Log(string.Format("Received {0}/{1} of {2}", header.PartNumber, header.PartTotal, header.Filename)); if (header.PartNumber == 1) { if (files.ContainsKey(header.Filename)) { UIConsole.Warn($"Files already has a key for file {header.Filename}"); } else { string newfilename = DateTime.Now.ToString("yyyyMMddHHmmssffff") + header.Filename; files.Add(header.Filename, new EmwinFile()); files[header.Filename].Parts = header.PartTotal; files[header.Filename].Received = 0; files[header.Filename].Output = Path.Combine("channels", Path.Combine("tmp", newfilename)); } } if (!files.ContainsKey(header.Filename)) { //UIConsole.GlobalConsole.Warn(string.Format("(EMWIN) Received incomplete part for {0}", header.Filename)); return; } else if (files[header.Filename].Received + 1 != header.PartNumber) { //UIConsole.GlobalConsole.Error(string.Format("(EMWIN) Missed {0} frames for file {1}", header.PartNumber - files[header.Filename].Received - 1, header.Filename)); files.Remove(header.Filename); return; } else { string dir = Path.GetDirectoryName(files[header.Filename].Output); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } var f = File.Open(files[header.Filename].Output, header.PartNumber == 1 ? FileMode.Create : FileMode.Append); f.Write(data, 0, data.Length); f.Close(); files[header.Filename].Received += 1; } if (header.PartNumber == header.PartTotal && files.ContainsKey(header.Filename)) { string output = files[header.Filename].Output; string basedir = new DirectoryInfo(Path.GetDirectoryName(output)).Parent.FullName; string newdir = Path.Combine(basedir, "EMWIN"); if (!Directory.Exists(newdir)) { Directory.CreateDirectory(newdir); } string fname = Path.Combine(newdir, header.Filename); if (File.Exists(fname)) { fname = DateTime.Now.ToString("yyyyMMddHHmmssffff") + "-" + header.Filename; fname = Path.Combine(newdir, fname); } File.Move(files[header.Filename].Output, fname); UIConsole.Log(string.Format("New EMWIN ({0})", header.Filename)); files.Remove(header.Filename); if (fname.Contains(".ZIS")) { PacketManager.ExtractZipFile(fname); } } } catch (Exception e) { UIConsole.Error($"(EMWIN) Error: {e.Message}"); } } }