[Ffmpeg-devel] [PATCH/RFC] 1-7 and 9-15 bits per pixel PGM files
Reimar Döffinger
Reimar.Doeffinger
Fri Apr 6 16:17:46 CEST 2007
Hello,
On Fri, Apr 06, 2007 at 03:01:09PM +0200, Ivo wrote:
> PGM files have a maxval value in their headers defining the maximum value a
> pixel can have. This can be anything from 1 to 65535. Currently pnm.c only
> supports 255 and 65535. The attached patch fixes this (not yet for PPM and
> PAM files which can also have any maxval from 1 to 65535 for the R, G and B
> components), but I am not sure if this is the way to go.
Is this transformation lossless (ignoring the case of a wrong maxval)?
> The patch upgrades anything below 255 to GRAY8 and anything from 256 to
> 65535 to GRAY16BE while "decoding" the image file. I could also add
> fourteen new PIX_FMT_*'s and their conversion routines to and from GRAY8/16
> to libswscale and assume all reasonable maxval's will be powers of two,
> minus one. What do you think?
If you only care for these maxvals the code can be extremely simplified,
even doing SIMD without normal C constructs.
IMO simple enough that it doesn't need extra PIX_FMTs.
> I will run into the same problem if I wanted to add Cineon support. .cin
> files can have up to 8 channels (as of version 4.5 the channels can only
> contain R, G or B components) and anything from 1 up to 255 bits per pixel,
> which can be different for each channel. Even the number of pixels per line
> and lines per image can be different for each channel and there are no
> further constraints (i.e. ch. 1-3 could be 1920x1080 12bits/component, and
> ch. 4-5 could be 640x360 7bits/component). How can we fit such things into
> the current PIX_FMT scheme?
Well, how are they stored? Do they actually use e.g. 12 bit per pixel,
or do they in reality use 16 bit per pixel with the highest 4 bits
unused? In that case I think they're idiots for needlessly complicating
a storage format, they should just have shifted the whole thing left.
If they actually use only 12 bit to store, then blowing it up is a small
thing (and by far not as costly as the arbitrary maxval).
> @@ -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;
Hmm... Isn't the current code here buggy anyway and should check for >=
256 instead of == 65535? Then that's a bugfix that should be applied
anyway and before the rest.
> @@ -259,6 +261,27 @@
> }
> break;
> }
> + if (avctx->pix_fmt == PIX_FMT_GRAY16BE && s->maxval != 65535) {
> + ptr = p->data[0];
> + for(i = 0; i < avctx->height; i++) {
> + unsigned int j, val;
> + for(j = 0;j < avctx->width; j++) {
> + val = (ptr[j<<1]<<8) | ptr[(j<<1)+1];
AV_RB16, or maybe even better the bytestream stuff.
> + val = ((val<<16) - val) / s->maxval;
Is ((val<<16) - val) really faster than 65535 * val? The later the
compiler might be able to optimize depending on whether shift or
multiply or some other code it comes up with is faster...
> + ptr[j<<1] = val>>8;
> + ptr[(j<<1)+1] = val & 0xff;
AV_WB16 or bytestream
Greetings,
Reimar D?ffinger
More information about the ffmpeg-devel
mailing list