[FFmpeg-user] Lossless compression of 10bit grayscale images (stored as 16bit pngs)

Tom Vercauteren tom.vercauteren at m4x.org
Thu Nov 4 10:40:55 EET 2021


> > Apologies for cross-posting a question I initially posted on stackoverflow
> > (
> > https://stackoverflow.com/q/69739665/17261462) but having had no response
> > there I thought this mailing list may be a better place for it.
> >
> > I am trying to encode 10 bit images losslessly in a video format. The
> > images are stored as 16 bit png files (but only use 10 bit - currently the
> > least significant ones) and I have been working with ffmpeg to create and
> > read back the video files.
> >
> > My best attempt so far is based on
> > https://stackoverflow.com/a/66180140/17261462 but as mentioned there, I
> > get
> > some pixel intensity differences which may be due to rounding when
> > converting between 10 and 16 bit representation. I tried a few different
> > means (bit shifting, left bit replication, floating point based scaling)
> > but haven't yet figured out how to get a trully lossless reconstruction.
> >
> > Below is a small piece of python code to replicate my issue. I probably am
> > doing something wrong there so feedback would be appreciated.
> >
> >
> Upload input png somewhere?
>
> I guess that png files use only first 10bits from least significant bit.

Thanks Paul. The python snippet I provided was creating the png on the
flies but for convenience I am attaching here an example 16bit png
that uses all least significant 10bits. I also provide alternative
versions using either the 10 most significant bits, rescaling the
intensities with
  ROUND(input * MAXOUTSAMPLE / MAXINSAMPLE
or using left bit replication
(http://www.libpng.org/pub/png/spec/1.1/PNG-Encoders.html).

For eae of use, here are also the ffmpeg commands in plain text and an
comparison with imagemagick so as to avoid the need for python.

Encoding:
ffmpeg -y -i gradient10bit-scaledto16bits.png -c:v libx265
-x265-params lossless=1 -pix_fmt gray10be
gradient10bit-scaledto16bits.mkv

Decoding back to png:
ffmpeg -y -i gradient10bit-scaledto16bits.mkv -pix_fmt gray16be
recons-gradient10bit-scaledto16bits.png

Comparison:
magick compare -verbose -metric mae gradient10bit-scaledto16bits.png
recons-gradient10bit-scaledto16bits.png diff-scaledto16bits.png

Best wishes,
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gradient10bit-lsb.png
Type: image/png
Size: 145 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/ffmpeg-user/attachments/20211104/a03524eb/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gradient10bit-msb.png
Type: image/png
Size: 141 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/ffmpeg-user/attachments/20211104/a03524eb/attachment-0001.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gradient10bit-scaledto16bits.png
Type: image/png
Size: 297 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/ffmpeg-user/attachments/20211104/a03524eb/attachment-0002.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gradient10bit-leftbitreplication.png
Type: image/png
Size: 155 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/ffmpeg-user/attachments/20211104/a03524eb/attachment-0003.png>


More information about the ffmpeg-user mailing list