Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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 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.     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 AVERROR_INVALIDDATA;
  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 AVERROR_INVALIDDATA;
  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.  */
  106. int ff_rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f,
  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, ret;
  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.  
  114.     if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0)
  115.         return ret;
  116.  
  117.     for (y = 0; y < h; y++) {
  118.         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->dsp->idct_put(dst, stride, block); \
  125. } while (0)
  126.             int16_t *block = c->block;
  127.             BLOCK(c->lquant, y1, f->linesize[0]);
  128.             y1 += 8;
  129.             BLOCK(c->lquant, y1, f->linesize[0]);
  130.             y1 += 8;
  131.             BLOCK(c->lquant, y2, f->linesize[0]);
  132.             y2 += 8;
  133.             BLOCK(c->lquant, y2, f->linesize[0]);
  134.             y2 += 8;
  135.             BLOCK(c->cquant, u,  f->linesize[1]);
  136.             u += 8;
  137.             BLOCK(c->cquant, v,  f->linesize[2]);
  138.             v += 8;
  139.         }
  140.         y1 += 2 * 8 * (f->linesize[0] - w);
  141.         y2 += 2 * 8 * (f->linesize[0] - w);
  142.         u += 8 * (f->linesize[1] - w);
  143.         v += 8 * (f->linesize[2] - w);
  144.     }
  145.     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 dsp specifies the idct to use for decoding
  152.  * @param width width of image, will be rounded down to the nearest multiple
  153.  *              of 16 for decoding
  154.  * @param height height of image, will be rounded down to the nearest multiple
  155.  *              of 16 for decoding
  156.  * @param lquant luma quantization table to use
  157.  * @param cquant chroma quantization table to use
  158.  */
  159. void ff_rtjpeg_decode_init(RTJpegContext *c, DSPContext *dsp,
  160.                            int width, int height,
  161.                            const uint32_t *lquant, const uint32_t *cquant) {
  162.     int i;
  163.     c->dsp = dsp;
  164.     for (i = 0; i < 64; i++) {
  165.         int z = ff_zigzag_direct[i];
  166.         int p = c->dsp->idct_permutation[i];
  167.         z = ((z << 3) | (z >> 3)) & 63; // rtjpeg uses a transposed variant
  168.  
  169.         // permute the scan and quantization tables for the chosen idct
  170.         c->scan[i] = c->dsp->idct_permutation[z];
  171.         c->lquant[p] = lquant[i];
  172.         c->cquant[p] = cquant[i];
  173.     }
  174.     c->w = width;
  175.     c->h = height;
  176. }
  177.