"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 }