/** * $Id:$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * The contents of this file may be used under the terms of either the GNU * General Public License Version 2 or later (the "GPL", see * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or * later (the "BL", see http://www.blender.org/BL/ ) which has to be * bought from the Blender Foundation to become active, in which case the * above mentioned GPL option does not apply. * * The Original Code is Copyright (C) 2002 by NaN Holding BV. * All rights reserved. * * The Original Code is: all of this file. * * Contributor(s): none yet. * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ #include "imbuf.h" #define OBJECTBLOK "dithers" /************************************************************************/ /* DITHERS */ /************************************************************************/ void (*ditherfunc)(struct ImBuf *, short, short) = dit0; long dithertype = '0'; short jitdit; void floyd(struct ImBuf * ibuf, short ofs, short bits) { short *buf,*errb,x,y,pix,err,and,nand; uchar *rect; buf = callocstruct(short,ibuf->x+2); if (buf == 0) return; rect= (uchar *)ibuf->rect; rect +=ofs; bits = 8 - bits; and = (1<y;y>0;y--){ errb = buf+1; for(x=ibuf->x;x>0;x--){ err = errb[-1] << 3; /* *8 */ err += errb[0]; err += errb[0] << 2; /* *5 */ err += errb[1]; err += errb[1] << 1; /* *3 */ err >>= 4; pix = *rect+err; if (pix>255) pix=255; *(errb++) = pix & and; *rect = pix & nand; rect += 4; } } free(buf); } void dit2_new(struct ImBuf * ibuf, short * deltab, short bits) { int x, y, errr, errg, errb, val, add, r, g, b, nr, ng, nb, i, j; int col[4]; uchar * rect, map[255], * cmap, * temp; /* mapping vullen */ add = (1 << bits) - 1; val = add; for (x = 0; x < 256; x++) { map[x] = val >> 8; val += add; } rect = (uchar *) ibuf->rect; /* grijswaardes voor iedere kleur berekenen */ cmap = malloc(4 * ibuf->maxcol); memcpy(cmap, ibuf->cmap, 4 * ibuf->maxcol); temp = cmap; for (i = 0; i < ibuf->maxcol; i++){ temp[0] = (.114 * temp[1]) + (.587 * temp[2]) + (.299 * temp[3]); temp += 4; } for(y = ibuf->y ; y > 0 ; y--){ if (y & 1) add = 2; else add = 0; for(x = ibuf->x ; x > 0 ; x--){ r = rect[0]; g = rect[1]; b = rect[2]; errr = errg = errb = 0; for (i = 0; i < 4; i++) { nr = r + errr; ng = g + errg; nb = b + errb; /* clippen */ if (nr & 0xff00) { if (nr < 0) nr = 0; else nr = 255; } if (ng & 0xff00) { if (ng < 0) ng = 0; else ng = 255; } if (nb & 0xff00) { if (nb < 0) nb = 0; else nb = 255; } nr = map[nr]; ng = map[ng]; nb = map[nb]; val = (((nb << bits) + ng) << bits) + nr; col[i] = val = deltab[val << 1]; val <<= 2; errr += r - cmap[val + 0]; errg += g - cmap[val + 1]; errb += b - cmap[val + 2]; } /* kleuren op grijswaarde sorteren */ for (i = 0; i < 4; i++) col[i] |= cmap[col[i] << 2] << 20; for (i = 0; i < 3; i++) { for (j = i + 1; j < 4; j++) { if (col[j] < col[i]) {val = col[i]; col[i] = col[j]; col[j] = val;} } } if (col[1] != col[2]) { /* geen diagonale dithering */ if ((col[0] == col[1]) || (col[2] == col[3])) {val = col[0]; col[0] = col[2]; col[2] = val;} } /* trillen verminderen */ val = col[0]; col[0] = col[3]; col[3] = val; ((uint *) rect)[0] = col[add + (x & 1)]; rect += 4; } } } void dit2(struct ImBuf * ibuf, short ofs, short bits) { short x,y,pix,and,add1,add2; uchar *rect; uchar dit[4]; rect= (uchar *)ibuf->rect; rect +=ofs; bits = 8 - bits; and = ~((1<>= -bits; dit[1] >>= -bits; dit[2] >>= -bits; dit[3] >>= -bits; } else{ dit[0] <<= bits; dit[1] <<= bits; dit[2] <<= bits; dit[3] <<= bits; } for(y=ibuf->y;y>0;y--){ if(y & 1){ add1=dit[0]; add2=dit[1]; } else{ add1=dit[2]; add2=dit[3]; } for(x=ibuf->x;x>0;x--){ pix = *rect; if (x & 1) pix += add1; else pix += add2; if (pix>255) pix=255; *rect = pix & and; rect += 4; } } } void dit3(struct ImBuf * ibuf, short ofs, short bits) { short x,y,pix,and,ofs2; uchar *rect; uchar dit1[6],dit2[6],*dit; rect= (uchar *)ibuf->rect; rect +=ofs; bits = 8-bits; and = ~((1<y;y>0;y--){ if ((y^ofs) & 1){ dit = dit1; } else{ dit = dit2; } ofs2 = ofs <<1; for(x=ibuf->x;x>0;x--){ ofs2++; if (ofs2>5) ofs2=0; pix = *rect + dit[ofs2]; if (pix>255) pix=255; *rect = pix & and; rect += 4; } } } void dit4(struct ImBuf * ibuf, short ofs, short bits) { short x,y,pix,and; uchar *rect; uchar dit[16],*add; static uchar dit4b[] = { 0,4,1,5,8,12,9,13,2,6,3,7,10,14,11,15 }; /* static uchar dit4g[] = {15,7,13,5,3,11,1,9,12,4,14,6,0,8,2,10}; */ static uchar dit4g[] = { 13,5,3,11,1,9,12,4,14,6,0,8,2,10,15,7 }; static uchar dit4r[] = { 0,8,2,10,12,4,14,6,3,11,1,9,15,7,13,5 }; rect= (uchar *)ibuf->rect; rect +=ofs; bits = 8 - bits; and = ~((1<=0 ; y--) dit[y] >>= -bits; } else{ for (y = 15 ; y>=0 ; y--) dit[y] <<= bits; } for(y=ibuf->y;y>0;y--){ add = &dit[4 * (y & 3)]; for(x=ibuf->x;x>0;x--){ pix = *rect; pix += add[x & 3]; if (pix>255) pix=255; *rect = pix & and; rect += 4; } } } void dit0(struct ImBuf * ibuf, short ofs, short bits) { int x, y, and, add, pix; uchar *rect; rect= (uchar *)ibuf->rect; rect +=ofs; bits = 8 - bits; and = ~((1 << bits)-1); add = 1 << (bits - 1); for (y = ibuf->y; y > 0; y--){ for (x = ibuf->x; x > 0; x--) { pix = *rect + add; if (pix > 255) pix = 255; *rect = pix & and; rect += 4; } } } void setjitdit(short onoff) { jitdit = onoff; } void setdither(void (*func)(struct ImBuf *, short, short)) { dithertype = (long) func; switch((long) func){ case 0: case '0': ditherfunc = dit0; break; case 2: case '2': ditherfunc = dit2; break; case '2+': ditherfunc = dit2; /* wordt officieel niet gebruikt */ break; case 3: case '3': ditherfunc = dit3; break; case 4: case '4': ditherfunc = dit4; break; case 'f': case 'F': ditherfunc = floyd; break; default: ditherfunc = func; break; } } long getdither() { return ( dithertype); }