Browse code

Fix 24 bpp CSCD decoding, as for Windows bitmaps in this (and only this) case the stride must be aligned to a multiple of 4. The original CSCD encoder just compresses bitmaps it gets via Windows API functions as-is, thus it uses exactly those alignment rules.

Originally committed as revision 25096 to svn://svn.ffmpeg.org/ffmpeg/trunk

Reimar Döffinger authored on 2010/09/11 02:33:31
Showing 1 changed files
... ...
@@ -35,19 +35,19 @@ typedef struct {
35 35
     unsigned char* decomp_buf;
36 36
 } CamStudioContext;
37 37
 
38
-static void copy_frame_default(AVFrame *f, const uint8_t *src,
38
+static void copy_frame_default(AVFrame *f, const uint8_t *src, int src_stride,
39 39
                                int linelen, int height) {
40 40
     int i;
41 41
     uint8_t *dst = f->data[0];
42 42
     dst += (height - 1) * f->linesize[0];
43 43
     for (i = height; i; i--) {
44 44
         memcpy(dst, src, linelen);
45
-        src += linelen;
45
+        src += src_stride;
46 46
         dst -= f->linesize[0];
47 47
     }
48 48
 }
49 49
 
50
-static void add_frame_default(AVFrame *f, const uint8_t *src,
50
+static void add_frame_default(AVFrame *f, const uint8_t *src, int src_stride,
51 51
                               int linelen, int height) {
52 52
     int i, j;
53 53
     uint8_t *dst = f->data[0];
... ...
@@ -55,15 +55,16 @@ static void add_frame_default(AVFrame *f, const uint8_t *src,
55 55
     for (i = height; i; i--) {
56 56
         for (j = linelen; j; j--)
57 57
             *dst++ += *src++;
58
+        src += src_stride - linelen;
58 59
         dst -= f->linesize[0] + linelen;
59 60
     }
60 61
 }
61 62
 
62 63
 #if !HAVE_BIGENDIAN
63
-#define copy_frame_16 copy_frame_default
64
-#define copy_frame_32 copy_frame_default
65
-#define add_frame_16 add_frame_default
66
-#define add_frame_32 add_frame_default
64
+#define copy_frame_16(f, s, l, h) copy_frame_default(f, s, l, l, h)
65
+#define copy_frame_32(f, s, l, h) copy_frame_default(f, s, l, l, h)
66
+#define add_frame_16(f, s, l, h) add_frame_default(f, s, l, l, h)
67
+#define add_frame_32(f, s, l, h) add_frame_default(f, s, l, l, h)
67 68
 #else
68 69
 static void copy_frame_16(AVFrame *f, const uint8_t *src,
69 70
                           int linelen, int height) {
... ...
@@ -192,7 +193,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
192 192
               copy_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height);
193 193
               break;
194 194
           default:
195
-              copy_frame_default(&c->pic, c->decomp_buf, c->linelen, c->height);
195
+              copy_frame_default(&c->pic, c->decomp_buf, FFALIGN(c->linelen, 4),
196
+                                 c->linelen, c->height);
196 197
         }
197 198
     } else {
198 199
         c->pic.pict_type = FF_P_TYPE;
... ...
@@ -205,7 +207,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
205 205
               add_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height);
206 206
               break;
207 207
           default:
208
-              add_frame_default(&c->pic, c->decomp_buf, c->linelen, c->height);
208
+              add_frame_default(&c->pic, c->decomp_buf, FFALIGN(c->linelen, 4),
209
+                                c->linelen, c->height);
209 210
         }
210 211
     }
211 212
 
... ...
@@ -216,6 +219,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
216 216
 
217 217
 static av_cold int decode_init(AVCodecContext *avctx) {
218 218
     CamStudioContext *c = avctx->priv_data;
219
+    int stride;
219 220
     switch (avctx->bits_per_coded_sample) {
220 221
         case 16: avctx->pix_fmt = PIX_FMT_RGB555; break;
221 222
         case 24: avctx->pix_fmt = PIX_FMT_BGR24; break;
... ...
@@ -230,7 +234,10 @@ static av_cold int decode_init(AVCodecContext *avctx) {
230 230
     c->pic.data[0] = NULL;
231 231
     c->linelen = avctx->width * avctx->bits_per_coded_sample / 8;
232 232
     c->height = avctx->height;
233
-    c->decomp_size = c->height * c->linelen;
233
+    stride = c->linelen;
234
+    if (avctx->bits_per_coded_sample == 24)
235
+        stride = FFALIGN(stride, 4);
236
+    c->decomp_size = c->height * stride;
234 237
     c->decomp_buf = av_malloc(c->decomp_size + AV_LZO_OUTPUT_PADDING);
235 238
     if (!c->decomp_buf) {
236 239
         av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");