photopea / UTIF.js

Fast and advanced TIFF decoder
MIT License
426 stars 87 forks source link

JPEG 7 compression - wrong colors #42

Open photopea opened 6 years ago

photopea commented 6 years ago

Following TIFFs with Type7 compression have incorrect colors. The PhotometricInterpretation is 2 (RGB), however, colors seem to be more like Lab*.

tiff.zip

photopea commented 6 years ago

@syvaidya could you take a look at it? Maybe the info about colors is inside the JPEG block.

syvaidya commented 6 years ago

I'll try to check tomorrow. Been really busy past few days.

On Sat 25 Aug, 2018, 2:07 PM Photopea, notifications@github.com wrote:

@syvaidya https://github.com/syvaidya could you take a look at it? Maybe the info about colors is inside the JPEG block.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/photopea/UTIF.js/issues/42#issuecomment-415953627, or mute the thread https://github.com/notifications/unsubscribe-auth/AC4oDhL-GkYM3Dk9GHWoOcVNQFWTEHYrks5uUQzTgaJpZM4WMTaA .

syvaidya commented 5 years ago

@photopea sorry for being so late, but finally i am on vacation and got time to check this. The problem seems to be with JpegDecoder. If I don't decode the buff and directly save it as jpg file, then that image is shown with correct colors in any image viewer. It looks like that JpegDecoder is messing up the colors.

EDIT: Checking further if we are messing up colors later after decode - may be related to tag 262 value.

EDIT 2: I've narrowed down the issue to be with JpegDecoder. I extracted the JPEG strip from the sample using UTIF, and saved it as JPEG file. It shows correctly in image viewers (like GIMP, default windows previewer, etc). But if I display it using jpg.js in an HTML then the colors are off. Most probably the issue is because the Chroma Subsampling for this image is 4:4:4 (1 1). Most other images where it was working fine, the subsampling was 4:2:0 (2 2). It would be better to get this raised with jpg.js maintainer.

EDIT 3: Some more details: It looks like if subsampling is 4:4:4 it generally means that data in JPEG is RGB and not YCbCr, and should not be converted. So if I change following line in jpg.js, then image is displayed correctly: From: var x= this._convertYccToRgb(data) To: var x= data;

mhelal0 commented 5 years ago

Hi, I have the same issue in the following file sample.zip, so how can i fix this issue?

skibulk commented 4 years ago

I am also having this issue. Using the file here.

photopea commented 4 years ago

@syvaidya Our JPG decoder comes from the PDF.js library. Actually, when such JPG is located inside a PDF file, Chrome PDF viewer renders it correctly, but Adobe Reader and PDF.js render it incorrectly. So I am afraid they will not fix it, as that is how Adobe software handles such JPG.

Also, if you open that raw JPG (below) in Photoshop, it is also displayed incorrectly. tuxHead

skibulk commented 4 years ago

I see you posted an issue in the pdf.js repo. Thank you. For reference and tracking purposes, that issue is located here.

syvaidya commented 4 years ago

@photopea @skibulk Looks like the issue got fixed in pdf.js. Not sure though which release it will be part of. Once it is released, we can update the library in UTIF.js too.

photopea commented 4 years ago

@syvaidya @skibulk I updated UTIF.js with the latest JPG decoder from PDF.js . It fixed the parsing of the two TIFFs from the beginning of this issue.

However, it still handles multipage_tiff_example.tif incorrectly (not as RGB) - white turns into pink. I extracted the JPG image from it (below) and JPG viewers also display it as pink.

I think in this case, the information, that the JPG contains RGB, is not stored in a JPG file itself, but in TIFF parameters . @syvaidya could you take a look at it? Are we constructing the JPG correctly? (copying JPG tables - t347).

strip

syvaidya commented 4 years ago

@photopea I have done some analysis. Problem is that actual JPEG data in the file (inside SOS 0xffda marker) the components are not marked as RGB, but photometric interpolation in TIFF is RGB. I checked TwelveMonkeys java library to see how it handles this, and in there it will not do YCC to RGB conversion if photometric interpolation is 2 (RGB). But in our case, we don't have any way to tell jpg.js library that even though SOS marker is saying that is not RGB, actually it is RGB, and should not be doing color conversion. I think I'll have to somehow manipulate SOS data if photometric interpolation is 2. Give me some time.

