-3

I am currently using C# to retrieve frames from a borescope (via the FFMPEG library). However, I came across a problem weeks ago and I can't solve it.

The images are returned in JPEG format (since the borescope stream is MJPEG).

Some images come without quality problems, but others come with a strange line in the middle followed by random staining. (At the end of the question there is an example of a normal image and one with problems).

Analyzing the structure of the files, I realized that there are some differences, but I don't really understand JPEG's binary structure very well, and I can't tell what is corrupted.

Getting to know what is corrupted in the image, which culminates in the quality problem, is very important to me because, through this, I can discard the frame using C#. However, without understanding this problem, I can't even discard the frame, much less fix it.

So, having the image without quality problems as a reference, what is the problem with the binary structure of the image with quality problems?

Examples:

JPEG 1: Image without quality problems

Image's preview (just to see the quality, do not download from here)

JPEG 2: Image with quality problems

Image's preview (just to see the quality, do not download from here)

It's possible to look into binary structure of images through online HEX editors like: Online hex editor, Hexed or Hex-works.

Thank you for reading and have a nice day.

atokzz
  • 63
  • 3

1 Answers1

1

There are at least 2 issues with the file.


The first I can detect with ImageMagick by running this command:

magick identify -verbose image.jpg

and it tells me that the data segment ends prematurely.

Image: outExemplo0169.jpeg
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Mime type: image/jpeg
  Class: DirectClass
  Geometry: 640x480+0+0
  Units: Undefined
  Colorspace: sRGB
  Type: TrueColor
  Base type: Undefined
  Endianess: Undefined
  Depth: 8-bit
  Channel depth:
    Red: 8-bit
    Green: 8-bit
    Blue: 8-bit
  Channel statistics:
    Pixels: 307200
    Red:
      min: 0  (0)
      max: 255 (1)
      mean: 107.234 (0.420527)
      standard deviation: 66.7721 (0.261851)
      kurtosis: -0.67934
      skewness: 0.577494
      entropy: 0.92876
    Green:
      min: 0  (0)
:2020-02-26T18:59:19+00:00 0:00.057 0.070u 7.0.9 Resource identify[80956]: resource.c/RelinquishMagickResource/1067/Resource
  Memory: 3686400B/0B/32GiB
identify: Corrupt JPEG data: premature end of data segment `outExemplo0169.jpeg' @ warning/jpeg.c/JPEGWarningHandler/399.

The second I can see with exiftool when I run this command:

exiftool -v -v -v outExemplo0169.jpeg 

  ExifToolVersion = 11.11
  FileName = outExemplo0169.jpeg
  Directory = .
  FileSize = 66214
  FileModifyDate = 1582743337
  FileAccessDate = 1582743559
  FileInodeChangeDate = 1582743337
  FilePermissions = 33188
  FileType = JPEG
  FileTypeExtension = JPG
  MIMEType = image/jpeg
JPEG APP0 (14 bytes):
    0006: 4a 46 49 46 00 01 01 00 00 01 00 01 00 00       [JFIF..........]
  + [BinaryData directory, 9 bytes]
  | JFIFVersion = 1 1
  | - Tag 0x0000 (2 bytes, int8u[2]):
  |     000b: 01 01                                           [..]
  | ResolutionUnit = 0
  | - Tag 0x0002 (1 bytes, int8u[1]):
  |     000d: 00                                              [.]
  | XResolution = 1
  | - Tag 0x0003 (2 bytes, int16u[1]):
  |     000e: 00 01                                           [..]
  | YResolution = 1
  | - Tag 0x0005 (2 bytes, int16u[1]):
  |     0010: 00 01                                           [..]
  | ThumbnailWidth = 0
  | - Tag 0x0007 (1 bytes, int8u[1]):
  |     0012: 00                                              [.]
  | ThumbnailHeight = 0
  | - Tag 0x0008 (1 bytes, int8u[1]):
  |     0013: 00                                              [.]
JPEG SOF0 (15 bytes):
    0018: 08 01 e0 02 80 03 01 21 00 02 11 01 03 11 01    [.......!.......]
  ImageWidth = 640
  ImageHeight = 480
  EncodingProcess = 0
  BitsPerSample = 8
  ColorComponents = 3
JPEG DQT (130 bytes):
    002b: 00 03 03 03 03 03 03 04 03 03 03 04 04 04 05 06 [................]
    003b: 09 06 06 05 05 06 0c 08 09 07 09 0e 0c 0e 0e 0d [................]
    004b: 0c 0d 0d 0f 11 15 12 0f 10 14 10 0d 0d 13 19 13 [................]
    005b: 14 16 17 18 18 18 0f 12 1a 1c 1a 17 1c 15 17 18 [................]
    006b: 17 01 04 04 04 06 05 06 0b 06 06 0b 17 0f 0d 0f [................]
    007b: 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 [................]
    008b: 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 [................]
    [snip 18 bytes]
JPEG DHT (416 bytes):
    00b1: 00 00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 [................]
    00c1: 00 00 01 02 03 04 05 06 07 08 09 0a 0b 10 00 02 [................]
    00d1: 01 03 03 02 04 03 05 05 04 04 00 00 01 7d 01 02 [.............}..]
    00e1: 03 00 04 11 05 12 21 31 41 06 13 51 61 07 22 71 [......!1A..Qa."q]
    00f1: 14 32 81 91 a1 08 23 42 b1 c1 15 52 d1 f0 24 33 [.2....#B...R..$3]
    0101: 62 72 82 09 0a 16 17 18 19 1a 25 26 27 28 29 2a [br........%&'()*]
    0111: 34 35 36 37 38 39 3a 43 44 45 46 47 48 49 4a 53 [456789:CDEFGHIJS]
    [snip 304 bytes]
JPEG SOS
JPEG EOI
Unknown trailer (50 bytes at offset 0x10274):
   10274: 42 6f 75 6e 64 61 72 79 45 42 6f 75 6e 64 61 72 [BoundaryEBoundar]
   10284: 79 53 00 00 01 00 90 08 01 00 fb 4b db 6a 2a 22 [yS.........K.j*"]
   10294: 00 00 2a 22 00 00 01 00 01 00 80 02 00 00 e0 01 [..*"............]
   102a4: 00 00        

So there are 50 extraneous bytes at the end including the text string "BoundaryEBoundaryS" which may be recognisable to you as coming from somewhere else in your processing chain?

One test you could do for JPEG quality is check the last 2 bytes are a valid EOI which means it should end in FF D9 - see here.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • So, as this C# app I mentioned get frames from boroscope, I have a lot of frames, some with problems, some with not. To verify what you analyzed, I made another code that only accepts images whose final bytes are 0xFF and 0xD9 (or D8). However, what happens is that both the good images and the bad images are coming without the correct EOI (in reality they come, but only before this 50bytes of garbage). So, the quality problems is not coming from this EOI problem, I think. – atokzz Feb 26 '20 at 20:16