home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / amiga / mpeg / mpgplyr1.lha / src / 2x2.c < prev    next >
C/C++ Source or Header  |  1992-12-08  |  8KB  |  369 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.  
  25. #define RAND_ERR_RANGE 7
  26. #define RAND_ERR_SUBVAL 3
  27.  
  28. /* Array containing actual pixel values for each possible 2x2 dither pattern. */
  29.  
  30. static unsigned char *dith_a;
  31.  
  32. /* Arrays mapping lum, cr, and cb values to portions of dither pattern code. 
  33.    The addtion of one value from each array yields a valid dither pattern
  34.    code.
  35. */
  36.  
  37. static int lval_a[256+RAND_ERR_RANGE-1];
  38. static int rval_a[256+RAND_ERR_RANGE-1];
  39. static int bval_a[256+RAND_ERR_RANGE-1];
  40.  
  41. /* Range of possible dither patterns in each channel. */
  42.  
  43. #define L_DITH_RANGE (((LUM_RANGE-1)*4)+1)
  44. #define CR_DITH_RANGE (((CR_RANGE-1)*4)+1)
  45. #define CB_DITH_RANGE (((CB_RANGE-1)*4)+1)
  46.  
  47. /* Arrays of random error terms added to break up contours. */
  48.  
  49. static int *randval_a;
  50. static int **randptr_a;
  51.  
  52.  
  53. /*
  54.  *--------------------------------------------------------------
  55.  *
  56.  *  Init2x2Dither--
  57.  *
  58.  *    Initializes structures used for 2x2 dithering.
  59.  *
  60.  * Results:
  61.  *    None.
  62.  *
  63.  * Side effects:
  64.  *    None.
  65.  *
  66.  *--------------------------------------------------------------
  67.  */
  68.  
  69. void
  70. Init2x2Dither()
  71. {  
  72.   unsigned char *dith_ca;
  73.   int numcodes;
  74.   int l_range, cr_range, cb_range;
  75.   int p1, p2, p3, p4;
  76.   int l_dith, cr_dith, cb_dith;
  77.   int big_part, small_part;
  78.   int i, j;
  79.  
  80.   l_range = L_DITH_RANGE;
  81.   cr_range = CR_DITH_RANGE;
  82.   cb_range = CB_DITH_RANGE;
  83.  
  84.   numcodes =  l_range * cr_range * cb_range;
  85.  
  86.   dith_a = (unsigned char *) malloc(numcodes*4);
  87.  
  88.   dith_ca =  dith_a;
  89.  
  90.   for (i=0; i<numcodes; i++) {
  91.     l_dith = i  % l_range;
  92.  
  93.     big_part = l_dith / 4;
  94.     small_part = l_dith % 4;
  95.  
  96.     p1 = big_part + ((small_part > 0) ? 1 : 0);
  97.     p2 = big_part + ((small_part > 2) ? 1 : 0);
  98.     p3 = big_part;
  99.     p4 = big_part + ((small_part > 1) ? 1 : 0);
  100.  
  101.     p1 *= CR_RANGE * CB_RANGE;
  102.     p2 *= CR_RANGE * CB_RANGE;
  103.     p3 *= CR_RANGE * CB_RANGE;
  104.     p4 *= CR_RANGE * CB_RANGE;
  105.  
  106.     cr_dith = (i/l_range) % cr_range;
  107.  
  108.     big_part = cr_dith / 4;
  109.     small_part = cr_dith % 4;
  110.  
  111.     p1 += (big_part + ((small_part > 0) ? 1 : 0))*CB_RANGE;
  112.     p2 += (big_part + ((small_part > 2) ? 1 : 0))*CB_RANGE;
  113.     p3 += (big_part)*CB_RANGE;
  114.     p4 += (big_part + ((small_part > 1) ? 1 : 0))*CB_RANGE;
  115.  
  116.     cb_dith = (i/(cr_range*l_range)) % cb_range;
  117.  
  118.     big_part = cb_dith / 4;
  119.     small_part = cb_dith % 4;
  120.  
  121.     p1 += (big_part + ((small_part > 0) ? 1 : 0));
  122.     p2 += (big_part + ((small_part > 2) ? 1 : 0));
  123.     p3 += (big_part);
  124.     p4 += (big_part + ((small_part > 1) ? 1 : 0));
  125.  
  126.     *dith_ca++ = p1;
  127.     *dith_ca++ = p2;
  128.     *dith_ca++ = p3;
  129.     *dith_ca++ = p4;
  130.   }
  131.  
  132.   for (i=RAND_ERR_SUBVAL; i<256+RAND_ERR_SUBVAL; i++) {
  133.     j = i-RAND_ERR_SUBVAL;
  134.     lval_a[i] = (j * L_DITH_RANGE)/256;
  135.     rval_a[i] = (j * CR_DITH_RANGE)/256;
  136.     bval_a[i] = (j * CB_DITH_RANGE)/256;
  137.  
  138.     bval_a[i] *= CR_DITH_RANGE * L_DITH_RANGE * 4;
  139.     rval_a[i] *= L_DITH_RANGE * 4;
  140.     lval_a[i] *= 4;
  141.   }
  142.  
  143.   for (i=0; i<RAND_ERR_SUBVAL; i++) {
  144.     lval_a[i] = lval_a[RAND_ERR_SUBVAL];
  145.     rval_a[i] = rval_a[RAND_ERR_SUBVAL];
  146.     bval_a[i] = bval_a[RAND_ERR_SUBVAL];
  147.   }
  148.  
  149.    for(i=256+RAND_ERR_SUBVAL; i<256+RAND_ERR_RANGE-1; i++) {
  150.      lval_a[i] = lval_a[255+RAND_ERR_SUBVAL];
  151.      rval_a[i] = rval_a[255+RAND_ERR_SUBVAL];
  152.      bval_a[i] = bval_a[255+RAND_ERR_SUBVAL];
  153.    }
  154. }
  155.  
  156.  
  157. /*
  158.  *--------------------------------------------------------------
  159.  *
  160.  * RandInit --
  161.  *
  162.  *    Initializes the random values used for 2x2 dithering.
  163.  *
  164.  * Results:
  165.  *    randval_a filled with random values.
  166.  *      randptr_a filled with random pointers to random value arrays.
  167.  *
  168.  * Side effects:
  169.  *      None.
  170.  *
  171.  *--------------------------------------------------------------
  172.  */
  173.  
  174. void RandInit(h, w)
  175.      int h, w;
  176. {
  177.   int i;
  178.  
  179.   randval_a = (int *) malloc(w*5*sizeof(int));
  180.   randptr_a = (int **) malloc(h*sizeof(int *));
  181.  
  182. #ifdef NO_LRAND48
  183.   for (i=0; i<w*5; i++) {
  184.     long int random();
  185.  
  186.     randval_a[i] = random() % RAND_ERR_RANGE;
  187.   }
  188.  
  189.   for (i=0; i<h; i++) {
  190.     long int random();
  191.  
  192.     randptr_a[i] = randval_a + (random() % (w*2));
  193.   }
  194. #else /* NO_LRAND48 */
  195.  
  196.   for (i=0; i<w*5; i++) {
  197.     long int lrand48();
  198.     
  199.     randval_a[i] = lrand48() % RAND_ERR_RANGE;
  200.   }
  201.   
  202.   for (i=0; i<h; i++) {
  203.     long int lrand48();
  204.  
  205.     randptr_a[i] = randval_a + (lrand48() % (w*2));
  206.   }
  207. #endif
  208.   
  209. }
  210.  
  211.  
  212. /*
  213.  *--------------------------------------------------------------
  214.  *
  215.  *  PostInit2x2Dither--
  216.  *
  217.  *    Remaps color numbers in dither patterns to actual pixel
  218.  *      values allocated by the X server.
  219.  *
  220.  * Results:
  221.  *      None.
  222.  *
  223.  * Side effects:
  224.  *      None.
  225.  *
  226.  *--------------------------------------------------------------
  227.  */
  228.  
  229. void
  230. PostInit2x2Dither() 
  231. {
  232.   unsigned char *dith_ca;
  233.   int i;
  234.  
  235.   dith_ca = dith_a;
  236.  
  237.   for (i=0; i < (L_DITH_RANGE * CR_DITH_RANGE * CB_DITH_RANGE); i++) {
  238.     
  239.     *dith_ca = pixel[*dith_ca];
  240.     dith_ca++;
  241.     *dith_ca = pixel[*dith_ca];
  242.     dith_ca++;
  243.     *dith_ca = pixel[*dith_ca];
  244.     dith_ca++;
  245.     *dith_ca = pixel[*dith_ca];
  246.     dith_ca++;
  247.   }
  248. }
  249.  
  250.  
  251. /*
  252.  *--------------------------------------------------------------
  253.  *
  254.  * Twox2DitherImage --
  255.  *
  256.  *    Dithers lum, cr, and cb channels togethor using predefined
  257.  *      and computed 2x2 dither patterns. Each possible combination of
  258.  *      lum, cr, and cb values combines to point to a particular dither
  259.  *      pattern (2x2) which is used to represent the pixel. This assumes
  260.  *      That the display plane is 4 times larger than the lumianance 
  261.  *      plane. 
  262.  *
  263.  * Results:
  264.  *      None.
  265.  *
  266.  * Side effects:
  267.  *      None.
  268.  *
  269.  *--------------------------------------------------------------
  270.  */
  271.  
  272. void 
  273. Twox2DitherImage(lum, cr, cb, out, h, w)
  274.     unsigned char *lum;
  275.     unsigned char *cr;
  276.     unsigned char *cb;
  277.     unsigned char *out;
  278.     int w, h;
  279. {
  280.   int i, j;
  281.   unsigned char *o1, *o2, *o3, *o4;
  282.   unsigned char *l1, *l2, *r, *b;
  283.   unsigned char *dith_ca;
  284.   int big_adv = 6*w;
  285.   int b_val, r_val, l_val;
  286.   int *randvalptr;
  287.   int randval;
  288.   static int first = 1;
  289.  
  290.   if (first) {
  291.     RandInit(h, w);
  292.     first = 0;
  293.   }
  294.  
  295.   o1 = out;
  296.   o2 = out+(2*w);
  297.   o3 = out+(4*w);
  298.   o4 = out+(6*w);
  299.   l1 = lum;
  300.   l2 = lum+w;
  301.   r = cr;
  302.   b = cb;
  303.  
  304.   for (i=0; i<h; i+=2) {
  305.     randvalptr = randptr_a[i];
  306.     for(j=0; j<w; j+= 2) {
  307.  
  308.       randval = *randvalptr++ + *b++;
  309.       b_val = bval_a[randval];
  310.  
  311.       randval = *randvalptr++ + *r++;
  312.       r_val = rval_a[randval];
  313.  
  314.       randval = *randvalptr++ + *l1++;
  315.       l_val = lval_a[randval];
  316.  
  317.       dith_ca = (dith_a + b_val + r_val + l_val);
  318.       
  319.       *o1++ = *dith_ca++;
  320.       *o1++ = *dith_ca++;
  321.       *o2++ = *dith_ca++;
  322.       *o2++ = *dith_ca++;
  323.  
  324.       randval = *randvalptr++ + *l1++;
  325.       l_val = lval_a[randval];
  326.  
  327.       dith_ca = (dith_a + b_val + r_val + l_val);
  328.       
  329.       *o1++ = *dith_ca++;
  330.       *o1++ = *dith_ca++;
  331.       *o2++ = *dith_ca++;
  332.       *o2++ = *dith_ca++;
  333.  
  334.       randval = *randvalptr++ + *l2++;
  335.       l_val = lval_a[randval];
  336.  
  337.       dith_ca = (dith_a + b_val + r_val + l_val);
  338.       
  339.       *o3++ = *dith_ca++;
  340.       *o3++ = *dith_ca++;
  341.       *o4++ = *dith_ca++;
  342.       *o4++ = *dith_ca++;
  343.  
  344.       randval = *randvalptr++ + *l2++;
  345.       l_val = lval_a[randval];
  346.  
  347.       dith_ca = (dith_a + b_val + r_val + l_val);
  348.       
  349.       *o3++ = *dith_ca++;
  350.       *o3++ = *dith_ca++;
  351.       *o4++ = *dith_ca++;
  352.       *o4++ = *dith_ca++;
  353.     }    
  354.  
  355.     l1 += w;
  356.     l2 += w;
  357.     o1 += big_adv;
  358.     o2 += big_adv;
  359.     o3 += big_adv;
  360.     o4 += big_adv;
  361.   }
  362. }
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.