Mercurial > libavcodec.hg
comparison cscd.c @ 12482:8cafb4db28cb libavcodec
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.
| author | reimar |
|---|---|
| date | Fri, 10 Sep 2010 17:33:31 +0000 |
| parents | ca1896830b44 |
| children |
comparison
equal
deleted
inserted
replaced
| 12481:e9a1e1ba768f | 12482:8cafb4db28cb |
|---|---|
| 33 int linelen, height, bpp; | 33 int linelen, height, bpp; |
| 34 unsigned int decomp_size; | 34 unsigned int decomp_size; |
| 35 unsigned char* decomp_buf; | 35 unsigned char* decomp_buf; |
| 36 } CamStudioContext; | 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 int linelen, int height) { | 39 int linelen, int height) { |
| 40 int i; | 40 int i; |
| 41 uint8_t *dst = f->data[0]; | 41 uint8_t *dst = f->data[0]; |
| 42 dst += (height - 1) * f->linesize[0]; | 42 dst += (height - 1) * f->linesize[0]; |
| 43 for (i = height; i; i--) { | 43 for (i = height; i; i--) { |
| 44 memcpy(dst, src, linelen); | 44 memcpy(dst, src, linelen); |
| 45 src += linelen; | 45 src += src_stride; |
| 46 dst -= f->linesize[0]; | 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 int linelen, int height) { | 51 int linelen, int height) { |
| 52 int i, j; | 52 int i, j; |
| 53 uint8_t *dst = f->data[0]; | 53 uint8_t *dst = f->data[0]; |
| 54 dst += (height - 1) * f->linesize[0]; | 54 dst += (height - 1) * f->linesize[0]; |
| 55 for (i = height; i; i--) { | 55 for (i = height; i; i--) { |
| 56 for (j = linelen; j; j--) | 56 for (j = linelen; j; j--) |
| 57 *dst++ += *src++; | 57 *dst++ += *src++; |
| 58 src += src_stride - linelen; | |
| 58 dst -= f->linesize[0] + linelen; | 59 dst -= f->linesize[0] + linelen; |
| 59 } | 60 } |
| 60 } | 61 } |
| 61 | 62 |
| 62 #if !HAVE_BIGENDIAN | 63 #if !HAVE_BIGENDIAN |
| 63 #define copy_frame_16 copy_frame_default | 64 #define copy_frame_16(f, s, l, h) copy_frame_default(f, s, l, l, h) |
| 64 #define copy_frame_32 copy_frame_default | 65 #define copy_frame_32(f, s, l, h) copy_frame_default(f, s, l, l, h) |
| 65 #define add_frame_16 add_frame_default | 66 #define add_frame_16(f, s, l, h) add_frame_default(f, s, l, l, h) |
| 66 #define add_frame_32 add_frame_default | 67 #define add_frame_32(f, s, l, h) add_frame_default(f, s, l, l, h) |
| 67 #else | 68 #else |
| 68 static void copy_frame_16(AVFrame *f, const uint8_t *src, | 69 static void copy_frame_16(AVFrame *f, const uint8_t *src, |
| 69 int linelen, int height) { | 70 int linelen, int height) { |
| 70 int i, j; | 71 int i, j; |
| 71 uint8_t *dst = f->data[0]; | 72 uint8_t *dst = f->data[0]; |
| 190 break; | 191 break; |
| 191 case 32: | 192 case 32: |
| 192 copy_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height); | 193 copy_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height); |
| 193 break; | 194 break; |
| 194 default: | 195 default: |
| 195 copy_frame_default(&c->pic, c->decomp_buf, c->linelen, c->height); | 196 copy_frame_default(&c->pic, c->decomp_buf, FFALIGN(c->linelen, 4), |
| 197 c->linelen, c->height); | |
| 196 } | 198 } |
| 197 } else { | 199 } else { |
| 198 c->pic.pict_type = FF_P_TYPE; | 200 c->pic.pict_type = FF_P_TYPE; |
| 199 c->pic.key_frame = 0; | 201 c->pic.key_frame = 0; |
| 200 switch (c->bpp) { | 202 switch (c->bpp) { |
| 203 break; | 205 break; |
| 204 case 32: | 206 case 32: |
| 205 add_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height); | 207 add_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height); |
| 206 break; | 208 break; |
| 207 default: | 209 default: |
| 208 add_frame_default(&c->pic, c->decomp_buf, c->linelen, c->height); | 210 add_frame_default(&c->pic, c->decomp_buf, FFALIGN(c->linelen, 4), |
| 211 c->linelen, c->height); | |
| 209 } | 212 } |
| 210 } | 213 } |
| 211 | 214 |
| 212 *picture = c->pic; | 215 *picture = c->pic; |
| 213 *data_size = sizeof(AVFrame); | 216 *data_size = sizeof(AVFrame); |
| 214 return buf_size; | 217 return buf_size; |
| 215 } | 218 } |
| 216 | 219 |
| 217 static av_cold int decode_init(AVCodecContext *avctx) { | 220 static av_cold int decode_init(AVCodecContext *avctx) { |
| 218 CamStudioContext *c = avctx->priv_data; | 221 CamStudioContext *c = avctx->priv_data; |
| 222 int stride; | |
| 219 switch (avctx->bits_per_coded_sample) { | 223 switch (avctx->bits_per_coded_sample) { |
| 220 case 16: avctx->pix_fmt = PIX_FMT_RGB555; break; | 224 case 16: avctx->pix_fmt = PIX_FMT_RGB555; break; |
| 221 case 24: avctx->pix_fmt = PIX_FMT_BGR24; break; | 225 case 24: avctx->pix_fmt = PIX_FMT_BGR24; break; |
| 222 case 32: avctx->pix_fmt = PIX_FMT_RGB32; break; | 226 case 32: avctx->pix_fmt = PIX_FMT_RGB32; break; |
| 223 default: | 227 default: |
| 228 } | 232 } |
| 229 c->bpp = avctx->bits_per_coded_sample; | 233 c->bpp = avctx->bits_per_coded_sample; |
| 230 c->pic.data[0] = NULL; | 234 c->pic.data[0] = NULL; |
| 231 c->linelen = avctx->width * avctx->bits_per_coded_sample / 8; | 235 c->linelen = avctx->width * avctx->bits_per_coded_sample / 8; |
| 232 c->height = avctx->height; | 236 c->height = avctx->height; |
| 233 c->decomp_size = c->height * c->linelen; | 237 stride = c->linelen; |
| 238 if (avctx->bits_per_coded_sample == 24) | |
| 239 stride = FFALIGN(stride, 4); | |
| 240 c->decomp_size = c->height * stride; | |
| 234 c->decomp_buf = av_malloc(c->decomp_size + AV_LZO_OUTPUT_PADDING); | 241 c->decomp_buf = av_malloc(c->decomp_size + AV_LZO_OUTPUT_PADDING); |
| 235 if (!c->decomp_buf) { | 242 if (!c->decomp_buf) { |
| 236 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); | 243 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); |
| 237 return 1; | 244 return 1; |
| 238 } | 245 } |
