LCOV - code coverage report
Current view: top level - libavcodec - rtjpeg.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 66 70 94.3 %
Date: 2017-12-18 20:14:19 Functions: 4 4 100.0 %

          Line data    Source code
       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      223200 : 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      223200 :     uint8_t dc = get_bits(gb, 8);
      51             : 
      52             :     // block not coded
      53      223200 :     if (dc == 255)
      54      102402 :        return 0;
      55             : 
      56             :     // number of non-zero coefficients
      57      120798 :     coeff = get_bits(gb, 6);
      58      120798 :     if (get_bits_left(gb) < (coeff << 1))
      59           0 :         return AVERROR_INVALIDDATA;
      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      120798 :     memset(block, 0, 64 * sizeof(int16_t));
      64             : 
      65             :     // 2 bits per coefficient
      66      876202 :     while (coeff) {
      67      691920 :         ac = get_sbits(gb, 2);
      68      691920 :         if (ac == -2)
      69       57314 :             break; // continue with more bits
      70      634606 :         PUT_COEFF(ac);
      71             :     }
      72             : 
      73             :     // 4 bits per coefficient
      74      120798 :     ALIGN(4);
      75      120798 :     if (get_bits_left(gb) < (coeff << 2))
      76           0 :         return AVERROR_INVALIDDATA;
      77      666260 :     while (coeff) {
      78      451590 :         ac = get_sbits(gb, 4);
      79      451590 :         if (ac == -8)
      80       26926 :             break; // continue with more bits
      81      424664 :         PUT_COEFF(ac);
      82             :     }
      83             : 
      84             :     // 8 bits per coefficient
      85      120798 :     ALIGN(8);
      86      120798 :     if (get_bits_left(gb) < (coeff << 3))
      87           0 :         return AVERROR_INVALIDDATA;
      88      395155 :     while (coeff) {
      89      153559 :         ac = get_sbits(gb, 8);
      90      153559 :         PUT_COEFF(ac);
      91             :     }
      92             : 
      93      120798 :     PUT_COEFF(dc);
      94      120798 :     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             :  */
     106          57 : int ff_rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f,
     107             :                                   const uint8_t *buf, int buf_size) {
     108             :     GetBitContext gb;
     109          57 :     int w = c->w / 16, h = c->h / 16;
     110             :     int x, y, ret;
     111          57 :     uint8_t *y1 = f->data[0], *y2 = f->data[0] + 8 * f->linesize[0];
     112          57 :     uint8_t *u = f->data[1], *v = f->data[2];
     113             : 
     114          57 :     if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0)
     115           0 :         return ret;
     116             : 
     117        1167 :     for (y = 0; y < h; y++) {
     118       38310 :         for (x = 0; x < w; x++) {
     119             : #define BLOCK(quant, dst, stride) do { \
     120             :     int res = get_block(&gb, block, c->scan, quant); \
     121             :     if (res < 0) \
     122             :         return res; \
     123             :     if (res > 0) \
     124             :         c->idsp.idct_put(dst, stride, block); \
     125             : } while (0)
     126       37200 :             int16_t *block = c->block;
     127       37200 :             BLOCK(c->lquant, y1, f->linesize[0]);
     128       37200 :             y1 += 8;
     129       37200 :             BLOCK(c->lquant, y1, f->linesize[0]);
     130       37200 :             y1 += 8;
     131       37200 :             BLOCK(c->lquant, y2, f->linesize[0]);
     132       37200 :             y2 += 8;
     133       37200 :             BLOCK(c->lquant, y2, f->linesize[0]);
     134       37200 :             y2 += 8;
     135       37200 :             BLOCK(c->cquant, u,  f->linesize[1]);
     136       37200 :             u += 8;
     137       37200 :             BLOCK(c->cquant, v,  f->linesize[2]);
     138       37200 :             v += 8;
     139             :         }
     140        1110 :         y1 += 2 * 8 * (f->linesize[0] - w);
     141        1110 :         y2 += 2 * 8 * (f->linesize[0] - w);
     142        1110 :         u += 8 * (f->linesize[1] - w);
     143        1110 :         v += 8 * (f->linesize[2] - w);
     144             :     }
     145          57 :     return get_bits_count(&gb) / 8;
     146             : }
     147             : 
     148             : /**
     149             :  * @brief initialize an RTJpegContext, may be called multiple times
     150             :  * @param c context to initialize
     151             :  * @param width width of image, will be rounded down to the nearest multiple
     152             :  *              of 16 for decoding
     153             :  * @param height height of image, will be rounded down to the nearest multiple
     154             :  *              of 16 for decoding
     155             :  * @param lquant luma quantization table to use
     156             :  * @param cquant chroma quantization table to use
     157             :  */
     158          54 : void ff_rtjpeg_decode_init(RTJpegContext *c, int width, int height,
     159             :                            const uint32_t *lquant, const uint32_t *cquant) {
     160             :     int i;
     161        3510 :     for (i = 0; i < 64; i++) {
     162        3456 :         int p = c->idsp.idct_permutation[i];
     163        3456 :         c->lquant[p] = lquant[i];
     164        3456 :         c->cquant[p] = cquant[i];
     165             :     }
     166          54 :     c->w = width;
     167          54 :     c->h = height;
     168          54 : }
     169             : 
     170           4 : void ff_rtjpeg_init(RTJpegContext *c, AVCodecContext *avctx)
     171             : {
     172             :     int i;
     173             : 
     174           4 :     ff_idctdsp_init(&c->idsp, avctx);
     175             : 
     176         260 :     for (i = 0; i < 64; i++) {
     177         256 :         int z = ff_zigzag_direct[i];
     178         256 :         z = ((z << 3) | (z >> 3)) & 63; // rtjpeg uses a transposed variant
     179             : 
     180             :         // permute the scan and quantization tables for the chosen idct
     181         256 :         c->scan[i] = c->idsp.idct_permutation[z];
     182             :     }
     183           4 : }

Generated by: LCOV version 1.13