FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavcodec
tscc.c
Go to the documentation of this file.
1
/*
2
* TechSmith Camtasia decoder
3
* Copyright (c) 2004 Konstantin Shishkov
4
*
5
* This file is part of FFmpeg.
6
*
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.
11
*
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.
16
*
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
20
*/
21
22
/**
23
* @file
24
* TechSmith Camtasia decoder
25
*
26
* Fourcc: TSCC
27
*
28
* Codec is very simple:
29
* it codes picture (picture difference, really)
30
* with algorithm almost identical to Windows RLE8,
31
* only without padding and with greater pixel sizes,
32
* then this coded picture is packed with ZLib
33
*
34
* Supports: BGR8,BGR555,BGR24 - only BGR8 and BGR555 tested
35
*
36
*/
37
38
#include <stdio.h>
39
#include <stdlib.h>
40
41
#include "
avcodec.h
"
42
#include "
internal.h
"
43
#include "
msrledec.h
"
44
45
#include <zlib.h>
46
47
typedef
struct
TsccContext {
48
49
AVCodecContext
*
avctx
;
50
AVFrame
*
frame
;
51
52
// Bits per pixel
53
int
bpp
;
54
// Decompressed data size
55
unsigned
int
decomp_size
;
56
// Decompression buffer
57
unsigned
char
*
decomp_buf
;
58
GetByteContext
gb
;
59
int
height
;
60
z_stream
zstream
;
61
62
uint32_t pal[256];
63
}
CamtasiaContext
;
64
65
static
int
decode_frame
(
AVCodecContext
*avctx,
void
*
data
,
int
*got_frame,
66
AVPacket
*avpkt)
67
{
68
const
uint8_t
*
buf
= avpkt->
data
;
69
int
buf_size = avpkt->
size
;
70
CamtasiaContext
*
const
c
= avctx->
priv_data
;
71
const
unsigned
char
*encoded =
buf
;
72
AVFrame
*
frame
= c->
frame
;
73
int
zret;
// Zlib return code
74
int
ret
,
len
= buf_size;
75
76
if
((ret =
ff_reget_buffer
(avctx, frame)) < 0)
77
return
ret
;
78
79
zret = inflateReset(&c->
zstream
);
80
if
(zret != Z_OK) {
81
av_log
(avctx,
AV_LOG_ERROR
,
"Inflate reset error: %d\n"
, zret);
82
return
AVERROR_UNKNOWN
;
83
}
84
c->
zstream
.next_in = (
uint8_t
*)encoded;
85
c->
zstream
.avail_in =
len
;
86
c->
zstream
.next_out = c->
decomp_buf
;
87
c->
zstream
.avail_out = c->
decomp_size
;
88
zret = inflate(&c->
zstream
, Z_FINISH);
89
// Z_DATA_ERROR means empty picture
90
if
((zret != Z_OK) && (zret != Z_STREAM_END) && (zret != Z_DATA_ERROR)) {
91
av_log
(avctx,
AV_LOG_ERROR
,
"Inflate error: %d\n"
, zret);
92
return
AVERROR_UNKNOWN
;
93
}
94
95
96
if
(zret != Z_DATA_ERROR) {
97
bytestream2_init
(&c->
gb
, c->
decomp_buf
,
98
c->
decomp_size
- c->
zstream
.avail_out);
99
ff_msrle_decode
(avctx, (
AVPicture
*)frame, c->
bpp
, &c->
gb
);
100
}
101
102
/* make the palette available on the way out */
103
if
(c->
avctx
->
pix_fmt
==
AV_PIX_FMT_PAL8
) {
104
const
uint8_t
*pal =
av_packet_get_side_data
(avpkt,
AV_PKT_DATA_PALETTE
, NULL);
105
106
if
(pal) {
107
frame->
palette_has_changed
= 1;
108
memcpy(c->
pal
, pal,
AVPALETTE_SIZE
);
109
}
110
memcpy(frame->
data
[1], c->
pal
,
AVPALETTE_SIZE
);
111
}
112
113
if
((ret =
av_frame_ref
(data, frame)) < 0)
114
return
ret
;
115
*got_frame = 1;
116
117
/* always report that the buffer was completely consumed */
118
return
buf_size;
119
}
120
121
static
av_cold
int
decode_init
(
AVCodecContext
*avctx)
122
{
123
CamtasiaContext
*
const
c
= avctx->
priv_data
;
124
int
zret;
// Zlib return code
125
126
c->
avctx
= avctx;
127
128
c->
height
= avctx->
height
;
129
130
// Needed if zlib unused or init aborted before inflateInit
131
memset(&c->
zstream
, 0,
sizeof
(z_stream));
132
switch
(avctx->
bits_per_coded_sample
){
133
case
8: avctx->
pix_fmt
=
AV_PIX_FMT_PAL8
;
break
;
134
case
16: avctx->
pix_fmt
=
AV_PIX_FMT_RGB555
;
break
;
135
case
24:
136
avctx->
pix_fmt
=
AV_PIX_FMT_BGR24
;
137
break
;
138
case
32: avctx->
pix_fmt
=
AV_PIX_FMT_RGB32
;
break
;
139
default
:
av_log
(avctx,
AV_LOG_ERROR
,
"Camtasia error: unknown depth %i bpp\n"
, avctx->
bits_per_coded_sample
);
140
return
AVERROR_PATCHWELCOME
;
141
}
142
c->
bpp
= avctx->
bits_per_coded_sample
;
143
// buffer size for RLE 'best' case when 2-byte code precedes each pixel and there may be padding after it too
144
c->
decomp_size
= (((avctx->
width
* c->
bpp
+ 7) >> 3) + 3 * avctx->
width
+ 2) * avctx->
height
+ 2;
145
146
/* Allocate decompression buffer */
147
if
(c->
decomp_size
) {
148
if
((c->
decomp_buf
=
av_malloc
(c->
decomp_size
)) == NULL) {
149
av_log
(avctx,
AV_LOG_ERROR
,
"Can't allocate decompression buffer.\n"
);
150
return
AVERROR
(ENOMEM);
151
}
152
}
153
154
c->
zstream
.zalloc = Z_NULL;
155
c->
zstream
.zfree = Z_NULL;
156
c->
zstream
.opaque = Z_NULL;
157
zret = inflateInit(&c->
zstream
);
158
if
(zret != Z_OK) {
159
av_log
(avctx,
AV_LOG_ERROR
,
"Inflate init error: %d\n"
, zret);
160
return
AVERROR_UNKNOWN
;
161
}
162
163
c->
frame
=
av_frame_alloc
();
164
165
return
0;
166
}
167
168
static
av_cold
int
decode_end
(
AVCodecContext
*avctx)
169
{
170
CamtasiaContext
*
const
c
= avctx->
priv_data
;
171
172
av_freep
(&c->
decomp_buf
);
173
av_frame_free
(&c->
frame
);
174
175
inflateEnd(&c->
zstream
);
176
177
return
0;
178
}
179
180
AVCodec
ff_tscc_decoder
= {
181
.
name
=
"camtasia"
,
182
.long_name =
NULL_IF_CONFIG_SMALL
(
"TechSmith Screen Capture Codec"
),
183
.type =
AVMEDIA_TYPE_VIDEO
,
184
.id =
AV_CODEC_ID_TSCC
,
185
.priv_data_size =
sizeof
(
CamtasiaContext
),
186
.
init
=
decode_init
,
187
.
close
=
decode_end
,
188
.
decode
=
decode_frame
,
189
.capabilities =
CODEC_CAP_DR1
,
190
};
Generated on Sun Jul 20 2014 23:05:55 for FFmpeg by
1.8.2