home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Multimed / Multimed.zip / mpegplay.zip / ORDERED2.C < prev    next >
C/C++ Source or Header  |  1994-02-16  |  9KB  |  325 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. /* This file contains C code to implement an ordered dither. */
  22.  
  23. #include "video.h"
  24. #include "proto.h"
  25. #include "dither.h"
  26.  
  27. #define DITH_SIZE 16
  28.  
  29.  
  30. /* Structures used to implement hybrid ordered dither/floyd-steinberg
  31.    dither algorithm.
  32. */
  33.  
  34. static unsigned char ***ditherPtr[DITH_SIZE];
  35.  
  36.  
  37. /*
  38.  *--------------------------------------------------------------
  39.  *
  40.  *  InitOrderedDither--
  41.  *
  42.  *    Structures intialized for ordered dithering. 
  43.  *
  44.  * Results:
  45.  *    None.
  46.  *
  47.  * Side effects:
  48.  *      None.
  49.  *
  50.  *--------------------------------------------------------------
  51.  */
  52.  
  53. void
  54. InitOrdered2Dither()
  55. {
  56.   unsigned char ****pos_2_cb;
  57.   unsigned char ***cb_2_cr;
  58.   unsigned char **cr_2_l;
  59.   int cb_val, cb_rval, cr_val, cr_rval, l_val, l_rval;
  60.   int i, j, pos;
  61.   int err_range, threshval;
  62.  
  63.   pos_2_cb = (unsigned char ****) malloc (DITH_SIZE*sizeof(unsigned char ***));
  64.   cb_2_cr = (unsigned char ***) malloc(CB_RANGE*sizeof(unsigned char **));
  65.   cr_2_l = (unsigned char **) malloc(CR_RANGE*sizeof(unsigned char *));
  66.  
  67.   for (pos=0; pos<DITH_SIZE; pos++) {
  68.     
  69.     pos_2_cb[pos] = (unsigned char ***) malloc(256*(sizeof(unsigned char **)));
  70.  
  71.     for (j=0; j<CB_RANGE; j++) {
  72.       cb_2_cr[j] = (unsigned char **) malloc(256*(sizeof(unsigned char *)));
  73.     }
  74.  
  75.     for (cb_val=0; cb_val<cb_values[0]; cb_val++) {
  76.       (pos_2_cb[pos])[cb_val] = cb_2_cr[0];
  77.     }
  78.  
  79.     for (cb_rval=0; cb_rval<(CB_RANGE-1); cb_rval++) {
  80.       err_range = cb_values[cb_rval+1] - cb_values[cb_rval];
  81.       threshval = ((pos*err_range)/DITH_SIZE)+cb_values[cb_rval];
  82.  
  83.       for (cb_val=cb_values[cb_rval]; cb_val<cb_values[cb_rval+1]; cb_val++) {
  84.     if (cb_val>threshval) (pos_2_cb[pos])[cb_val] = cb_2_cr[cb_rval+1];
  85.     else (pos_2_cb[pos])[cb_val] = cb_2_cr[cb_rval];
  86.       }
  87.     }
  88.  
  89.     for (cb_val=cb_values[CB_RANGE-1]; cb_val<256; cb_val++) {
  90.       (pos_2_cb[pos])[cb_val] = cb_2_cr[CB_RANGE-1];
  91.     }
  92.  
  93.     for (cb_rval=0; cb_rval<CB_RANGE; cb_rval++) {
  94.       
  95.       for (j=0; j<CR_RANGE; j++) {
  96.     cr_2_l[j] = (unsigned char *) malloc(256*(sizeof(unsigned char)));
  97.       }
  98.  
  99.       for (cr_val=0; cr_val < cr_values[0]; cr_val++) {
  100.     (cb_2_cr[cb_rval])[cr_val] = cr_2_l[0];
  101.       }
  102.  
  103.       for (cr_rval=0; cr_rval<(CR_RANGE-1); cr_rval++) {
  104.     err_range = cr_values[cr_rval+1] - cr_values[cr_rval];
  105.     threshval = ((pos*err_range)/DITH_SIZE)+cr_values[cr_rval];
  106.     
  107.     for (cr_val=cr_values[cr_rval]; cr_val<cr_values[cr_rval+1]; cr_val++) {
  108.       if (cr_val>threshval) (cb_2_cr[cb_rval])[cr_val] = cr_2_l[cr_rval+1];
  109.       else (cb_2_cr[cb_rval])[cr_val] = cr_2_l[cr_rval];
  110.     }
  111.       }
  112.       
  113.       for (cr_val=cr_values[CR_RANGE-1]; cr_val<256; cr_val++) {
  114.     (cb_2_cr[cb_rval])[cr_val] = cr_2_l[CR_RANGE-1];
  115.       }
  116.       
  117.       for (cr_rval=0; cr_rval<CR_RANGE; cr_rval++) {
  118.     
  119.     for (l_val = 0; l_val < lum_values[0]; l_val++) {
  120.       (cr_2_l[cr_rval])[l_val] = PIXEL(cb_rval+(cr_rval*CB_RANGE)+
  121.                         (0*CR_RANGE*CB_RANGE));
  122.     }
  123.  
  124.     for (l_rval=0; l_rval<(LUM_RANGE-1); l_rval++) {
  125.       err_range = lum_values[l_rval+1] - lum_values[l_rval];
  126.       threshval = ((pos*err_range) /DITH_SIZE) + lum_values[l_rval];
  127.  
  128.       for (l_val = lum_values[l_rval]; l_val < lum_values[l_rval+1]; l_val++) {
  129.         if (l_val>threshval) (cr_2_l[cr_rval])[l_val] = 
  130.           PIXEL(cb_rval+(cr_rval*CB_RANGE)+((l_rval+1)*CR_RANGE*CB_RANGE));
  131.         else (cr_2_l[cr_rval])[l_val] =
  132.           PIXEL(cb_rval+(cr_rval*CB_RANGE)+(l_rval*CR_RANGE*CB_RANGE));
  133.       }
  134.     }
  135.  
  136.     for (l_val = lum_values[LUM_RANGE-1]; l_val < 256; l_val++) {
  137.       (cr_2_l[cr_rval])[l_val] = 
  138.         PIXEL(cb_rval+(cr_rval*CB_RANGE)+((LUM_RANGE-1)*CR_RANGE*CB_RANGE));
  139.     }
  140.       }
  141.     }
  142.   }
  143.  
  144.   for (i=0; i<DITH_SIZE; i++) {
  145.     ditherPtr[i] = pos_2_cb[i];
  146.   }
  147. }
  148.  
  149. /*
  150.  *--------------------------------------------------------------
  151.  *
  152.  * Ordered2DitherImage --
  153.  *
  154.  *    Dithers an image using an ordered dither.
  155.  *    Assumptions made:
  156.  *      1) The color space is allocated y:cr:cb = 8:4:4
  157.  *      2) The spatial resolution of y:cr:cb is 4:1:1
  158.  *      The channels are dithered based on the standard
  159.  *      ordered dither pattern for a 4x4 area. 
  160.  *
  161.  * Results:
  162.  *    None.
  163.  *
  164.  * Side effects:
  165.  *    None.
  166.  *
  167.  *--------------------------------------------------------------
  168.  */
  169. void
  170. Ordered2DitherImage (lum, cr, cb, out, h, w)
  171.     unsigned char *lum;
  172.     unsigned char *cr;
  173.     unsigned char *cb;
  174.     unsigned char *out;
  175.     int w, h;
  176. {
  177.   unsigned char *l, *r, *b, *o1, *o2;
  178.   unsigned char *l2;
  179.   unsigned char L, R, B;
  180.   int i, j;
  181.   unsigned char ***dp0 = ditherPtr[0];
  182.   unsigned char ***dp2 = ditherPtr[2];
  183.   unsigned char ***dp4 = ditherPtr[4];
  184.   unsigned char ***dp6 = ditherPtr[6];
  185.   unsigned char ***dp8 = ditherPtr[8];
  186.   unsigned char ***dp10 = ditherPtr[10];
  187.   unsigned char ***dp12 = ditherPtr[12];
  188.   unsigned char ***dp14 = ditherPtr[14];
  189.   unsigned char ***dp1 = ditherPtr[1];
  190.   unsigned char ***dp3 = ditherPtr[3];
  191.   unsigned char ***dp5 = ditherPtr[5];
  192.   unsigned char ***dp7 = ditherPtr[7];
  193.   unsigned char ***dp9 = ditherPtr[9];
  194.   unsigned char ***dp11 = ditherPtr[11];
  195.   unsigned char ***dp13 = ditherPtr[13];
  196.   unsigned char ***dp15 = ditherPtr[15];
  197.  
  198.   l = lum;
  199.   l2 = lum+w;
  200.   r = cr;
  201.   b = cb;
  202.   o1 = out;
  203.   o2 = out+w;
  204.  
  205.   for (i=0; i<h; i+=4) {
  206.  
  207.     for (j=0; j<w; j+=8) {
  208.  
  209.       R = r[0]; B = b[0];
  210.  
  211.       L = l[0];
  212.       o1[0] = ((dp0[B])[R])[L];
  213.       L = l[1];
  214.       o1[1] = ((dp8[B])[R])[L];
  215.       L = l2[0];
  216.       o2[0] = ((dp12[B])[R])[L];
  217.       L = l2[1];
  218.       o2[1] = ((dp4[B])[R])[L];
  219.  
  220.       R = r[1]; B = b[1];
  221.  
  222.       L = l[2];
  223.       o1[2] = ((dp2[B])[R])[L];
  224.       L = l[3];
  225.       o1[3] = ((dp10[B])[R])[L];
  226.       L = l2[2];
  227.       o2[2] = ((dp14[B])[R])[L];
  228.       L = l2[3];
  229.       o2[3] = ((dp6[B])[R])[L];
  230.  
  231.       R = r[2]; B = b[2];
  232.  
  233.       L = l[4];
  234.       o1[4] = ((dp0[B])[R])[L];
  235.       L = l[5];
  236.       o1[5] = ((dp8[B])[R])[L];
  237.       L = l2[4];
  238.       o2[4] = ((dp12[B])[R])[L];
  239.       L = l2[5];
  240.       o2[5] = ((dp4[B])[R])[L];
  241.  
  242.       R = r[3]; B = b[3];
  243.  
  244.       L = l[6];
  245.       o1[6] = ((dp2[B])[R])[L];
  246.       L = l[7];
  247.       o1[7] = ((dp10[B])[R])[L];
  248.       L = l2[6];
  249.       o2[6] = ((dp14[B])[R])[L];
  250.       L = l2[7];
  251.       o2[7] = ((dp6[B])[R])[L];
  252.  
  253.       l += 8;
  254.       l2 += 8;
  255.       r += 4;
  256.       b += 4;
  257.       o1 += 8;
  258.       o2 += 8;
  259.     }
  260.  
  261.     l += w; l2 += w;
  262.     o1 += w; o2 += w;
  263.  
  264.     for (j=0; j<w; j+=8) {
  265.  
  266.       R = r[0]; B = b[0];
  267.  
  268.       L = l[0];
  269.       o1[0] = ((dp3[B])[R])[L];
  270.       L = l[1];
  271.       o1[1] = ((dp11[B])[R])[L];
  272.       L = l2[0];
  273.       o2[0] = ((dp15[B])[R])[L];
  274.       L = l2[1];
  275.       o2[1] = ((dp7[B])[R])[L];
  276.  
  277.       R = r[1]; B = b[1];
  278.  
  279.       L = l[2];
  280.       o1[2] = ((dp1[B])[R])[L];
  281.       L = l[3];
  282.       o1[3] = ((dp9[B])[R])[L];
  283.       L = l2[2];
  284.       o2[2] = ((dp13[B])[R])[L];
  285.       L = l2[3];
  286.       o2[3] = ((dp5[B])[R])[L];
  287.  
  288.       R = r[2]; B = b[2];
  289.  
  290.       L = l[4];
  291.       o1[4] = ((dp3[B])[R])[L];
  292.       L = l[5];
  293.       o1[5] = ((dp11[B])[R])[L];
  294.       L = l2[4];
  295.       o2[4] = ((dp15[B])[R])[L];
  296.       L = l2[5];
  297.       o2[5] = ((dp7[B])[R])[L];
  298.  
  299.       R = r[3]; B = b[3];
  300.  
  301.       L = l[6];
  302.       o1[6] = ((dp1[B])[R])[L];
  303.       L = l[7];
  304.       o1[7] = ((dp9[B])[R])[L];
  305.       L = l2[6];
  306.       o2[6] = ((dp13[B])[R])[L];
  307.       L = l2[7];
  308.       o2[7] = ((dp5[B])[R])[L];
  309.  
  310.       l += 8;
  311.       l2 += 8;
  312.       r += 4;
  313.       b += 4;
  314.       o1 += 8;
  315.       o2 += 8;
  316.     }
  317.  
  318.     l += w; l2 += w;
  319.     o1 += w; o2 += w;
  320.   }
  321. }
  322.  
  323.  
  324.   
  325.