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);
        }
Beispiel #2
0
        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;
        }