home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / amiga / mpeg / mpgplyr1.lha / src / ordered.c < prev    next >
C/C++ Source or Header  |  1992-12-08  |  8KB  |  286 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 "dither.h"
  25.  
  26. #define DITH_SIZE 16
  27.  
  28.  
  29. /* Structures used to implement hybrid ordered dither/floyd-steinberg
  30.    dither algorithm.
  31. */
  32.  
  33. static unsigned char *l_darrays[DITH_SIZE];
  34. static unsigned char *cr_darrays[DITH_SIZE];
  35. static unsigned char *cb_darrays[DITH_SIZE];
  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. InitOrderedDither()
  55. {
  56.   int i, j, k, err_range, threshval;
  57.   unsigned char *lmark, *cmark;
  58.  
  59.   for (i=0; i<DITH_SIZE; i++) {
  60.     lmark = l_darrays[i] = (unsigned char *) malloc(256);
  61.  
  62.     for (j=0; j<lum_values[0]; j++) {
  63.       *lmark++ = 0;
  64.     }
  65.  
  66.     for (j=0; j<(LUM_RANGE-1); j++) {
  67.       err_range = lum_values[j+1] - lum_values[j];
  68.       threshval = ((i * err_range) / DITH_SIZE)+lum_values[j];
  69.  
  70.       for (k=lum_values[j]; k<lum_values[j+1]; k++) {
  71.     if (k > threshval) *lmark++ = ((j+1) * (CR_RANGE * CB_RANGE));
  72.     else *lmark++ = (j * (CR_RANGE * CB_RANGE));
  73.       }
  74.     }
  75.  
  76.     for (j=lum_values[LUM_RANGE-1]; j<256; j++) {
  77.       *lmark++ = (LUM_RANGE-1)*(CR_RANGE * CB_RANGE);
  78.     }
  79.   }
  80.  
  81.   for (i=0; i<DITH_SIZE; i++) {
  82.     cmark = cr_darrays[i] = (unsigned char *) malloc(256);
  83.  
  84.     for (j=0; j<cr_values[0]; j++) {
  85.       *cmark++ = 0;
  86.     }
  87.  
  88.     for (j=0; j<(CR_RANGE-1); j++) {
  89.       err_range = cr_values[j+1] - cr_values[j];
  90.       threshval = ((i * err_range) / DITH_SIZE)+cr_values[j];
  91.  
  92.       for (k=cr_values[j]; k<cr_values[j+1]; k++) {
  93.     if (k > threshval) *cmark++ = ((j+1) * CB_RANGE);
  94.     else *cmark++ = (j * CB_RANGE);
  95.       }
  96.     }
  97.  
  98.     for (j=cr_values[CR_RANGE-1]; j<256; j++) {
  99.       *cmark++ = (CR_RANGE-1)*(CB_RANGE);
  100.     }
  101.   }
  102.  
  103.   for (i=0; i<DITH_SIZE; i++) {
  104.     cmark = cb_darrays[i] = (unsigned char *) malloc(256);
  105.  
  106.     for (j=0; j<cb_values[0]; j++) {
  107.       *cmark++ = 0;
  108.     }
  109.  
  110.     for (j=0; j<(CB_RANGE-1); j++) {
  111.       err_range = cb_values[j+1] - cb_values[j];
  112.       threshval = ((i * err_range) / DITH_SIZE)+cb_values[j];
  113.  
  114.       for (k=cb_values[j]; k<cb_values[j+1]; k++) {
  115.     if (k > threshval) *cmark++ = j+1;
  116.     else *cmark++ = j;
  117.       }
  118.     }
  119.  
  120.     for (j=cb_values[CB_RANGE-1]; j<256; j++) {
  121.       *cmark++ = CB_RANGE-1;
  122.     }
  123.   }
  124. }
  125.  
  126. /*
  127.  *--------------------------------------------------------------
  128.  *
  129.  * OrderedDitherImage --
  130.  *
  131.  *    Dithers an image using an ordered dither.
  132.  *    Assumptions made:
  133.  *      1) The color space is allocated y:cr:cb = 8:4:4
  134.  *      2) The spatial resolution of y:cr:cb is 4:1:1
  135.  *      The channels are dithered based on the standard
  136.  *      ordered dither pattern for a 4x4 area. 
  137.  *
  138.  * Results:
  139.  *    None.
  140.  *
  141.  * Side effects:
  142.  *    None.
  143.  *
  144.  *--------------------------------------------------------------
  145.  */
  146. void
  147. OrderedDitherImage (lum, cr, cb, out, h, w)
  148.     unsigned char *lum;
  149.     unsigned char *cr;
  150.     unsigned char *cb;
  151.     unsigned char *out;
  152.     int w, h;
  153. {
  154.   unsigned char *l, *r, *b, *o1, *o2;
  155.   unsigned char *l2;
  156.   unsigned char L, R, B;
  157.   int i, j;
  158.  
  159.   l = lum;
  160.   l2 = lum+w;
  161.   r = cr;
  162.   b = cb;
  163.   o1 = out;
  164.   o2 = out+w;
  165.  
  166.   for (i=0; i<h; i+=4) {
  167.  
  168.     for (j=0; j<w; j+=8) {
  169.  
  170.       R = r[0]; B = b[0];
  171.  
  172.       L = l[0];
  173.       o1[0] = pixel[(l_darrays[0][L] + cr_darrays[0][R] + cb_darrays[0][B])];
  174.       L = l[1];
  175.       o1[1] = pixel[(l_darrays[8][L] + cr_darrays[8][R] + cb_darrays[8][B])];
  176.       L = l2[0];
  177.       o2[0] = pixel[(l_darrays[12][L] + cr_darrays[12][R] + cb_darrays[12][B])];
  178.       L = l2[1];
  179.       o2[1] = pixel[(l_darrays[4][L] + cr_darrays[4][R] + cb_darrays[4][B])];
  180.  
  181.       R = r[1]; B = b[1];
  182.  
  183.       L = l[2];
  184.       o1[2] = pixel[(l_darrays[2][L] + cr_darrays[2][R] + cb_darrays[2][B])];
  185.       L = l[3];
  186.       o1[3] = pixel[(l_darrays[10][L] + cr_darrays[10][R] + cb_darrays[10][B])];
  187.       L = l2[2];
  188.       o2[2] = pixel[(l_darrays[14][L] + cr_darrays[14][R] + cb_darrays[14][B])];
  189.       L = l2[3];
  190.       o2[3] = pixel[(l_darrays[6][L] + cr_darrays[6][R] + cb_darrays[6][B])];
  191.  
  192.       R = r[2]; B = b[2];
  193.  
  194.       L = l[4];
  195.       o1[4] = pixel[(l_darrays[0][L] + cr_darrays[0][R] + cb_darrays[0][B])];
  196.       L = l[5];
  197.       o1[5] = pixel[(l_darrays[8][L] + cr_darrays[8][R] + cb_darrays[8][B])];
  198.       L = l2[4];
  199.       o2[4] = pixel[(l_darrays[12][L] + cr_darrays[12][R] + cb_darrays[12][B])];
  200.       L = l2[5];
  201.       o2[5] = pixel[(l_darrays[4][L] + cr_darrays[4][R] + cb_darrays[4][B])];
  202.  
  203.       R = r[3]; B = b[3];
  204.  
  205.       L = l[6];
  206.       o1[6] = pixel[(l_darrays[2][L] + cr_darrays[2][R] + cb_darrays[2][B])];
  207.       L = l[7];
  208.       o1[7] = pixel[(l_darrays[10][L] + cr_darrays[10][R] + cb_darrays[10][B])];
  209.       L = l2[6];
  210.       o2[6] = pixel[(l_darrays[14][L] + cr_darrays[14][R] + cb_darrays[14][B])];
  211.       L = l2[7];
  212.       o2[7] = pixel[(l_darrays[6][L] + cr_darrays[6][R] + cb_darrays[6][B])];
  213.  
  214.       l += 8;
  215.       l2 += 8;
  216.       r += 4;
  217.       b += 4;
  218.       o1 += 8;
  219.       o2 += 8;
  220.     }
  221.  
  222.     l += w; l2 += w;
  223.     o1 += w; o2 += w;
  224.  
  225.     for (j=0; j<w; j+=8) {
  226.  
  227.       R = r[0]; B = b[0];
  228.  
  229.       L = l[0];
  230.       o1[0] = pixel[(l_darrays[3][L] + cr_darrays[3][R] + cb_darrays[3][B])];
  231.       L = l[1];
  232.       o1[1] = pixel[(l_darrays[11][L] + cr_darrays[11][R] + cb_darrays[11][B])];
  233.       L = l2[0];
  234.       o2[0] = pixel[(l_darrays[15][L] + cr_darrays[15][R] + cb_darrays[15][B])];
  235.       L = l2[1];
  236.       o2[1] = pixel[(l_darrays[7][L] + cr_darrays[7][R] + cb_darrays[7][B])];
  237.  
  238.       R = r[1]; B = b[1];
  239.  
  240.       L = l[2];
  241.       o1[2] = pixel[(l_darrays[1][L] + cr_darrays[1][R] + cb_darrays[1][B])];
  242.       L = l[3];
  243.       o1[3] = pixel[(l_darrays[9][L] + cr_darrays[9][R] + cb_darrays[9][B])];
  244.       L = l2[2];
  245.       o2[2] = pixel[(l_darrays[13][L] + cr_darrays[13][R] + cb_darrays[13][B])];
  246.       L = l2[3];
  247.       o2[3] = pixel[(l_darrays[5][L] + cr_darrays[5][R] + cb_darrays[5][B])];
  248.  
  249.       R = r[2]; B = b[2];
  250.  
  251.       L = l[4];
  252.       o1[4] = pixel[(l_darrays[3][L] + cr_darrays[3][R] + cb_darrays[3][B])];
  253.       L = l[5];
  254.       o1[5] = pixel[(l_darrays[11][L] + cr_darrays[11][R] + cb_darrays[11][B])];
  255.       L = l2[4];
  256.       o2[4] = pixel[(l_darrays[15][L] + cr_darrays[15][R] + cb_darrays[15][B])];
  257.       L = l2[5];
  258.       o2[5] = pixel[(l_darrays[7][L] + cr_darrays[7][R] + cb_darrays[7][B])];
  259.  
  260.       R = r[3]; B = b[3];
  261.  
  262.       L = l[6];
  263.       o1[6] = pixel[(l_darrays[1][L] + cr_darrays[1][R] + cb_darrays[1][B])];
  264.       L = l[7];
  265.       o1[7] = pixel[(l_darrays[9][L] + cr_darrays[9][R] + cb_darrays[9][B])];
  266.       L = l2[6];
  267.       o2[6] = pixel[(l_darrays[13][L] + cr_darrays[13][R] + cb_darrays[13][B])];
  268.       L = l2[7];
  269.       o2[7] = pixel[(l_darrays[5][L] + cr_darrays[5][R] + cb_darrays[5][B])];
  270.  
  271.       l += 8;
  272.       l2 += 8;
  273.       r += 4;
  274.       b += 4;
  275.       o1 += 8;
  276.       o2 += 8;
  277.     }
  278.  
  279.     l += w; l2 += w;
  280.     o1 += w; o2 += w;
  281.   }
  282. }
  283.  
  284.  
  285.   
  286.