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

Michael Niedermayer michaelni
Sat Apr 7 16:27:11 CEST 2007


Hi

On Sat, Apr 07, 2007 at 03:43:40PM +0200, Ivo wrote:
> On Friday 06 April 2007 21:13, Justin Ruggles wrote:
> > Ivo wrote:
> > > OK. I think it is reasonable to assume only maxvals of (2^n)-1 for
> > > 0<n<=16 are used in the wild. I have never seen anything other than
> > > 255, 1023, 2047, 4095, 16383 and 65535.
> >
> > I have seen others in the wild.  For example, when the dcraw program
> > converts raw camera images formats to pnm it uses the camera's native
> > raw format maximum value, which is sometimes a very odd non-power-of-two
> > number.  My guess is that it's either due to the A/D converter and/or to
> > give some headroom for in-camera postprocessing.
> 
> I see. I have thought about it and I think the shift/or "upgrading" to 
> 8/16-bits per component is better than multiply/division, even in this 

division is too slow, always mupltply by the reciprocal and shift


> case, because it won't introduce rounding errors and can be downgraded 
> losslessly (simple shift). 

hmm

[...]
>          pnm_get(s, buf1, sizeof(buf1));
> -        if(atoi(buf1) == 65535 && avctx->pix_fmt == PIX_FMT_GRAY8)
> +        s->bpp = av_log2(atoi(buf1)) + 1;
> +        if (s->bpp > 16) {
> +            av_log(avctx, AV_LOG_ERROR, "maxval is larger than 65535\n");
> +            return -1;
> +        }
> +        if(s->bpp > 8 && avctx->pix_fmt == PIX_FMT_GRAY8)
>              avctx->pix_fmt = PIX_FMT_GRAY16BE;
>      }
>      /* more check if YUV420 */
> @@ -259,6 +265,23 @@
>          }
>          break;
>      }
> +    /* upgrade values to full range of PIX_FMT */
> +    if (avctx->pix_fmt == PIX_FMT_GRAY8 && s->bpp < 8) {
> +        unsigned int j;
> +        for(ptr = p->data[0], i = 0; i < avctx->height; i++, ptr += linesize) {
> +            for(j = 0; j < avctx->width; j++)
> +                ptr[j] = ptr[j]<<(8-s->bpp) | ptr[j]>>(s->bpp-(8-s->bpp));

will fail if bpp<4 (negative shift)
try:
pix <<= 8-bpp;
pix += pix>>bpp;


> +        }
> +    } else if (avctx->pix_fmt == PIX_FMT_GRAY16BE && s->bpp < 16) {
> +        unsigned int j, val;
> +        for(ptr = p->data[0], i = 0; i < avctx->height; i++, ptr += linesize) {
> +            for(j = 0; j < avctx->width; j++) {
> +                val = AV_RB16(&ptr[j<<1]);
> +                val = val<<(16-s->bpp) | val>>(s->bpp-(16-s->bpp));
> +                AV_WB16(&ptr[j<<1], val);

16bit formats should be in native endian internally (for obvious reasons)

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Democracy is the form of government in which you can choose your dictator
-------------- 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/20070407/cae3f2e9/attachment.pgp>



More information about the ffmpeg-devel mailing list