[FFmpeg-devel] [PATCH] 1bpp and 2bpp support in QTRLE
Michael Niedermayer
michaelni
Sun Aug 31 16:52:53 CEST 2008
On Sun, Aug 31, 2008 at 12:13:13PM +0200, Stefan Gehrer wrote:
> Hi,
>
> patch is based on Roberto's patch here
> (http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/2007-January/022046.html)
> and adds support for 1bpp and 2bpp decoding in qtrle.c.
> The samples from http://samples.mplayerhq.hu/V-codecs/QTRLE/
> play visually ok, but the 1bpp decoding produces warnings
> about trying to write pixels past the end of the image.
>
> Stefan
> Index: qtrle.c
> ===================================================================
> --- qtrle.c (revision 15121)
> +++ qtrle.c (working copy)
[...]
> static void qtrle_decode_2bpp(QtrleContext *s, int stream_ptr, int row_ptr, int lines_to_change)
> {
> + int rle_code, i;
> + int pixel_ptr;
> + int row_inc = s->frame.linesize[0];
> + unsigned char pi[16]; /* 16 palette indices */
> + unsigned char *rgb = s->frame.data[0];
> + int pixel_limit = s->frame.linesize[0] * s->avctx->height;
> +
> + while (lines_to_change--) {
> + CHECK_STREAM_PTR(2);
> + pixel_ptr = row_ptr + (16 * (s->buf[stream_ptr++] - 1));
> +
> + while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
> + if (rle_code == 0) {
> + /* there's another skip code in the stream */
> + CHECK_STREAM_PTR(1);
> + pixel_ptr += (16 * (s->buf[stream_ptr++] - 1));
> + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */
> + } else if (rle_code < 0) {
> + /* decode the run length code */
> + rle_code = -rle_code;
> + /* get the next 4 bytes from the stream, treat them as palette
> + * indices, and output them rle_code times */
> + CHECK_STREAM_PTR(4);
> + for (i = 15; i >= 0; i--) {
> + pi[15-i] = ((s->buf[stream_ptr]) >> ((i *2) & 0x07)) & 0x03;
> + stream_ptr+= ((i & 0x03) == 0);
> + }
> + CHECK_PIXEL_PTR(rle_code * 16);
> +
> + while (rle_code--) {
> + for (i = 0; i < 16; i++)
> + rgb[pixel_ptr++] = pi[i];
> + }
> + } else {
> + /* copy the same pixel directly to output 4 times */
> + rle_code *= 4;
> + CHECK_STREAM_PTR(rle_code);
> + CHECK_PIXEL_PTR(rle_code*4);
> +
> + while (rle_code--) {
> + rgb[pixel_ptr++] = ((s->buf[stream_ptr]) >> 6) & 0x03;
> + rgb[pixel_ptr++] = ((s->buf[stream_ptr]) >> 4) & 0x03;
> + rgb[pixel_ptr++] = ((s->buf[stream_ptr]) >> 2) & 0x03;
> + rgb[pixel_ptr++] = (s->buf[stream_ptr++]) & 0x03;
> + }
> + }
> + }
> + row_ptr += row_inc;
> + }
> }
this looks like it can be in a common function handling 4bpp as well.
it that is marked as inline gcc should optimize the bpp out.
>
> static void qtrle_decode_4bpp(QtrleContext *s, int stream_ptr, int row_ptr, int lines_to_change)
> @@ -347,10 +442,13 @@
> s->avctx = avctx;
> switch (avctx->bits_per_sample) {
> case 1:
> + case 33:
> + avctx->pix_fmt = PIX_FMT_MONOWHITE;
> + break;
> +
> case 2:
> case 4:
> case 8:
> - case 33:
> case 34:
> case 36:
> case 40:
> @@ -387,6 +485,7 @@
> QtrleContext *s = avctx->priv_data;
> int header, start_line;
> int stream_ptr, height, row_ptr;
> + int has_palette = 0;
>
> s->buf = buf;
> s->size = buf_size;
> @@ -433,28 +532,19 @@
> case 2:
> case 34:
> qtrle_decode_2bpp(s, stream_ptr, row_ptr, height);
> + has_palette = 1;
> break;
>
> case 4:
> case 36:
> qtrle_decode_4bpp(s, stream_ptr, row_ptr, height);
> - /* make the palette available on the way out */
> - memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE);
> - if (s->avctx->palctrl->palette_changed) {
> - s->frame.palette_has_changed = 1;
> - s->avctx->palctrl->palette_changed = 0;
> - }
> + has_palette = 1;
> break;
>
> case 8:
> case 40:
> qtrle_decode_8bpp(s, stream_ptr, row_ptr, height);
> - /* make the palette available on the way out */
> - memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE);
> - if (s->avctx->palctrl->palette_changed) {
> - s->frame.palette_has_changed = 1;
> - s->avctx->palctrl->palette_changed = 0;
> - }
> + has_palette = 1;
> break;
>
> case 16:
> @@ -474,6 +564,16 @@
> avctx->bits_per_sample);
> break;
> }
> +
> + if(has_palette) {
> + /* make the palette available on the way out */
> + memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE);
> + if (s->avctx->palctrl->palette_changed) {
> + s->frame.palette_has_changed = 1;
> + s->avctx->palctrl->palette_changed = 0;
> + }
> + }
> +
> done:
> *data_size = sizeof(AVFrame);
> *(AVFrame*)data = s->frame;
The avctx->palctrl->palette_changed stuff is deprecated due to race
conditions caused by the design.
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
The educated differ from the uneducated as much as the living from the
dead. -- Aristotle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080831/15c557ed/attachment.pgp>
More information about the ffmpeg-devel
mailing list