+ 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;
+ int num_pixels = (bpp == 4) ? 8 : 16;
+
+ while (lines_to_change--) {
+ pixel_ptr = row_ptr + (num_pixels * (bytestream2_get_byte(&s->g) - 1));
+ CHECK_PIXEL_PTR(0);
+
+ while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
+ if (rle_code == 0) {
+ /* there's another skip code in the stream */
+ pixel_ptr += (num_pixels * (bytestream2_get_byte(&s->g) - 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
+ * indexes, and output them rle_code times */
+ for (i = num_pixels-1; i >= 0; i--) {
+ pi[num_pixels-1-i] = (bytestream2_peek_byte(&s->g) >> ((i*bpp) & 0x07)) & ((1<<bpp)-1);
+ bytestream2_skip(&s->g, ((i & ((num_pixels>>2)-1)) == 0));
+ }
+ CHECK_PIXEL_PTR(rle_code * num_pixels);
+ while (rle_code--) {
+ for (i = 0; i < num_pixels; i++)
+ rgb[pixel_ptr++] = pi[i];
+ }
+ } else {
+ /* copy the same pixel directly to output 4 times */
+ rle_code *= 4;
+ CHECK_PIXEL_PTR(rle_code*(num_pixels>>2));
+ while (rle_code--) {
+ if(bpp == 4) {
+ int x = bytestream2_get_byte(&s->g);
+ rgb[pixel_ptr++] = (x >> 4) & 0x0f;
+ rgb[pixel_ptr++] = x & 0x0f;
+ } else {
+ int x = bytestream2_get_byte(&s->g);
+ rgb[pixel_ptr++] = (x >> 6) & 0x03;
+ rgb[pixel_ptr++] = (x >> 4) & 0x03;
+ rgb[pixel_ptr++] = (x >> 2) & 0x03;
+ rgb[pixel_ptr++] = x & 0x03;
+ }
+ }
+ }
+ }
+ row_ptr += row_inc;
+ }