home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / mpeg_play-2.1 / mb_ordered.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-09  |  13.0 KB  |  539 lines

  1. /*
  2.  * mb_ordered.c
  3.  *
  4.  *      This file contains C code to implement an macroblock ordered dither.
  5.  *
  6.  */
  7.  
  8. /*  
  9.  * Copyright (c) 1995 The Regents of the University of California.
  10.  * All rights reserved.
  11.  * 
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose, without fee, and without written agreement is
  14.  * hereby granted, provided that the above copyright notice and the following
  15.  * two paragraphs appear in all copies of this software.
  16.  * 
  17.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  18.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  19.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  20.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  21.  * 
  22.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  23.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  24.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  25.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  26.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  27.  */
  28.  
  29. #include "video.h"
  30. #include "proto.h"
  31. #include "dither.h"
  32.  
  33. #define DITH_SIZE 16
  34.  
  35.  
  36. /* Structures used to implement macroblock ordered
  37.    dither algorithm.
  38. */
  39.  
  40. static unsigned char ***ditherPtr[DITH_SIZE];
  41.  
  42.  
  43. /*
  44.  *--------------------------------------------------------------
  45.  *
  46.  *  InitMBOrderedDither--
  47.  *
  48.  *    Structures intialized for ordered dithering. 
  49.  *
  50.  * Results:
  51.  *    None.
  52.  *
  53.  * Side effects:
  54.  *      None.
  55.  *
  56.  *--------------------------------------------------------------
  57.  */
  58.  
  59. void
  60. InitMBOrderedDither()
  61. {
  62.   unsigned char ****pos_2_cb;
  63.   unsigned char ***cb_2_cr;
  64.   unsigned char **cr_2_l;
  65.   int cb_val, cb_rval, cr_val, cr_rval, l_val, l_rval;
  66.   int i, j, pos;
  67.   int err_range, threshval;
  68.  
  69.   pos_2_cb = (unsigned char ****) malloc (DITH_SIZE*sizeof(unsigned char ***));
  70.   cb_2_cr = (unsigned char ***) malloc(CB_RANGE*sizeof(unsigned char **));
  71.   cr_2_l = (unsigned char **) malloc(CR_RANGE*sizeof(unsigned char *));
  72.  
  73.   for (pos=0; pos<DITH_SIZE; pos++) {
  74.     
  75.     pos_2_cb[pos] = (unsigned char ***) malloc(256*(sizeof(unsigned char **)));
  76.  
  77.     for (j=0; j<CB_RANGE; j++) {
  78.       cb_2_cr[j] = (unsigned char **) malloc(256*(sizeof(unsigned char *)));
  79.     }
  80.  
  81.     for (cb_val=0; cb_val<cb_values[0]; cb_val++) {
  82.       (pos_2_cb[pos])[cb_val] = cb_2_cr[0];
  83.     }
  84.  
  85.     for (cb_rval=0; cb_rval<(CB_RANGE-1); cb_rval++) {
  86.       err_range = cb_values[cb_rval+1] - cb_values[cb_rval];
  87.       threshval = ((pos*err_range)/DITH_SIZE)+cb_values[cb_rval];
  88.  
  89.       for (cb_val=cb_values[cb_rval]; cb_val<cb_values[cb_rval+1]; cb_val++) {
  90.     if (cb_val>threshval) (pos_2_cb[pos])[cb_val] = cb_2_cr[cb_rval+1];
  91.     else (pos_2_cb[pos])[cb_val] = cb_2_cr[cb_rval];
  92.       }
  93.     }
  94.  
  95.     for (cb_val=cb_values[CB_RANGE-1]; cb_val<256; cb_val++) {
  96.       (pos_2_cb[pos])[cb_val] = cb_2_cr[CB_RANGE-1];
  97.     }
  98.  
  99.     for (cb_rval=0; cb_rval<CB_RANGE; cb_rval++) {
  100.       
  101.       for (j=0; j<CR_RANGE; j++) {
  102.     cr_2_l[j] = (unsigned char *) malloc(256*(sizeof(unsigned char)));
  103.       }
  104.  
  105.       for (cr_val=0; cr_val < cr_values[0]; cr_val++) {
  106.     (cb_2_cr[cb_rval])[cr_val] = cr_2_l[0];
  107.       }
  108.  
  109.       for (cr_rval=0; cr_rval<(CR_RANGE-1); cr_rval++) {
  110.     err_range = cr_values[cr_rval+1] - cr_values[cr_rval];
  111.     threshval = ((pos*err_range)/DITH_SIZE)+cr_values[cr_rval];
  112.     
  113.     for (cr_val=cr_values[cr_rval]; cr_val<cr_values[cr_rval+1]; cr_val++) {
  114.       if (cr_val>threshval) (cb_2_cr[cb_rval])[cr_val] = cr_2_l[cr_rval+1];
  115.       else (cb_2_cr[cb_rval])[cr_val] = cr_2_l[cr_rval];
  116.     }
  117.       }
  118.       
  119.       for (cr_val=cr_values[CR_RANGE-1]; cr_val<256; cr_val++) {
  120.     (cb_2_cr[cb_rval])[cr_val] = cr_2_l[CR_RANGE-1];
  121.       }
  122.       
  123.       for (cr_rval=0; cr_rval<CR_RANGE; cr_rval++) {
  124.     
  125.     for (l_val = 0; l_val < lum_values[0]; l_val++) {
  126.       (cr_2_l[cr_rval])[l_val] = pixel[cb_rval+(cr_rval*CB_RANGE)+
  127.                         (0*CR_RANGE*CB_RANGE)];
  128.     }
  129.  
  130.     for (l_rval=0; l_rval<(LUM_RANGE-1); l_rval++) {
  131.       err_range = lum_values[l_rval+1] - lum_values[l_rval];
  132.       threshval = ((pos*err_range) /DITH_SIZE) + lum_values[l_rval];
  133.  
  134.       for (l_val = lum_values[l_rval]; l_val < lum_values[l_rval+1]; l_val++) {
  135.         if (l_val>threshval) (cr_2_l[cr_rval])[l_val] = 
  136.           pixel[cb_rval+(cr_rval*CB_RANGE)+((l_rval+1)*CR_RANGE*CB_RANGE)];
  137.         else (cr_2_l[cr_rval])[l_val] =
  138.           pixel[cb_rval+(cr_rval*CB_RANGE)+(l_rval*CR_RANGE*CB_RANGE)];
  139.       }
  140.     }
  141.  
  142.     for (l_val = lum_values[LUM_RANGE-1]; l_val < 256; l_val++) {
  143.       (cr_2_l[cr_rval])[l_val] = 
  144.         pixel[cb_rval+(cr_rval*CB_RANGE)+((LUM_RANGE-1)*CR_RANGE*CB_RANGE)];
  145.     }
  146.       }
  147.     }
  148.   }
  149.  
  150.   for (i=0; i<DITH_SIZE; i++) {
  151.     ditherPtr[i] = pos_2_cb[i];
  152.   }
  153. }
  154.  
  155.  
  156.  
  157. /*
  158.  *--------------------------------------------------------------
  159.  *
  160.  * MBOrderedDitherImage --
  161.  *
  162.  *    Dithers an image using an ordered dither at macroblock level.
  163.  *    Assumptions made:
  164.  *      1) The color space is allocated y:cr:cb = 8:4:4
  165.  *      2) The spatial resolution of y:cr:cb is 4:1:1
  166.  *      The channels are dithered based on the standard
  167.  *      ordered dither pattern for a 4x4 area. 
  168.  *
  169.  * Results:
  170.  *    None.
  171.  *
  172.  * Side effects:
  173.  *    None.
  174.  *
  175.  *--------------------------------------------------------------
  176.  */
  177. void
  178. MBOrderedDitherImage (lum, cr, cb, out, h, w)
  179.     unsigned char *lum;
  180.     unsigned char *cr;
  181.     unsigned char *cb;
  182.     unsigned char *out;
  183.     int h, w;
  184. {
  185.   unsigned char *l, *r, *b, *o1, *o2;
  186.   unsigned char *l2;
  187.   unsigned char L, R, B;
  188.   int i, j, mbaddr, mbwidth;
  189.   unsigned char ***dp0 = ditherPtr[0];
  190.   unsigned char ***dp2 = ditherPtr[2];
  191.   unsigned char ***dp4 = ditherPtr[4];
  192.   unsigned char ***dp6 = ditherPtr[6];
  193.   unsigned char ***dp8 = ditherPtr[8];
  194.   unsigned char ***dp10 = ditherPtr[10];
  195.   unsigned char ***dp12 = ditherPtr[12];
  196.   unsigned char ***dp14 = ditherPtr[14];
  197.   unsigned char ***dp1 = ditherPtr[1];
  198.   unsigned char ***dp3 = ditherPtr[3];
  199.   unsigned char ***dp5 = ditherPtr[5];
  200.   unsigned char ***dp7 = ditherPtr[7];
  201.   unsigned char ***dp9 = ditherPtr[9];
  202.   unsigned char ***dp11 = ditherPtr[11];
  203.   unsigned char ***dp13 = ditherPtr[13];
  204.   unsigned char ***dp15 = ditherPtr[15];
  205.  
  206.   l = lum;
  207.   l2 = lum + w;
  208.   r = cr;
  209.   b = cb;
  210.   o1 = out;
  211.   o2 = out+w;
  212.   mbwidth = w / 16;
  213.  
  214.   for (i=0; i<h; i+=4) {
  215.  
  216.     mbaddr = (i / 16) * mbwidth ;
  217.  
  218.     for (j=0; j<w; j+=8) {
  219.  
  220.       if (ditherFlags[mbaddr+(j/16)]) {
  221.     R = r[0]; B = b[0];
  222.     
  223.     L = l[0];
  224.     o1[0] = ((dp0[B])[R])[L];
  225.     L = l[1];
  226.     o1[1] = ((dp8[B])[R])[L];
  227.     L = l2[0];
  228.     o2[0] = ((dp12[B])[R])[L];
  229.     L = l2[1];
  230.     o2[1] = ((dp4[B])[R])[L];
  231.     
  232.     R = r[1]; B = b[1];
  233.     
  234.     L = l[2];
  235.     o1[2] = ((dp2[B])[R])[L];
  236.     L = l[3];
  237.     o1[3] = ((dp10[B])[R])[L];
  238.     L = l2[2];
  239.     o2[2] = ((dp14[B])[R])[L];
  240.     L = l2[3];
  241.     o2[3] = ((dp6[B])[R])[L];
  242.     
  243.     R = r[2]; B = b[2];
  244.     
  245.     L = l[4];
  246.     o1[4] = ((dp0[B])[R])[L];
  247.     L = l[5];
  248.     o1[5] = ((dp8[B])[R])[L];
  249.     L = l2[4];
  250.     o2[4] = ((dp12[B])[R])[L];
  251.     L = l2[5];
  252.     o2[5] = ((dp4[B])[R])[L];
  253.     
  254.     R = r[3]; B = b[3];
  255.     
  256.     L = l[6];
  257.     o1[6] = ((dp2[B])[R])[L];
  258.     L = l[7];
  259.     o1[7] = ((dp10[B])[R])[L];
  260.     L = l2[6];
  261.     o2[6] = ((dp14[B])[R])[L];
  262.     L = l2[7];
  263.     o2[7] = ((dp6[B])[R])[L];
  264.       }
  265.       
  266.       l += 8;
  267.       l2 += 8;
  268.       r += 4;
  269.       b += 4;
  270.       o1 += 8;
  271.       o2 += 8;
  272.     }
  273.     
  274.     l += w; l2 += w;
  275.     o1 += w; o2 += w;
  276.  
  277.     for (j=0; j<w; j+=8) {
  278.  
  279.       if (ditherFlags[mbaddr+(j/16)]) {
  280.  
  281.     R = r[0]; B = b[0];
  282.     
  283.     L = l[0];
  284.     o1[0] = ((dp3[B])[R])[L];
  285.     L = l[1];
  286.     o1[1] = ((dp11[B])[R])[L];
  287.     L = l2[0];
  288.     o2[0] = ((dp15[B])[R])[L];
  289.     L = l2[1];
  290.     o2[1] = ((dp7[B])[R])[L];
  291.     
  292.     R = r[1]; B = b[1];
  293.     
  294.     L = l[2];
  295.     o1[2] = ((dp1[B])[R])[L];
  296.     L = l[3];
  297.     o1[3] = ((dp9[B])[R])[L];
  298.     L = l2[2];
  299.     o2[2] = ((dp13[B])[R])[L];
  300.     L = l2[3];
  301.     o2[3] = ((dp5[B])[R])[L];
  302.     
  303.     R = r[2]; B = b[2];
  304.     
  305.     L = l[4];
  306.     o1[4] = ((dp3[B])[R])[L];
  307.     L = l[5];
  308.     o1[5] = ((dp11[B])[R])[L];
  309.     L = l2[4];
  310.     o2[4] = ((dp15[B])[R])[L];
  311.     L = l2[5];
  312.     o2[5] = ((dp7[B])[R])[L];
  313.     
  314.     R = r[3]; B = b[3];
  315.     
  316.     L = l[6];
  317.     o1[6] = ((dp1[B])[R])[L];
  318.     L = l[7];
  319.     o1[7] = ((dp9[B])[R])[L];
  320.     L = l2[6];
  321.     o2[6] = ((dp13[B])[R])[L];
  322.     L = l2[7];
  323.     o2[7] = ((dp5[B])[R])[L];
  324.       }
  325.  
  326.       l += 8;
  327.       l2 += 8;
  328.       r += 4;
  329.       b += 4;
  330.       o1 += 8;
  331.       o2 += 8;
  332.     }
  333.     
  334.     l += w; l2 += w;
  335.     o1 += w; o2 += w;
  336.   }
  337. }
  338.  
  339.  
  340.  
  341. /*
  342.  *--------------------------------------------------------------
  343.  *
  344.  * MBOrderedDitherDisplayCopy --
  345.  *
  346.  *    Copies an image to the display (?)
  347.  *
  348.  * Results:
  349.  *    None.
  350.  *
  351.  * Side effects:
  352.  *    None.
  353.  *
  354.  *--------------------------------------------------------------
  355.  */
  356. void
  357. MBOrderedDitherDisplayCopy(vid_stream, mb_addr, motion_forw, r_right_forw,
  358.         r_down_forw, motion_back, r_right_back, r_down_back, past, future)
  359.     VidStream *vid_stream;
  360.     int mb_addr;
  361.     int motion_forw, r_right_forw, r_down_forw;
  362.     int motion_back, r_right_back, r_down_back;
  363.     unsigned char *past, *future;
  364. {
  365.   int right_back = 0, right_forw = 0, down_back, down_forw;
  366.   unsigned char *dest;
  367.   unsigned char *src1 = 0, *src2 = 0;
  368.   int row, col, row_size, rr;
  369.   int mc, mr;
  370.  
  371.   row = (mb_addr / vid_stream->mb_width) << 4;
  372.   col = (mb_addr % vid_stream->mb_width) << 4;
  373.   row_size = vid_stream->mb_width << 4;
  374.  
  375.   dest = vid_stream->current->display + (row * row_size) + col;
  376.  
  377.   if (motion_forw) {
  378.     right_forw = r_right_forw >> 1;
  379.     down_forw = r_down_forw >> 1;
  380.     src1 = past + ((row + down_forw) * row_size) + (col + right_forw);
  381.   }
  382.  
  383.   if (motion_back) {
  384.     right_back = r_right_back >> 1;
  385.     down_back = r_down_back >> 1;
  386.     src2 = future + ((row + down_back) * row_size) + (col + right_back);
  387.   }
  388.    
  389.   if (motion_forw) {
  390.     if (motion_back) {
  391.       for (rr = 0; rr<16; rr++) {
  392.         dest[0] = src1[0];      dest[1] = src2[1];
  393.         dest[2] = src1[2];      dest[3] = src2[3];
  394.         dest[4] = src1[4];      dest[5] = src2[5];
  395.         dest[6] = src1[6];      dest[7] = src2[7];
  396.         dest[8] = src1[8];      dest[9] = src2[9];
  397.         dest[10] = src1[10];    dest[11] = src2[11];
  398.         dest[12] = src1[12];    dest[13] = src2[13];
  399.         dest[14] = src1[14];    dest[15] = src2[15];
  400.  
  401.         dest += row_size;
  402.         src1 += row_size;
  403.         src2 += row_size;
  404.       }
  405.     }
  406.     else {
  407.       mc = col & 0x3;
  408.       mr = right_forw & 0x3;
  409.       if (!mc && !mr) {
  410.     /* Use 32 bit copy */
  411.     int *d, *s;
  412.  
  413.     d = (int *) dest;
  414.     s = (int *) src1;
  415.     row_size /= 4;
  416.     
  417.     for (rr = 0; rr < 16; rr++) {
  418.       d[0] = s[0];
  419.       d[1] = s[1];
  420.       d[2] = s[2];
  421.       d[3] = s[3]; 
  422.       d += row_size;
  423.       s += row_size;
  424.     }
  425.       } else if ((!mc || (mc == 2)) &&
  426.          (!mr || (mr == 2))) {
  427.     /* Use 16 bit copy */
  428.     short int *d, * s;
  429.     
  430.     d = (short int *) dest;
  431.     s = (short int *) src1;
  432.     row_size /= 2;
  433.     
  434.     for (rr = 0; rr < 16; rr++) {
  435.       d[0] = s[0];
  436.       d[1] = s[1];
  437.       d[2] = s[2];
  438.       d[3] = s[3]; 
  439.       d[4] = s[4];
  440.       d[5] = s[5];
  441.       d[6] = s[6];
  442.       d[7] = s[7]; 
  443.       d += row_size;
  444.       s += row_size;
  445.     }
  446.       }
  447.       else {
  448.     for (rr = 0; rr < 16; rr++) {
  449.       dest[0] = src1[0];
  450.       dest[1] = src1[1];
  451.       dest[2] = src1[2];
  452.       dest[3] = src1[3];
  453.       dest[4] = src1[4];
  454.       dest[5] = src1[5];
  455.       dest[6] = src1[6];
  456.       dest[7] = src1[7];
  457.       dest[8] = src1[8];
  458.       dest[9] = src1[9];
  459.       dest[10] = src1[10];
  460.       dest[11] = src1[11];
  461.       dest[12] = src1[12];
  462.       dest[13] = src1[13];
  463.       dest[14] = src1[14];
  464.       dest[15] = src1[15];
  465.       
  466.       dest += row_size;
  467.       src1 += row_size;
  468.     }
  469.       }
  470.     }
  471.   } else if (motion_back) {
  472.     mc = col & 0x3;
  473.     mr = right_back & 0x3;
  474.     if (!mc && !mr) {
  475.       /* Use 32 bit copy */
  476.       int *d, *s;
  477.       
  478.       d = (int *) dest;
  479.       s = (int *) src2;
  480.       row_size /= 4;
  481.       
  482.       for (rr = 0; rr < 16; rr++) {
  483.         d[0] = s[0];
  484.         d[1] = s[1];
  485.         d[2] = s[2];
  486.         d[3] = s[3]; 
  487.         d += row_size;
  488.         s += row_size;
  489.       }
  490.     }
  491.     else if ((!mc || mc == 2) &&
  492.          (!mr || mr == 2)) {
  493.       /* Use 8 bit copy */
  494.       short int *d, *s;
  495.       
  496.       d = (short int *) dest;
  497.       s = (short int *) src2;
  498.       row_size /= 2;
  499.       
  500.       for (rr = 0; rr < 16; rr++) {
  501.         d[0] = s[0];
  502.         d[1] = s[1];
  503.         d[2] = s[2];
  504.         d[3] = s[3]; 
  505.         d[4] = s[4];
  506.         d[5] = s[5];
  507.         d[6] = s[6];
  508.         d[7] = s[7]; 
  509.         d += row_size;
  510.         s += row_size;
  511.       }
  512.     }
  513.     else {
  514.       for (rr = 0; rr < 16; rr++) {
  515.         /* Use 8 bit copy */
  516.         dest[0] = src2[0];
  517.         dest[1] = src2[1];
  518.         dest[2] = src2[2];
  519.         dest[3] = src2[3];
  520.         dest[4] = src2[4];
  521.         dest[5] = src2[5];
  522.         dest[6] = src2[6];
  523.         dest[7] = src2[7];
  524.         dest[8] = src2[8];
  525.         dest[9] = src2[9];
  526.         dest[10] = src2[10];
  527.         dest[11] = src2[11];
  528.         dest[12] = src2[12];
  529.         dest[13] = src2[13];
  530.         dest[14] = src2[14];
  531.         dest[15] = src2[15];
  532.  
  533.         dest += row_size;
  534.         src2 += row_size;
  535.       }
  536.     }
  537.   }
  538. }
  539.