[FFmpeg-devel] [PATCH] X-Face image encoder and decoder
Stefano Sabatini
stefasab at gmail.com
Sat Oct 13 01:44:43 CEST 2012
On date Wednesday 2012-10-10 01:43:01 +0200, Michael Niedermayer encoded:
> Hi
>
> On Tue, Oct 09, 2012 at 05:10:05PM +0200, Stefano Sabatini wrote:
> > On date Thursday 2012-07-26 23:54:50 +0200, Stefano Sabatini encoded:
> > > Hi,
> > >
> > > this is a yet unready version of an X-Face encoder and decoder I did
> > > for fun. I tried to contact the libcompface author to see if he's OK
> > > with the licensing port.
> >
> > James Ashton (in CC:) replied telling that he's OK with LGPL
> > relicensing.
> >
> > > I post it here for backup purposes, and to see if there is some
> > > interest for it (but I warn again that it is not yet ready for
> > > inclusion, so don't review yet).
> > >
> > > Todo:
> > > - add documentation
> > > - add missing buffer checks
> > >
> >
> > > I also wonder if we could adapt our big integer implementation
> > > (libavutil/integer.h) for it, and if someone can recommend fancy
> > > options for creating a 48x48x1 image with ffmpeg in the best possible
> > > way (dithering options, etc.).
> >
> > Updated against the integer patch I posted recently.
> > --
> > FFmpeg = Fabulous and Fundamental Multimedia Philosophical Elastic Gem
>
> [...]
> > libavcodec/Makefile | 2 +
> > libavcodec/allcodecs.c | 1 +
> > libavcodec/avcodec.h | 1 +
> > libavcodec/codec_desc.c | 7 +
> > libavcodec/xface.c | 591 +++++++++++++++++++++++++++++++++++++++++++++++
> > libavcodec/xface.h | 56 +++++
> > libavcodec/xfacedec.c | 225 ++++++++++++++++++
> > libavcodec/xfaceenc.c | 244 +++++++++++++++++++
> > libavformat/img2.c | 1 +
> > 9 files changed, 1128 insertions(+), 0 deletions(-)
> > create mode 100644 libavcodec/xface.c
> > create mode 100644 libavcodec/xface.h
> > create mode 100644 libavcodec/xfacedec.c
> > create mode 100644 libavcodec/xfaceenc.c
>
> the code looks fine, i could point to some possible tricks to
> make it faster but its kind of silly for 48x48 images on modern hw
> so some of the comments below should not be taken serious :)
>
>
> [...]
> > +static const uint8_t g_00[1<<12] = {
> > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> > + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
> > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> > + 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
>
> these tables could be stored more compactly by using bits instead of
> bytes
Done (I'm attaching conversion program+patch for archival reasons,
will squash them together when committing / at the next iteration).
> [...]
> > +void ff_xface_generate_face(uint8_t *dst, uint8_t * const src)
> > +{
> > + int m, l, k, j, i, h;
> > +
> > + for (j = 0; j < XFACE_HEIGHT; j++) {
> > + for (i = 0; i < XFACE_WIDTH; i++) {
> > + h = i + j * XFACE_WIDTH;
> > + k = 0;
> > +
> > + /*
> > + Compute k, encoding the bits *before* the current one, contained in the
> > + image buffer. That is, given the grid:
> > +
> > + l i
> > + | |
> > + v v
> > + +--+--+--+--+--+
> > + m -> | 1| 2| 3| 4| 5|
> > + +--+--+--+--+--+
> > + | 6| 7| 8| 9|10|
> > + +--+--+--+--+--+
> > + j -> |11|12| *| | |
> > + +--+--+--+--+--+
> > +
> > + the value k for the pixel marked as "*" will contain the bit encoding of
> > + the values in the matrix marked from "1" to "12". In case the pixel is
> > + near the border of the grid, the number of values contained within the
> > + grid will be lesser than 12.
> > + */
> > +
> > + for (l = i - 2; l <= i + 2; l++) {
> > + for (m = j - 2; m <= j; m++) {
> > + if (l >= i && m == j)
> > + continue;
> > + if (l > 0 && l <= XFACE_WIDTH && m > 0)
>
> > + k = *(src + l + m * XFACE_WIDTH) ? k * 2 + 1 : k * 2;
>
> k = 2*k + src[src + l + m * XFACE_WIDTH];
Changed.
> also instead of reading 12 values you can reuse the k from the
> left pixel, shift it by 1 bit and update just 3 values, but given the
> small size its not worth the work
Uhm yes, but both for lazyness and for staying close to the original
source I'm keeping it the current way.
> [...]
> > +
> > +/* define the face size - 48x48x1 */
> > +#define XFACE_WIDTH 48
> > +#define XFACE_HEIGHT 48
> > +#define XFACE_PIXELS (XFACE_WIDTH * XFACE_HEIGHT)
> > +
> > +/* compressed output uses the full range of printable characters.
> > + * in ASCII these are in a contiguous block so we just need to know
> > + * the first and last. The total number of printables is needed too */
> > +#define XFACE_FIRSTPRINT '!'
> > +#define XFACE_LASTPRINT '~'
> > +#define XFACE_NUMPRINTS (XFACE_LASTPRINT - XFACE_FIRSTPRINT + 1)
> > +
> > +/* Each face is encoded using 9 octrees of 16x16 each. Each level of the
> > + * trees has varying probabilities of being white, grey or black.
> > + * The table below is based on sampling many faces */
> > +enum { BLACK = 0, GREY, WHITE };
>
> some of these comments could/should be made to /** doxgen comments
>
> also i suspect that several pop_integer() calls could be merged using
> a large LUT to decode several symbols at a time and then adjust b
> for all of them at once. Again not worth for 48x48 images
>
> Thanks to james and stefano for writing and porting this codec !
Patch updated.
Note: what's the best way to check encoder+decoder in FATE? Also
what's the recommended way to add an xface test? Would this require to
add a sample to SAMPLES, or should we rely on the encoder?.
--
FFmpeg = Furious and Fast Mind-dumbing Portable Esoteric Gnome
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-lavc-add-xface-image-decoder-and-encoder.patch
Type: text/x-diff
Size: 50726 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20121013/6658ac7e/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-lavc-xface-write-program-to-generate-compact-guess-t.patch
Type: text/x-diff
Size: 2680 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20121013/6658ac7e/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-lavc-xface-make-guess-tables-more-compact.patch
Type: text/x-diff
Size: 28347 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20121013/6658ac7e/attachment-0002.bin>
More information about the ffmpeg-devel
mailing list