00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "libavutil/common.h"
00022 #include "bitstream.h"
00023 #include "dsputil.h"
00024 #include "rtjpeg.h"
00025
00026 #define PUT_COEFF(c) \
00027 i = scan[coeff--]; \
00028 block[i] = (c) * quant[i];
00029
00031 #define ALIGN(a) \
00032 n = (-get_bits_count(gb)) & (a - 1); \
00033 if (n) {skip_bits(gb, n);}
00034
00046 static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *scan,
00047 const uint32_t *quant) {
00048 int coeff, i, n;
00049 int8_t ac;
00050 uint8_t dc = get_bits(gb, 8);
00051
00052
00053 if (dc == 255)
00054 return 0;
00055
00056
00057 coeff = get_bits(gb, 6);
00058
00059
00060 memset(block, 0, 64 * sizeof(DCTELEM));
00061
00062
00063 while (coeff) {
00064 ac = get_sbits(gb, 2);
00065 if (ac == -2)
00066 break;
00067 PUT_COEFF(ac);
00068 }
00069
00070
00071 ALIGN(4);
00072 while (coeff) {
00073 ac = get_sbits(gb, 4);
00074 if (ac == -8)
00075 break;
00076 PUT_COEFF(ac);
00077 }
00078
00079
00080 ALIGN(8);
00081 while (coeff) {
00082 ac = get_sbits(gb, 8);
00083 PUT_COEFF(ac);
00084 }
00085
00086 PUT_COEFF(dc);
00087 return 1;
00088 }
00089
00099 int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f,
00100 const uint8_t *buf, int buf_size) {
00101 DECLARE_ALIGNED_16(DCTELEM, block[64]);
00102 GetBitContext gb;
00103 int w = c->w / 16, h = c->h / 16;
00104 int x, y;
00105 uint8_t *y1 = f->data[0], *y2 = f->data[0] + 8 * f->linesize[0];
00106 uint8_t *u = f->data[1], *v = f->data[2];
00107 init_get_bits(&gb, buf, buf_size * 8);
00108 for (y = 0; y < h; y++) {
00109 for (x = 0; x < w; x++) {
00110 if (get_block(&gb, block, c->scan, c->lquant))
00111 c->dsp->idct_put(y1, f->linesize[0], block);
00112 y1 += 8;
00113 if (get_block(&gb, block, c->scan, c->lquant))
00114 c->dsp->idct_put(y1, f->linesize[0], block);
00115 y1 += 8;
00116 if (get_block(&gb, block, c->scan, c->lquant))
00117 c->dsp->idct_put(y2, f->linesize[0], block);
00118 y2 += 8;
00119 if (get_block(&gb, block, c->scan, c->lquant))
00120 c->dsp->idct_put(y2, f->linesize[0], block);
00121 y2 += 8;
00122 if (get_block(&gb, block, c->scan, c->cquant))
00123 c->dsp->idct_put(u, f->linesize[1], block);
00124 u += 8;
00125 if (get_block(&gb, block, c->scan, c->cquant))
00126 c->dsp->idct_put(v, f->linesize[2], block);
00127 v += 8;
00128 }
00129 y1 += 2 * 8 * (f->linesize[0] - w);
00130 y2 += 2 * 8 * (f->linesize[0] - w);
00131 u += 8 * (f->linesize[1] - w);
00132 v += 8 * (f->linesize[2] - w);
00133 }
00134 return get_bits_count(&gb) / 8;
00135 }
00136
00148 void rtjpeg_decode_init(RTJpegContext *c, DSPContext *dsp,
00149 int width, int height,
00150 const uint32_t *lquant, const uint32_t *cquant) {
00151 int i;
00152 c->dsp = dsp;
00153 for (i = 0; i < 64; i++) {
00154 int z = ff_zigzag_direct[i];
00155 int p = c->dsp->idct_permutation[i];
00156 z = ((z << 3) | (z >> 3)) & 63;
00157
00158
00159 c->scan[i] = c->dsp->idct_permutation[z];
00160 c->lquant[p] = lquant[i];
00161 c->cquant[p] = cquant[i];
00162 }
00163 c->w = width;
00164 c->h = height;
00165 }