home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / REND.LZH / PIC1600 / REDUCE.C < prev    next >
C/C++ Source or Header  |  1996-06-18  |  5KB  |  173 lines

  1. #include    <stdio.h>
  2. #include    <stdlib.h>
  3. #include    <string.h>
  4. #include    "piclib.h"
  5.  
  6. PicReduceData *PicColorReduceOpen(int sizex, int mode)
  7. {
  8.     PicReduceData *data;
  9.     if ((data = malloc(sizeof(PicReduceData))) == NULL) {
  10.         return NULL;
  11.     }
  12.     data->mode = mode;
  13.     data->y = 0;
  14.     data->x = sizex;
  15.     data->nowbuf = data->nextbuf = NULL;
  16.     switch (mode) {
  17.     case REDUCE_NORMAL:
  18.         break;
  19.     case REDUCE_DITHER_ORDERED:
  20.         break;
  21.     case REDUCE_DITHER_RANDOM:
  22.         break;
  23.     case REDUCE_DITHER_ERROR:
  24.     case REDUCE_DITHER_ERROR216:
  25.         if ((data->nowbuf = malloc(sizeof(Pixel)*(sizex+2))) == NULL) {
  26.             free(data);
  27.             return NULL;
  28.         }
  29.         if ((data->nextbuf = malloc(sizeof(Pixel)*(sizex+2))) == NULL) {
  30.             free(data->nowbuf);
  31.             free(data);
  32.             return NULL;
  33.         }
  34.         memset(data->nowbuf, 0, sizeof(Pixel)*(sizex+2));
  35.         memset(data->nextbuf, 0, sizeof(Pixel)*(sizex+2));
  36.         break;
  37.     }
  38.     return data;
  39. }
  40.  
  41. int        PicColorReduce(PicReduceData *data, Pixel *dst, Pixel *p)
  42. {
  43.     static const int dither_map[2][2] = {{0,6}, {4,2}};
  44.     int r, g, b, x;
  45.     switch (data->mode) {
  46.     case REDUCE_DITHER_ORDERED:
  47.         for (x = 0; x < data->x; ++x) {
  48.             g = (int)((p[x]>>24) & 0xff); g = g - g/32 + dither_map[x&1][data->y&1];
  49.             r = (int)((p[x]>>16) & 0xff); r = r - r/32 + dither_map[x&1][data->y&1];
  50.             b = (int)((p[x]>> 8) & 0xff); b = b - b/32 + dither_map[x&1][data->y&1];
  51.             dst[x] = (g << 24) + (r << 16) + (b << 8) + (p[x]&0xff);
  52.         }
  53.         data->y++;
  54.         break;
  55.     case REDUCE_DITHER_RANDOM:
  56.         {
  57.             int diff;
  58.             for (x = 0; x < data->x; ++x) {
  59.                 diff = (rand()>>12)%8;
  60.                 g = (int)((p[x] >> 24) & 0xff); g = g - g/32 + diff;
  61.                 r = (int)((p[x] >> 16) & 0xff); r = r - r/32 + diff;
  62.                 b = (int)((p[x] >>  8) & 0xff); b = b - b/32 + diff;
  63.                 dst[x] = (g << 24) + (r << 16) + (b << 8) + (p[x]&0xff);
  64.             }
  65.         }
  66.         break;
  67.     case REDUCE_DITHER_ERROR:
  68.         {
  69.             int x;
  70.             int er = 0, eg = 0, eb = 0, ee;
  71.             int tmp;
  72.             Pixel *now, *next;
  73.             now = data->nowbuf;
  74.             next = data->nextbuf;
  75.             data->nowbuf = next;
  76.             data->nextbuf = now;
  77.             memset(next, 0, sizeof(Pixel)*data->x);
  78.             for (x = 0; x < data->x; ++x) {
  79.                 tmp = (int)((p[x] >> 24) & 0xff); tmp = tmp - (tmp/32);
  80.                 g = tmp & 0xf8;
  81.                 ee = (tmp & 7) * 8+ eg + (int)((now[x] >> 24) & 0xff);
  82. /*printf("(%3d):%3d:%3d=%3d+%3d+%3d", x, g, ee, (tmp&7)*8, eg, ((now[x] >> 24) & 0xff));*/
  83.                 if (ee > 64) {ee = 0; g += 8;}
  84.                 eg = (ee * 3 + 4)/8;
  85. /*printf("-> %3d:%3d\n", g, eg);*/
  86.                 next[x  ] += eg << 24;
  87.                 next[x+1] += (ee-eg*2) << 24;
  88.  
  89.                 tmp = (int)((p[x] >> 16) & 0xff); tmp = tmp - (tmp/32);
  90.                 r = tmp & 0xf8;
  91.                 ee = (tmp & 7) * 8 + er + (int)((now[x] >> 16) & 0xff);
  92.                 if (ee > 64) {ee = 0; r+=8;}
  93.                 er = (ee * 3 + 4)/8;
  94.                 next[x  ] += er << 16;
  95.                 next[x+1] += (ee-er*2) << 16;
  96.  
  97.                 tmp = (int)((p[x] >>  8) & 0xff); tmp = tmp - (tmp/32);
  98.                 b = tmp & 0xf8;
  99.                 ee = (tmp & 7) * 8 + eb + (int)((now[x] >>  8) & 0xff);
  100.                 if (ee > 64) {ee = 0; b+=8;}
  101.                 eb = (ee * 3 + 4)/8;
  102.                 next[x  ] += eb << 8;
  103.                 next[x+1] += (ee-eb*2) << 8;
  104.  
  105.                 dst[x] = (g << 24) + (r << 16) + (b << 8) + (p[x]&0xff);
  106.             }
  107.         }
  108.         break;
  109.     case REDUCE_DITHER_ERROR216:
  110.         {
  111.             int x;
  112.             int er = 0, eg = 0, eb = 0, ee;
  113.             Pixel *now, *next;
  114.             now = data->nowbuf;
  115.             next = data->nextbuf;
  116.             data->nowbuf = next;
  117.             data->nextbuf = now;
  118.             memset(next, 0, sizeof(Pixel)*data->x);
  119.             for (x = 0; x < data->x; ++x) {
  120.                 ee = (int)((p[x] >> 24) & 0xff) + eg + (int)((now[x] >> 24) & 0xff);
  121.                 g = ee / 32; ee = ee % 32;
  122.                 eg = (ee * 3 + 4) / 8;
  123.                 next[x  ] += eg << 24;
  124.                 next[x+1] += (ee-eg*2) << 24;
  125.  
  126.                 ee = (int)((p[x] >> 16) & 0xff) + er + (int)((now[x] >> 16) & 0xff);
  127.                 r = ee / 32; ee = ee % 32;
  128.                 er = (ee * 3 + 4) / 8;
  129.                 next[x  ] += er << 16;
  130.                 next[x+1] += (ee-er*2) << 16;
  131.  
  132.                 ee = (int)((p[x] >>  8) & 0xff) + eb + (int)((now[x] >>  8) & 0xff);
  133.                 b = ee / 32; ee = ee % 32;
  134.                 eb = (ee * 3 + 4) / 8;
  135.                 next[x  ] += eb <<  8;
  136.                 next[x+1] += (ee-eb*2) <<  8;
  137.  
  138.                 if (--r < 0) r = 0;
  139.                 if (r > 5) r = 5;
  140.                 if (--g < 0) g = 0;
  141.                 if (g > 5) g = 5;
  142.                 if (--b < 0) b = 0;
  143.                 if (b > 5) b = 5;
  144.  
  145.                 dst[x] = ((g * 51) << 24)
  146.                        + ((r * 51) << 16)
  147.                        + ((b * 51) <<  8) + (p[x]&0xff);
  148.             }
  149.         }
  150.         break;
  151.     default:
  152.         if (dst != p) {
  153.             memcpy(dst, p, sizeof(Pixel) * data->x);
  154.         }
  155.         break;
  156.     }
  157.     return TRUE;
  158. }
  159.  
  160.  
  161. int        PicColorReduceClose(PicReduceData *data)
  162. {
  163.     if (data != NULL) {
  164.         if (data->nowbuf != NULL) {
  165.             free(data->nowbuf);
  166.         }
  167.         if (data->nextbuf != NULL) {
  168.             free(data->nextbuf);
  169.         }
  170.     }
  171.     return TRUE;
  172. }
  173.