Libav
|
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 "get_bits.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 00047 static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *scan, 00048 const uint32_t *quant) { 00049 int coeff, i, n; 00050 int8_t ac; 00051 uint8_t dc = get_bits(gb, 8); 00052 00053 // block not coded 00054 if (dc == 255) 00055 return 0; 00056 00057 // number of non-zero coefficients 00058 coeff = get_bits(gb, 6); 00059 if (get_bits_count(gb) + (coeff << 1) >= gb->size_in_bits) 00060 return -1; 00061 00062 // normally we would only need to clear the (63 - coeff) last values, 00063 // but since we do not know where they are we just clear the whole block 00064 memset(block, 0, 64 * sizeof(DCTELEM)); 00065 00066 // 2 bits per coefficient 00067 while (coeff) { 00068 ac = get_sbits(gb, 2); 00069 if (ac == -2) 00070 break; // continue with more bits 00071 PUT_COEFF(ac); 00072 } 00073 00074 // 4 bits per coefficient 00075 ALIGN(4); 00076 if (get_bits_count(gb) + (coeff << 2) >= gb->size_in_bits) 00077 return -1; 00078 while (coeff) { 00079 ac = get_sbits(gb, 4); 00080 if (ac == -8) 00081 break; // continue with more bits 00082 PUT_COEFF(ac); 00083 } 00084 00085 // 8 bits per coefficient 00086 ALIGN(8); 00087 if (get_bits_count(gb) + (coeff << 3) >= gb->size_in_bits) 00088 return -1; 00089 while (coeff) { 00090 ac = get_sbits(gb, 8); 00091 PUT_COEFF(ac); 00092 } 00093 00094 PUT_COEFF(dc); 00095 return 1; 00096 } 00097 00107 int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, 00108 const uint8_t *buf, int buf_size) { 00109 GetBitContext gb; 00110 int w = c->w / 16, h = c->h / 16; 00111 int x, y; 00112 uint8_t *y1 = f->data[0], *y2 = f->data[0] + 8 * f->linesize[0]; 00113 uint8_t *u = f->data[1], *v = f->data[2]; 00114 init_get_bits(&gb, buf, buf_size * 8); 00115 for (y = 0; y < h; y++) { 00116 for (x = 0; x < w; x++) { 00117 DCTELEM *block = c->block; 00118 if (get_block(&gb, block, c->scan, c->lquant) > 0) 00119 c->dsp->idct_put(y1, f->linesize[0], block); 00120 y1 += 8; 00121 if (get_block(&gb, block, c->scan, c->lquant) > 0) 00122 c->dsp->idct_put(y1, f->linesize[0], block); 00123 y1 += 8; 00124 if (get_block(&gb, block, c->scan, c->lquant) > 0) 00125 c->dsp->idct_put(y2, f->linesize[0], block); 00126 y2 += 8; 00127 if (get_block(&gb, block, c->scan, c->lquant) > 0) 00128 c->dsp->idct_put(y2, f->linesize[0], block); 00129 y2 += 8; 00130 if (get_block(&gb, block, c->scan, c->cquant) > 0) 00131 c->dsp->idct_put(u, f->linesize[1], block); 00132 u += 8; 00133 if (get_block(&gb, block, c->scan, c->cquant) > 0) 00134 c->dsp->idct_put(v, f->linesize[2], block); 00135 v += 8; 00136 } 00137 y1 += 2 * 8 * (f->linesize[0] - w); 00138 y2 += 2 * 8 * (f->linesize[0] - w); 00139 u += 8 * (f->linesize[1] - w); 00140 v += 8 * (f->linesize[2] - w); 00141 } 00142 return get_bits_count(&gb) / 8; 00143 } 00144 00156 void rtjpeg_decode_init(RTJpegContext *c, DSPContext *dsp, 00157 int width, int height, 00158 const uint32_t *lquant, const uint32_t *cquant) { 00159 int i; 00160 c->dsp = dsp; 00161 for (i = 0; i < 64; i++) { 00162 int z = ff_zigzag_direct[i]; 00163 int p = c->dsp->idct_permutation[i]; 00164 z = ((z << 3) | (z >> 3)) & 63; // rtjpeg uses a transposed variant 00165 00166 // permute the scan and quantization tables for the chosen idct 00167 c->scan[i] = c->dsp->idct_permutation[z]; 00168 c->lquant[p] = lquant[i]; 00169 c->cquant[p] = cquant[i]; 00170 } 00171 c->w = width; 00172 c->h = height; 00173 }