home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Multimed / Multimed.zip / mpegplay.zip / 2X2.C < prev    next >
C/C++ Source or Header  |  1994-02-16  |  10KB  |  392 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21.  
  22. #include "video.h"
  23. #include "dither.h"
  24. #include "proto.h"
  25.  
  26. #define RAND_ERR_RANGE 7
  27. #define RAND_ERR_SUBVAL 3
  28.  
  29. /* Array containing actual pixel values for each possible 2x2 dither pattern. */
  30.  
  31. static unsigned char *dith_a;
  32.  
  33. /* Arrays mapping lum, cr, and cb values to portions of dither pattern code. 
  34.    The addtion of one value from each array yields a valid dither pattern
  35.    code.
  36. */
  37.  
  38. static int lval_a[256+RAND_ERR_RANGE-1];
  39. static int rval_a[256+RAND_ERR_RANGE-1];
  40. static int bval_a[256+RAND_ERR_RANGE-1];
  41.  
  42. /* Range of possible dither patterns in each channel. */
  43.  
  44. #define L_DITH_RANGE (((LUM_RANGE-1)*4)+1)
  45. #define CR_DITH_RANGE (((CR_RANGE-1)*4)+1)
  46. #define CB_DITH_RANGE (((CB_RANGE-1)*4)+1)
  47.  
  48. /* Arrays of random error terms added to break up contours. */
  49.  
  50. static int *randval_a;
  51. static int **randptr_a;
  52.  
  53.  
  54. /*
  55.  *--------------------------------------------------------------
  56.  *
  57.  *  Init2x2Dither--
  58.  *
  59.  *    Initializes structures used for 2x2 dithering.
  60.  *
  61.  * Results:
  62.  *    None.
  63.  *
  64.  * Side effects:
  65.  *    None.
  66.  *
  67.  *--------------------------------------------------------------
  68.  */
  69.  
  70. void
  71. Init2x2Dither()
  72. {  
  73.   unsigned char *dith_ca;
  74.   int numcodes;
  75.   int l_range, cr_range, cb_range;
  76.   int p1, p2, p3, p4;
  77.   int l_dith, cr_dith, cb_dith;
  78.   int big_part, small_part;
  79.   int i, j;
  80.  
  81.   l_range = L_DITH_RANGE;
  82.   cr_range = CR_DITH_RANGE;
  83.   cb_range = CB_DITH_RANGE;
  84.  
  85.   numcodes =  l_range * cr_range * cb_range;
  86.  
  87.   dith_a = (unsigned char *) malloc(numcodes*4);
  88.  
  89.   dith_ca =  dith_a;
  90.  
  91.   for (i=0; i<numcodes; i++) {
  92.     l_dith = i  % l_range;
  93.  
  94.     big_part = l_dith / 4;
  95.     small_part = l_dith % 4;
  96.  
  97.     p1 = big_part + ((small_part > 0) ? 1 : 0);
  98.     p2 = big_part + ((small_part > 2) ? 1 : 0);
  99.     p3 = big_part;
  100.     p4 = big_part + ((small_part > 1) ? 1 : 0);
  101.  
  102.     p1 *= CR_RANGE * CB_RANGE;
  103.     p2 *= CR_RANGE * CB_RANGE;
  104.     p3 *= CR_RANGE * CB_RANGE;
  105.     p4 *= CR_RANGE * CB_RANGE;
  106.  
  107.     cr_dith = (i/l_range) % cr_range;
  108.  
  109.     big_part = cr_dith / 4;
  110.     small_part = cr_dith % 4;
  111.  
  112.     p1 += (big_part + ((small_part > 0) ? 1 : 0))*CB_RANGE;
  113.     p2 += (big_part + ((small_part > 2) ? 1 : 0))*CB_RANGE;
  114.     p3 += (big_part)*CB_RANGE;
  115.     p4 += (big_part + ((small_part > 1) ? 1 : 0))*CB_RANGE;
  116.  
  117.     cb_dith = (i/(cr_range*l_range)) % cb_range;
  118.  
  119.     big_part = cb_dith / 4;
  120.     small_part = cb_dith % 4;
  121.  
  122.     p1 += (big_part + ((small_part > 0) ? 1 : 0));
  123.     p2 += (big_part + ((small_part > 2) ? 1 : 0));
  124.     p3 += (big_part);
  125.     p4 += (big_part + ((small_part > 1) ? 1 : 0));
  126.  
  127.     *dith_ca++ = p1;
  128.     *dith_ca++ = p2;
  129.     *dith_ca++ = p3;
  130.     *dith_ca++ = p4;
  131.   }
  132.  
  133.   for (i=RAND_ERR_SUBVAL; i<256+RAND_ERR_SUBVAL; i++) {
  134.     j = i-RAND_ERR_SUBVAL;
  135.     lval_a[i] = (j * L_DITH_RANGE)/256;
  136.     rval_a[i] = (j * CR_DITH_RANGE)/256;
  137.     bval_a[i] = (j * CB_DITH_RANGE)/256;
  138.  
  139.     bval_a[i] *= CR_DITH_RANGE * L_DITH_RANGE * 4;
  140.     rval_a[i] *= L_DITH_RANGE * 4;
  141.     lval_a[i] *= 4;
  142.   }
  143.  
  144.   for (i=0; i<RAND_ERR_SUBVAL; i++) {
  145.     lval_a[i] = lval_a[RAND_ERR_SUBVAL];
  146.     rval_a[i] = rval_a[RAND_ERR_SUBVAL];
  147.     bval_a[i] = bval_a[RAND_ERR_SUBVAL];
  148.   }
  149.  
  150.    for(i=256+RAND_ERR_SUBVAL; i<256+RAND_ERR_RANGE-1; i++) {
  151.      lval_a[i] = lval_a[255+RAND_ERR_SUBVAL];
  152.      rval_a[i] = rval_a[255+RAND_ERR_SUBVAL];
  153.      bval_a[i] = bval_a[255+RAND_ERR_SUBVAL];
  154.    }
  155. }
  156.  
  157.  
  158. /*
  159.  *--------------------------------------------------------------
  160.  *
  161.  * RandInit --
  162.  *
  163.  *    Initializes the random values used for 2x2 dithering.
  164.  *
  165.  * Results:
  166.  *    randval_a filled with random values.
  167.  *      randptr_a filled with random pointers to random value arrays.
  168.  *
  169.  * Side effects:
  170.  *      None.
  171.  *
  172.  *--------------------------------------------------------------
  173.  */
  174.  
  175. void RandInit(h, w)
  176.      int h, w;
  177. {
  178.   int i;
  179.  
  180.   randval_a = (int *) malloc(w*5*sizeof(int));
  181.   randptr_a = (int **) malloc(h*sizeof(int *));
  182.  
  183.  
  184. #ifdef NO_LRAND48
  185.   for (i=0; i<w*5; i++) {
  186. #ifdef OS2
  187. /* @@@ AK, Called rand() on OS/2 */
  188.     extern int rand(void);
  189.     #define random() rand()
  190. #else
  191.     long int random();
  192. #endif
  193.     randval_a[i] = random() % RAND_ERR_RANGE;
  194.   }
  195.  
  196.   for (i=0; i<h; i++) {
  197. #ifdef OS2
  198. /* @@@ AK, Called rand() on OS/2 */
  199.     extern int rand(void);
  200.     #define random() rand()
  201. #else
  202.     long int random();
  203. #endif
  204.  
  205.     randptr_a[i] = randval_a + (random() % (w*2));
  206.   }
  207. #else /* NO_LRAND48 */
  208.  
  209.   for (i=0; i<w*5; i++) {
  210.     long int lrand48();
  211.     
  212.     randval_a[i] = lrand48() % RAND_ERR_RANGE;
  213.   }
  214.   
  215.   for (i=0; i<h; i++) {
  216.     long int lrand48();
  217.  
  218.     randptr_a[i] = randval_a + (lrand48() % (w*2));
  219.   }
  220. #endif
  221.   
  222. }
  223.  
  224.  
  225. /*
  226.  *--------------------------------------------------------------
  227.  *
  228.  *  PostInit2x2Dither--
  229.  *
  230.  *    Remaps color numbers in dither patterns to actual pixel
  231.  *      values allocated by the X server.
  232.  *
  233.  * Results:
  234.  *      None.
  235.  *
  236.  * Side effects:
  237.  *      None.
  238.  *
  239.  *--------------------------------------------------------------
  240.  */
  241.  
  242. void
  243. PostInit2x2Dither() 
  244. {
  245. /* @@@ See comments accompanying definition of pixel array */
  246. #ifndef OS2
  247.   unsigned char *dith_ca;
  248.   int i;
  249.  
  250.   dith_ca = dith_a;
  251.  
  252.   for (i=0; i < (L_DITH_RANGE * CR_DITH_RANGE * CB_DITH_RANGE); i++) {
  253.     
  254.     *dith_ca = pixel[*dith_ca];
  255.     dith_ca++;
  256.     *dith_ca = pixel[*dith_ca];
  257.     dith_ca++;
  258.     *dith_ca = pixel[*dith_ca];
  259.     dith_ca++;
  260.     *dith_ca = pixel[*dith_ca];
  261.     dith_ca++;
  262.   }
  263. #endif
  264. }
  265.  
  266.  
  267. /*
  268.  *--------------------------------------------------------------
  269.  *
  270.  * Twox2DitherImage --
  271.  *
  272.  *    Dithers lum, cr, and cb channels togethor using predefined
  273.  *      and computed 2x2 dither patterns. Each possible combination of
  274.  *      lum, cr, and cb values combines to point to a particular dither
  275.  *      pattern (2x2) which is used to represent the pixel. This assumes
  276.  *      That the display plane is 4 times larger than the lumianance 
  277.  *      plane. 
  278.  *
  279.  * Results:
  280.  *      None.
  281.  *
  282.  * Side effects:
  283.  *      None.
  284.  *
  285.  *--------------------------------------------------------------
  286.  */
  287.  
  288. void 
  289. Twox2DitherImage(lum, cr, cb, out, h, w)
  290.     unsigned char *lum;
  291.     unsigned char *cr;
  292.     unsigned char *cb;
  293.     unsigned char *out;
  294.     int w, h;
  295. {
  296.   int i, j;
  297.   unsigned short *o1, *o2, *o3, *o4;
  298.   unsigned char *l1, *l2, *base;
  299.   unsigned char B, R;
  300.   unsigned short *dith_ca;
  301.   int big_adv = 3*w;
  302.   int b_val, r_val, l_val;
  303.   int *randvalptr;
  304.   int randval;
  305.   static int first = 1;
  306.  
  307.   if (first) {
  308.     RandInit(h, w);
  309.     first = 0;
  310.   }
  311.  
  312.   o1 = (unsigned short *)out;
  313.   o2 = (unsigned short *)(out+(2*w));
  314.   o3 = (unsigned short *)(out+(4*w));
  315.   o4 = (unsigned short *)(out+(6*w));
  316.   l1 = lum;
  317.   l2 = lum+w;
  318.  
  319.   for (i=0; i<h; i+=2) {
  320.     for(j=0; j<w; j+= 4) {
  321.  
  322.       B = cb[0];
  323.       b_val = bval_a[B];
  324.       R = cr[0];
  325.       r_val = rval_a[R];
  326.       base = dith_a + b_val + r_val;
  327.  
  328.       l_val = lval_a[l1[0]];
  329.       dith_ca = (unsigned short *)(base + l_val);
  330.       o1[0] = dith_ca[0];
  331.       o2[0] = dith_ca[1];
  332.  
  333.       l_val = lval_a[l1[1]];
  334.       dith_ca = (unsigned short *)(base + l_val);
  335.       o1[1] = dith_ca[0];
  336.       o2[1] = dith_ca[1];
  337.  
  338.       l_val = lval_a[l2[0]];
  339.       dith_ca = (unsigned short *)(base + l_val);
  340.       o3[0] = dith_ca[0];
  341.       o4[0] = dith_ca[1];
  342.  
  343.       l_val = lval_a[l2[1]];
  344.       dith_ca = (unsigned short *)(base + l_val);
  345.       o3[1] = dith_ca[0];
  346.       o4[1] = dith_ca[1];
  347.  
  348.       B = cb[1];
  349.       b_val = bval_a[B];
  350.       R = cr[1];
  351.       r_val = rval_a[R];
  352.       base = dith_a + b_val + r_val;
  353.  
  354.       l_val = lval_a[l1[2]];
  355.       dith_ca = (unsigned short *)(base + l_val);
  356.       o1[2] = dith_ca[0];
  357.       o2[2] = dith_ca[1];
  358.  
  359.       l_val = lval_a[l1[3]];
  360.       dith_ca = (unsigned short *)(base + l_val);
  361.       o1[3] = dith_ca[0];
  362.       o2[3] = dith_ca[1];
  363.  
  364.       l_val = lval_a[l2[2]];
  365.       dith_ca = (unsigned short *)(base + l_val);
  366.       o3[2] = dith_ca[0];
  367.       o4[2] = dith_ca[1];
  368.  
  369.       l_val = lval_a[l2[3]];
  370.       dith_ca = (unsigned short *)(base + l_val);
  371.       o3[3] = dith_ca[0];
  372.       o4[3] = dith_ca[1];
  373.  
  374.       o1 += 4;
  375.       o2 += 4;
  376.       o3 += 4;
  377.       o4 += 4;
  378.       l1 += 4;
  379.       l2 += 4;
  380.       cb += 2;
  381.       cr += 2;
  382.     }    
  383.  
  384.     l1 += w;
  385.     l2 += w;
  386.     o1 += big_adv;
  387.     o2 += big_adv;
  388.     o3 += big_adv;
  389.     o4 += big_adv;
  390.   }
  391. }
  392.