comparison qtrle.c @ 2049:19c713e14316 libavcodec

Add support for qtrle4 (16 colors/gray levels)
author rtognimp
date Mon, 31 May 2004 20:18:08 +0000
parents 39ad6cd5d4a6
children f67b63ed036d
comparison
equal deleted inserted replaced
2048:533717e2910f 2049:19c713e14316
72 { 72 {
73 } 73 }
74 74
75 static void qtrle_decode_4bpp(QtrleContext *s) 75 static void qtrle_decode_4bpp(QtrleContext *s)
76 { 76 {
77 int stream_ptr;
78 int header;
79 int start_line;
80 int lines_to_change;
81 int rle_code;
82 int row_ptr, pixel_ptr;
83 int row_inc = s->frame.linesize[0];
84 unsigned char pi1, pi2, pi3, pi4, pi5, pi6, pi7, pi8; /* 8 palette indices */
85 unsigned char *rgb = s->frame.data[0];
86 int pixel_limit = s->frame.linesize[0] * s->avctx->height;
87
88 /* check if this frame is even supposed to change */
89 if (s->size < 8)
90 return;
91
92 /* start after the chunk size */
93 stream_ptr = 4;
94
95 /* fetch the header */
96 CHECK_STREAM_PTR(2);
97 header = BE_16(&s->buf[stream_ptr]);
98 stream_ptr += 2;
99
100 /* if a header is present, fetch additional decoding parameters */
101 if (header & 0x0008) {
102 CHECK_STREAM_PTR(8);
103 start_line = BE_16(&s->buf[stream_ptr]);
104 stream_ptr += 4;
105 lines_to_change = BE_16(&s->buf[stream_ptr]);
106 stream_ptr += 4;
107 } else {
108 start_line = 0;
109 lines_to_change = s->avctx->height;
110 }
111
112 row_ptr = row_inc * start_line;
113 while (lines_to_change--) {
114 CHECK_STREAM_PTR(2);
115 pixel_ptr = row_ptr + (8 * (s->buf[stream_ptr++] - 1));
116
117 while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
118 if (rle_code == 0) {
119 /* there's another skip code in the stream */
120 CHECK_STREAM_PTR(1);
121 pixel_ptr += (8 * (s->buf[stream_ptr++] - 1));
122 } else if (rle_code < 0) {
123 /* decode the run length code */
124 rle_code = -rle_code;
125 /* get the next 4 bytes from the stream, treat them as palette
126 * indices, and output them rle_code times */
127 CHECK_STREAM_PTR(4);
128 pi1 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
129 pi2 = (s->buf[stream_ptr++]) & 0x0f;
130 pi3 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
131 pi4 = (s->buf[stream_ptr++]) & 0x0f;
132 pi5 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
133 pi6 = (s->buf[stream_ptr++]) & 0x0f;
134 pi7 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
135 pi8 = (s->buf[stream_ptr++]) & 0x0f;
136
137 CHECK_PIXEL_PTR(rle_code * 8);
138
139 while (rle_code--) {
140 rgb[pixel_ptr++] = pi1;
141 rgb[pixel_ptr++] = pi2;
142 rgb[pixel_ptr++] = pi3;
143 rgb[pixel_ptr++] = pi4;
144 rgb[pixel_ptr++] = pi5;
145 rgb[pixel_ptr++] = pi6;
146 rgb[pixel_ptr++] = pi7;
147 rgb[pixel_ptr++] = pi8;
148 }
149 } else {
150 /* copy the same pixel directly to output 4 times */
151 rle_code *= 4;
152 CHECK_STREAM_PTR(rle_code);
153 CHECK_PIXEL_PTR(rle_code*2);
154
155 while (rle_code--) {
156 rgb[pixel_ptr++] = ((s->buf[stream_ptr]) >> 4) & 0x0f;
157 rgb[pixel_ptr++] = (s->buf[stream_ptr++]) & 0x0f;
158 }
159 }
160 }
161 row_ptr += row_inc;
162 }
77 } 163 }
78 164
79 static void qtrle_decode_8bpp(QtrleContext *s) 165 static void qtrle_decode_8bpp(QtrleContext *s)
80 { 166 {
81 int stream_ptr; 167 int stream_ptr;
471 break; 557 break;
472 558
473 case 4: 559 case 4:
474 case 36: 560 case 36:
475 qtrle_decode_4bpp(s); 561 qtrle_decode_4bpp(s);
562 /* make the palette available on the way out */
563 memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE);
564 if (s->avctx->palctrl->palette_changed) {
565 s->frame.palette_has_changed = 1;
566 s->avctx->palctrl->palette_changed = 0;
567 }
476 break; 568 break;
477 569
478 case 8: 570 case 8:
479 case 40: 571 case 40:
480 qtrle_decode_8bpp(s); 572 qtrle_decode_8bpp(s);