photopea commented 4 years ago

@syvaidya I can rewrite the JPEG decoder, to make it not convert YCC to RGB. But how do we decide when it is needed?

From what I see, the PhotometricInterpretation is always 2 for JPG inside TIFF, even for YCC data.

syvaidya commented 4 years ago

@photopea I was also thinking of patching JpegDecoder, but you are right. I am also not sure how we'll determine whether YCC to RGB conversion is required or not. Can you give me various TIFF samples that you have, so that I can check what other libraries are doing for each and maybe it will give some idea.

syvaidya commented 4 years ago

@photopea by the way, will you be okay if I convert the source code to a proper npm project, and then keep jpg.js and pako modules external to actual code? We can keep the built UTIF.js checked-in to github, but every time source changes, we'll have to do npm build.

photopea commented 4 years ago

@syvaidya I don't have any JPG7-TIFFs other than these three. Maybe you can find more online.

I am not a user of NPM. I really doubt the latest JPG decoder is available on npm (I copy-pasted it and manually edited some parts for better minification). The current UTIF.js does not have a JPG dependency. I can also replace the pako.js dependency with my own inflator 4 kB, 2x faster than pako.js . My current LZW decoder is 774 Bytes, which shows, how much simpler LZW is than Deflate :)

syvaidya commented 4 years ago

@photopea I understand. At least can we have all the third party code unminified within UTIF.js? It is difficult to fix something in JpegDecoder when it is minified. Maybe you can give UTIF.js which contains no minified code, and then another UTIF.min.js which has full code minified (for production use).

jebastincharles commented 4 years ago

@syvaidya Can you show some light whether the above issue is fixed?.

syvaidya commented 4 years ago

No it is not. @photopea I frankly need non-minified code to be able to debug this within jpg.js. Did you think about my suggestion in last comment?

photopea commented 4 years ago

@syvaidya The current unminified JPEG decoder is here: https://pastebin.com/xd3kMuBB . But I don't think we need to modify it or even know how it works.

Note, that we fixed the original problem of this issue (making UTIF.js work with the two TIFF files at the beginning). So now, we are trying to make it work only with this file: http://www.nightprogrammer.org/wp-uploads/2013/02/multipage_tiff_example.tif .

I am completely fine with closing this issue and leaving it as it is. Since the TIFF specification has never been "complete" at any point, I think we should not care about these cases.

benwiley4000 commented 3 years ago

I'm running into this issue with a dataset of compression-7-encoded tiff images... I assume there's no news?

photopea commented 3 years ago

@benwiley4000 do your TIFF images work well in other programs?

benwiley4000 commented 3 years ago

@photopea they work well in macOS Preview, which supports JPEG and LZW compression, and they were created by a data scientist who used a python image library to encode the images. Unfortunately I can't share the image set. When I converted the images to LZW they displayed great with UTIF.

LZW:

Screen Shot 2020-11-04 at 6 39 49 PM Screen Shot 2020-11-04 at 6 39 44 PM

JPEG-in-TIFF:

Screen Shot 2020-11-04 at 6 39 37 PM Screen Shot 2020-11-04 at 6 39 32 PM

Is it possible to consider an alternative JPEG-decoding library, such as jpeg-js? (I know nothing about the jpeg-in-tiff spec so I don't know if this makes sense or not).

photopea commented 3 years ago

I think the error is the same as in our previous images.

BTW. if you can choose to what format save, why don't you save directly into JPG? The JPG inside TIFF just makes the output files bigger.

You can have multiple images in one TIFF file, but having multiple JPG files in a folder is pretty much the same.

benwiley4000 commented 3 years ago

@photopea good question, I asked the same question to the guy building the dataset. He said he's using the TIFF basically as a container format for storing files and metadata. Ultimately I'm not the one building the dataset so I'm trying to support what users are throwing my way. 😄

But I definitely mentioned that LZW-compression has better support.

aashay8 commented 3 years ago

+1