Libav
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
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 Libav.
6
*
7
* Libav 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
* Libav 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 Libav; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
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
51
// Bits per pixel
52
int
bpp
;
53
// Decompressed data size
54
unsigned
int
decomp_size
;
55
// Decompression buffer
56
unsigned
char
*
decomp_buf
;
57
GetByteContext
gb
;
58
int
height
;
59
z_stream
zstream
;
60
61
uint32_t pal[256];
62
}
CamtasiaContext
;
63
64
static
int
decode_frame
(
AVCodecContext
*avctx,
void
*
data
,
int
*got_frame,
65
AVPacket
*avpkt)
66
{
67
const
uint8_t
*buf = avpkt->
data
;
68
int
buf_size = avpkt->
size
;
69
CamtasiaContext
*
const
c = avctx->
priv_data
;
70
const
unsigned
char
*encoded = buf;
71
AVFrame
*frame =
data
;
72
int
zret;
// Zlib return code
73
int
ret,
len
= buf_size;
74
75
if
((ret =
ff_get_buffer
(avctx, frame, 0)) < 0){
76
av_log
(avctx,
AV_LOG_ERROR
,
"get_buffer() failed\n"
);
77
return
ret;
78
}
79
80
zret = inflateReset(&c->
zstream
);
81
if
(zret != Z_OK) {
82
av_log
(avctx,
AV_LOG_ERROR
,
"Inflate reset error: %d\n"
, zret);
83
return
AVERROR_UNKNOWN
;
84
}
85
c->
zstream
.next_in = encoded;
86
c->
zstream
.avail_in =
len
;
87
c->
zstream
.next_out = c->
decomp_buf
;
88
c->
zstream
.avail_out = c->
decomp_size
;
89
zret = inflate(&c->
zstream
, Z_FINISH);
90
// Z_DATA_ERROR means empty picture
91
if
((zret != Z_OK) && (zret != Z_STREAM_END) && (zret != Z_DATA_ERROR)) {
92
av_log
(avctx,
AV_LOG_ERROR
,
"Inflate error: %d\n"
, zret);
93
return
AVERROR_UNKNOWN
;
94
}
95
96
97
if
(zret != Z_DATA_ERROR) {
98
bytestream2_init
(&c->
gb
, c->
decomp_buf
,
99
c->
decomp_size
- c->
zstream
.avail_out);
100
ff_msrle_decode
(avctx, (
AVPicture
*)frame, c->
bpp
, &c->
gb
);
101
}
102
103
/* make the palette available on the way out */
104
if
(c->
avctx
->
pix_fmt
==
AV_PIX_FMT_PAL8
) {
105
const
uint8_t
*pal =
av_packet_get_side_data
(avpkt,
AV_PKT_DATA_PALETTE
,
NULL
);
106
107
if
(pal) {
108
frame->
palette_has_changed
= 1;
109
memcpy(c->
pal
, pal,
AVPALETTE_SIZE
);
110
}
111
memcpy(frame->
data
[1], c->
pal
,
AVPALETTE_SIZE
);
112
}
113
114
*got_frame = 1;
115
116
/* always report that the buffer was completely consumed */
117
return
buf_size;
118
}
119
120
static
av_cold
int
decode_init
(
AVCodecContext
*avctx)
121
{
122
CamtasiaContext
*
const
c = avctx->
priv_data
;
123
int
zret;
// Zlib return code
124
125
c->
avctx
= avctx;
126
127
c->
height
= avctx->
height
;
128
129
// Needed if zlib unused or init aborted before inflateInit
130
memset(&c->
zstream
, 0,
sizeof
(z_stream));
131
switch
(avctx->
bits_per_coded_sample
){
132
case
8: avctx->
pix_fmt
=
AV_PIX_FMT_PAL8
;
break
;
133
case
16: avctx->
pix_fmt
=
AV_PIX_FMT_RGB555
;
break
;
134
case
24:
135
avctx->
pix_fmt
=
AV_PIX_FMT_BGR24
;
136
break
;
137
case
32: avctx->
pix_fmt
=
AV_PIX_FMT_RGB32
;
break
;
138
default
:
av_log
(avctx,
AV_LOG_ERROR
,
"Camtasia error: unknown depth %i bpp\n"
, avctx->
bits_per_coded_sample
);
139
return
AVERROR_INVALIDDATA
;
140
}
141
c->
bpp
= avctx->
bits_per_coded_sample
;
142
// buffer size for RLE 'best' case when 2-byte code precedes each pixel and there may be padding after it too
143
c->
decomp_size
= (((avctx->
width
* c->
bpp
+ 7) >> 3) + 3 * avctx->
width
+ 2) * avctx->
height
+ 2;
144
145
/* Allocate decompression buffer */
146
if
(c->
decomp_size
) {
147
if
((c->
decomp_buf
=
av_malloc
(c->
decomp_size
)) ==
NULL
) {
148
av_log
(avctx,
AV_LOG_ERROR
,
"Can't allocate decompression buffer.\n"
);
149
return
AVERROR
(ENOMEM);
150
}
151
}
152
153
c->
zstream
.zalloc = Z_NULL;
154
c->
zstream
.zfree = Z_NULL;
155
c->
zstream
.opaque = Z_NULL;
156
zret = inflateInit(&c->
zstream
);
157
if
(zret != Z_OK) {
158
av_log
(avctx,
AV_LOG_ERROR
,
"Inflate init error: %d\n"
, zret);
159
return
AVERROR_UNKNOWN
;
160
}
161
162
return
0;
163
}
164
165
static
av_cold
int
decode_end
(
AVCodecContext
*avctx)
166
{
167
CamtasiaContext
*
const
c = avctx->
priv_data
;
168
169
av_freep
(&c->
decomp_buf
);
170
171
inflateEnd(&c->
zstream
);
172
173
return
0;
174
}
175
176
AVCodec
ff_tscc_decoder
= {
177
.
name
=
"camtasia"
,
178
.long_name =
NULL_IF_CONFIG_SMALL
(
"TechSmith Screen Capture Codec"
),
179
.type =
AVMEDIA_TYPE_VIDEO
,
180
.id =
AV_CODEC_ID_TSCC
,
181
.priv_data_size =
sizeof
(
CamtasiaContext
),
182
.
init
=
decode_init
,
183
.
close
=
decode_end
,
184
.
decode
=
decode_frame
,
185
.capabilities =
CODEC_CAP_DR1
,
186
};
Generated on Thu Sep 30 2021 23:03:16 for Libav by
1.8.1.2