getpic.cc
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:23k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /*
  2.   File: getpic.cc
  3. */
  4. #include <string.h>
  5. #include "all.hh"
  6. #ifdef HAVE_MMX
  7. extern "C" void IDCT_mmx(short *);
  8. extern "C" void add_block_mmx(unsigned char *, short *, int);
  9. extern "C" void set_block_mmx(unsigned char *, short *, int);
  10. static unsigned long long MMX_128 = 0x80008000800080LL;
  11. #endif
  12. /* ---------------------------------------------------
  13. */
  14. static void j_rev_dct_sparse (short *data)
  15. {
  16.   short int val;
  17.   int v;
  18.   int quant;
  19.   v = *data;
  20. #ifdef HAVE_MMX
  21.   quant = 8 * 16;
  22. #else
  23.   quant = 8;
  24. #endif
  25.   if (v < 0) {
  26.     val = -v;
  27.     val += (quant >> 1);
  28.     val /= quant;
  29.     val = -val;
  30.   }
  31.   else {
  32.     val = (v + (quant >> 1)) / quant;
  33.   }
  34.   *data = val;
  35.   return;
  36. }
  37. // decode one frame or field picture
  38. void LayerData::getpicture(int framenum){
  39.   if (pict_struct==FRAME_PICTURE && secondfield){
  40.     /* recover from illegal number of field pictures */
  41.     printf("odd number of field picturesn");
  42.     secondfield = 0;
  43.   }
  44.   for (int i=0; i<3; i++){
  45.     if (pict_type==B_TYPE) newframe[i] = auxframe[i];
  46.     else {
  47.       if (!secondfield){
  48.         unsigned char* tmp = oldrefframe[i];
  49.         oldrefframe[i] = refframe[i];
  50.         refframe[i] = tmp;
  51.       }
  52.       newframe[i] = refframe[i];
  53.     }
  54.     if (pict_struct==BOTTOM_FIELD)
  55.       newframe[i]+= (i==0) ? coded_picture_width : chrom_width;
  56.   }
  57. //if (pict_scal && !secondfield) getspatref();
  58.   getMBs(framenum);
  59.   if (framenum!=0){
  60.     if (pict_struct==FRAME_PICTURE || secondfield){
  61.       if (pict_type==B_TYPE) display->dither(auxframe);
  62.       else                   display->dither(oldrefframe);
  63.     }
  64.     else display->display_second_field();
  65.   }
  66.   if (pict_struct!=FRAME_PICTURE) secondfield = !secondfield;
  67. }
  68. // store last frame
  69. void LayerData::putlast(){
  70.   if (secondfield) printf("last frame incomplete, not storedn");
  71.   else display->dither(refframe);
  72. }
  73. /* decode all macroblocks of the current picture */
  74. void LayerData::getMBs(int framenum){
  75.   int comp;
  76.   int MBA, MBAmax, MBAinc, mb_type, cbp, motion_type(0), dct_type;
  77.   int slice_vert_pos_ext;
  78.   int bx, by;
  79.   unsigned int code;
  80.   int dc_dct_pred[3];
  81.   int mv_count, mv_format, mvscale;
  82.   int PMV[2][2][2], mv_field_sel[2][2];
  83.   int dmv, dmvector[2];
  84.   int qs;
  85.   int stwtype, stwclass; 
  86.   int SNRcbp;
  87. //  int SNRMBA(0), SNRmb_type,, SNRMBAinc(0), SNRdct_type, dummy; // SNR scal.
  88.   /* number of macroblocks per picture */
  89.   MBAmax = mb_width*mb_height;
  90.   if (pict_struct!=FRAME_PICTURE)
  91.     MBAmax>>=1; /* field picture has half as mnay macroblocks as frame */
  92.   MBA = 0; /* macroblock address */
  93.   MBAinc = 0;
  94. /*
  95.   if (twostreams && enhan.scalable_mode==SC_SNR){
  96.     SNRMBA=0;
  97.     SNRMBAinc=0;
  98.   }
  99. */
  100.   fault=0;
  101.   for (;;){
  102. #ifdef TRACE
  103.     if (trace) printf("frame %d, MB %dn",framenum,MBA);
  104. #endif
  105.     if (!prog_seq && pict_struct==FRAME_PICTURE && MBA==(MBAmax>>1) &&
  106.         framenum!=0)
  107. // && display->getType()==T_X11)
  108.       display->display_second_field();
  109. //  ld = &base;
  110.     if (MBAinc==0){
  111. //      if (scalable_mode==SC_DP && pri_brk==1) ld = &enhan;
  112.       if (!input->showbits(23) || fault){ /* startcode or fault */
  113. resync: /* if fault: resynchronize to next startcode */
  114.         fault = 0;
  115.         if (MBA>=MBAmax) return; /* all macroblocks decoded */
  116.         code=input->startcode();
  117.         if (code<Slice_min_start || code>Slice_max_start){
  118.           /* only slice headers are allowed in picture_data */
  119.           if (!quiet) printf("Premature end of picturen");
  120.           return;
  121.         }
  122.         input->flushbits(32);
  123.         /* decode slice header (may change quant_scale) */
  124.         slice_vert_pos_ext = getslicehdr();
  125. /*
  126.         if (scalable_mode==SC_DP){
  127.           ld = &enhan;
  128.           input->startcode();
  129.           code = input->showbits(32);
  130.           if (code<SLICE_MIN_START || code>SLICE_MAX_START){
  131.             // only slice headers are allowed in picture_data
  132.             if (!quiet) printf("Premature end of picturen");
  133.             return;
  134.           }
  135.           input->flushbits(32);
  136.           // decode slice header (may change quant_scale)
  137.           slice_vert_pos_ext = getslicehdr();
  138. //          if (pri_brk!=1) ld = &base;
  139.         }
  140. */
  141.         /* decode macroblock address increment */
  142.         MBAinc = getMBA();
  143.         if (fault) goto resync;
  144.         /* set current location */
  145.         MBA = ((slice_vert_pos_ext<<7) + (code&255) - 1)*mb_width + MBAinc - 1;
  146.         MBAinc = 1; /* first macroblock in slice: not skipped */
  147.         /* reset all DC coefficient and motion vector predictors */
  148.         dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0;
  149.         PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
  150.         PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0;
  151.       }
  152.       else { /* neither startcode nor fault */
  153.         if (MBA>=MBAmax){
  154.           if (!quiet) printf("Too many macroblocks in picturen");
  155.           return;
  156.         }
  157. /*
  158.         if (scalable_mode==SC_DP && pri_brk==1) ld = &enhan;
  159. */
  160.         /* decode macroblock address increment */
  161.         MBAinc = getMBA();
  162.         if (fault) goto resync;
  163.       }
  164.     }
  165.     if (MBA>=MBAmax){
  166.       /* MBAinc points beyond picture dimensions */
  167.       if (!quiet) printf("Too many macroblocks in picturen");
  168.       return;
  169.     }
  170.     if (MBAinc==1) /* not skipped */{
  171. /*
  172.       if (scalable_mode==SC_DP){
  173.         if (pri_brk<=2) ld = &enhan;
  174.         else ld = &base;
  175.       }
  176. */
  177.       macroblock_modes(&mb_type, &stwtype, &stwclass,
  178.         &motion_type, &mv_count, &mv_format, &dmv, &mvscale, &dct_type);
  179.       if (fault) goto resync;
  180.       if (mb_type & MB_QUANT){
  181.         qs = input->getbits(5);
  182. #ifdef TRACE
  183.         if (trace){
  184.           printf("quantiser_scale_code (");
  185.           printbits(qs,5,5);
  186.           printf("): %dn",qs);
  187.         }
  188. #endif
  189.         if (mpeg2)
  190.              quant_scale = qscale_type ? non_linear_mquant_table[qs] : (qs << 1);
  191.         else quant_scale = qs;
  192.         if (scalable_mode==SC_DP)
  193.           /* make sure quant_scale is valid */
  194.           quant_scale = quant_scale;
  195.       }
  196.       /* motion vectors */
  197.       /* decode forward motion vectors */
  198.       if ((mb_type & MB_FORWARD) || ((mb_type & MB_INTRA) && conceal_mv)){
  199.         if (mpeg2)
  200.           motion_vectors(PMV,dmvector,mv_field_sel,
  201.             0,mv_count,mv_format,h_forw_r_size,v_forw_r_size,dmv,mvscale);
  202.         else
  203.           motion_vector(PMV[0][0],dmvector,
  204.             forw_r_size,forw_r_size,0,0,full_forw);
  205.       }
  206.       if (fault) goto resync;
  207.       /* decode backward motion vectors */
  208.       if (mb_type & MB_BACKWARD){
  209.         if (mpeg2)
  210.           motion_vectors(PMV,dmvector,mv_field_sel,
  211.             1,mv_count,mv_format,h_back_r_size,v_back_r_size,0,mvscale);
  212.         else
  213.           motion_vector(PMV[0][1],dmvector,
  214.             back_r_size,back_r_size,0,0,full_back);
  215.       }
  216.       if (fault) goto resync;
  217.       if ((mb_type & MB_INTRA) && conceal_mv)
  218.         input->flushbits(1); /* remove marker_bit */
  219. /*
  220.       if (scalable_mode==SC_DP && pri_brk==3) ld = &enhan;
  221. */
  222.       /* macroblock_pattern */
  223.       if (mb_type & MB_PATTERN){
  224.         cbp = getCBP();
  225.         if (chroma_format==CHROMA422){
  226.           cbp = (cbp<<2) | input->getbits(2); /* coded_block_pattern_1 */
  227. #ifdef TRACE
  228.           if (trace){
  229.             printf("coded_block_pattern_1: ");
  230.             printbits(cbp,2,2);
  231.             printf(" (%d)n",cbp&3);
  232.           }
  233. #endif
  234.         }
  235.         else if (chroma_format==CHROMA444){
  236.           cbp = (cbp<<6) | input->getbits(6); /* coded_block_pattern_2 */
  237. #ifdef TRACE
  238.           if (trace){
  239.             printf("coded_block_pattern_2: ");
  240.             printbits(cbp,6,6);
  241.             printf(" (%d)n",cbp&63);
  242.           }
  243. #endif
  244.         }
  245.       }
  246.       else
  247.         cbp = (mb_type & MB_INTRA) ? (1<<blk_cnt)-1 : 0;
  248.       if (fault) goto resync;
  249.       /* decode blocks */
  250.       clearblock(0,blk_cnt);
  251.       for (comp=0; comp<blk_cnt; comp++){
  252. //        if (scalable_mode==SC_DP) ld = &base;
  253.         if (cbp & (1<<(blk_cnt-1-comp))){
  254.           if (mb_type & MB_INTRA){
  255.             if (mpeg2) getmpg2intrablock(comp,dc_dct_pred);
  256.             else           getintrablock(comp,dc_dct_pred);
  257.           }
  258.           else {
  259.             if (mpeg2) getmpg2interblock(comp);
  260.             else           getinterblock(comp);
  261.           }
  262.           if (fault) goto resync;
  263.         }
  264.       }
  265.       /* reset intra_dc predictors */
  266.       if (!(mb_type & MB_INTRA))
  267.         dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0;
  268.       /* reset motion vector predictors */
  269.       if ((mb_type & MB_INTRA) && !conceal_mv){
  270.         /* intra mb without concealment motion vectors */
  271.         PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
  272.         PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0;
  273.       }
  274.       if ((pict_type==P_TYPE) && !(mb_type & (MB_FORWARD|MB_INTRA))){
  275.         /* non-intra mb without forward mv in a P picture */
  276.         PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
  277.         /* derive motion_type */
  278.         if (pict_struct==FRAME_PICTURE) motion_type = MC_FRAME;
  279.         else
  280.         {
  281.           motion_type = MC_FIELD;
  282.           /* predict from field of same parity */
  283.           mv_field_sel[0][0] = (pict_struct==BOTTOM_FIELD);
  284.         }
  285.       }
  286.       if (stwclass==4)
  287.       {
  288.         /* purely spatially predicted macroblock */
  289.         PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
  290.         PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0;
  291.       }
  292.     }
  293.     else { /* MBAinc!=1: skipped macroblock */
  294. //      if (scalable_mode==SC_DP) ld = &base;
  295.       clearblock(0,blk_cnt);
  296.       /* reset intra_dc predictors */
  297.       dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0;
  298.       /* reset motion vector predictors */
  299.       if (pict_type==P_TYPE)
  300.         PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
  301.       /* derive motion_type */
  302.       if (pict_struct==FRAME_PICTURE)
  303.         motion_type = MC_FRAME;
  304.       else
  305.       {
  306.         motion_type = MC_FIELD;
  307.         /* predict from field of same parity */
  308.         mv_field_sel[0][0]=mv_field_sel[0][1] = (pict_struct==BOTTOM_FIELD);
  309.       }
  310.       /* skipped I are spatial-only predicted, */
  311.       /* skipped P and B are temporal-only predicted */
  312.       stwtype = (pict_type==I_TYPE) ? 8 : 0;
  313.       /* clear MB_INTRA */
  314.       mb_type&= ~MB_INTRA;
  315.       cbp = 0; /* no block data */
  316.     }
  317.     SNRcbp = 0;
  318. #ifdef ENHANCEMENT
  319.     if (twostreams && enhan.scalable_mode==SC_SNR){
  320.       ld = &enhan;
  321.       if (SNRMBAinc==0){
  322.         if (!input->showbits(23)){ /* startcode */
  323.           code=input->startcode();
  324. //          code = input->showbits(32);
  325.           if (code<SLICE_MIN_START || code>SLICE_MAX_START){
  326.             /* only slice headers are allowed in picture_data */
  327.             if (!quiet)
  328.               printf("Premature end of picturen");
  329.             return;
  330.           }
  331.           input->flushbits(32);
  332.           /* decode slice header (may change quant_scale) */
  333.           slice_vert_pos_ext = getslicehdr();
  334.           /* decode macroblock address increment */
  335.           SNRMBAinc = getMBA();
  336.           /* set current location */
  337.           SNRMBA =
  338.             ((slice_vert_pos_ext<<7) + (code&255) - 1)*mb_width + SNRMBAinc - 1;
  339.           SNRMBAinc = 1; /* first macroblock in slice: not skipped */
  340.         }
  341.         else { /* not startcode */
  342.           if (SNRMBA>=MBAmax){
  343.             if (!quiet) printf("Too many macroblocks in picturen");
  344.             return;
  345.           }
  346.           /* decode macroblock address increment */
  347.           SNRMBAinc = getMBA();
  348.         }
  349.       }
  350.       if (SNRMBA!=MBA){
  351.         /* streams out of sync */
  352.         if (!quiet) printf("Cant't synchronize streamsn");
  353.         return;
  354.       }
  355.       if (SNRMBAinc==1){     /* not skipped */
  356.         macroblock_modes(&SNRmb_type, &dummy, &dummy,
  357.           &dummy, &dummy, &dummy, &dummy, &dummy,
  358.           &SNRdct_type);
  359.         if (SNRmb_type & MB_PATTERN) dct_type = SNRdct_type;
  360.         if (SNRmb_type & MB_QUANT){
  361.           qs = input->getbits(5);
  362.           quant_scale = qscale_type ? non_linear_mquant_table[qs] : qs<<1;
  363.         }
  364.         /* macroblock_pattern */
  365.         if (SNRmb_type & MB_PATTERN)
  366.         {
  367.           SNRcbp = getCBP();
  368.           if (chroma_format==CHROMA422)
  369.             SNRcbp = (SNRcbp<<2) | input->getbits(2); /* coded_block_pattern_1 */
  370.           else if (chroma_format==CHROMA444)
  371.             SNRcbp = (SNRcbp<<6) | input->getbits(6); /* coded_block_pattern_2 */
  372.         }
  373.         else
  374.           SNRcbp = 0;
  375.         /* decode blocks */
  376.         clearblock(0,blk_cnt);
  377.         for (comp=0; comp<blk_cnt; comp++)
  378.         {
  379.           if (SNRcbp & (1<<(blk_cnt-1-comp)))
  380.             getmpg2interblock(comp);
  381.         }
  382.       }
  383.       else /* SNRMBAinc!=1: skipped macroblock */
  384.       {
  385.         clearblock(0,blk_cnt);
  386.       }
  387. //      ld = &base;
  388.     }
  389. #endif
  390.     /* pixel coordinates of top left corner of current macroblock */
  391.     bx = 16*(MBA%mb_width);
  392.     by = 16*(MBA/mb_width);
  393.     /* motion compensation */
  394.     if (!(mb_type & MB_INTRA))
  395.       reconstruct(bx,by,mb_type,motion_type,PMV,mv_field_sel,dmvector,
  396.                   stwtype);
  397. #ifdef ENHANCEMENT
  398.     if (scalable_mode==SC_DP) ld = &base;
  399. #endif
  400.     /* copy or add block data into picture */
  401.     for (comp=0; comp<blk_cnt; comp++){
  402.       if ((cbp|SNRcbp) & (1<<(blk_cnt-1-comp))){
  403. #ifdef ENHANCEMENT
  404.         if (twostreams && enhan.scalable_mode==SC_SNR &&
  405.             SNRcbp & (1<<(blk_cnt-1-comp)))
  406.           sumblock(comp); /* add SNR enhancement layer data to base layer */
  407. #endif
  408.         /* inverse DCT */
  409. //        if (sparse[comp])
  410. //           j_rev_dct_sparse(block[comp]);
  411. //        else {
  412. #ifdef HAVE_MMX
  413.      IDCT_mmx(block[comp]);
  414. #else
  415.           idct->conversion(block[comp]);
  416. #endif
  417. //        }
  418.         addblock(comp,bx,by,dct_type,(mb_type & MB_INTRA)==0);
  419.       }
  420.     }
  421.     /* advance to next macroblock */
  422.     MBA++;
  423.     MBAinc--;
  424. #ifdef ENHANCEMENT
  425.     if (twostreams && enhan.scalable_mode==SC_SNR){
  426.       SNRMBA++;
  427.       SNRMBAinc--;
  428.     }
  429. #endif
  430.   }
  431. }
  432. void LayerData::macroblock_modes(int *pmb_type, int *pstwtype, int *pstwclass,
  433.   int *pmotion_type, int *pmv_count, int *pmv_format, int *pdmv, int *pmvscale,
  434.   int *pdct_type)
  435. {
  436.   int mb_type;
  437.   int stwtype, stwcode, stwclass;
  438.   int motion_type(0), mv_count, mv_format, dmv, mvscale;
  439.   int dct_type;
  440.   static unsigned char stwc_table[3][4]
  441.     = { {6,3,7,4}, {2,1,5,4}, {2,5,7,4} };
  442.   static unsigned char stwclass_table[9]
  443.     = {0, 1, 2, 1, 1, 2, 3, 3, 4};
  444.   /* get macroblock_type */
  445.   mb_type = getMBtype();
  446.   if (fault) return;
  447.   /* get spatial_temporal_weight_code */
  448.   if (mb_type & MB_WEIGHT)
  449.   {
  450.     if (stwc_table_index==0)
  451.       stwtype = 4;
  452.     else
  453.     {
  454.       stwcode = input->getbits(2);
  455.       stwtype = stwc_table[stwc_table_index-1][stwcode];
  456.     }
  457.   }
  458.   else
  459.     stwtype = (mb_type & MB_CLASS4) ? 8 : 0;
  460.   /* derive spatial_temporal_weight_class (Table 7-18) */
  461.   stwclass = stwclass_table[stwtype];
  462.   /* get frame/field motion type */
  463.   if (mb_type & (MB_FORWARD|MB_BACKWARD)){
  464.     if (pict_struct==FRAME_PICTURE){ /* frame_motion_type */
  465.       motion_type = frame_pred_dct ? MC_FRAME : input->getbits(2);
  466. #ifdef TRACE
  467.       if (!frame_pred_dct && trace){
  468.         printf("frame_motion_type (");
  469.         printbits(motion_type,2,2);
  470.         printf("): %sn",motion_type==MC_FIELD?"Field":
  471.                          motion_type==MC_FRAME?"Frame":
  472.                          motion_type==MC_DMV?"Dual_Prime":"Invalid");
  473.       }
  474. #endif
  475.     }
  476.     else { /* field_motion_type */
  477.       motion_type = input->getbits(2);
  478. #ifdef TRACE
  479.       if (trace){
  480.         printf("field_motion_type (");
  481.         printbits(motion_type,2,2);
  482.         printf("): %sn",motion_type==MC_FIELD?"Field":
  483.                          motion_type==MC_16X8?"16x8 MC":
  484.                          motion_type==MC_DMV?"Dual_Prime":"Invalid");
  485.       }
  486. #endif
  487.     }
  488.   }
  489.   else if ((mb_type & MB_INTRA) && conceal_mv)
  490.   {
  491.     /* concealment motion vectors */
  492.     motion_type = (pict_struct==FRAME_PICTURE) ? MC_FRAME : MC_FIELD;
  493.   }
  494.   /* derive mv_count, mv_format and dmv, (table 6-17, 6-18) */
  495.   if (pict_struct==FRAME_PICTURE)
  496.   {
  497.     mv_count = (motion_type==MC_FIELD && stwclass<2) ? 2 : 1;
  498.     mv_format = (motion_type==MC_FRAME) ? MV_FRAME : MV_FIELD;
  499.   }
  500.   else
  501.   {
  502.     mv_count = (motion_type==MC_16X8) ? 2 : 1;
  503.     mv_format = MV_FIELD;
  504.   }
  505.   dmv = (motion_type==MC_DMV); /* dual prime */
  506.   /* field mv predictions in frame pictures have to be scaled */
  507.   mvscale = ((mv_format==MV_FIELD) && (pict_struct==FRAME_PICTURE));
  508.   /* get dct_type (frame DCT / field DCT) */
  509.   dct_type = (pict_struct==FRAME_PICTURE)
  510.              && (!frame_pred_dct)
  511.              && (mb_type & (MB_PATTERN|MB_INTRA))
  512.              ? input->getbits(1)
  513.              : 0;
  514. #ifdef TRACE
  515.   if (trace  && (pict_struct==FRAME_PICTURE)
  516.              && (!frame_pred_dct)
  517.              && (mb_type & (MB_PATTERN|MB_INTRA)))
  518.     printf("dct_type (%d): %sn",dct_type,dct_type?"Field":"Frame");
  519. #endif
  520.   /* return values */
  521.   *pmb_type = mb_type;
  522.   *pstwtype = stwtype;
  523.   *pstwclass = stwclass;
  524.   *pmotion_type = motion_type;
  525.   *pmv_count = mv_count;
  526.   *pmv_format = mv_format;
  527.   *pdmv = dmv;
  528.   *pmvscale = mvscale;
  529.   *pdct_type = dct_type;
  530. }
  531. /* set block to zero */
  532. void LayerData::clearblock(int comp,int size){
  533.   sparse[comp] = 1;
  534.   memset(block[comp],0,sizeof(short)*64*size);
  535. }
  536. #ifdef ENHANCEMENT
  537. /* add SNR enhancement layer block data to base layer */
  538. void LayerData::sumblock(int comp){
  539.   short *bp1, *bp2;
  540.   bp1 = block[comp];
  541. #ifdef ENHANCEMANT
  542.   bp2 = enhan.block[comp];
  543. #endif
  544.   for (int i=0; i<64; i++) *bp1++ += *bp2++;
  545. }
  546. #endif
  547. /* limit coefficients to -2048..2047 */
  548. /* move/add 8x8-Block from block[comp] to refframe */
  549. void LayerData::addblock(int comp, int bx, int by, int dct_type, int addflag){
  550.   int cc,i, iincr;
  551.   unsigned char *rfp;
  552.   short *bp;
  553.   int spar = sparse[comp];
  554. #ifndef HAVE_MMX
  555.   unsigned char *clp2=display->getClpTable();
  556.   if (!addflag) clp2 += 128;
  557. #endif
  558.   cc = (comp<4) ? 0 : (comp&1)+1; /* color component index */
  559.   if (cc==0){   /* luminance */
  560.     if (pict_struct==FRAME_PICTURE)
  561.       if (dct_type){
  562.         /* field DCT coding */
  563.         rfp = newframe[0]
  564.               + coded_picture_width*(by+((comp&2)>>1)) + bx + ((comp&1)<<3);
  565.         iincr = (coded_picture_width<<1);
  566.       }
  567.       else{
  568.         /* frame DCT coding */
  569.         rfp = newframe[0]
  570.               + coded_picture_width*(by+((comp&2)<<2)) + bx + ((comp&1)<<3);
  571.         iincr = coded_picture_width;
  572.       }
  573.     else {
  574.       /* field picture */
  575.       rfp = newframe[0]
  576.             + (coded_picture_width<<1)*(by+((comp&2)<<2)) + bx + ((comp&1)<<3);
  577.       iincr = (coded_picture_width<<1);
  578.     }
  579.   }
  580.   else {
  581.     /* chrominance */
  582.     /* scale coordinates */
  583.     if (chroma_format!=CHROMA444)  bx >>= 1;
  584.     if (chroma_format==CHROMA420)  by >>= 1;
  585.     if (pict_struct==FRAME_PICTURE){
  586.       if (dct_type && (chroma_format!=CHROMA420)){
  587.         /* field DCT coding */
  588.         rfp = newframe[cc]
  589.               + chrom_width*(by+((comp&2)>>1)) + bx + (comp&8);
  590.         iincr = (chrom_width<<1);
  591.       }
  592.       else {
  593.         /* frame DCT coding */
  594.         rfp = newframe[cc]
  595.               + chrom_width*(by+((comp&2)<<2)) + bx + (comp&8);
  596.         iincr = chrom_width;
  597.       }
  598.     }
  599.     else {
  600.       /* field picture */
  601.       rfp = newframe[cc]
  602.             + (chrom_width<<1)*(by+((comp&2)<<2)) + bx + (comp&8);
  603.       iincr = (chrom_width<<1);
  604.     }
  605.   }
  606.   bp = block[comp];
  607.   if (addflag) {
  608. #ifdef HAVE_MMX
  609.     if (spar) {
  610.        __asm__ __volatile__(
  611.             "movq       (%2),%%mm6n"  /* 4 blockvals */
  612.             "pxor       %%mm4,%%mm4n"
  613.             "punpcklwd  %%mm6,%%mm6n"
  614.             "punpcklwd  %%mm6,%%mm6n"
  615.             ".align 8n"
  616.             "1:"
  617.                 "movq       (%1),  %%mm0n"     /* 8 rindex1 */
  618.                 "movq       %%mm0, %%mm2n"
  619.                 "punpcklbw  %%mm4, %%mm0n"
  620.                 "punpckhbw  %%mm4, %%mm2n"
  621.                 "paddw      %%mm6, %%mm0n"
  622.                 "paddw      %%mm6, %%mm2n"
  623.                 "packuswb   %%mm2, %%mm0n"
  624.                 "movq       %%mm0, (%1)n"
  625.                 "leal       (%1,%3), %1n"
  626.               "loop       1bn"
  627.               :              /* scr   dest */
  628.               : "c" (8),"r" (rfp), "r" (bp), "r" (iincr)
  629.                 );
  630.     }
  631.     else {
  632.        __asm__ __volatile__(
  633.          "pxor    %%mm4,%%mm4n"
  634.          ".align 8n"
  635.          "1:"
  636.            "movq       (%2), %%mm0n"   /* 8 rfp 0 1 2 3 4 5 6 7*/
  637.            "movq       (%1), %%mm6n"   /* 4 blockvals 0 1 2 3 */
  638.            "movq       %%mm0, %%mm2n"
  639.            "movq       8(%1), %%mm5n"  /* 4 blockvals 0 1 2 3 */
  640.            "punpcklbw  %%mm4, %%mm0n"  /* 0 2 4 6 */
  641.            "punpckhbw  %%mm4, %%mm2n"  /* 1 3 5 7 */
  642.            "paddw      %%mm6, %%mm0n"
  643.            "paddw      %%mm5, %%mm2n"
  644.            "packuswb   %%mm2, %%mm0n"
  645.            "addl       $16, %1n"
  646.            "movq       %%mm0, (%2)n"
  647.            "leal       (%2,%3), %2n"
  648.          "loop       1bn"
  649.          :              /* scr   dest */
  650.          : "c" (8),"r" (bp), "r" (rfp), "r" (iincr)
  651.        );
  652. //      add_block_mmx(rfp,bp,iincr);
  653.     }
  654. #else
  655.     for (i=0; i<8; i++){
  656.       rfp[0] = clp2[bp[0] + rfp[0]];
  657.       rfp[1] = clp2[bp[1] + rfp[1]];
  658.       rfp[2] = clp2[bp[2] + rfp[2]];
  659.       rfp[3] = clp2[bp[3] + rfp[3]];
  660.       rfp[4] = clp2[bp[4] + rfp[4]];
  661.       rfp[5] = clp2[bp[5] + rfp[5]];
  662.       rfp[6] = clp2[bp[6] + rfp[6]];
  663.       rfp[7] = clp2[bp[7] + rfp[7]];
  664.       rfp+= iincr;
  665.       bp += 8;
  666.     }
  667. #endif
  668.   }
  669.   else {
  670. #ifdef HAVE_MMX
  671.      if (spar) {
  672.             __asm__ __volatile__(
  673.             "movd       (%2),           %%mm0n"                // " 0 0 0  v1"
  674.             "punpcklwd  %%mm0,          %%mm0n"    // " 0 0 v1 v1"
  675.             "punpcklwd  %%mm0,          %%mm0n"
  676.             "paddw      MMX_128,        %%mm0n"
  677.             "packuswb   %%mm0,          %%mm0n"
  678.             "leal       (%0,%1,2),      %%eaxn"
  679.             "movq        %%mm0,         (%0, %1)n"
  680.             "movq        %%mm0,         (%%eax)n"
  681.             "leal        (%%eax,%1,2),  %0n"
  682.             "movq        %%mm0,         (%%eax, %1)n"
  683.             "movq        %%mm0,         (%0)n"
  684.             "leal        (%0,%1,2),     %%eaxn"
  685.             "movq        %%mm0,         (%0, %1)n"
  686.             "movq        %%mm0,         (%%eax)n"
  687.             "movq        %%mm0,         (%%eax, %1)n"
  688.             :
  689.             : "D" (rfp), "c" (iincr), "b" (bp)
  690.             : "eax");
  691.     }
  692.     else {
  693.        __asm__ __volatile__(
  694.             "movq        MMX_128,%%mm4n"
  695.             ".align 8n"
  696.             "1:"
  697.               "movq      (%1),   %%mm0n"
  698.               "movq      8(%1),  %%mm1n"
  699.               "paddw     %%mm4,  %%mm0n"
  700.               "movq      16(%1), %%mm2n"
  701.               "paddw     %%mm4,  %%mm1n"
  702.               "movq      24(%1), %%mm3n"
  703.               "paddw     %%mm4,  %%mm2n"
  704.               "packuswb  %%mm1,  %%mm0n"
  705.               "paddw     %%mm4,  %%mm3n"
  706.               "addl $32, %1n"
  707.               "packuswb  %%mm3,  %%mm2n"
  708.               "movq   %%mm0, (%2)n"
  709.               "movq   %%mm2, (%2,%3)n"
  710.               "leal       (%2,%3,2), %2n"
  711.             "loop       1bn"
  712.             :
  713.             : "c" (4), "r" (bp), "r" (rfp), "r" (iincr)
  714.         );
  715. //      set_block_mmx(rfp,bp,iincr);
  716.     }
  717. #else
  718.     for (i=0; i<8; i++){
  719.       rfp[0] = clp2[bp[0]];
  720.       rfp[1] = clp2[bp[1]];
  721.       rfp[2] = clp2[bp[2]];
  722.       rfp[3] = clp2[bp[3]];
  723.       rfp[4] = clp2[bp[4]];
  724.       rfp[5] = clp2[bp[5]];
  725.       rfp[6] = clp2[bp[6]];
  726.       rfp[7] = clp2[bp[7]];
  727.       rfp+= iincr;
  728.       bp += 8;
  729.     }
  730. #endif
  731.   }
  732. }