• Show log

    Commit

  • Hash : 6d48aaac
    Author : DRC
    Date : 2025-10-22T10:30:53

    TJ: Handle lossless/CS params w/ YUV enc/compress
    
    - If TJPARAM_LOSSLESS was set, then tj3EncodeYUV*8() called
      jpeg_enable_lossless() (via setCompDefaults()), which caused the
      underlying libjpeg API to silently disable subsampling and color
      conversion.  This led to three issues:
    
      1. Attempting to encode RGB pixels produced incorrect YCbCr or
         grayscale components, since color conversion did not occur.  The
         same issue occurred if TJPARAM_COLORSPACE was explicitly set to
         TJCS_RGB.
      2. Attempting to encode RGB pixels into a grayscale plane caused
         tj3EncodeYUVPlanes8() to overflow the caller's destination pointer
         array if the array was not big enough to accommodate three
         pointers.  If called from tj3EncodeYUV8(), tj3EncodeYUVPlanes8()
         did not overflow the caller's destination pointer array, but a
         segfault occurred when it attempted to copy to the Cb and Cr
         pointers, which were NULL.  The same issue occurred if
         TJPARAM_COLORSPACE was explicitly set to anything other than
         TJCS_GRAY.
      3. Attempting to encode RGB pixels into subsampled YUV planes caused
         tj3EncodeYUV*8() to overflow the caller's buffer(s) if the
         buffer(s) were not big enough to accommodate 4:4:4 (non-subsampled)
         YUV planes.  That would have been the case if the caller allocated
         its buffer(s) based on the return value of tj3YUVBufSize() or
         tj3YUVPlaneSize().  The same issue occurs if TJPARAM_SUBSAMP is
         explicitly set to TJSAMP_444.
    
      tj3EncodeYUV*8() now ignores TJPARAM_LOSSLESS and TJPARAM_COLORSPACE.
    
    - If TJPARAM_LOSSLESS was set, then attempting to compress a grayscale
      plane into a JPEG image caused tj3CompressFromYUVPlanes8() to overflow
      the caller's source pointer array if the array was not big enough to
      accommodate three pointers.  If called from tj3CompressFromYUV8(),
      tj3CompressFromYUVPlanes8() did not overflow the caller's source
      pointer array, but a segfault occurred when it attempted to copy from
      the Cb and Cr pointers, which were NULL.  This was similar to Issue 2
      above.  The same issue occurred if TJPARAM_COLORSPACE was explicitly
      set to anything other than TJCS_GRAY.
    
      tj3CompressFromYUV*8() now throws an error if TJPARAM_LOSSLESS is set,
      and it now ignores TJPARAM_COLORSPACE.
    
    These issues did not pose a security risk, since security exploits
    involve supported workflows that function normally except when supplied
    with malformed input data.  It is documented that colorspace conversion,
    chrominance subsampling, and compression from planar YUV images are
    unavailable when TJPARAM_LOSSLESS is set.  When TJPARAM_LOSSLESS is set,
    the library effectively sets TJPARAM_SUBSAMP to TJSAMP_444 and
    TJPARAM_COLORSPACE to TJCS_RGB, TJCS_GRAY, or TJCS_CMYK, depending on
    the pixel format of the source image.  That behavior is strongly implied
    by the documentation of TJPARAM_LOSSLESS, although the documentation
    isn't specific about whether TJPARAM_LOSSLESS applies to
    tj3EncodeYUV*8().  In any case, setting TJPARAM_LOSSLESS before calling
    tj3CompressFromYUV*8() was never a supported or functional workflow, and
    setting TJPARAM_LOSSLESS before calling tj3EncodeYUV*8() was never a
    functional workflow.  Thus, there should be no applications "in the
    wild" that use either workflow.  Such applications would crash every
    time they attempted to encode to or compress from a YUV image.  In other
    words, setting TJPARAM_LOSSLESS or TJPARAM_COLORSPACE required the
    caller to understand the ramifications of the loss of color conversion
    and/or subsampling, and failing to do so was essentially API abuse
    (albeit subtle API abuse, hence the desire to make the behavior more
    intuitive.)
    
    This commit also removes no-op code introduced by
    6da05150efa9b7a190d05bf82295127c778d15ab.  Since setCompDefaults()
    returns after calling jpeg_enable_lossless(), modifying the subsampling
    level locally had no effect.  The libjpeg API already silently disables
    subsampling in jinit_c_master_control() if lossless compression is
    enabled, so it was not necessary for setCompDefaults() to handle that.
    
    Fixes #839
    

  • Properties

  • Git HTTP https://git.kmx.io/kc3-lang/libjpeg-turbo.git
    Git SSH git@git.kmx.io:kc3-lang/libjpeg-turbo.git
    Public access ? public
    Description

    Fork of libjpeg with SIMD

    Users
    thodg_m kc3_lang_org thodg_w www_kmx_io thodg_l thodg
    Tags