Imagesharp: Jpeg image decoded as grayscale

Created on 14 Feb 2018  路  8Comments  路  Source: SixLabors/ImageSharp

Prerequisites

  • [x] I have written a descriptive issue title
  • [x] I have verified that I am running the latest version of ImageSharp
  • [x] I have verified if the problem exist in both DEBUG and RELEASE mode
  • [x] I have searched open and closed issues to ensure it has not already been reported

Description

There is an CMYK jpg image that decodes successfully with ImageSharp, but after encoding it back as jpg (or png) it becomes grayscale.

When converting this image to RGB with ImageMagick, colors are little bit changed but it remains colorful.

Steps to Reproduce

Here is the repro project with the sample image included GrayscaleRepro.zip.

System Configuration

  • ImageSharp version: 1.0.0-beta0002
  • Environment (Operating system, version and so on):
System Version: macOS 10.12.6 (16G1212)
Kernel Version: Darwin 16.7.0
  • .NET Framework version:
.NET Command Line Tools (2.1.4)

Product Information:
 Version:            2.1.4
 Commit SHA-1 hash:  5e8add2190

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  10.12
 OS Platform: Darwin
 RID:         osx.10.12-x64
 Base Path:   /usr/local/share/dotnet/sdk/2.1.4/

Microsoft .NET Core Shared Framework Host

  Version  : 2.0.5
  Build    : 17373eb129b3b05aa18ece963f8795d65ef8ea54
bug jpeg

All 8 comments

Thanks @denisivan0v for all the info and the sample program. We really, really, appreciate it when people like you make the extra effort. 馃憤

@antonfirsov This is an odd one.

JpegSnoop is reporting a YCCK color profile same as our YCCK sample in the repo so I don't know off the top of my head what the cause would be.

*** Marker: APP14 (xFFEE) ***
  OFFSET: 0x00000014
  Length            = 14
  DCTEncodeVersion  = 25600
  APP14Flags0       = 0
  APP14Flags1       = 0
  ColorTransform    = 2 [YCCK]

Could you have a look when you can?I'm not gonna have a chance for at least a week and a half.

Maybe I can check this in the next few days. Will definitely do it for beta3.

I've just checked this using the PDFJS port and it decodes correctly. I should be able to use it as a reference for the Golang one.

Ok.... The conversion algorithm itself looks correct, the input data less so.

For [0,0] the k value should be 255 but we're getting 128. The Golang port is simply too complicated for me to understand without a lot of picking apart and testing so I don't know why that is the case. Maybe we are pulling the wrong component list somehow. cb and cr are both 128.

I still find the readability of that decoder an issue. I only wish we'd managed to make the other one a bit faster, I've forgotten most of the code I wrote for it but I could understand the pipeline more.

jpeg is hard 鈽癸笍

@JimBobSquarePants I will also try to check it as soon as I'm finished with the MemoryManager stuff.

Can you point me to the code parts you investigated? ("k value")

@antonfirsov Yeah of course.

The PDFJs method that I used to determine the correct k value is here.

https://github.com/SixLabors/ImageSharp/blob/98a777322f548a2a193bcf7bf31f6ca4d348cd67/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsYCbCrToRgbTables.cs#L102

For the Golang port we are looking here.

https://github.com/SixLabors/ImageSharp/blob/98a777322f548a2a193bcf7bf31f6ca4d348cd67/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYccK.cs#L18

Using the sample image we should get input YCbCrk values for each component at [0,0] of 0, 128, 128, 255 which when converted to RGBA gives us white. The Golang values are 0, 128, 128, 128.

@JimBobSquarePants as far as I understand, the conversion methods are correct in both decoders, they are just consuming the wrong k in the "golang" case. I guess the "golang" spectral data is wrong for the input provided in this issue (the "pdfjs" one is inaccurate for others).

We have these tests to verify the spectral coefficients produced in the stream parsing phase directly against libjpeg-turbo launched as a separate process (windows only execution).

Currently the pdfjs spectral test cases are skipped (many failing!) but you can enable them to play around. For the input in this issue I expect the opposite: ~pdfjs fails & golang succeeds~. I mean: golang fails pdfjs succeeds - seems like bed time for me! :)

Any further investingation, or even a branch with new failing spectral tests is a progress IMO 馃槃

@JimBobSquarePants as far as I understand, the conversion methods are correct in both decoders, they are just consuming the wrong k in the "golang" case. I guess the "golang" spectral data is wrong for the input provided in this issue (the "pdfjs" one is inaccurate for others).

@antonfirsov Yeah that's right, the maths is correct, just the input is funky. I'll see what I can do.

Was this page helpful?
0 / 5 - 0 ratings