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
AVFrame
*
frame
= c->
frame
;
72
int
ret
;
73
74
if
((ret =
ff_reget_buffer
(avctx, frame)) < 0)
75
return
ret
;
76
77
ret = inflateReset(&c->
zstream
);
78
if
(ret != Z_OK) {
79
av_log
(avctx,
AV_LOG_ERROR
,
"Inflate reset error: %d\n"
, ret);
80
return
AVERROR_UNKNOWN
;
81
}
82
c->
zstream
.next_in =
buf
;
83
c->
zstream
.avail_in = buf_size;
84
c->
zstream
.next_out = c->
decomp_buf
;
85
c->
zstream
.avail_out = c->
decomp_size
;
86
ret = inflate(&c->
zstream
, Z_FINISH);
87
// Z_DATA_ERROR means empty picture
88
if
((ret != Z_OK) && (ret != Z_STREAM_END) && (ret != Z_DATA_ERROR)) {
89
av_log
(avctx,
AV_LOG_ERROR
,
"Inflate error: %d\n"
, ret);
90
return
AVERROR_UNKNOWN
;
91
}
92
93
94
if
(ret != Z_DATA_ERROR) {
95
bytestream2_init
(&c->
gb
, c->
decomp_buf
,
96
c->
decomp_size
- c->
zstream
.avail_out);
97
ff_msrle_decode
(avctx, (
AVPicture
*)frame, c->
bpp
, &c->
gb
);
98
}
99
100
/* make the palette available on the way out */
101
if
(c->
avctx
->
pix_fmt
==
AV_PIX_FMT_PAL8
) {
102
const
uint8_t
*pal =
av_packet_get_side_data
(avpkt,
AV_PKT_DATA_PALETTE
, NULL);
103
104
if
(pal) {
105
frame->
palette_has_changed
= 1;
106
memcpy(c->
pal
, pal,
AVPALETTE_SIZE
);
107
}
108
memcpy(frame->
data
[1], c->
pal
,
AVPALETTE_SIZE
);
109
}
110
111
if
((ret =
av_frame_ref
(data, frame)) < 0)
112
return
ret
;
113
*got_frame = 1;
114
115
/* always report that the buffer was completely consumed */
116
return
buf_size;
117
}
118
119
static
av_cold
int
decode_init
(
AVCodecContext
*avctx)
120
{
121
CamtasiaContext
*
const
c
= avctx->
priv_data
;
122
int
zret;
// Zlib return code
123
124
c->
avctx
= avctx;
125
126
c->
height
= avctx->
height
;
127
128
// Needed if zlib unused or init aborted before inflateInit
129
memset(&c->
zstream
, 0,
sizeof
(z_stream));
130
switch
(avctx->
bits_per_coded_sample
){
131
case
8: avctx->
pix_fmt
=
AV_PIX_FMT_PAL8
;
break
;
132
case
16: avctx->
pix_fmt
=
AV_PIX_FMT_RGB555
;
break
;
133
case
24:
134
avctx->
pix_fmt
=
AV_PIX_FMT_BGR24
;
135
break
;
136
case
32: avctx->
pix_fmt
=
AV_PIX_FMT_RGB32
;
break
;
137
default
:
av_log
(avctx,
AV_LOG_ERROR
,
"Camtasia error: unknown depth %i bpp\n"
, avctx->
bits_per_coded_sample
);
138
return
AVERROR_PATCHWELCOME
;
139
}
140
c->
bpp
= avctx->
bits_per_coded_sample
;
141
// buffer size for RLE 'best' case when 2-byte code precedes each pixel and there may be padding after it too
142
c->
decomp_size
= (((avctx->
width
* c->
bpp
+ 7) >> 3) + 3 * avctx->
width
+ 2) * avctx->
height
+ 2;
143
144
/* Allocate decompression buffer */
145
if
(c->
decomp_size
) {
146
if
(!(c->
decomp_buf
=
av_malloc
(c->
decomp_size
))) {
147
av_log
(avctx,
AV_LOG_ERROR
,
"Can't allocate decompression buffer.\n"
);
148
return
AVERROR
(ENOMEM);
149
}
150
}
151
152
c->
zstream
.zalloc = Z_NULL;
153
c->
zstream
.zfree = Z_NULL;
154
c->
zstream
.opaque = Z_NULL;
155
zret = inflateInit(&c->
zstream
);
156
if
(zret != Z_OK) {
157
av_log
(avctx,
AV_LOG_ERROR
,
"Inflate init error: %d\n"
, zret);
158
return
AVERROR_UNKNOWN
;
159
}
160
161
c->
frame
=
av_frame_alloc
();
162
163
return
0;
164
}
165
166
static
av_cold
int
decode_end
(
AVCodecContext
*avctx)
167
{
168
CamtasiaContext
*
const
c
= avctx->
priv_data
;
169
170
av_freep
(&c->
decomp_buf
);
171
av_frame_free
(&c->
frame
);
172
173
inflateEnd(&c->
zstream
);
174
175
return
0;
176
}
177
178
AVCodec
ff_tscc_decoder
= {
179
.
name
=
"camtasia"
,
180
.long_name =
NULL_IF_CONFIG_SMALL
(
"TechSmith Screen Capture Codec"
),
181
.type =
AVMEDIA_TYPE_VIDEO
,
182
.id =
AV_CODEC_ID_TSCC
,
183
.priv_data_size =
sizeof
(
CamtasiaContext
),
184
.
init
=
decode_init
,
185
.
close
=
decode_end
,
186
.
decode
=
decode_frame
,
187
.capabilities =
CODEC_CAP_DR1
,
188
};
Generated on Sun Sep 14 2014 18:56:04 for FFmpeg by
1.8.2