[FFmpeg-devel] [PATCH v3 1/3] avcodec/mjpegdec: fix non-subsampled RGB JPEGs

Leo Izen leo.izen at gmail.com
Thu Apr 20 00:15:00 EEST 2023


On 4/19/23 16:37, Michael Niedermayer wrote:
> On Wed, Apr 19, 2023 at 03:23:41PM -0400, Leo Izen wrote:
>> On 4/19/23 14:58, Michael Niedermayer wrote:
>>> On Wed, Apr 19, 2023 at 02:11:24PM -0400, Leo Izen wrote:
>>>> The change introduced in b18a9c29713abc3a1b081de3f320ab53a47120c6
>>>> created a regression for non-subsampled progressive RGB jpegs. This
>>>> should fix that.
>>>> ---
>>>>    libavcodec/mjpegdec.c | 3 ++-
>>>>    1 file changed, 2 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
>>>> index 01537d4774..1e3ddb72fb 100644
>>>> --- a/libavcodec/mjpegdec.c
>>>> +++ b/libavcodec/mjpegdec.c
>>>> @@ -1698,7 +1698,8 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask,
>>>>            s->h_scount[i]  = s->h_count[index];
>>>>            s->v_scount[i]  = s->v_count[index];
>>>> -        if(nb_components == 3 && s->nb_components == 3 && s->avctx->pix_fmt == AV_PIX_FMT_GBRP)
>>>> +        if((nb_components == 3 || nb_components == 1) && s->nb_components == 3
>>>> +                && s->avctx->pix_fmt == AV_PIX_FMT_GBRP && !s->progressive)
>>>>                index = (index+2)%3;
>>>
>>> Why is progressive/!progressive special cased in all the new RGB code ?
>>>
>>
>> With progressive, I decode RGB in RGB-order, and then pivot it into
>> GBR-order, whereas baseline is just decoded directly into GBR-order. If you
>> decode progressive directly in GBR-order the buffers will be the wrong size
>> and it will overrun the subsampled buffer when filling it with a
>> non-subsampled one. See the allocation block on line 766 of mjpegdec.c. This
>> depends on h_count and v_count, which cannot be changed or pivoted as if you
>> do so, progressive JPEGs will fail to decode at all (invalid VLC entries,
>> etc.)
>>
>> Ideally, you'd just alloc them the right size, but s->component_index[i]
>> won't refer to the right index for many progressive files, depending on
>> whether the SOS marker has 1 or 3 components. If you have SOS markers with
>> one component it will not properly pivot the colors.
>>
>> Initially, I didn't have the checks and just always decoded in RGB order and
>> then pivoted, but that broke some baseline files like the ones in Trac
>> #4045. I used some casework so I could handle all files I tested with this.
>>
>> If anyone has any suggestions on how to make the casework more elegant I'm
>> all ears but this is the solution I found to work with every sample I
>> tested.
> 
> First i would document which array is in PIXFMT vs. JPEG order
> when anything is in 2 different orders at different points or for
> different cases thats probably not a good idea.
> But even if such bad cases exist, it should be documented
> 
> progressive is complicated because one could argue that it needs
> to be possible to both add pieces into the image and also to
> make these pieces immedeatly available to the user so some
> application could present to the user the image as it is
> "progressing". Ok we maybe dont care for that feature but its
> still not a bad way to look at the problem.
> I presume all jpeg streams can be decoded without too much problems
> if everything is in jpeg order.
> at the same time to present it we need planes to be scaled and
> ordered into a standard RGB/GBR/YUV form.
> I think these 2 worlds JPEG vs presentation should be more clearly
> seperated,
> 
> am i seeing the issue correctly or am i missing the problems here ?
> 
> thx

I could try to see if I can decode *every* image in JPEG order and then 
pivot the planes from RGB to GBR order at the end, but it might take me 
a bit more time to figure it out. I'll take a look at it this week. It 
would be a more elegant solution and wouldn't require us to document 
which planes go where in which places of the code.

- Leo Izen



More information about the ffmpeg-devel mailing list