rtjpeg.c
Go to the documentation of this file.
1 /*
2  * RTJpeg decoding functions
3  * Copyright (c) 2006 Reimar Doeffinger
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 #include "libavutil/common.h"
22 #include "get_bits.h"
23 #include "rtjpeg.h"
24 
25 #define PUT_COEFF(c) \
26  i = scan[coeff--]; \
27  block[i] = (c) * quant[i];
28 
29 /// aligns the bitstream to the given power of two
30 #define ALIGN(a) \
31  n = (-get_bits_count(gb)) & (a - 1); \
32  if (n) {skip_bits(gb, n);}
33 
34 /**
35  * @brief read one block from stream
36  * @param gb contains stream data
37  * @param block where data is written to
38  * @param scan array containing the mapping stream address -> block position
39  * @param quant quantization factors
40  * @return 0 means the block is not coded, < 0 means an error occurred.
41  *
42  * Note: GetBitContext is used to make the code simpler, since all data is
43  * aligned this could be done faster in a different way, e.g. as it is done
44  * in MPlayer libmpcodecs/native/rtjpegn.c.
45  */
46 static inline int get_block(GetBitContext *gb, int16_t *block, const uint8_t *scan,
47  const uint32_t *quant) {
48  int coeff, i, n;
49  int8_t ac;
50  uint8_t dc = get_bits(gb, 8);
51 
52  // block not coded
53  if (dc == 255)
54  return 0;
55 
56  // number of non-zero coefficients
57  coeff = get_bits(gb, 6);
58  if (get_bits_left(gb) < (coeff << 1))
59  return -1;
60 
61  // normally we would only need to clear the (63 - coeff) last values,
62  // but since we do not know where they are we just clear the whole block
63  memset(block, 0, 64 * sizeof(int16_t));
64 
65  // 2 bits per coefficient
66  while (coeff) {
67  ac = get_sbits(gb, 2);
68  if (ac == -2)
69  break; // continue with more bits
70  PUT_COEFF(ac);
71  }
72 
73  // 4 bits per coefficient
74  ALIGN(4);
75  if (get_bits_left(gb) < (coeff << 2))
76  return -1;
77  while (coeff) {
78  ac = get_sbits(gb, 4);
79  if (ac == -8)
80  break; // continue with more bits
81  PUT_COEFF(ac);
82  }
83 
84  // 8 bits per coefficient
85  ALIGN(8);
86  if (get_bits_left(gb) < (coeff << 3))
87  return -1;
88  while (coeff) {
89  ac = get_sbits(gb, 8);
90  PUT_COEFF(ac);
91  }
92 
93  PUT_COEFF(dc);
94  return 1;
95 }
96 
97 /**
98  * @brief decode one rtjpeg YUV420 frame
99  * @param c context, must be initialized via ff_rtjpeg_decode_init
100  * @param f AVFrame to place decoded frame into. If parts of the frame
101  * are not coded they are left unchanged, so consider initializing it
102  * @param buf buffer containing input data
103  * @param buf_size length of input data in bytes
104  * @return number of bytes consumed from the input buffer
105  */
107  const uint8_t *buf, int buf_size) {
108  GetBitContext gb;
109  int w = c->w / 16, h = c->h / 16;
110  int x, y;
111  uint8_t *y1 = f->data[0], *y2 = f->data[0] + 8 * f->linesize[0];
112  uint8_t *u = f->data[1], *v = f->data[2];
113  init_get_bits(&gb, buf, buf_size * 8);
114  for (y = 0; y < h; y++) {
115  for (x = 0; x < w; x++) {
116 #define BLOCK(quant, dst, stride) do { \
117  int res = get_block(&gb, block, c->scan, quant); \
118  if (res < 0) \
119  return res; \
120  if (res > 0) \
121  c->dsp->idct_put(dst, stride, block); \
122 } while (0)
123  int16_t *block = c->block;
124  BLOCK(c->lquant, y1, f->linesize[0]);
125  y1 += 8;
126  BLOCK(c->lquant, y1, f->linesize[0]);
127  y1 += 8;
128  BLOCK(c->lquant, y2, f->linesize[0]);
129  y2 += 8;
130  BLOCK(c->lquant, y2, f->linesize[0]);
131  y2 += 8;
132  BLOCK(c->cquant, u, f->linesize[1]);
133  u += 8;
134  BLOCK(c->cquant, v, f->linesize[2]);
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  */
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 }
float v
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
static int get_block(GetBitContext *gb, int16_t *block, const uint8_t *scan, const uint32_t *quant)
read one block from stream
Definition: rtjpeg.c:46
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:240
DSPContext * dsp
Definition: rtjpeg.h:34
y1
Definition: lab5.m:33
Sinusoidal phase f
uint32_t cquant[64]
Definition: rtjpeg.h:37
static int get_sbits(GetBitContext *s, int n)
Definition: get_bits.h:225
output residual component w
uint8_t
#define BLOCK(quant, dst, stride)
int ff_rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, const uint8_t *buf, int buf_size)
decode one rtjpeg YUV420 frame
Definition: rtjpeg.c:106
void ff_rtjpeg_decode_init(RTJpegContext *c, DSPContext *dsp, int width, int height, const uint32_t *lquant, const uint32_t *cquant)
initialize an RTJpegContext, may be called multiple times
Definition: rtjpeg.c:156
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:193
bitstream reader API header.
uint8_t idct_permutation[64]
idct input permutation.
Definition: dsputil.h:249
end end ac
Discrete Time axis x
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:557
float u
y2
Definition: lab5.m:34
uint8_t scan[64]
Definition: rtjpeg.h:35
static int width
Definition: tests/utils.c:158
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
uint32_t lquant[64]
Definition: rtjpeg.h:36
FIXME Range Coding of cr are mx and my are Motion Vector top and top right vectors is used as motion vector prediction the used motion vector is the sum of the predictor and(mvx_diff, mvy_diff)*mv_scale Intra DC Predicton block[y][x] dc[1]
Definition: snow.txt:392
#define ALIGN(a)
aligns the bitstream to the given power of two
Definition: rtjpeg.c:30
void * buf
Definition: avisynth_c.h:594
BYTE int const BYTE int int int height
Definition: avisynth_c.h:713
synthesis window for stochastic i
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:379
static const double coeff[2][5]
Definition: vf_ow.c:64
const uint8_t * quant
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:115
common internal and external API header
static double c[64]
function y
Definition: D.m:1
#define PUT_COEFF(c)
Definition: rtjpeg.c:25
DSPContext.
Definition: dsputil.h:127