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

Paul B Mahol onemda at gmail.com
Sat Nov 6 15:01:53 EET 2021


On Thu, Nov 4, 2021 at 9:41 AM Tom Vercauteren <tom.vercauteren at m4x.org>
wrote:

> > > 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.
>
>
You can always store it into rawvideo (without any headers) and than
interpret it as 10bit with specifying ffmpeg rawvideo demuxer parameters.



> 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
> _______________________________________________
> ffmpeg-user mailing list
> ffmpeg-user at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-user
>
> To unsubscribe, visit link above, or email
> ffmpeg-user-request at ffmpeg.org with subject "unsubscribe".
>


More information about the ffmpeg-user mailing list