Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Indeo Video v3 compatible decoder
  3.  * Copyright (c) 2009 - 2011 Maxim Poliakovski
  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.  
  22. /**
  23.  * @file
  24.  * This is a decoder for Intel Indeo Video v3.
  25.  * It is based on vector quantization, run-length coding and motion compensation.
  26.  * Known container formats: .avi and .mov
  27.  * Known FOURCCs: 'IV31', 'IV32'
  28.  *
  29.  * @see http://wiki.multimedia.cx/index.php?title=Indeo_3
  30.  */
  31.  
  32. #include "libavutil/imgutils.h"
  33. #include "libavutil/intreadwrite.h"
  34. #include "avcodec.h"
  35. #include "copy_block.h"
  36. #include "bytestream.h"
  37. #include "get_bits.h"
  38. #include "hpeldsp.h"
  39. #include "internal.h"
  40.  
  41. #include "indeo3data.h"
  42.  
  43. /* RLE opcodes. */
  44. enum {
  45.     RLE_ESC_F9    = 249, ///< same as RLE_ESC_FA + do the same with next block
  46.     RLE_ESC_FA    = 250, ///< INTRA: skip block, INTER: copy data from reference
  47.     RLE_ESC_FB    = 251, ///< apply null delta to N blocks / skip N blocks
  48.     RLE_ESC_FC    = 252, ///< same as RLE_ESC_FD + do the same with next block
  49.     RLE_ESC_FD    = 253, ///< apply null delta to all remaining lines of this block
  50.     RLE_ESC_FE    = 254, ///< apply null delta to all lines up to the 3rd line
  51.     RLE_ESC_FF    = 255  ///< apply null delta to all lines up to the 2nd line
  52. };
  53.  
  54.  
  55. /* Some constants for parsing frame bitstream flags. */
  56. #define BS_8BIT_PEL     (1 << 1) ///< 8bit pixel bitdepth indicator
  57. #define BS_KEYFRAME     (1 << 2) ///< intra frame indicator
  58. #define BS_MV_Y_HALF    (1 << 4) ///< vertical mv halfpel resolution indicator
  59. #define BS_MV_X_HALF    (1 << 5) ///< horizontal mv halfpel resolution indicator
  60. #define BS_NONREF       (1 << 8) ///< nonref (discardable) frame indicator
  61. #define BS_BUFFER        9       ///< indicates which of two frame buffers should be used
  62.  
  63.  
  64. typedef struct Plane {
  65.     uint8_t         *buffers[2];
  66.     uint8_t         *pixels[2]; ///< pointer to the actual pixel data of the buffers above
  67.     uint32_t        width;
  68.     uint32_t        height;
  69.     uint32_t        pitch;
  70. } Plane;
  71.  
  72. #define CELL_STACK_MAX  20
  73.  
  74. typedef struct Cell {
  75.     int16_t         xpos;       ///< cell coordinates in 4x4 blocks
  76.     int16_t         ypos;
  77.     int16_t         width;      ///< cell width  in 4x4 blocks
  78.     int16_t         height;     ///< cell height in 4x4 blocks
  79.     uint8_t         tree;       ///< tree id: 0- MC tree, 1 - VQ tree
  80.     const int8_t    *mv_ptr;    ///< ptr to the motion vector if any
  81. } Cell;
  82.  
  83. typedef struct Indeo3DecodeContext {
  84.     AVCodecContext *avctx;
  85.     HpelDSPContext  hdsp;
  86.  
  87.     GetBitContext   gb;
  88.     int             need_resync;
  89.     int             skip_bits;
  90.     const uint8_t   *next_cell_data;
  91.     const uint8_t   *last_byte;
  92.     const int8_t    *mc_vectors;
  93.     unsigned        num_vectors;    ///< number of motion vectors in mc_vectors
  94.  
  95.     int16_t         width, height;
  96.     uint32_t        frame_num;      ///< current frame number (zero-based)
  97.     uint32_t        data_size;      ///< size of the frame data in bytes
  98.     uint16_t        frame_flags;    ///< frame properties
  99.     uint8_t         cb_offset;      ///< needed for selecting VQ tables
  100.     uint8_t         buf_sel;        ///< active frame buffer: 0 - primary, 1 -secondary
  101.     const uint8_t   *y_data_ptr;
  102.     const uint8_t   *v_data_ptr;
  103.     const uint8_t   *u_data_ptr;
  104.     int32_t         y_data_size;
  105.     int32_t         v_data_size;
  106.     int32_t         u_data_size;
  107.     const uint8_t   *alt_quant;     ///< secondary VQ table set for the modes 1 and 4
  108.     Plane           planes[3];
  109. } Indeo3DecodeContext;
  110.  
  111.  
  112. static uint8_t requant_tab[8][128];
  113.  
  114. /*
  115.  *  Build the static requantization table.
  116.  *  This table is used to remap pixel values according to a specific
  117.  *  quant index and thus avoid overflows while adding deltas.
  118.  */
  119. static av_cold void build_requant_tab(void)
  120. {
  121.     static int8_t offsets[8] = { 1, 1, 2, -3, -3, 3, 4, 4 };
  122.     static int8_t deltas [8] = { 0, 1, 0,  4,  4, 1, 0, 1 };
  123.  
  124.     int i, j, step;
  125.  
  126.     for (i = 0; i < 8; i++) {
  127.         step = i + 2;
  128.         for (j = 0; j < 128; j++)
  129.                 requant_tab[i][j] = (j + offsets[i]) / step * step + deltas[i];
  130.     }
  131.  
  132.     /* some last elements calculated above will have values >= 128 */
  133.     /* pixel values shall never exceed 127 so set them to non-overflowing values */
  134.     /* according with the quantization step of the respective section */
  135.     requant_tab[0][127] = 126;
  136.     requant_tab[1][119] = 118;
  137.     requant_tab[1][120] = 118;
  138.     requant_tab[2][126] = 124;
  139.     requant_tab[2][127] = 124;
  140.     requant_tab[6][124] = 120;
  141.     requant_tab[6][125] = 120;
  142.     requant_tab[6][126] = 120;
  143.     requant_tab[6][127] = 120;
  144.  
  145.     /* Patch for compatibility with the Intel's binary decoders */
  146.     requant_tab[1][7] = 10;
  147.     requant_tab[4][8] = 10;
  148. }
  149.  
  150.  
  151. static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx)
  152. {
  153.     int p;
  154.  
  155.     ctx->width = ctx->height = 0;
  156.  
  157.     for (p = 0; p < 3; p++) {
  158.         av_freep(&ctx->planes[p].buffers[0]);
  159.         av_freep(&ctx->planes[p].buffers[1]);
  160.         ctx->planes[p].pixels[0] = ctx->planes[p].pixels[1] = 0;
  161.     }
  162. }
  163.  
  164.  
  165. static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx,
  166.                                           AVCodecContext *avctx, int luma_width, int luma_height)
  167. {
  168.     int p, chroma_width, chroma_height;
  169.     int luma_pitch, chroma_pitch, luma_size, chroma_size;
  170.  
  171.     if (luma_width  < 16 || luma_width  > 640 ||
  172.         luma_height < 16 || luma_height > 480 ||
  173.         luma_width  &  3 || luma_height &   3) {
  174.         av_log(avctx, AV_LOG_ERROR, "Invalid picture dimensions: %d x %d!\n",
  175.                luma_width, luma_height);
  176.         return AVERROR_INVALIDDATA;
  177.     }
  178.  
  179.     ctx->width  = luma_width ;
  180.     ctx->height = luma_height;
  181.  
  182.     chroma_width  = FFALIGN(luma_width  >> 2, 4);
  183.     chroma_height = FFALIGN(luma_height >> 2, 4);
  184.  
  185.     luma_pitch   = FFALIGN(luma_width,   16);
  186.     chroma_pitch = FFALIGN(chroma_width, 16);
  187.  
  188.     /* Calculate size of the luminance plane.  */
  189.     /* Add one line more for INTRA prediction. */
  190.     luma_size = luma_pitch * (luma_height + 1);
  191.  
  192.     /* Calculate size of a chrominance planes. */
  193.     /* Add one line more for INTRA prediction. */
  194.     chroma_size = chroma_pitch * (chroma_height + 1);
  195.  
  196.     /* allocate frame buffers */
  197.     for (p = 0; p < 3; p++) {
  198.         ctx->planes[p].pitch  = !p ? luma_pitch  : chroma_pitch;
  199.         ctx->planes[p].width  = !p ? luma_width  : chroma_width;
  200.         ctx->planes[p].height = !p ? luma_height : chroma_height;
  201.  
  202.         ctx->planes[p].buffers[0] = av_malloc(!p ? luma_size : chroma_size);
  203.         ctx->planes[p].buffers[1] = av_malloc(!p ? luma_size : chroma_size);
  204.  
  205.         if (!ctx->planes[p].buffers[0] || !ctx->planes[p].buffers[1]) {
  206.             free_frame_buffers(ctx);
  207.             return AVERROR(ENOMEM);
  208.         }
  209.  
  210.         /* fill the INTRA prediction lines with the middle pixel value = 64 */
  211.         memset(ctx->planes[p].buffers[0], 0x40, ctx->planes[p].pitch);
  212.         memset(ctx->planes[p].buffers[1], 0x40, ctx->planes[p].pitch);
  213.  
  214.         /* set buffer pointers = buf_ptr + pitch and thus skip the INTRA prediction line */
  215.         ctx->planes[p].pixels[0] = ctx->planes[p].buffers[0] + ctx->planes[p].pitch;
  216.         ctx->planes[p].pixels[1] = ctx->planes[p].buffers[1] + ctx->planes[p].pitch;
  217.         memset(ctx->planes[p].pixels[0], 0, ctx->planes[p].pitch * ctx->planes[p].height);
  218.         memset(ctx->planes[p].pixels[1], 0, ctx->planes[p].pitch * ctx->planes[p].height);
  219.     }
  220.  
  221.     return 0;
  222. }
  223.  
  224. /**
  225.  *  Copy pixels of the cell(x + mv_x, y + mv_y) from the previous frame into
  226.  *  the cell(x, y) in the current frame.
  227.  *
  228.  *  @param ctx      pointer to the decoder context
  229.  *  @param plane    pointer to the plane descriptor
  230.  *  @param cell     pointer to the cell  descriptor
  231.  */
  232. static int copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
  233. {
  234.     int     h, w, mv_x, mv_y, offset, offset_dst;
  235.     uint8_t *src, *dst;
  236.  
  237.     /* setup output and reference pointers */
  238.     offset_dst  = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2);
  239.     dst         = plane->pixels[ctx->buf_sel] + offset_dst;
  240.     if(cell->mv_ptr){
  241.     mv_y        = cell->mv_ptr[0];
  242.     mv_x        = cell->mv_ptr[1];
  243.     }else
  244.         mv_x= mv_y= 0;
  245.  
  246.     /* -1 because there is an extra line on top for prediction */
  247.     if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 ||
  248.         ((cell->ypos + cell->height) << 2) + mv_y > plane->height     ||
  249.         ((cell->xpos + cell->width)  << 2) + mv_x > plane->width) {
  250.         av_log(ctx->avctx, AV_LOG_ERROR,
  251.                "Motion vectors point out of the frame.\n");
  252.         return AVERROR_INVALIDDATA;
  253.     }
  254.  
  255.     offset      = offset_dst + mv_y * plane->pitch + mv_x;
  256.     src         = plane->pixels[ctx->buf_sel ^ 1] + offset;
  257.  
  258.     h = cell->height << 2;
  259.  
  260.     for (w = cell->width; w > 0;) {
  261.         /* copy using 16xH blocks */
  262.         if (!((cell->xpos << 2) & 15) && w >= 4) {
  263.             for (; w >= 4; src += 16, dst += 16, w -= 4)
  264.                 ctx->hdsp.put_pixels_tab[0][0](dst, src, plane->pitch, h);
  265.         }
  266.  
  267.         /* copy using 8xH blocks */
  268.         if (!((cell->xpos << 2) & 7) && w >= 2) {
  269.             ctx->hdsp.put_pixels_tab[1][0](dst, src, plane->pitch, h);
  270.             w -= 2;
  271.             src += 8;
  272.             dst += 8;
  273.         } else if (w >= 1) {
  274.             ctx->hdsp.put_pixels_tab[2][0](dst, src, plane->pitch, h);
  275.             w--;
  276.             src += 4;
  277.             dst += 4;
  278.         }
  279.     }
  280.  
  281.     return 0;
  282. }
  283.  
  284.  
  285. /* Average 4/8 pixels at once without rounding using SWAR */
  286. #define AVG_32(dst, src, ref) \
  287.     AV_WN32A(dst, ((AV_RN32(src) + AV_RN32(ref)) >> 1) & 0x7F7F7F7FUL)
  288.  
  289. #define AVG_64(dst, src, ref) \
  290.     AV_WN64A(dst, ((AV_RN64(src) + AV_RN64(ref)) >> 1) & 0x7F7F7F7F7F7F7F7FULL)
  291.  
  292.  
  293. /*
  294.  *  Replicate each even pixel as follows:
  295.  *  ABCDEFGH -> AACCEEGG
  296.  */
  297. static inline uint64_t replicate64(uint64_t a) {
  298. #if HAVE_BIGENDIAN
  299.     a &= 0xFF00FF00FF00FF00ULL;
  300.     a |= a >> 8;
  301. #else
  302.     a &= 0x00FF00FF00FF00FFULL;
  303.     a |= a << 8;
  304. #endif
  305.     return a;
  306. }
  307.  
  308. static inline uint32_t replicate32(uint32_t a) {
  309. #if HAVE_BIGENDIAN
  310.     a &= 0xFF00FF00UL;
  311.     a |= a >> 8;
  312. #else
  313.     a &= 0x00FF00FFUL;
  314.     a |= a << 8;
  315. #endif
  316.     return a;
  317. }
  318.  
  319.  
  320. /* Fill n lines with 64bit pixel value pix */
  321. static inline void fill_64(uint8_t *dst, const uint64_t pix, int32_t n,
  322.                            int32_t row_offset)
  323. {
  324.     for (; n > 0; dst += row_offset, n--)
  325.         AV_WN64A(dst, pix);
  326. }
  327.  
  328.  
  329. /* Error codes for cell decoding. */
  330. enum {
  331.     IV3_NOERR       = 0,
  332.     IV3_BAD_RLE     = 1,
  333.     IV3_BAD_DATA    = 2,
  334.     IV3_BAD_COUNTER = 3,
  335.     IV3_UNSUPPORTED = 4,
  336.     IV3_OUT_OF_DATA = 5
  337. };
  338.  
  339.  
  340. #define BUFFER_PRECHECK \
  341. if (*data_ptr >= last_ptr) \
  342.     return IV3_OUT_OF_DATA; \
  343.  
  344. #define RLE_BLOCK_COPY \
  345.     if (cell->mv_ptr || !skip_flag) \
  346.         copy_block4(dst, ref, row_offset, row_offset, 4 << v_zoom)
  347.  
  348. #define RLE_BLOCK_COPY_8 \
  349.     pix64 = AV_RN64(ref);\
  350.     if (is_first_row) {/* special prediction case: top line of a cell */\
  351.         pix64 = replicate64(pix64);\
  352.         fill_64(dst + row_offset, pix64, 7, row_offset);\
  353.         AVG_64(dst, ref, dst + row_offset);\
  354.     } else \
  355.         fill_64(dst, pix64, 8, row_offset)
  356.  
  357. #define RLE_LINES_COPY \
  358.     copy_block4(dst, ref, row_offset, row_offset, num_lines << v_zoom)
  359.  
  360. #define RLE_LINES_COPY_M10 \
  361.     pix64 = AV_RN64(ref);\
  362.     if (is_top_of_cell) {\
  363.         pix64 = replicate64(pix64);\
  364.         fill_64(dst + row_offset, pix64, (num_lines << 1) - 1, row_offset);\
  365.         AVG_64(dst, ref, dst + row_offset);\
  366.     } else \
  367.         fill_64(dst, pix64, num_lines << 1, row_offset)
  368.  
  369. #define APPLY_DELTA_4 \
  370.     AV_WN16A(dst + line_offset    ,\
  371.              (AV_RN16(ref    ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
  372.     AV_WN16A(dst + line_offset + 2,\
  373.              (AV_RN16(ref + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\
  374.     if (mode >= 3) {\
  375.         if (is_top_of_cell && !cell->ypos) {\
  376.             AV_COPY32U(dst, dst + row_offset);\
  377.         } else {\
  378.             AVG_32(dst, ref, dst + row_offset);\
  379.         }\
  380.     }
  381.  
  382. #define APPLY_DELTA_8 \
  383.     /* apply two 32-bit VQ deltas to next even line */\
  384.     if (is_top_of_cell) { \
  385.         AV_WN32A(dst + row_offset    , \
  386.                  (replicate32(AV_RN32(ref    )) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
  387.         AV_WN32A(dst + row_offset + 4, \
  388.                  (replicate32(AV_RN32(ref + 4)) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
  389.     } else { \
  390.         AV_WN32A(dst + row_offset    , \
  391.                  (AV_RN32(ref    ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
  392.         AV_WN32A(dst + row_offset + 4, \
  393.                  (AV_RN32(ref + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
  394.     } \
  395.     /* odd lines are not coded but rather interpolated/replicated */\
  396.     /* first line of the cell on the top of image? - replicate */\
  397.     /* otherwise - interpolate */\
  398.     if (is_top_of_cell && !cell->ypos) {\
  399.         AV_COPY64U(dst, dst + row_offset);\
  400.     } else \
  401.         AVG_64(dst, ref, dst + row_offset);
  402.  
  403.  
  404. #define APPLY_DELTA_1011_INTER \
  405.     if (mode == 10) { \
  406.         AV_WN32A(dst                 , \
  407.                  (AV_RN32(dst                 ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
  408.         AV_WN32A(dst + 4             , \
  409.                  (AV_RN32(dst + 4             ) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
  410.         AV_WN32A(dst + row_offset    , \
  411.                  (AV_RN32(dst + row_offset    ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
  412.         AV_WN32A(dst + row_offset + 4, \
  413.                  (AV_RN32(dst + row_offset + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
  414.     } else { \
  415.         AV_WN16A(dst                 , \
  416.                  (AV_RN16(dst                 ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
  417.         AV_WN16A(dst + 2             , \
  418.                  (AV_RN16(dst + 2             ) + delta_tab->deltas[dyad2]) & 0x7F7F);\
  419.         AV_WN16A(dst + row_offset    , \
  420.                  (AV_RN16(dst + row_offset    ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
  421.         AV_WN16A(dst + row_offset + 2, \
  422.                  (AV_RN16(dst + row_offset + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\
  423.     }
  424.  
  425.  
  426. static int decode_cell_data(Indeo3DecodeContext *ctx, Cell *cell,
  427.                             uint8_t *block, uint8_t *ref_block,
  428.                             int pitch, int h_zoom, int v_zoom, int mode,
  429.                             const vqEntry *delta[2], int swap_quads[2],
  430.                             const uint8_t **data_ptr, const uint8_t *last_ptr)
  431. {
  432.     int           x, y, line, num_lines;
  433.     int           rle_blocks = 0;
  434.     uint8_t       code, *dst, *ref;
  435.     const vqEntry *delta_tab;
  436.     unsigned int  dyad1, dyad2;
  437.     uint64_t      pix64;
  438.     int           skip_flag = 0, is_top_of_cell, is_first_row = 1;
  439.     int           row_offset, blk_row_offset, line_offset;
  440.  
  441.     row_offset     =  pitch;
  442.     blk_row_offset = (row_offset << (2 + v_zoom)) - (cell->width << 2);
  443.     line_offset    = v_zoom ? row_offset : 0;
  444.  
  445.     if (cell->height & v_zoom || cell->width & h_zoom)
  446.         return IV3_BAD_DATA;
  447.  
  448.     for (y = 0; y < cell->height; is_first_row = 0, y += 1 + v_zoom) {
  449.         for (x = 0; x < cell->width; x += 1 + h_zoom) {
  450.             ref = ref_block;
  451.             dst = block;
  452.  
  453.             if (rle_blocks > 0) {
  454.                 if (mode <= 4) {
  455.                     RLE_BLOCK_COPY;
  456.                 } else if (mode == 10 && !cell->mv_ptr) {
  457.                     RLE_BLOCK_COPY_8;
  458.                 }
  459.                 rle_blocks--;
  460.             } else {
  461.                 for (line = 0; line < 4;) {
  462.                     num_lines = 1;
  463.                     is_top_of_cell = is_first_row && !line;
  464.  
  465.                     /* select primary VQ table for odd, secondary for even lines */
  466.                     if (mode <= 4)
  467.                         delta_tab = delta[line & 1];
  468.                     else
  469.                         delta_tab = delta[1];
  470.                     BUFFER_PRECHECK;
  471.                     code = bytestream_get_byte(data_ptr);
  472.                     if (code < 248) {
  473.                         if (code < delta_tab->num_dyads) {
  474.                             BUFFER_PRECHECK;
  475.                             dyad1 = bytestream_get_byte(data_ptr);
  476.                             dyad2 = code;
  477.                             if (dyad1 >= delta_tab->num_dyads || dyad1 >= 248)
  478.                                 return IV3_BAD_DATA;
  479.                         } else {
  480.                             /* process QUADS */
  481.                             code -= delta_tab->num_dyads;
  482.                             dyad1 = code / delta_tab->quad_exp;
  483.                             dyad2 = code % delta_tab->quad_exp;
  484.                             if (swap_quads[line & 1])
  485.                                 FFSWAP(unsigned int, dyad1, dyad2);
  486.                         }
  487.                         if (mode <= 4) {
  488.                             APPLY_DELTA_4;
  489.                         } else if (mode == 10 && !cell->mv_ptr) {
  490.                             APPLY_DELTA_8;
  491.                         } else {
  492.                             APPLY_DELTA_1011_INTER;
  493.                         }
  494.                     } else {
  495.                         /* process RLE codes */
  496.                         switch (code) {
  497.                         case RLE_ESC_FC:
  498.                             skip_flag  = 0;
  499.                             rle_blocks = 1;
  500.                             code       = 253;
  501.                             /* FALLTHROUGH */
  502.                         case RLE_ESC_FF:
  503.                         case RLE_ESC_FE:
  504.                         case RLE_ESC_FD:
  505.                             num_lines = 257 - code - line;
  506.                             if (num_lines <= 0)
  507.                                 return IV3_BAD_RLE;
  508.                             if (mode <= 4) {
  509.                                 RLE_LINES_COPY;
  510.                             } else if (mode == 10 && !cell->mv_ptr) {
  511.                                 RLE_LINES_COPY_M10;
  512.                             }
  513.                             break;
  514.                         case RLE_ESC_FB:
  515.                             BUFFER_PRECHECK;
  516.                             code = bytestream_get_byte(data_ptr);
  517.                             rle_blocks = (code & 0x1F) - 1; /* set block counter */
  518.                             if (code >= 64 || rle_blocks < 0)
  519.                                 return IV3_BAD_COUNTER;
  520.                             skip_flag = code & 0x20;
  521.                             num_lines = 4 - line; /* enforce next block processing */
  522.                             if (mode >= 10 || (cell->mv_ptr || !skip_flag)) {
  523.                                 if (mode <= 4) {
  524.                                     RLE_LINES_COPY;
  525.                                 } else if (mode == 10 && !cell->mv_ptr) {
  526.                                     RLE_LINES_COPY_M10;
  527.                                 }
  528.                             }
  529.                             break;
  530.                         case RLE_ESC_F9:
  531.                             skip_flag  = 1;
  532.                             rle_blocks = 1;
  533.                             /* FALLTHROUGH */
  534.                         case RLE_ESC_FA:
  535.                             if (line)
  536.                                 return IV3_BAD_RLE;
  537.                             num_lines = 4; /* enforce next block processing */
  538.                             if (cell->mv_ptr) {
  539.                                 if (mode <= 4) {
  540.                                     RLE_LINES_COPY;
  541.                                 } else if (mode == 10 && !cell->mv_ptr) {
  542.                                     RLE_LINES_COPY_M10;
  543.                                 }
  544.                             }
  545.                             break;
  546.                         default:
  547.                             return IV3_UNSUPPORTED;
  548.                         }
  549.                     }
  550.  
  551.                     line += num_lines;
  552.                     ref  += row_offset * (num_lines << v_zoom);
  553.                     dst  += row_offset * (num_lines << v_zoom);
  554.                 }
  555.             }
  556.  
  557.             /* move to next horizontal block */
  558.             block     += 4 << h_zoom;
  559.             ref_block += 4 << h_zoom;
  560.         }
  561.  
  562.         /* move to next line of blocks */
  563.         ref_block += blk_row_offset;
  564.         block     += blk_row_offset;
  565.     }
  566.     return IV3_NOERR;
  567. }
  568.  
  569.  
  570. /**
  571.  *  Decode a vector-quantized cell.
  572.  *  It consists of several routines, each of which handles one or more "modes"
  573.  *  with which a cell can be encoded.
  574.  *
  575.  *  @param ctx      pointer to the decoder context
  576.  *  @param avctx    ptr to the AVCodecContext
  577.  *  @param plane    pointer to the plane descriptor
  578.  *  @param cell     pointer to the cell  descriptor
  579.  *  @param data_ptr pointer to the compressed data
  580.  *  @param last_ptr pointer to the last byte to catch reads past end of buffer
  581.  *  @return         number of consumed bytes or negative number in case of error
  582.  */
  583. static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
  584.                        Plane *plane, Cell *cell, const uint8_t *data_ptr,
  585.                        const uint8_t *last_ptr)
  586. {
  587.     int           x, mv_x, mv_y, mode, vq_index, prim_indx, second_indx;
  588.     int           zoom_fac;
  589.     int           offset, error = 0, swap_quads[2];
  590.     uint8_t       code, *block, *ref_block = 0;
  591.     const vqEntry *delta[2];
  592.     const uint8_t *data_start = data_ptr;
  593.  
  594.     /* get coding mode and VQ table index from the VQ descriptor byte */
  595.     code     = *data_ptr++;
  596.     mode     = code >> 4;
  597.     vq_index = code & 0xF;
  598.  
  599.     /* setup output and reference pointers */
  600.     offset = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2);
  601.     block  =  plane->pixels[ctx->buf_sel] + offset;
  602.  
  603.     if (!cell->mv_ptr) {
  604.         /* use previous line as reference for INTRA cells */
  605.         ref_block = block - plane->pitch;
  606.     } else if (mode >= 10) {
  607.         /* for mode 10 and 11 INTER first copy the predicted cell into the current one */
  608.         /* so we don't need to do data copying for each RLE code later */
  609.         int ret = copy_cell(ctx, plane, cell);
  610.         if (ret < 0)
  611.             return ret;
  612.     } else {
  613.         /* set the pointer to the reference pixels for modes 0-4 INTER */
  614.         mv_y      = cell->mv_ptr[0];
  615.         mv_x      = cell->mv_ptr[1];
  616.  
  617.         /* -1 because there is an extra line on top for prediction */
  618.         if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 ||
  619.             ((cell->ypos + cell->height) << 2) + mv_y > plane->height     ||
  620.             ((cell->xpos + cell->width)  << 2) + mv_x > plane->width) {
  621.             av_log(ctx->avctx, AV_LOG_ERROR,
  622.                    "Motion vectors point out of the frame.\n");
  623.             return AVERROR_INVALIDDATA;
  624.         }
  625.  
  626.         offset   += mv_y * plane->pitch + mv_x;
  627.         ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset;
  628.     }
  629.  
  630.     /* select VQ tables as follows: */
  631.     /* modes 0 and 3 use only the primary table for all lines in a block */
  632.     /* while modes 1 and 4 switch between primary and secondary tables on alternate lines */
  633.     if (mode == 1 || mode == 4) {
  634.         code        = ctx->alt_quant[vq_index];
  635.         prim_indx   = (code >> 4)  + ctx->cb_offset;
  636.         second_indx = (code & 0xF) + ctx->cb_offset;
  637.     } else {
  638.         vq_index += ctx->cb_offset;
  639.         prim_indx = second_indx = vq_index;
  640.     }
  641.  
  642.     if (prim_indx >= 24 || second_indx >= 24) {
  643.         av_log(avctx, AV_LOG_ERROR, "Invalid VQ table indexes! Primary: %d, secondary: %d!\n",
  644.                prim_indx, second_indx);
  645.         return AVERROR_INVALIDDATA;
  646.     }
  647.  
  648.     delta[0] = &vq_tab[second_indx];
  649.     delta[1] = &vq_tab[prim_indx];
  650.     swap_quads[0] = second_indx >= 16;
  651.     swap_quads[1] = prim_indx   >= 16;
  652.  
  653.     /* requantize the prediction if VQ index of this cell differs from VQ index */
  654.     /* of the predicted cell in order to avoid overflows. */
  655.     if (vq_index >= 8 && ref_block) {
  656.         for (x = 0; x < cell->width << 2; x++)
  657.             ref_block[x] = requant_tab[vq_index & 7][ref_block[x] & 127];
  658.     }
  659.  
  660.     error = IV3_NOERR;
  661.  
  662.     switch (mode) {
  663.     case 0: /*------------------ MODES 0 & 1 (4x4 block processing) --------------------*/
  664.     case 1:
  665.     case 3: /*------------------ MODES 3 & 4 (4x8 block processing) --------------------*/
  666.     case 4:
  667.         if (mode >= 3 && cell->mv_ptr) {
  668.             av_log(avctx, AV_LOG_ERROR, "Attempt to apply Mode 3/4 to an INTER cell!\n");
  669.             return AVERROR_INVALIDDATA;
  670.         }
  671.  
  672.         zoom_fac = mode >= 3;
  673.         error = decode_cell_data(ctx, cell, block, ref_block, plane->pitch,
  674.                                  0, zoom_fac, mode, delta, swap_quads,
  675.                                  &data_ptr, last_ptr);
  676.         break;
  677.     case 10: /*-------------------- MODE 10 (8x8 block processing) ---------------------*/
  678.     case 11: /*----------------- MODE 11 (4x8 INTER block processing) ------------------*/
  679.         if (mode == 10 && !cell->mv_ptr) { /* MODE 10 INTRA processing */
  680.             error = decode_cell_data(ctx, cell, block, ref_block, plane->pitch,
  681.                                      1, 1, mode, delta, swap_quads,
  682.                                      &data_ptr, last_ptr);
  683.         } else { /* mode 10 and 11 INTER processing */
  684.             if (mode == 11 && !cell->mv_ptr) {
  685.                av_log(avctx, AV_LOG_ERROR, "Attempt to use Mode 11 for an INTRA cell!\n");
  686.                return AVERROR_INVALIDDATA;
  687.             }
  688.  
  689.             zoom_fac = mode == 10;
  690.             error = decode_cell_data(ctx, cell, block, ref_block, plane->pitch,
  691.                                      zoom_fac, 1, mode, delta, swap_quads,
  692.                                      &data_ptr, last_ptr);
  693.         }
  694.         break;
  695.     default:
  696.         av_log(avctx, AV_LOG_ERROR, "Unsupported coding mode: %d\n", mode);
  697.         return AVERROR_INVALIDDATA;
  698.     }//switch mode
  699.  
  700.     switch (error) {
  701.     case IV3_BAD_RLE:
  702.         av_log(avctx, AV_LOG_ERROR, "Mode %d: RLE code %X is not allowed at the current line\n",
  703.                mode, data_ptr[-1]);
  704.         return AVERROR_INVALIDDATA;
  705.     case IV3_BAD_DATA:
  706.         av_log(avctx, AV_LOG_ERROR, "Mode %d: invalid VQ data\n", mode);
  707.         return AVERROR_INVALIDDATA;
  708.     case IV3_BAD_COUNTER:
  709.         av_log(avctx, AV_LOG_ERROR, "Mode %d: RLE-FB invalid counter: %d\n", mode, code);
  710.         return AVERROR_INVALIDDATA;
  711.     case IV3_UNSUPPORTED:
  712.         av_log(avctx, AV_LOG_ERROR, "Mode %d: unsupported RLE code: %X\n", mode, data_ptr[-1]);
  713.         return AVERROR_INVALIDDATA;
  714.     case IV3_OUT_OF_DATA:
  715.         av_log(avctx, AV_LOG_ERROR, "Mode %d: attempt to read past end of buffer\n", mode);
  716.         return AVERROR_INVALIDDATA;
  717.     }
  718.  
  719.     return data_ptr - data_start; /* report number of bytes consumed from the input buffer */
  720. }
  721.  
  722.  
  723. /* Binary tree codes. */
  724. enum {
  725.     H_SPLIT    = 0,
  726.     V_SPLIT    = 1,
  727.     INTRA_NULL = 2,
  728.     INTER_DATA = 3
  729. };
  730.  
  731.  
  732. #define SPLIT_CELL(size, new_size) (new_size) = ((size) > 2) ? ((((size) + 2) >> 2) << 1) : 1
  733.  
  734. #define UPDATE_BITPOS(n) \
  735.     ctx->skip_bits  += (n); \
  736.     ctx->need_resync = 1
  737.  
  738. #define RESYNC_BITSTREAM \
  739.     if (ctx->need_resync && !(get_bits_count(&ctx->gb) & 7)) { \
  740.         skip_bits_long(&ctx->gb, ctx->skip_bits);              \
  741.         ctx->skip_bits   = 0;                                  \
  742.         ctx->need_resync = 0;                                  \
  743.     }
  744.  
  745. #define CHECK_CELL \
  746.     if (curr_cell.xpos + curr_cell.width > (plane->width >> 2) ||               \
  747.         curr_cell.ypos + curr_cell.height > (plane->height >> 2)) {             \
  748.         av_log(avctx, AV_LOG_ERROR, "Invalid cell: x=%d, y=%d, w=%d, h=%d\n",   \
  749.                curr_cell.xpos, curr_cell.ypos, curr_cell.width, curr_cell.height); \
  750.         return AVERROR_INVALIDDATA;                                                              \
  751.     }
  752.  
  753.  
  754. static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
  755.                          Plane *plane, int code, Cell *ref_cell,
  756.                          const int depth, const int strip_width)
  757. {
  758.     Cell    curr_cell;
  759.     int     bytes_used, ret;
  760.  
  761.     if (depth <= 0) {
  762.         av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n");
  763.         return AVERROR_INVALIDDATA; // unwind recursion
  764.     }
  765.  
  766.     curr_cell = *ref_cell; // clone parent cell
  767.     if (code == H_SPLIT) {
  768.         SPLIT_CELL(ref_cell->height, curr_cell.height);
  769.         ref_cell->ypos   += curr_cell.height;
  770.         ref_cell->height -= curr_cell.height;
  771.         if (ref_cell->height <= 0 || curr_cell.height <= 0)
  772.             return AVERROR_INVALIDDATA;
  773.     } else if (code == V_SPLIT) {
  774.         if (curr_cell.width > strip_width) {
  775.             /* split strip */
  776.             curr_cell.width = (curr_cell.width <= (strip_width << 1) ? 1 : 2) * strip_width;
  777.         } else
  778.             SPLIT_CELL(ref_cell->width, curr_cell.width);
  779.         ref_cell->xpos  += curr_cell.width;
  780.         ref_cell->width -= curr_cell.width;
  781.         if (ref_cell->width <= 0 || curr_cell.width <= 0)
  782.             return AVERROR_INVALIDDATA;
  783.     }
  784.  
  785.     while (get_bits_left(&ctx->gb) >= 2) { /* loop until return */
  786.         RESYNC_BITSTREAM;
  787.         switch (code = get_bits(&ctx->gb, 2)) {
  788.         case H_SPLIT:
  789.         case V_SPLIT:
  790.             if (parse_bintree(ctx, avctx, plane, code, &curr_cell, depth - 1, strip_width))
  791.                 return AVERROR_INVALIDDATA;
  792.             break;
  793.         case INTRA_NULL:
  794.             if (!curr_cell.tree) { /* MC tree INTRA code */
  795.                 curr_cell.mv_ptr = 0; /* mark the current strip as INTRA */
  796.                 curr_cell.tree   = 1; /* enter the VQ tree */
  797.             } else { /* VQ tree NULL code */
  798.                 RESYNC_BITSTREAM;
  799.                 code = get_bits(&ctx->gb, 2);
  800.                 if (code >= 2) {
  801.                     av_log(avctx, AV_LOG_ERROR, "Invalid VQ_NULL code: %d\n", code);
  802.                     return AVERROR_INVALIDDATA;
  803.                 }
  804.                 if (code == 1)
  805.                     av_log(avctx, AV_LOG_ERROR, "SkipCell procedure not implemented yet!\n");
  806.  
  807.                 CHECK_CELL
  808.                 if (!curr_cell.mv_ptr)
  809.                     return AVERROR_INVALIDDATA;
  810.  
  811.                 ret = copy_cell(ctx, plane, &curr_cell);
  812.                 return ret;
  813.             }
  814.             break;
  815.         case INTER_DATA:
  816.             if (!curr_cell.tree) { /* MC tree INTER code */
  817.                 unsigned mv_idx;
  818.                 /* get motion vector index and setup the pointer to the mv set */
  819.                 if (!ctx->need_resync)
  820.                     ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];
  821.                 if (ctx->next_cell_data >= ctx->last_byte) {
  822.                     av_log(avctx, AV_LOG_ERROR, "motion vector out of array\n");
  823.                     return AVERROR_INVALIDDATA;
  824.                 }
  825.                 mv_idx = *(ctx->next_cell_data++);
  826.                 if (mv_idx >= ctx->num_vectors) {
  827.                     av_log(avctx, AV_LOG_ERROR, "motion vector index out of range\n");
  828.                     return AVERROR_INVALIDDATA;
  829.                 }
  830.                 curr_cell.mv_ptr = &ctx->mc_vectors[mv_idx << 1];
  831.                 curr_cell.tree   = 1; /* enter the VQ tree */
  832.                 UPDATE_BITPOS(8);
  833.             } else { /* VQ tree DATA code */
  834.                 if (!ctx->need_resync)
  835.                     ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];
  836.  
  837.                 CHECK_CELL
  838.                 bytes_used = decode_cell(ctx, avctx, plane, &curr_cell,
  839.                                          ctx->next_cell_data, ctx->last_byte);
  840.                 if (bytes_used < 0)
  841.                     return AVERROR_INVALIDDATA;
  842.  
  843.                 UPDATE_BITPOS(bytes_used << 3);
  844.                 ctx->next_cell_data += bytes_used;
  845.                 return 0;
  846.             }
  847.             break;
  848.         }
  849.     }//while
  850.  
  851.     return AVERROR_INVALIDDATA;
  852. }
  853.  
  854.  
  855. static int decode_plane(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
  856.                         Plane *plane, const uint8_t *data, int32_t data_size,
  857.                         int32_t strip_width)
  858. {
  859.     Cell            curr_cell;
  860.     unsigned        num_vectors;
  861.  
  862.     /* each plane data starts with mc_vector_count field, */
  863.     /* an optional array of motion vectors followed by the vq data */
  864.     num_vectors = bytestream_get_le32(&data); data_size -= 4;
  865.     if (num_vectors > 256) {
  866.         av_log(ctx->avctx, AV_LOG_ERROR,
  867.                "Read invalid number of motion vectors %d\n", num_vectors);
  868.         return AVERROR_INVALIDDATA;
  869.     }
  870.     if (num_vectors * 2 > data_size)
  871.         return AVERROR_INVALIDDATA;
  872.  
  873.     ctx->num_vectors = num_vectors;
  874.     ctx->mc_vectors  = num_vectors ? data : 0;
  875.  
  876.     /* init the bitreader */
  877.     init_get_bits(&ctx->gb, &data[num_vectors * 2], (data_size - num_vectors * 2) << 3);
  878.     ctx->skip_bits   = 0;
  879.     ctx->need_resync = 0;
  880.  
  881.     ctx->last_byte = data + data_size;
  882.  
  883.     /* initialize the 1st cell and set its dimensions to whole plane */
  884.     curr_cell.xpos   = curr_cell.ypos = 0;
  885.     curr_cell.width  = plane->width  >> 2;
  886.     curr_cell.height = plane->height >> 2;
  887.     curr_cell.tree   = 0; // we are in the MC tree now
  888.     curr_cell.mv_ptr = 0; // no motion vector = INTRA cell
  889.  
  890.     return parse_bintree(ctx, avctx, plane, INTRA_NULL, &curr_cell, CELL_STACK_MAX, strip_width);
  891. }
  892.  
  893.  
  894. #define OS_HDR_ID   MKBETAG('F', 'R', 'M', 'H')
  895.  
  896. static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
  897.                                 const uint8_t *buf, int buf_size)
  898. {
  899.     GetByteContext gb;
  900.     const uint8_t   *bs_hdr;
  901.     uint32_t        frame_num, word2, check_sum, data_size;
  902.     uint32_t        y_offset, u_offset, v_offset, starts[3], ends[3];
  903.     uint16_t        height, width;
  904.     int             i, j;
  905.  
  906.     bytestream2_init(&gb, buf, buf_size);
  907.  
  908.     /* parse and check the OS header */
  909.     frame_num = bytestream2_get_le32(&gb);
  910.     word2     = bytestream2_get_le32(&gb);
  911.     check_sum = bytestream2_get_le32(&gb);
  912.     data_size = bytestream2_get_le32(&gb);
  913.  
  914.     if ((frame_num ^ word2 ^ data_size ^ OS_HDR_ID) != check_sum) {
  915.         av_log(avctx, AV_LOG_ERROR, "OS header checksum mismatch!\n");
  916.         return AVERROR_INVALIDDATA;
  917.     }
  918.  
  919.     /* parse the bitstream header */
  920.     bs_hdr = gb.buffer;
  921.  
  922.     if (bytestream2_get_le16(&gb) != 32) {
  923.         av_log(avctx, AV_LOG_ERROR, "Unsupported codec version!\n");
  924.         return AVERROR_INVALIDDATA;
  925.     }
  926.  
  927.     ctx->frame_num   =  frame_num;
  928.     ctx->frame_flags =  bytestream2_get_le16(&gb);
  929.     ctx->data_size   = (bytestream2_get_le32(&gb) + 7) >> 3;
  930.     ctx->cb_offset   =  bytestream2_get_byte(&gb);
  931.  
  932.     if (ctx->data_size == 16)
  933.         return 4;
  934.     ctx->data_size = FFMIN(ctx->data_size, buf_size - 16);
  935.  
  936.     bytestream2_skip(&gb, 3); // skip reserved byte and checksum
  937.  
  938.     /* check frame dimensions */
  939.     height = bytestream2_get_le16(&gb);
  940.     width  = bytestream2_get_le16(&gb);
  941.     if (av_image_check_size(width, height, 0, avctx))
  942.         return AVERROR_INVALIDDATA;
  943.  
  944.     if (width != ctx->width || height != ctx->height) {
  945.         int res;
  946.  
  947.         av_dlog(avctx, "Frame dimensions changed!\n");
  948.  
  949.         if (width  < 16 || width  > 640 ||
  950.             height < 16 || height > 480 ||
  951.             width  &  3 || height &   3) {
  952.             av_log(avctx, AV_LOG_ERROR,
  953.                    "Invalid picture dimensions: %d x %d!\n", width, height);
  954.             return AVERROR_INVALIDDATA;
  955.         }
  956.         free_frame_buffers(ctx);
  957.         if ((res = allocate_frame_buffers(ctx, avctx, width, height)) < 0)
  958.              return res;
  959.         avcodec_set_dimensions(avctx, width, height);
  960.     }
  961.  
  962.     y_offset = bytestream2_get_le32(&gb);
  963.     v_offset = bytestream2_get_le32(&gb);
  964.     u_offset = bytestream2_get_le32(&gb);
  965.     bytestream2_skip(&gb, 4);
  966.  
  967.     /* unfortunately there is no common order of planes in the buffer */
  968.     /* so we use that sorting algo for determining planes data sizes  */
  969.     starts[0] = y_offset;
  970.     starts[1] = v_offset;
  971.     starts[2] = u_offset;
  972.  
  973.     for (j = 0; j < 3; j++) {
  974.         ends[j] = ctx->data_size;
  975.         for (i = 2; i >= 0; i--)
  976.             if (starts[i] < ends[j] && starts[i] > starts[j])
  977.                 ends[j] = starts[i];
  978.     }
  979.  
  980.     ctx->y_data_size = ends[0] - starts[0];
  981.     ctx->v_data_size = ends[1] - starts[1];
  982.     ctx->u_data_size = ends[2] - starts[2];
  983.     if (FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 ||
  984.         FFMIN3(y_offset, v_offset, u_offset) < gb.buffer - bs_hdr + 16 ||
  985.         FFMIN3(ctx->y_data_size, ctx->v_data_size, ctx->u_data_size) <= 0) {
  986.         av_log(avctx, AV_LOG_ERROR, "One of the y/u/v offsets is invalid\n");
  987.         return AVERROR_INVALIDDATA;
  988.     }
  989.  
  990.     ctx->y_data_ptr = bs_hdr + y_offset;
  991.     ctx->v_data_ptr = bs_hdr + v_offset;
  992.     ctx->u_data_ptr = bs_hdr + u_offset;
  993.     ctx->alt_quant  = gb.buffer;
  994.  
  995.     if (ctx->data_size == 16) {
  996.         av_log(avctx, AV_LOG_DEBUG, "Sync frame encountered!\n");
  997.         return 16;
  998.     }
  999.  
  1000.     if (ctx->frame_flags & BS_8BIT_PEL) {
  1001.         avpriv_request_sample(avctx, "8-bit pixel format");
  1002.         return AVERROR_PATCHWELCOME;
  1003.     }
  1004.  
  1005.     if (ctx->frame_flags & BS_MV_X_HALF || ctx->frame_flags & BS_MV_Y_HALF) {
  1006.         avpriv_request_sample(avctx, "Halfpel motion vectors");
  1007.         return AVERROR_PATCHWELCOME;
  1008.     }
  1009.  
  1010.     return 0;
  1011. }
  1012.  
  1013.  
  1014. /**
  1015.  *  Convert and output the current plane.
  1016.  *  All pixel values will be upsampled by shifting right by one bit.
  1017.  *
  1018.  *  @param[in]  plane        pointer to the descriptor of the plane being processed
  1019.  *  @param[in]  buf_sel      indicates which frame buffer the input data stored in
  1020.  *  @param[out] dst          pointer to the buffer receiving converted pixels
  1021.  *  @param[in]  dst_pitch    pitch for moving to the next y line
  1022.  *  @param[in]  dst_height   output plane height
  1023.  */
  1024. static void output_plane(const Plane *plane, int buf_sel, uint8_t *dst,
  1025.                          int dst_pitch, int dst_height)
  1026. {
  1027.     int             x,y;
  1028.     const uint8_t   *src  = plane->pixels[buf_sel];
  1029.     uint32_t        pitch = plane->pitch;
  1030.  
  1031.     dst_height = FFMIN(dst_height, plane->height);
  1032.     for (y = 0; y < dst_height; y++) {
  1033.         /* convert four pixels at once using SWAR */
  1034.         for (x = 0; x < plane->width >> 2; x++) {
  1035.             AV_WN32A(dst, (AV_RN32A(src) & 0x7F7F7F7F) << 1);
  1036.             src += 4;
  1037.             dst += 4;
  1038.         }
  1039.  
  1040.         for (x <<= 2; x < plane->width; x++)
  1041.             *dst++ = *src++ << 1;
  1042.  
  1043.         src += pitch     - plane->width;
  1044.         dst += dst_pitch - plane->width;
  1045.     }
  1046. }
  1047.  
  1048.  
  1049. static av_cold int decode_init(AVCodecContext *avctx)
  1050. {
  1051.     Indeo3DecodeContext *ctx = avctx->priv_data;
  1052.  
  1053.     ctx->avctx     = avctx;
  1054.     avctx->pix_fmt = AV_PIX_FMT_YUV410P;
  1055.  
  1056.     build_requant_tab();
  1057.  
  1058.     ff_hpeldsp_init(&ctx->hdsp, avctx->flags);
  1059.  
  1060.     return allocate_frame_buffers(ctx, avctx, avctx->width, avctx->height);
  1061. }
  1062.  
  1063.  
  1064. static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
  1065.                         AVPacket *avpkt)
  1066. {
  1067.     Indeo3DecodeContext *ctx = avctx->priv_data;
  1068.     const uint8_t *buf = avpkt->data;
  1069.     int buf_size       = avpkt->size;
  1070.     AVFrame *frame     = data;
  1071.     int res;
  1072.  
  1073.     res = decode_frame_headers(ctx, avctx, buf, buf_size);
  1074.     if (res < 0)
  1075.         return res;
  1076.  
  1077.     /* skip sync(null) frames */
  1078.     if (res) {
  1079.         // we have processed 16 bytes but no data was decoded
  1080.         *got_frame = 0;
  1081.         return buf_size;
  1082.     }
  1083.  
  1084.     /* skip droppable INTER frames if requested */
  1085.     if (ctx->frame_flags & BS_NONREF &&
  1086.        (avctx->skip_frame >= AVDISCARD_NONREF))
  1087.         return 0;
  1088.  
  1089.     /* skip INTER frames if requested */
  1090.     if (!(ctx->frame_flags & BS_KEYFRAME) && avctx->skip_frame >= AVDISCARD_NONKEY)
  1091.         return 0;
  1092.  
  1093.     /* use BS_BUFFER flag for buffer switching */
  1094.     ctx->buf_sel = (ctx->frame_flags >> BS_BUFFER) & 1;
  1095.  
  1096.     if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
  1097.         return res;
  1098.  
  1099.     /* decode luma plane */
  1100.     if ((res = decode_plane(ctx, avctx, ctx->planes, ctx->y_data_ptr, ctx->y_data_size, 40)))
  1101.         return res;
  1102.  
  1103.     /* decode chroma planes */
  1104.     if ((res = decode_plane(ctx, avctx, &ctx->planes[1], ctx->u_data_ptr, ctx->u_data_size, 10)))
  1105.         return res;
  1106.  
  1107.     if ((res = decode_plane(ctx, avctx, &ctx->planes[2], ctx->v_data_ptr, ctx->v_data_size, 10)))
  1108.         return res;
  1109.  
  1110.     output_plane(&ctx->planes[0], ctx->buf_sel,
  1111.                  frame->data[0], frame->linesize[0],
  1112.                  avctx->height);
  1113.     output_plane(&ctx->planes[1], ctx->buf_sel,
  1114.                  frame->data[1], frame->linesize[1],
  1115.                  (avctx->height + 3) >> 2);
  1116.     output_plane(&ctx->planes[2], ctx->buf_sel,
  1117.                  frame->data[2], frame->linesize[2],
  1118.                  (avctx->height + 3) >> 2);
  1119.  
  1120.     *got_frame = 1;
  1121.  
  1122.     return buf_size;
  1123. }
  1124.  
  1125.  
  1126. static av_cold int decode_close(AVCodecContext *avctx)
  1127. {
  1128.     free_frame_buffers(avctx->priv_data);
  1129.  
  1130.     return 0;
  1131. }
  1132.  
  1133. AVCodec ff_indeo3_decoder = {
  1134.     .name           = "indeo3",
  1135.     .long_name      = NULL_IF_CONFIG_SMALL("Intel Indeo 3"),
  1136.     .type           = AVMEDIA_TYPE_VIDEO,
  1137.     .id             = AV_CODEC_ID_INDEO3,
  1138.     .priv_data_size = sizeof(Indeo3DecodeContext),
  1139.     .init           = decode_init,
  1140.     .close          = decode_close,
  1141.     .decode         = decode_frame,
  1142.     .capabilities   = CODEC_CAP_DR1,
  1143. };
  1144.