• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/rtjpeg.c

Go to the documentation of this file.
00001 /*
00002  * RTJpeg decoding functions
00003  * Copyright (c) 2006 Reimar Doeffinger
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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     // block not coded
00053     if (dc == 255)
00054        return 0;
00055 
00056     // number of non-zero coefficients
00057     coeff = get_bits(gb, 6);
00058     // normally we would only need to clear the (63 - coeff) last values,
00059     // but since we do not know where they are we just clear the whole block
00060     memset(block, 0, 64 * sizeof(DCTELEM));
00061 
00062     // 2 bits per coefficient
00063     while (coeff) {
00064         ac = get_sbits(gb, 2);
00065         if (ac == -2)
00066             break; // continue with more bits
00067         PUT_COEFF(ac);
00068     }
00069 
00070     // 4 bits per coefficient
00071     ALIGN(4);
00072     while (coeff) {
00073         ac = get_sbits(gb, 4);
00074         if (ac == -8)
00075             break; // continue with more bits
00076         PUT_COEFF(ac);
00077     }
00078 
00079     // 8 bits per coefficient
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; // rtjpeg uses a transposed variant
00157 
00158         // permute the scan and quantization tables for the chosen idct
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 }

Generated on Tue Nov 4 2014 12:59:22 for ffmpeg by  doxygen 1.7.1