3 * Copyright (c) 2006 Reimar Doeffinger
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #include "libavutil/common.h"
31 #include "libavutil/lzo.h"
35 int linelen
, height
, bpp
;
36 unsigned int decomp_size
;
37 unsigned char* decomp_buf
;
40 static void copy_frame_default(AVFrame
*f
, const uint8_t *src
,
41 int linelen
, int height
) {
42 int i
, src_stride
= FFALIGN(linelen
, 4);
43 uint8_t *dst
= f
->data
[0];
44 dst
+= (height
- 1) * f
->linesize
[0];
45 for (i
= height
; i
; i
--) {
46 memcpy(dst
, src
, linelen
);
48 dst
-= f
->linesize
[0];
52 static void add_frame_default(AVFrame
*f
, const uint8_t *src
,
53 int linelen
, int height
) {
54 int i
, j
, src_stride
= FFALIGN(linelen
, 4);
55 uint8_t *dst
= f
->data
[0];
56 dst
+= (height
- 1) * f
->linesize
[0];
57 for (i
= height
; i
; i
--) {
58 for (j
= linelen
; j
; j
--)
60 src
+= src_stride
- linelen
;
61 dst
-= f
->linesize
[0] + linelen
;
65 static int decode_frame(AVCodecContext
*avctx
, void *data
, int *got_frame
,
67 const uint8_t *buf
= avpkt
->data
;
68 int buf_size
= avpkt
->size
;
69 CamStudioContext
*c
= avctx
->priv_data
;
73 av_log(avctx
, AV_LOG_ERROR
, "coded frame too small\n");
74 return AVERROR_INVALIDDATA
;
77 if ((ret
= ff_reget_buffer(avctx
, c
->pic
)) < 0)
81 switch ((buf
[0] >> 1) & 7) {
82 case 0: { // lzo compression
83 int outlen
= c
->decomp_size
, inlen
= buf_size
- 2;
84 if (av_lzo1x_decode(c
->decomp_buf
, &outlen
, &buf
[2], &inlen
))
85 av_log(avctx
, AV_LOG_ERROR
, "error during lzo decompression\n");
88 case 1: { // zlib compression
90 unsigned long dlen
= c
->decomp_size
;
91 if (uncompress(c
->decomp_buf
, &dlen
, &buf
[2], buf_size
- 2) != Z_OK
)
92 av_log(avctx
, AV_LOG_ERROR
, "error during zlib decompression\n");
95 av_log(avctx
, AV_LOG_ERROR
, "compiled without zlib support\n");
96 return AVERROR(ENOSYS
);
100 av_log(avctx
, AV_LOG_ERROR
, "unknown compression\n");
101 return AVERROR_INVALIDDATA
;
104 // flip upside down, add difference frame
105 if (buf
[0] & 1) { // keyframe
106 c
->pic
->pict_type
= AV_PICTURE_TYPE_I
;
107 c
->pic
->key_frame
= 1;
108 copy_frame_default(c
->pic
, c
->decomp_buf
,
109 c
->linelen
, c
->height
);
111 c
->pic
->pict_type
= AV_PICTURE_TYPE_P
;
112 c
->pic
->key_frame
= 0;
113 add_frame_default(c
->pic
, c
->decomp_buf
,
114 c
->linelen
, c
->height
);
118 if ((ret
= av_frame_ref(data
, c
->pic
)) < 0)
124 static av_cold
int decode_init(AVCodecContext
*avctx
) {
125 CamStudioContext
*c
= avctx
->priv_data
;
127 switch (avctx
->bits_per_coded_sample
) {
128 case 16: avctx
->pix_fmt
= AV_PIX_FMT_RGB555LE
; break;
129 case 24: avctx
->pix_fmt
= AV_PIX_FMT_BGR24
; break;
130 case 32: avctx
->pix_fmt
= AV_PIX_FMT_BGRA
; break;
132 av_log(avctx
, AV_LOG_ERROR
,
133 "CamStudio codec error: invalid depth %i bpp\n",
134 avctx
->bits_per_coded_sample
);
135 return AVERROR_INVALIDDATA
;
137 c
->bpp
= avctx
->bits_per_coded_sample
;
138 c
->linelen
= avctx
->width
* avctx
->bits_per_coded_sample
/ 8;
139 c
->height
= avctx
->height
;
140 stride
= FFALIGN(c
->linelen
, 4);
141 c
->decomp_size
= c
->height
* stride
;
142 c
->decomp_buf
= av_malloc(c
->decomp_size
+ AV_LZO_OUTPUT_PADDING
);
143 if (!c
->decomp_buf
) {
144 av_log(avctx
, AV_LOG_ERROR
, "Can't allocate decompression buffer.\n");
145 return AVERROR(ENOMEM
);
147 c
->pic
= av_frame_alloc();
149 return AVERROR(ENOMEM
);
153 static av_cold
int decode_end(AVCodecContext
*avctx
) {
154 CamStudioContext
*c
= avctx
->priv_data
;
155 av_freep(&c
->decomp_buf
);
156 av_frame_free(&c
->pic
);
160 AVCodec ff_cscd_decoder
= {
162 .long_name
= NULL_IF_CONFIG_SMALL("CamStudio"),
163 .type
= AVMEDIA_TYPE_VIDEO
,
164 .id
= AV_CODEC_ID_CSCD
,
165 .priv_data_size
= sizeof(CamStudioContext
),
168 .decode
= decode_frame
,
169 .capabilities
= CODEC_CAP_DR1
,