cinepak.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:23k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * cinepak.c: cinepak video decoder
  3.  *****************************************************************************
  4.  * Copyright (C) 1999-2001 VideoLAN
  5.  * $Id: cinepak.c 8551 2004-08-28 17:36:02Z gbazin $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include <vlc/vlc.h>
  27. #include <vlc/vout.h>
  28. #include <vlc/decoder.h>
  29. /*****************************************************************************
  30.  * Module descriptor
  31.  *****************************************************************************/
  32. static int  OpenDecoder ( vlc_object_t * );
  33. static void CloseDecoder( vlc_object_t * );
  34. vlc_module_begin();
  35.     set_description( _("Cinepak video decoder") );
  36.     set_capability( "decoder", 100 );
  37.     set_callbacks( OpenDecoder, CloseDecoder );
  38. vlc_module_end();
  39. /*****************************************************************************
  40.  * Local prototypes
  41.  *****************************************************************************/
  42. #define CINEPAK_MAXSTRIP 32
  43. typedef struct
  44. {
  45.     uint8_t i_y[4];
  46.     uint8_t i_u, i_v;
  47. } cinepak_codebook_t;
  48. typedef struct
  49. {
  50.     int b_grayscale; /* force to grayscale */
  51.     int i_width;
  52.     int i_height;
  53.     int i_stride_x;
  54.     int i_stride_y;
  55.     uint8_t *p_y, *p_u, *p_v;
  56.     int i_stride[3]; /* our 3 planes */
  57.     int i_lines[3];
  58.     uint8_t *p_pix[3];
  59.     cinepak_codebook_t codebook_v1[CINEPAK_MAXSTRIP][256];
  60.     cinepak_codebook_t codebook_v4[CINEPAK_MAXSTRIP][256];
  61. } cinepak_context_t;
  62. /*****************************************************************************
  63.  * decoder_sys_t : decoder descriptor
  64.  *****************************************************************************/
  65. struct decoder_sys_t
  66. {
  67.     /*
  68.      * Cinepak properties
  69.      */
  70.     cinepak_context_t context;
  71. };
  72. static picture_t *DecodeBlock ( decoder_t *, block_t ** );
  73. static int cinepak_decode_frame( cinepak_context_t *, int, uint8_t * );
  74. /*****************************************************************************
  75.  * OpenDecoder: probe the decoder and return score
  76.  *****************************************************************************
  77.  * Tries to launch a decoder and return score so that the interface is able
  78.  * to chose.
  79.  *****************************************************************************/
  80. static int OpenDecoder( vlc_object_t *p_this )
  81. {
  82.     decoder_t *p_dec = (decoder_t*)p_this;
  83.     decoder_sys_t *p_sys;
  84.     vlc_value_t val;
  85.     if( p_dec->fmt_in.i_codec != VLC_FOURCC('c','v','i','d') &&
  86.         p_dec->fmt_in.i_codec != VLC_FOURCC('C','V','I','D') )
  87.     {
  88.         return VLC_EGENERIC;
  89.     }
  90.     /* Allocate the memory needed to store the decoder's structure */
  91.     if( ( p_dec->p_sys = p_sys = malloc(sizeof(decoder_sys_t)) ) == NULL )
  92.     {
  93.         msg_Err( p_dec, "out of memory" );
  94.         return VLC_EGENERIC;
  95.     }
  96.     memset( &p_sys->context, 0, sizeof( cinepak_context_t ) );
  97.     var_Create( p_dec, "grayscale", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
  98.     var_Get( p_dec, "grayscale", &val );
  99.     p_sys->context.b_grayscale = val.b_bool;
  100.     p_dec->pf_decode_video = DecodeBlock;
  101.     msg_Dbg( p_dec, "cinepak decoder started" );
  102.     return VLC_SUCCESS;
  103. }
  104. /****************************************************************************
  105.  * DecodeBlock: the whole thing
  106.  ****************************************************************************
  107.  * This function must be fed with whole frames.
  108.  ****************************************************************************/
  109. static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
  110. {
  111.     decoder_sys_t *p_sys = p_dec->p_sys;
  112.     int i_status, i_plane;
  113.     uint8_t *p_dst, *p_src;
  114.     picture_t *p_pic;
  115.     block_t *p_block;
  116.     if( !pp_block || !*pp_block )
  117.     {
  118.         return NULL;
  119.     }
  120.     p_block = *pp_block;
  121.     *pp_block = NULL;
  122.     i_status = cinepak_decode_frame( &p_sys->context, p_block->i_buffer,
  123.                                      p_block->p_buffer );
  124.     if( i_status < 0 )
  125.     {
  126.         msg_Warn( p_dec, "cannot decode one frame (%d bytes)",
  127.                   p_block->i_buffer );
  128.         block_Release( p_block );
  129.         return NULL;
  130.     }
  131.     p_dec->fmt_out.video.i_width = p_sys->context.i_width;
  132.     p_dec->fmt_out.video.i_height = p_sys->context.i_height;
  133.     p_dec->fmt_out.video.i_aspect = p_sys->context.i_width
  134.         * VOUT_ASPECT_FACTOR / p_sys->context.i_height;
  135.     p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0');
  136.     /* Get a new picture */
  137.     if( ( p_pic = p_dec->pf_vout_buffer_new( p_dec ) ) )
  138.     {
  139.         for( i_plane = 0; i_plane < 3; i_plane++ )
  140.         {
  141.             int i_line, i_lines;
  142.             p_dst = p_pic->p[i_plane].p_pixels;
  143.             p_src = p_sys->context.p_pix[i_plane];
  144.             i_lines = __MIN( p_sys->context.i_lines[i_plane],
  145.                              p_pic->p[i_plane].i_visible_lines );
  146.             for( i_line = 0; i_line < i_lines; i_line++ )
  147.             {
  148.                 memcpy( p_dst, p_src,
  149.                         __MIN( p_pic->p[i_plane].i_pitch,
  150.                                p_sys->context.i_stride[i_plane] ) );
  151.                 p_dst += p_pic->p[i_plane].i_pitch;
  152.                 p_src += p_sys->context.i_stride[i_plane];
  153.             }
  154.         }
  155.         p_pic->date = p_block->i_pts ? p_block->i_pts : p_block->i_dts;
  156.     }
  157.     block_Release( p_block );
  158.     return p_pic;
  159. }
  160. /*****************************************************************************
  161.  * CloseDecoder: decoder destruction
  162.  *****************************************************************************/
  163. static void CloseDecoder( vlc_object_t *p_this )
  164. {
  165.     decoder_t     *p_dec = (decoder_t *)p_this;
  166.     decoder_sys_t *p_sys = p_dec->p_sys;
  167.     int i;
  168.     msg_Dbg( p_dec, "cinepak decoder stopped" );
  169.     for( i = 0; i < 3; i++ )
  170.     {
  171.         if( p_sys->context.p_pix[i] ) free( p_sys->context.p_pix[i] );
  172.     }
  173.     free( p_sys );
  174. }
  175. /*****************************************************************************
  176.  * local Functions
  177.  *****************************************************************************/
  178. #define GET2BYTES( p ) 
  179.     GetWBE( p ); p+= 2;
  180. /* FIXME */
  181. #define GET3BYTES( p ) 
  182.     (GetDWBE( p ) >> 8); p+= 3;
  183. #define GET4BYTES( p ) 
  184.     GetDWBE( p ); p+= 4;
  185. #define FREE( p ) 
  186.     if( p ) free( p )
  187. static void cinepak_LoadCodebook( cinepak_codebook_t *p_codebook,
  188.                                   uint8_t *p_data, int b_grayscale )
  189. {
  190.     int i, i_y[4], i_u, i_v, i_Cb, i_Cr;
  191.     int i_uv;
  192. #define SCALEBITS 12
  193. #define FIX( x ) ( (int)( (x) * ( 1L << SCALEBITS ) + 0.5 ) )
  194.     for( i = 0; i < 4; i++ )
  195.     {
  196.         i_y[i] = (uint8_t)( *(p_data++) );
  197.     }
  198.     if( b_grayscale )
  199.     {
  200.         i_u  = (int8_t)( *(p_data++) );
  201.         i_v  = (int8_t)( *(p_data++) );
  202.     }
  203.     else
  204.     {
  205.         i_u  = 0;
  206.         i_v  = 0;
  207.     }
  208.     /*
  209.           | Y  |   | 1 -0.0655  0.0110 | | CY |
  210.           | Cb | = | 0  1.1656 -0.0062 | | CU |
  211.           | Cr |   | 0  0.0467  1.4187 | | CV |
  212.      */
  213.     i_uv = ( FIX( -0.0655 ) * i_u + FIX( 0.0110 ) * i_v ) >> SCALEBITS;
  214.     for( i = 0; i < 4; i++ )
  215.     {
  216.         i_y[i] += i_uv;
  217.     }
  218.     i_Cb  = ( FIX( 1.1656 ) * i_u + FIX( -0.0062 ) * i_v ) >> SCALEBITS;
  219.     i_Cr  = ( FIX( 0.0467 ) * i_u + FIX(  1.4187 ) * i_v ) >> SCALEBITS;
  220.     for( i = 0; i < 4; i++ )
  221.     {
  222.         p_codebook->i_y[i] = __MIN( __MAX( 0, i_y[i] ), 255 );
  223.     }
  224.     p_codebook->i_u  = __MIN( __MAX( 0, i_Cb + 128 ), 255 );
  225.     p_codebook->i_v  = __MIN( __MAX( 0, i_Cr + 128 ), 255 );
  226. #undef FIX
  227. #undef SCALEBITS
  228. }
  229. static void cinepak_Getv4( cinepak_context_t *p_context,
  230.                            int i_strip, int i_x, int i_y,
  231.                            int i_x2, int i_y2, uint8_t *p_data )
  232. {
  233.     uint8_t i_index[4];
  234.     int i,j;
  235.     uint8_t *p_dst_y, *p_dst_u, *p_dst_v;
  236. #define PIX_SET_Y( x, y, v ) 
  237.     p_dst_y[(x) + (y)* p_context->i_stride[0]] = (v);
  238. #define PIX_SET_UV( i, p, x, y, v ) 
  239.     p[(x) + (y)* (p_context->i_stride[i])] = (v);
  240.     for( i = 0; i < 4; i++ )
  241.     {
  242.         i_index[i] = *(p_data++);
  243.     }
  244.     /* y plane */
  245.     p_dst_y = p_context->p_pix[0] + p_context->i_stride[0] * i_y + i_x;
  246.     p_dst_u = p_context->p_pix[1] + p_context->i_stride[1] * (i_y/2) + (i_x/2);
  247.     p_dst_v = p_context->p_pix[2] + p_context->i_stride[2] * (i_y/2) + (i_x/2);
  248.     for( i = 0; i < 2; i++ )
  249.     {
  250.         for( j = 0; j < 2; j ++ )
  251.         {
  252.             PIX_SET_Y( 2*j + 0, 2*i + 0,
  253.                        p_context->codebook_v4[i_strip][i_index[j+2*i]].i_y[0]);
  254.             PIX_SET_Y( 2*j + 1, 2*i + 0,
  255.                        p_context->codebook_v4[i_strip][i_index[j+2*i]].i_y[1]);
  256.             PIX_SET_Y( 2*j + 0, 2*i + 1,
  257.                        p_context->codebook_v4[i_strip][i_index[j+2*i]].i_y[2]);
  258.             PIX_SET_Y( 2*j + 1, 2*i + 1,
  259.                        p_context->codebook_v4[i_strip][i_index[j+2*i]].i_y[3]);
  260.             PIX_SET_UV( 1, p_dst_u, j, i,
  261.                         p_context->codebook_v4[i_strip][i_index[j+2*i]].i_u );
  262.             PIX_SET_UV( 2, p_dst_v, j, i,
  263.                         p_context->codebook_v4[i_strip][i_index[j+2*i]].i_v );
  264.         }
  265.     }
  266. #undef PIX_SET_Y
  267. #undef PIX_SET_UV
  268. }
  269. static void cinepak_Getv1( cinepak_context_t *p_context,
  270.                            int i_strip, int i_x,  int i_y,
  271.                            int i_x2, int i_y2, uint8_t *p_data )
  272. {
  273.     uint8_t i_index;
  274.     int i,j;
  275.     uint8_t *p_dst_y, *p_dst_u, *p_dst_v;
  276. #define PIX_SET_Y( x, y, v ) 
  277.     p_dst_y[(x) + (y)* p_context->i_stride[0]] = (v);
  278. #define PIX_SET_UV( i,p, x, y, v ) 
  279.     p[(x) + (y)* (p_context->i_stride[i])] = (v);
  280.     i_index = *(p_data++);
  281.     /* y plane */
  282.     p_dst_y = p_context->p_pix[0] + p_context->i_stride[0] * i_y + i_x;
  283.     p_dst_u = p_context->p_pix[1] + p_context->i_stride[1] * (i_y/2) + (i_x/2);
  284.     p_dst_v = p_context->p_pix[2] + p_context->i_stride[2] * (i_y/2) + (i_x/2);
  285.     for( i = 0; i < 2; i++ )
  286.     {
  287.         for( j = 0; j < 2; j ++ )
  288.         {
  289.             PIX_SET_Y( 2*j + 0, 2*i + 0,
  290.                        p_context->codebook_v1[i_strip][i_index].i_y[2*i+j] );
  291.             PIX_SET_Y( 2*j + 1, 2*i + 0,
  292.                        p_context->codebook_v1[i_strip][i_index].i_y[2*i+j] );
  293.             PIX_SET_Y( 2*j + 0, 2*i + 1,
  294.                        p_context->codebook_v1[i_strip][i_index].i_y[2*i+j] );
  295.             PIX_SET_Y( 2*j + 1, 2*i + 1,
  296.                        p_context->codebook_v1[i_strip][i_index].i_y[2*i+j] );
  297.             PIX_SET_UV( 1,p_dst_u, j, i,
  298.                         p_context->codebook_v1[i_strip][i_index].i_u );
  299.             PIX_SET_UV( 2,p_dst_v, j, i,
  300.                         p_context->codebook_v1[i_strip][i_index].i_v );
  301.         }
  302.     }
  303. #undef PIX_SET_Y
  304. #undef PIX_SET_UV
  305. }
  306. /*****************************************************************************
  307.  * The function that decode one frame
  308.  *****************************************************************************/
  309. static int cinepak_decode_frame( cinepak_context_t *p_context,
  310.                                  int i_length, uint8_t *p_data )
  311. {
  312.     int i_strip;
  313.     int i_frame_flags;
  314.     int i_frame_size;
  315.     int i_width, i_height;
  316.     int i_frame_strips;
  317.     int i_index;
  318.     int i_strip_x1 =0, i_strip_y1=0;
  319.     int i_strip_x2 =0, i_strip_y2=0;
  320.     if( i_length <= 10 )
  321.     {
  322.         /* Broken header or no data */
  323.         return( -1 );
  324.     }
  325.     /* get header */
  326.     i_frame_flags  = *(p_data++);
  327.     i_frame_size = GET3BYTES( p_data );
  328.     i_width  = GET2BYTES( p_data );
  329.     i_height = GET2BYTES( p_data );
  330.     i_frame_strips = GET2BYTES( p_data );
  331.     if( !i_frame_size || !i_width || !i_height )
  332.     {
  333.         /* Broken header */
  334.         return( -1 );
  335.     }
  336.     /* Check if we have a picture buffer with good size */
  337.     if( ( p_context->i_width != i_width ) ||
  338.         ( p_context->i_height != i_height ) )
  339.     {
  340.         int i;
  341.         for( i = 0; i < 3; i++ )
  342.         {
  343.             FREE( p_context->p_pix[i] );
  344.         }
  345.         p_context->i_width = i_width;
  346.         p_context->i_height = i_height;
  347.         p_context->i_stride[0] = ( i_width + 3 ) & 0xfffc;
  348.         p_context->i_stride[1] = p_context->i_stride[2] =
  349.                 p_context->i_stride[0] / 2;
  350.         p_context->i_lines[0] = ( i_height + 3 ) & 0xfffc;
  351.         p_context->i_lines[1] = p_context->i_lines[2] =
  352.                 p_context->i_lines[0] /2;
  353.         for( i = 0; i < 3; i++ )
  354.         {
  355.             p_context->p_pix[i] = malloc( p_context->i_stride[i] *
  356.                                           p_context->i_lines[i] );
  357.             /* Set it to all black */
  358.             memset( p_context->p_pix[i], ( i == 0 ) ? 0 : 128 ,
  359.                     p_context->i_stride[i] * p_context->i_lines[i] );
  360.         }
  361.     }
  362.     if( i_frame_size != i_length )
  363.     {
  364.         i_length = __MIN( i_length, i_frame_size );
  365.     }
  366.     i_length -= 10;
  367.     if( i_frame_strips >= CINEPAK_MAXSTRIP )
  368.     {
  369.         i_frame_strips = CINEPAK_MAXSTRIP;
  370.     }
  371.     /* Now decode each strip */
  372.     for( i_strip = 0; i_strip < i_frame_strips; i_strip++ )
  373.     {
  374.         int i_strip_id;
  375.         int i_strip_size;
  376.         if( i_length <= 12 )
  377.         {
  378.             break;
  379.         }
  380.         i_strip_id   = GET2BYTES( p_data );
  381.         i_strip_size = GET2BYTES( p_data );
  382.         i_strip_size = __MIN( i_strip_size, i_length );
  383.         /* FIXME I don't really understand how it's work; */
  384.         i_strip_y1  = i_strip_y2 + GET2BYTES( p_data );
  385.         i_strip_x1  = GET2BYTES( p_data );
  386.         i_strip_y2  = i_strip_y2 + GET2BYTES( p_data );
  387.         i_strip_x2  = GET2BYTES( p_data );
  388.         i_length -= i_strip_size;
  389.         i_strip_size -= 12;
  390.         /* init codebook , if needed */
  391.         if( ( i_strip > 0 )&&( !(i_frame_flags&0x01) ) )
  392.         {
  393.             memcpy( &p_context->codebook_v1[i_strip],
  394.                     &p_context->codebook_v1[i_strip-1],
  395.                     sizeof(cinepak_codebook_t[256] ) );
  396.             memcpy( &p_context->codebook_v4[i_strip],
  397.                     &p_context->codebook_v4[i_strip-1],
  398.                     sizeof(cinepak_codebook_t[256] ) );
  399.         }
  400.         /* Now parse all chunk in this strip */
  401.         while( i_strip_size > 0 )
  402.         {
  403.             cinepak_codebook_t (*p_codebook)[CINEPAK_MAXSTRIP][256];
  404.             int i_mode;
  405.             int i_chunk_id;
  406.             int i_chunk_size;
  407.             uint32_t i_vector_flags;
  408.             int i_count;
  409.             int i;
  410.             int i_x, i_y; /* (0,0) begin in fact at (x1,y1) ... */
  411.             i_chunk_id   = GET2BYTES( p_data );
  412.             i_chunk_size = GET2BYTES( p_data );
  413.             i_chunk_size  = __MIN( i_chunk_size, i_strip_size );
  414.             i_strip_size -= i_chunk_size;
  415.             i_chunk_size -= 4;
  416.             i_x = 0;
  417.             i_y = 0;
  418.             if( i_chunk_size < 0 )
  419.             {
  420.                 break;
  421.             }
  422.             switch( i_chunk_id )
  423.             {
  424.             case( 0x2000 ): /* 12bits v4 Intra*/
  425.             case( 0x2200 ): /* 12bits v1 Intra*/
  426.             case( 0x2400 ): /* 8bits v4 Intra*/
  427.             case( 0x2600 ): /* 8bits v1 Intra */
  428.                 i_mode = ( ( i_chunk_id&0x0400 ) == 0 );
  429.                 p_codebook = ( i_chunk_id&0x0200 ) ?
  430.                                &p_context->codebook_v1 :
  431.                                &p_context->codebook_v4;
  432.                 i_count = __MIN( i_chunk_size / ( i_mode ? 6 : 4 ), 256 );
  433.                 for( i = 0; i < i_count; i++ )
  434.                 {
  435.                     cinepak_LoadCodebook( &((*p_codebook)[i_strip][i]),
  436.                                           p_data,
  437.                                           i_mode&~p_context->b_grayscale );
  438.                     p_data += i_mode ? 6 : 4;
  439.                     i_chunk_size -= i_mode ? 6 : 4;
  440.                 }
  441.                 break;
  442.             case( 0x2100 ): /* selective 12bits v4 Inter*/
  443.             case( 0x2300 ): /* selective 12bits v1 Inter*/
  444.             case( 0x2500 ): /* selective 8bits v4 Inter*/
  445.             case( 0x2700 ): /* selective 8bits v1 Inter*/
  446.                 i_mode = ( ( i_chunk_id&0x0400 ) == 0 );
  447.                 p_codebook = ( i_chunk_id&0x0200 ) ?
  448.                                &p_context->codebook_v1 :
  449.                                &p_context->codebook_v4;
  450.                 i_index = 0;
  451.                 while( (i_chunk_size > 4)&&(i_index<256))
  452.                 {
  453.                     i_vector_flags = GET4BYTES( p_data );
  454.                     i_chunk_size -= 4;
  455.                     for( i = 0; i < 32; i++ )
  456.                     {
  457.                         if( ( i_chunk_size < ( i_mode ? 6 : 4 ) )
  458.                             || (i_index >= 256 ) )
  459.                         {
  460.                             break;
  461.                         }
  462.                         if( i_vector_flags&0x80000000UL )
  463.                         {
  464.                             cinepak_LoadCodebook(
  465.                                 &((*p_codebook)[i_strip][i_index]),
  466.                                 p_data, i_mode&~p_context->b_grayscale );
  467.                             p_data += i_mode ? 6 : 4;
  468.                             i_chunk_size -= i_mode ? 6 : 4;
  469.                         }
  470.                         i_index++;
  471.                         i_vector_flags <<= 1;
  472.                     }
  473.                 }
  474.                 break;
  475.             case( 0x3000 ): /* load image Intra */
  476.                 while( (i_chunk_size >= 4 )&&(i_y<i_strip_y2-i_strip_y1) )
  477.                 {
  478.                     i_vector_flags = GET4BYTES( p_data );
  479.                     i_chunk_size -= 4;
  480.                     i_strip_size -= 4;
  481.                     i_length     -= 4;
  482.                     for( i = 0; i < 32; i++ )
  483.                     {
  484.                         if( ( i_y >= i_strip_y2 - i_strip_y1) ||
  485.                             ( i_chunk_size<=0 ) )
  486.                         {
  487.                             break;
  488.                         }
  489.                         if( i_vector_flags&0x80000000UL )
  490.                         {
  491.                             cinepak_Getv4( p_context,
  492.                                            i_strip,
  493.                                            i_strip_x1 + i_x,
  494.                                            i_strip_y1 + i_y,
  495.                                            i_strip_x2, i_strip_y2,
  496.                                            p_data );
  497.                             p_data += 4;
  498.                             i_chunk_size -= 4;
  499.                         }
  500.                         else
  501.                         {
  502.                             cinepak_Getv1( p_context,
  503.                                            i_strip,
  504.                                            i_strip_x1 + i_x,
  505.                                            i_strip_y1 + i_y,
  506.                                            i_strip_x2, i_strip_y2,
  507.                                            p_data );
  508.                             p_data++;
  509.                             i_chunk_size--;
  510.                         }
  511.                         i_x += 4;
  512.                         if( i_x >= i_strip_x2 - i_strip_x1 )
  513.                         {
  514.                             i_x = 0;
  515.                             i_y += 4;
  516.                         }
  517.                         i_vector_flags <<= 1;
  518.                     }
  519.                 }
  520.                 break;
  521.             case( 0x3100 ): /* load image Inter */
  522.                 while( ( i_chunk_size > 4 )&&( i_y < i_strip_y2 - i_strip_y1) )
  523.                 {
  524.                     uint32_t i_mask;
  525.                     i_vector_flags = GET4BYTES( p_data );
  526.                     i_chunk_size -= 4;
  527.                     i_mask = 0x80000000UL;
  528.                     while( (i_chunk_size > 0 ) && ( i_mask )
  529.                            && ( i_y < i_strip_y2 - i_strip_y1 ) )
  530.                     {
  531.                         if( i_vector_flags&i_mask )
  532.                         {
  533.                             i_mask >>= 1;
  534.                             if( !i_mask )
  535.                             {
  536.                                 if( i_chunk_size < 4 )
  537.                                 {
  538.                                     break;
  539.                                 }
  540.                                 i_vector_flags = GET4BYTES( p_data );
  541.                                 i_chunk_size -= 4;
  542.                                 i_mask = 0x80000000UL;
  543.                             }
  544.                             if( i_vector_flags&i_mask )
  545.                             {
  546.                                 if( i_chunk_size < 4 ) break;
  547.                                 cinepak_Getv4( p_context,
  548.                                                i_strip,
  549.                                                i_strip_x1 + i_x,
  550.                                                i_strip_y1 + i_y,
  551.                                                i_strip_x2, i_strip_y2,
  552.                                                p_data );
  553.                                 p_data += 4;
  554.                                 i_chunk_size -= 4;
  555.                             }
  556.                             else
  557.                             {
  558.                                 if( i_chunk_size < 1 ) break;
  559.                                 cinepak_Getv1( p_context,
  560.                                                i_strip,
  561.                                                i_strip_x1 + i_x,
  562.                                                i_strip_y1 + i_y,
  563.                                                i_strip_x2, i_strip_y2,
  564.                                                p_data );
  565.                                 p_data++;
  566.                                 i_chunk_size--;
  567.                             }
  568.                         }
  569.                         i_mask >>= 1;
  570.                         i_x += 4;
  571.                         if( i_x >= i_strip_x2 - i_strip_x1 )
  572.                         {
  573.                             i_x = 0;
  574.                             i_y += 4;
  575.                         }
  576.                     }
  577.                 }
  578.                 break;
  579.             case( 0x3200 ): /* load intra picture but all v1*/
  580.                 while( ( i_chunk_size > 0 ) &&
  581.                        ( i_y < i_strip_y2 - i_strip_y1 ) )
  582.                 {
  583.                     cinepak_Getv1( p_context,
  584.                                    i_strip,
  585.                                    i_strip_x1 + i_x,
  586.                                    i_strip_y1 + i_y,
  587.                                    i_strip_x2, i_strip_y2,
  588.                                    p_data );
  589.                     p_data++;
  590.                     i_chunk_size--;
  591.                     i_x += 4;
  592.                     if( i_x >= i_strip_x2 - i_strip_x1 )
  593.                     {
  594.                         i_x = 0;
  595.                         i_y += 4;
  596.                     }
  597.                 }
  598.                 break;
  599.             default:
  600.                 break;
  601.             }
  602.             p_data += i_chunk_size ; /* skip remains bytes */
  603.         }
  604.     }
  605.     return( 0 );
  606. }