mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-24 03:59:43 +00:00
Add support for qtrle4 (16 colors/gray levels)
Originally committed as revision 3183 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
e05655fbbd
commit
8b408dbf0f
@ -74,6 +74,92 @@ static void qtrle_decode_2bpp(QtrleContext *s)
|
||||
|
||||
static void qtrle_decode_4bpp(QtrleContext *s)
|
||||
{
|
||||
int stream_ptr;
|
||||
int header;
|
||||
int start_line;
|
||||
int lines_to_change;
|
||||
int rle_code;
|
||||
int row_ptr, pixel_ptr;
|
||||
int row_inc = s->frame.linesize[0];
|
||||
unsigned char pi1, pi2, pi3, pi4, pi5, pi6, pi7, pi8; /* 8 palette indices */
|
||||
unsigned char *rgb = s->frame.data[0];
|
||||
int pixel_limit = s->frame.linesize[0] * s->avctx->height;
|
||||
|
||||
/* check if this frame is even supposed to change */
|
||||
if (s->size < 8)
|
||||
return;
|
||||
|
||||
/* start after the chunk size */
|
||||
stream_ptr = 4;
|
||||
|
||||
/* fetch the header */
|
||||
CHECK_STREAM_PTR(2);
|
||||
header = BE_16(&s->buf[stream_ptr]);
|
||||
stream_ptr += 2;
|
||||
|
||||
/* if a header is present, fetch additional decoding parameters */
|
||||
if (header & 0x0008) {
|
||||
CHECK_STREAM_PTR(8);
|
||||
start_line = BE_16(&s->buf[stream_ptr]);
|
||||
stream_ptr += 4;
|
||||
lines_to_change = BE_16(&s->buf[stream_ptr]);
|
||||
stream_ptr += 4;
|
||||
} else {
|
||||
start_line = 0;
|
||||
lines_to_change = s->avctx->height;
|
||||
}
|
||||
|
||||
row_ptr = row_inc * start_line;
|
||||
while (lines_to_change--) {
|
||||
CHECK_STREAM_PTR(2);
|
||||
pixel_ptr = row_ptr + (8 * (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 += (8 * (s->buf[stream_ptr++] - 1));
|
||||
} 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);
|
||||
pi1 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
|
||||
pi2 = (s->buf[stream_ptr++]) & 0x0f;
|
||||
pi3 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
|
||||
pi4 = (s->buf[stream_ptr++]) & 0x0f;
|
||||
pi5 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
|
||||
pi6 = (s->buf[stream_ptr++]) & 0x0f;
|
||||
pi7 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
|
||||
pi8 = (s->buf[stream_ptr++]) & 0x0f;
|
||||
|
||||
CHECK_PIXEL_PTR(rle_code * 8);
|
||||
|
||||
while (rle_code--) {
|
||||
rgb[pixel_ptr++] = pi1;
|
||||
rgb[pixel_ptr++] = pi2;
|
||||
rgb[pixel_ptr++] = pi3;
|
||||
rgb[pixel_ptr++] = pi4;
|
||||
rgb[pixel_ptr++] = pi5;
|
||||
rgb[pixel_ptr++] = pi6;
|
||||
rgb[pixel_ptr++] = pi7;
|
||||
rgb[pixel_ptr++] = pi8;
|
||||
}
|
||||
} else {
|
||||
/* copy the same pixel directly to output 4 times */
|
||||
rle_code *= 4;
|
||||
CHECK_STREAM_PTR(rle_code);
|
||||
CHECK_PIXEL_PTR(rle_code*2);
|
||||
|
||||
while (rle_code--) {
|
||||
rgb[pixel_ptr++] = ((s->buf[stream_ptr]) >> 4) & 0x0f;
|
||||
rgb[pixel_ptr++] = (s->buf[stream_ptr++]) & 0x0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
row_ptr += row_inc;
|
||||
}
|
||||
}
|
||||
|
||||
static void qtrle_decode_8bpp(QtrleContext *s)
|
||||
@ -473,6 +559,12 @@ static int qtrle_decode_frame(AVCodecContext *avctx,
|
||||
case 4:
|
||||
case 36:
|
||||
qtrle_decode_4bpp(s);
|
||||
/* 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;
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
|
Loading…
Reference in New Issue
Block a user