comparison tscc.c @ 7885:f874e1d5cf07 libavcodec

Factorize out code used for MS RLE format decoding in different decoders.
author kostya
date Thu, 18 Sep 2008 05:20:54 +0000
parents 4525dcd81357
children bbac1857dd86
comparison
equal deleted inserted replaced
7884:4077df298ba2 7885:f874e1d5cf07
37 37
38 #include <stdio.h> 38 #include <stdio.h>
39 #include <stdlib.h> 39 #include <stdlib.h>
40 40
41 #include "avcodec.h" 41 #include "avcodec.h"
42 #include "msrledec.h"
42 43
43 #ifdef CONFIG_ZLIB 44 #ifdef CONFIG_ZLIB
44 #include <zlib.h> 45 #include <zlib.h>
45 #endif 46 #endif
46 47
62 int height; 63 int height;
63 #ifdef CONFIG_ZLIB 64 #ifdef CONFIG_ZLIB
64 z_stream zstream; 65 z_stream zstream;
65 #endif 66 #endif
66 } CamtasiaContext; 67 } CamtasiaContext;
67
68 /*
69 *
70 * Decode RLE - almost identical to Windows BMP RLE8
71 * and enhanced to bigger color depths
72 *
73 */
74
75 static int decode_rle(CamtasiaContext *c, unsigned int srcsize)
76 {
77 unsigned char *src = c->decomp_buf;
78 unsigned char *output, *output_end;
79 int p1, p2, line=c->height, pos=0, i;
80 uint16_t pix16;
81 uint32_t pix32;
82
83 output = c->pic.data[0] + (c->height - 1) * c->pic.linesize[0];
84 output_end = c->pic.data[0] + (c->height) * c->pic.linesize[0];
85 while(src < c->decomp_buf + srcsize) {
86 p1 = *src++;
87 if(p1 == 0) { //Escape code
88 p2 = *src++;
89 if(p2 == 0) { //End-of-line
90 output = c->pic.data[0] + (--line) * c->pic.linesize[0];
91 if (line < 0)
92 return -1;
93 pos = 0;
94 continue;
95 } else if(p2 == 1) { //End-of-picture
96 return 0;
97 } else if(p2 == 2) { //Skip
98 p1 = *src++;
99 p2 = *src++;
100 line -= p2;
101 if (line < 0)
102 return -1;
103 pos += p1;
104 output = c->pic.data[0] + line * c->pic.linesize[0] + pos * (c->bpp / 8);
105 continue;
106 }
107 // Copy data
108 if (output + p2 * (c->bpp / 8) > output_end) {
109 src += p2 * (c->bpp / 8);
110 continue;
111 }
112 if ((c->bpp == 8) || (c->bpp == 24)) {
113 for(i = 0; i < p2 * (c->bpp / 8); i++) {
114 *output++ = *src++;
115 }
116 // RLE8 copy is actually padded - and runs are not!
117 if(c->bpp == 8 && (p2 & 1)) {
118 src++;
119 }
120 } else if (c->bpp == 16) {
121 for(i = 0; i < p2; i++) {
122 pix16 = AV_RL16(src);
123 src += 2;
124 *(uint16_t*)output = pix16;
125 output += 2;
126 }
127 } else if (c->bpp == 32) {
128 for(i = 0; i < p2; i++) {
129 pix32 = AV_RL32(src);
130 src += 4;
131 *(uint32_t*)output = pix32;
132 output += 4;
133 }
134 }
135 pos += p2;
136 } else { //Run of pixels
137 int pix[4]; //original pixel
138 switch(c->bpp){
139 case 8: pix[0] = *src++;
140 break;
141 case 16: pix16 = AV_RL16(src);
142 src += 2;
143 *(uint16_t*)pix = pix16;
144 break;
145 case 24: pix[0] = *src++;
146 pix[1] = *src++;
147 pix[2] = *src++;
148 break;
149 case 32: pix32 = AV_RL32(src);
150 src += 4;
151 *(uint32_t*)pix = pix32;
152 break;
153 }
154 if (output + p1 * (c->bpp / 8) > output_end)
155 continue;
156 for(i = 0; i < p1; i++) {
157 switch(c->bpp){
158 case 8: *output++ = pix[0];
159 break;
160 case 16: *(uint16_t*)output = pix16;
161 output += 2;
162 break;
163 case 24: *output++ = pix[0];
164 *output++ = pix[1];
165 *output++ = pix[2];
166 break;
167 case 32: *(uint32_t*)output = pix32;
168 output += 4;
169 break;
170 }
171 }
172 pos += p1;
173 }
174 }
175
176 av_log(c->avctx, AV_LOG_ERROR, "Camtasia warning: no End-of-picture code\n");
177 return 1;
178 }
179 68
180 /* 69 /*
181 * 70 *
182 * Decode a frame 71 * Decode a frame
183 * 72 *
221 return -1; 110 return -1;
222 } 111 }
223 112
224 113
225 if(zret != Z_DATA_ERROR) 114 if(zret != Z_DATA_ERROR)
226 decode_rle(c, c->zstream.avail_out); 115 ff_msrle_decode(avctx, &c->pic, c->bpp, c->decomp_buf, c->zstream.avail_out);
227 116
228 /* make the palette available on the way out */ 117 /* make the palette available on the way out */
229 if (c->avctx->pix_fmt == PIX_FMT_PAL8) { 118 if (c->avctx->pix_fmt == PIX_FMT_PAL8) {
230 memcpy(c->pic.data[1], c->avctx->palctrl->palette, AVPALETTE_SIZE); 119 memcpy(c->pic.data[1], c->avctx->palctrl->palette, AVPALETTE_SIZE);
231 if (c->avctx->palctrl->palette_changed) { 120 if (c->avctx->palctrl->palette_changed) {