Opened 12 years ago

Closed 22 months ago

Last modified 22 months ago

#1851 closed defect (invalid)

libswscale does incorrect range conversion for RGB->YUV and RGB->RGB

Reported by: gjdfgh Owned by:
Priority: normal Component: swscale
Version: git-master Keywords:
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

libswscale seems to do completely confused range conversions for RGB->YUV. RGB->RGB randomly ignores the source range (at least in the unscaled case), and always ignores the destination range. YUV->RGB ignores destination range as well. The only cases that appear to be working as expected are conversions with YUV->YUV.

Here's the output of a test program, that scales a solid image filled with gray=200, using various colorspace and range parameters. "200" is the input value, and the number after that the retrieved luma value or that of a RGB component. "no-scale" means it has been scaled with same source and destination width/height. The test program is attached as swscale.c to this ticket.

no-scale rgb-lim rgb-lim  200 -> 200
no-scale rgb-lim rgb-ful  200 -> 200
no-scale rgb-lim yuv-lim  200 -> 188
no-scale rgb-lim yuv-ful  200 -> 200
no-scale rgb-ful rgb-lim  200 -> 200
no-scale rgb-ful rgb-ful  200 -> 200
no-scale rgb-ful yuv-lim  200 -> 177
no-scale rgb-ful yuv-ful  200 -> 188
no-scale yuv-lim rgb-lim  200 -> 214
no-scale yuv-lim rgb-ful  200 -> 214
no-scale yuv-lim yuv-lim  200 -> 200
no-scale yuv-lim yuv-ful  200 -> 214
no-scale yuv-ful rgb-lim  200 -> 200
no-scale yuv-ful rgb-ful  200 -> 200
no-scale yuv-ful yuv-lim  200 -> 188
no-scale yuv-ful yuv-ful  200 -> 200

scale    rgb-lim rgb-lim  200 -> 200
scale    rgb-lim rgb-ful  200 -> 200
scale    rgb-lim yuv-lim  200 -> 188
scale    rgb-lim yuv-ful  200 -> 200
scale    rgb-ful rgb-lim  200 -> 188
scale    rgb-ful rgb-ful  200 -> 188
scale    rgb-ful yuv-lim  200 -> 177
scale    rgb-ful yuv-ful  200 -> 188
scale    yuv-lim rgb-lim  200 -> 214
scale    yuv-lim rgb-ful  200 -> 214
scale    yuv-lim yuv-lim  200 -> 200
scale    yuv-lim yuv-ful  200 -> 214
scale    yuv-ful rgb-lim  200 -> 200
scale    yuv-ful rgb-ful  200 -> 200
scale    yuv-ful yuv-lim  200 -> 188
scale    yuv-ful yuv-ful  200 -> 200

YUV->RGB ignores destination ranges, and always assumes full destination range.

RGB->YUV looks completely messed up. Maybe someone flipped a bit somewhere?

Scaled RGB->RGB ignores the destination range, and always seems to assume limitted range (so that rgb-lim->* does no conversion). Unscaled RGB->RGB ignores ranges completely, at least when the same pixel format is used.

If there's some logic behind this, I don't get it, and it's not documented.

If libswscale simply doesn't support limitted RGB range (which would lower its usefulness), at least the RGB->RGB case must be fixed.

Attachments (1)

swscale.c (3.1 KB ) - added by gjdfgh 12 years ago.
Test program

Download all attachments as: .zip

Change History (12)

by gjdfgh, 12 years ago

Attachment: swscale.c added

Test program

comment:1 by Michael Niedermayer, 12 years ago

Resolution: invalid
Status: newclosed

There exists just one 8bit RGB range and that is 0..255, the difference in ranges is specific to YUV. I think thats the only source of errors in the table so iam closing this, but if theres another problem that i missed, please reopen.
Also ive changed sws so it ignores the range for RGB instead of doing something quite random if such combination is used

comment:2 by gjdfgh, 12 years ago

Limited RGB does seem to exist: for RGB output to TVs and projectors.

Having no limited RGB support is probably better to breaking completely unrelated conversions, though.

comment:3 by Balling, 3 years ago

Can we reopen this for limited RGB support in the future?

comment:4 by Balling, 3 years ago

Resolution: invalid
Status: closedreopened

Support for limited range rgb is needed. I do not care what you say. If input limited range rgb is working, then why output does not?

Last edited 3 years ago by Balling (previous) (diff)

comment:5 by Balling, 3 years ago

We need to start by either removing the deprecation of yuvj formats or by removing them alltogether (there is patchset from Paul). I vote for the first one. It is a joke that even opening JPEG (since jpeg does not support new method with setting range not by pixel_format, also see a funny bug in mpv, https://github.com/mpv-player/mpv/issues/9053#issuecomment-1046052804) causes a warning for every tile or whatever! It is nuts! Warnings obviously make it slower out of nothing.

Version 3, edited 3 years ago by Balling (previous) (next) (diff)

comment:7 by Carl Eugen Hoyos, 2 years ago

Priority: importantnormal
Resolution: invalid
Status: reopenedclosed

Please do not reopen ancient tickets.

comment:8 by Balling, 22 months ago

Resolution: invalid
Status: closedreopened

Please do not reopen ancient tickets.

https://w3c.github.io/PNG-spec/#cICP-chunk

PNG cICP now requires limited range RGB. HAHAHA, wasted.

comment:9 by Elon Musk, 22 months ago

Resolution: invalid
Status: reopenedclosed

It supports both, 0 is limited, 1 is full.

comment:10 by Balling, 22 months ago

It supports both, 0 is limited, 1 is full.

Indeed. And we do not.

See:

A Matrix Coefficients value othen than 0 signals a transformation between colour difference and RGB representations, which is not used in this International Standard since PNG images are RGB images.

That means limited range is RGB limited range. YCbCr is not supported in PNG even in newest spec.

Last edited 22 months ago by Balling (previous) (diff)
Note: See TracTickets for help on using tickets.