ffmpeg / libavcodec / rtjpeg.c @ 2912e87a
History  View  Annotate  Download (5.91 KB)
1 
/*


2 
* RTJpeg decoding functions

3 
* Copyright (c) 2006 Reimar Doeffinger

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 021101301 USA

20 
*/

21 
#include "libavutil/common.h" 
22 
#include "get_bits.h" 
23 
#include "dsputil.h" 
24 
#include "rtjpeg.h" 
25  
26 
#define PUT_COEFF(c) \

27 
i = scan[coeff]; \ 
28 
block[i] = (c) * quant[i]; 
29  
30 
//! aligns the bitstream to the give power of two

31 
#define ALIGN(a) \

32 
n = (get_bits_count(gb)) & (a  1); \

33 
if (n) {skip_bits(gb, n);}

34  
35 
/**

36 
* \brief read one block from stream

37 
* \param gb contains stream data

38 
* \param block where data is written to

39 
* \param scan array containing the mapping stream address > block position

40 
* \param quant quantization factors

41 
* \return 0 means the block is not coded, < 0 means an error occurred.

42 
*

43 
* Note: GetBitContext is used to make the code simpler, since all data is

44 
* aligned this could be done faster in a different way, e.g. as it is done

45 
* in MPlayer libmpcodecs/native/rtjpegn.c.

46 
*/

47 
static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *scan, 
48 
const uint32_t *quant) {

49 
int coeff, i, n;

50 
int8_t ac; 
51 
uint8_t dc = get_bits(gb, 8);

52  
53 
// block not coded

54 
if (dc == 255) 
55 
return 0; 
56  
57 
// number of nonzero coefficients

58 
coeff = get_bits(gb, 6);

59 
if (get_bits_count(gb) + (coeff << 1) >= gb>size_in_bits) 
60 
return 1; 
61  
62 
// normally we would only need to clear the (63  coeff) last values,

63 
// but since we do not know where they are we just clear the whole block

64 
memset(block, 0, 64 * sizeof(DCTELEM)); 
65  
66 
// 2 bits per coefficient

67 
while (coeff) {

68 
ac = get_sbits(gb, 2);

69 
if (ac == 2) 
70 
break; // continue with more bits 
71 
PUT_COEFF(ac); 
72 
} 
73  
74 
// 4 bits per coefficient

75 
ALIGN(4);

76 
if (get_bits_count(gb) + (coeff << 2) >= gb>size_in_bits) 
77 
return 1; 
78 
while (coeff) {

79 
ac = get_sbits(gb, 4);

80 
if (ac == 8) 
81 
break; // continue with more bits 
82 
PUT_COEFF(ac); 
83 
} 
84  
85 
// 8 bits per coefficient

86 
ALIGN(8);

87 
if (get_bits_count(gb) + (coeff << 3) >= gb>size_in_bits) 
88 
return 1; 
89 
while (coeff) {

90 
ac = get_sbits(gb, 8);

91 
PUT_COEFF(ac); 
92 
} 
93  
94 
PUT_COEFF(dc); 
95 
return 1; 
96 
} 
97  
98 
/**

99 
* \brief decode one rtjpeg YUV420 frame

100 
* \param c context, must be initialized via rtjpeg_decode_init

101 
* \param f AVFrame to place decoded frame into. If parts of the frame

102 
* are not coded they are left unchanged, so consider initializing it

103 
* \param buf buffer containing input data

104 
* \param buf_size length of input data in bytes

105 
* \return number of bytes consumed from the input buffer

106 
*/

107 
int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f,

108 
const uint8_t *buf, int buf_size) { 
109 
GetBitContext gb; 
110 
int w = c>w / 16, h = c>h / 16; 
111 
int x, y;

112 
uint8_t *y1 = f>data[0], *y2 = f>data[0] + 8 * f>linesize[0]; 
113 
uint8_t *u = f>data[1], *v = f>data[2]; 
114 
init_get_bits(&gb, buf, buf_size * 8);

115 
for (y = 0; y < h; y++) { 
116 
for (x = 0; x < w; x++) { 
117 
DCTELEM *block = c>block; 
118 
if (get_block(&gb, block, c>scan, c>lquant) > 0) 
119 
c>dsp>idct_put(y1, f>linesize[0], block);

120 
y1 += 8;

121 
if (get_block(&gb, block, c>scan, c>lquant) > 0) 
122 
c>dsp>idct_put(y1, f>linesize[0], block);

123 
y1 += 8;

124 
if (get_block(&gb, block, c>scan, c>lquant) > 0) 
125 
c>dsp>idct_put(y2, f>linesize[0], block);

126 
y2 += 8;

127 
if (get_block(&gb, block, c>scan, c>lquant) > 0) 
128 
c>dsp>idct_put(y2, f>linesize[0], block);

129 
y2 += 8;

130 
if (get_block(&gb, block, c>scan, c>cquant) > 0) 
131 
c>dsp>idct_put(u, f>linesize[1], block);

132 
u += 8;

133 
if (get_block(&gb, block, c>scan, c>cquant) > 0) 
134 
c>dsp>idct_put(v, f>linesize[2], block);

135 
v += 8;

136 
} 
137 
y1 += 2 * 8 * (f>linesize[0]  w); 
138 
y2 += 2 * 8 * (f>linesize[0]  w); 
139 
u += 8 * (f>linesize[1]  w); 
140 
v += 8 * (f>linesize[2]  w); 
141 
} 
142 
return get_bits_count(&gb) / 8; 
143 
} 
144  
145 
/**

146 
* \brief initialize an RTJpegContext, may be called multiple times

147 
* \param c context to initialize

148 
* \param dsp specifies the idct to use for decoding

149 
* \param width width of image, will be rounded down to the nearest multiple

150 
* of 16 for decoding

151 
* \param height height of image, will be rounded down to the nearest multiple

152 
* of 16 for decoding

153 
* \param lquant luma quantization table to use

154 
* \param cquant chroma quantization table to use

155 
*/

156 
void rtjpeg_decode_init(RTJpegContext *c, DSPContext *dsp,

157 
int width, int height, 
158 
const uint32_t *lquant, const uint32_t *cquant) { 
159 
int i;

160 
c>dsp = dsp; 
161 
for (i = 0; i < 64; i++) { 
162 
int z = ff_zigzag_direct[i];

163 
int p = c>dsp>idct_permutation[i];

164 
z = ((z << 3)  (z >> 3)) & 63; // rtjpeg uses a transposed variant 
165  
166 
// permute the scan and quantization tables for the chosen idct

167 
c>scan[i] = c>dsp>idct_permutation[z]; 
168 
c>lquant[p] = lquant[i]; 
169 
c>cquant[p] = cquant[i]; 
170 
} 
171 
c>w = width; 
172 
c>h = height; 
173 
} 