public async Task HandleSelectedImage(ImageItem i) { SourceImage = i; JPEGByteFile file = new JPEGByteFile(); try { file = await JPEGAnalyzerService.GetFileSegmentsAsync(i.File); } catch (IOException e) { Console.WriteLine($"Excepion thrown while reading file segments: {e}"); } await UpdateDisplayedMetadataSegments(file); }
public static async Task <JPEGByteFile> GetFileSegmentsAsync(StorageFile file) { List <Segment> segments = new List <Segment>(); byte[] fileBytes = new byte[] { }; bool fileReadSucceeded = true; try { IBuffer buffer = await FileIO.ReadBufferAsync(file); fileBytes = buffer.ToArray(); } catch (Exception e) { Console.WriteLine($"Excepion while reading file bytes: {e}"); fileReadSucceeded = false; } if (!fileReadSucceeded) { throw new IOException(); } JPEGByteFile ret = new JPEGByteFile() { File = file, FileBytes = fileBytes }; if (fileBytes[0] != 0xFF || fileBytes[1] != 0xD8) { throw new FileFormatException(); } Int32 cntr = 2; Int32 effectiveLength = (Int32)fileBytes.Length; while (cntr < effectiveLength) { if (fileBytes[cntr++] != 0xFF) { throw new FileFormatException(); } if (fileBytes[cntr] == 0xD9) // End of image { break; } Segment segment = new Segment() { SegmentStartByteIndexInFile = cntr - 1 }; Int32 segmentDataLength = 0; try { segment.Name = JPEGResources.SegmentNameDictionary[fileBytes[cntr]]; } catch (Exception e) { Console.WriteLine($"Exception thrown during Segment name dictionary lookup: {e}"); throw new FileFormatException(); } if (JPEGResources.RemovableSegments.Contains(fileBytes[cntr])) { segment.Removable = true; } if (fileBytes[cntr] == 0xDA) // case there's only SOS segment left (it doesn't include segment length, so it needs special treatment) { int compressedImageSegmentLength = 0; while (!(fileBytes[cntr] == 0xFF && fileBytes[cntr + 1] == 0xD9)) { cntr++; compressedImageSegmentLength++; } segment.Length = compressedImageSegmentLength - 1; segment.ExcessBytesAfterSegment = effectiveLength - cntr - 2; // two bytes for the 0xFFD9 EOI marker segment.SegmentIndexInFile = segments.Count; segment.SegmentEndByteIndexInFile = cntr + 2; segments.Add(segment); break; } cntr++; try { byte[] lengthBytes = (byte[])fileBytes.Skip(cntr).Take(2).ToArray(); if (BitConverter.IsLittleEndian) { Array.Reverse(lengthBytes); } segmentDataLength = (Int32)BitConverter.ToUInt16(lengthBytes, 0); } catch (Exception e) { Console.WriteLine($"Exception thrown during Segment length exctraction: {e}"); throw new FileFormatException(); } segment.Length = segmentDataLength; cntr += 2; try { byte[] rawBytes = fileBytes.Skip(cntr - 4).Take(segmentDataLength + 2).ToArray(); byte[] midBytes = new byte[rawBytes.Length]; int startPivot = 0, endPivot = 0, midBytesPivot = 0, minReadableTextLength = 8; byte minAscii = 0x20, maxAscii = 0x7f; while (endPivot < rawBytes.Length) { byte currentEndPivotByte = rawBytes[endPivot], currentStartPivotByte = rawBytes[startPivot]; if (currentEndPivotByte >= minAscii && currentEndPivotByte < maxAscii) { endPivot++; continue; } if (endPivot - startPivot > minReadableTextLength) { while (startPivot < endPivot) { midBytes[midBytesPivot++] = rawBytes[startPivot++]; } } else { startPivot = endPivot; } if (midBytesPivot > 0 && midBytes[midBytesPivot - 1] != (byte)'\n') { midBytes[midBytesPivot++] = (byte)'\n'; } startPivot = ++endPivot; } byte[] resultBytes = new byte[midBytesPivot]; midBytes.Take(midBytesPivot).ToArray().CopyTo(resultBytes, 0); segment.Content = resultBytes; } catch (Exception e) { Console.WriteLine($"Exception thrown during Segment data exctraction: {e}"); throw new FileFormatException(); } cntr += segmentDataLength - 2; // without the two length bytes which were already added to cntr segment.SegmentEndByteIndexInFile = cntr; int excessCntr = 0; while (cntr + excessCntr + 1 < effectiveLength && !(fileBytes[cntr + excessCntr] == 0xFF && JPEGResources.SegmentNameDictionary.ContainsKey(fileBytes[cntr + excessCntr + 1]))) { excessCntr++; } cntr += excessCntr; segment.ExcessBytesAfterSegment = excessCntr; segment.SegmentIndexInFile = segments.Count; segments.Add(segment); } ret.Segments = segments; return(ret); }
public async Task UpdateDisplayedMetadataSegments(JPEGByteFile file) { loadingTextBlock.Visibility = Visibility.Visible; SourceByteFile = file; ClearBlockChildren(); int segmentCntr = 0; foreach (Segment s in SourceByteFile.Segments) { TextBlock title = new TextBlock { Text = s.Name, Style = (Style)Application.Current.Resources["DetailSubTitleStyle"], Margin = (Thickness)Application.Current.Resources["SmallTopMargin"] }; block.Children.Add(title); TextBlock content = new TextBlock { Text = "Length: " + s.Length.ToString() + " B, Excess bytes after segment: " + s.ExcessBytesAfterSegment.ToString() + " B", Style = (Style)Application.Current.Resources["DetailBodyBaseMediumStyle"] }; block.Children.Add(content); StackPanel buttons = new StackPanel { Orientation = Orientation.Horizontal, Spacing = 20 }; if (s.ExcessBytesAfterSegment > 0) { Button removeExcessBytesAfterSegmentButton = new Button() { Content = "Remove excess bytes", Tag = "BTN-" + segmentCntr }; removeExcessBytesAfterSegmentButton.Click += RemoveExcessBytesAfterSegmentButton_Click; buttons.Children.Add(removeExcessBytesAfterSegmentButton); } if (s.Removable) { Button removeSegmentButton = new Button() { Content = "Remove segment", Tag = "BTN-" + segmentCntr }; removeSegmentButton.Click += RemoveSegmentButton_Click; buttons.Children.Add(removeSegmentButton); } if (buttons.Children.Count > 0) { block.Children.Add(buttons); } if (s.Removable) { TextBlock t0 = new TextBlock() { Text = "Content:", Padding = new Thickness(0, 5, 0, 3) }; block.Children.Add(t0); TextBlock t = new TextBlock() { Text = Encoding.ASCII.GetString(s.Content), TextWrapping = TextWrapping.Wrap }; block.Children.Add(t); } segmentCntr++; } FFTService ImgFFT = new FFTService(file.File); await ImgFFT.ReadImage(); ImgFFT.ForwardFFT();// Finding 2D FFT of Image ImgFFT.FFTShift(); await ImgFFT.FFTPlotAsync(ImgFFT.FFTShifted); TextBlock magnitudeTitle = new TextBlock { Text = "Fourier transform magnitude", Style = (Style)Application.Current.Resources["DetailSubTitleStyle"], Margin = (Thickness)Application.Current.Resources["SmallTopMargin"] }; block.Children.Add(magnitudeTitle); block.Children.Add(new Image() { Source = ImgFFT.FourierPlot }); TextBlock phaseTitle = new TextBlock { Text = "Fourier transform phase", Style = (Style)Application.Current.Resources["DetailSubTitleStyle"], Margin = (Thickness)Application.Current.Resources["SmallTopMargin"] }; block.Children.Add(phaseTitle); block.Children.Add(new Image() { Source = ImgFFT.PhasePlot }); loadingTextBlock.Visibility = Visibility.Collapsed; }