"Fossies" - the Fresh Open Source Software Archive 
Member "xzgv-0.9.2/src/dither.c" (3 Sep 2017, 2234 Bytes) of package /linux/misc/old/xzgv-0.9.2.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "dither.c" see the
Fossies "Dox" file reference documentation.
1 /* xzgv v0.1 - picture viewer for X, with file selector.
2 * Copyright (C) 1999 Russell Marks. See main.c for license details.
3 *
4 * dither.c - dithering routine.
5 */
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdlib.h>
10 #include "dither.h"
11
12
13 static int *evenerr=NULL,*odderr=NULL;
14 static unsigned char *dbuf=NULL;
15
16
17 int ditherinit(int w)
18 {
19 ditherfinish(); /* make sure any previous mem is unallocated */
20 if((evenerr=calloc(3*(w+10),sizeof(int)))==NULL ||
21 (odderr =calloc(3*(w+10),sizeof(int)))==NULL ||
22 (dbuf =malloc(w))==NULL)
23 return(0);
24 else
25 return(1);
26 }
27
28
29 void ditherfinish()
30 {
31 if(evenerr!=NULL) { free(evenerr); evenerr=NULL; }
32 if(odderr!=NULL) { free(odderr); odderr=NULL; }
33 if(dbuf!=NULL) { free(dbuf); dbuf=NULL; }
34 }
35
36
37 void ditherline(unsigned char *theline,int linenum,int width)
38 {
39 int x,y,lx;
40 int c0,c1,c2,times2;
41 int terr0,terr1,terr2,actual0,actual1,actual2;
42 int start,addon,r,g,b;
43 int *thiserr;
44 int *nexterr;
45
46 y=linenum;
47 if((y&1)==0)
48 {start=0; addon=1;
49 thiserr=evenerr+3; nexterr=odderr+width*3;}
50 else
51 {start=width-1; addon=-1;
52 thiserr=odderr+3; nexterr=evenerr+width*3;}
53 nexterr[0]=nexterr[1]=nexterr[2]=0;
54 x=start;
55 for(lx=0;lx<width;lx++)
56 {
57 r=theline[x*3];
58 g=theline[x*3+1];
59 b=theline[x*3+2];
60
61 terr0=r+((thiserr[0]+8)>>4);
62 terr1=g+((thiserr[1]+8)>>4);
63 terr2=b+((thiserr[2]+8)>>4);
64
65 /* is this going to screw up on white? */
66 actual0=(terr0>>5)*255/7;
67 actual1=(terr1>>5)*255/7;
68 actual2=(terr2>>6)*255/3;
69
70 if(actual0<0) actual0=0; if(actual0>255) actual0=255;
71 if(actual1<0) actual1=0; if(actual1>255) actual1=255;
72 if(actual2<0) actual2=0; if(actual2>255) actual2=255;
73
74 c0=terr0-actual0;
75 c1=terr1-actual1;
76 c2=terr2-actual2;
77
78 times2=(c0<<1);
79 nexterr[-3] =c0; c0+=times2;
80 nexterr[ 3]+=c0; c0+=times2;
81 nexterr[ 0]+=c0; c0+=times2;
82 thiserr[ 3]+=c0;
83
84 times2=(c1<<1);
85 nexterr[-2] =c1; c1+=times2;
86 nexterr[ 4]+=c1; c1+=times2;
87 nexterr[ 1]+=c1; c1+=times2;
88 thiserr[ 4]+=c1;
89
90 times2=(c2<<1);
91 nexterr[-1] =c2; c2+=times2;
92 nexterr[ 5]+=c2; c2+=times2;
93 nexterr[ 2]+=c2; c2+=times2;
94 thiserr[ 5]+=c2;
95
96 dbuf[x]=(actual0>>5)*32+(actual1>>5)*4+(actual2>>6);
97
98 thiserr+=3;
99 nexterr-=3;
100 x+=addon;
101 }
102
103 memcpy(theline,dbuf,width);
104 }