[Ffmpeg-devel] [PATCH/RFC] 1-7 and 9-15 bits per pixel PGM files

Michael Niedermayer michaelni
Mon Apr 9 12:19:37 CEST 2007


Hi

On Mon, Apr 09, 2007 at 12:05:16PM +0200, Ivo wrote:
> On Monday 09 April 2007 11:27, Ivo wrote:
> > I see. pix_fmt will stay changed after the first run. Fixed.
> 
> That was buggy. Here's a better patch.
> 
> --Ivo

> Index: libavcodec/pnm.c
> ===================================================================
> --- libavcodec/pnm.c	(revision 8687)
> +++ libavcodec/pnm.c	(working copy)
> @@ -26,6 +26,7 @@
>      uint8_t *bytestream_start;
>      uint8_t *bytestream_end;
>      AVFrame picture;
> +    int maxval;                 ///< maximum value of a pixel
>  } PNMContext;
>  
>  static inline int pnm_space(int c)
> @@ -142,7 +143,8 @@
>          return -1;
>      if (avctx->pix_fmt != PIX_FMT_MONOWHITE) {
>          pnm_get(s, buf1, sizeof(buf1));
> -        if(atoi(buf1) == 65535 && avctx->pix_fmt == PIX_FMT_GRAY8)
> +        s->maxval = atoi(buf1);
> +        if(s->maxval >= 256 && avctx->pix_fmt == PIX_FMT_GRAY8)
>              avctx->pix_fmt = PIX_FMT_GRAY16BE;
>      }
>      /* more check if YUV420 */
> @@ -259,6 +261,22 @@
>          }
>          break;
>      }
> +    /* upgrade values to full range of PIX_FMT */
> +    if (avctx->pix_fmt == PIX_FMT_GRAY8 && s->maxval < 255) {
> +        unsigned int j, f = (255*128 + s->maxval/2) / s->maxval;
> +        for(ptr = p->data[0], i = 0; i < avctx->height; i++, ptr += linesize)
> +            for(j = 0; j < avctx->width; j++)
> +                ptr[j] = (ptr[j] * f + 64)>>7;
> +    } else if ( (avctx->pix_fmt == PIX_FMT_GRAY16BE ||
> +                 avctx->pix_fmt == PIX_FMT_GRAY16) && s->maxval < 65535) {
> +        unsigned int j, val, f = (65535*32768 + s->maxval/2) / s->maxval;
> +        for(ptr = p->data[0], i = 0; i < avctx->height; i++, ptr += linesize)
> +            for(j = 0; j < avctx->width; j++) {
> +                val = be2me_16(((uint16_t *)ptr)[j]);
> +                ((uint16_t *)ptr)[j] = (val * f + 16384)>>15;
> +            }
> +        avctx->pix_fmt = PIX_FMT_GRAY16;
> +    }

after closer inspection this performs a senseless 2nd pass over the data,
this is completely unacceptable, doing convertion during an existing
copy of the data is ok if convertion cannot be avoided without bloating
the pix_fmts, adding an extra pass for convertion is NOT ok as this
convertion can be done equally fast outside the codec

also the pix_fmt MUST be set correctly before get_buffer() it cannot be
hacked at the end of the frame decode function

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

The misfortune of the wise is better than the prosperity of the fool.
-- Epicurus
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070409/bfdcc62a/attachment.pgp>



More information about the ffmpeg-devel mailing list