6 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version. The Blender
12 * Foundation also sells licenses for use in proprietary software under
13 * the Blender License. See http://www.blender.org/BL/ for information
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software Foundation,
23 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
26 * All rights reserved.
28 * The Original Code is: all of this file.
30 * Contributor(s): none yet.
32 * ***** END GPL/BL DUAL LICENSE BLOCK *****
37 #include "BLI_blenlib.h"
38 #include "DNA_listBase.h"
40 #include "imbuf_patch.h"
41 #include "IMB_imbuf_types.h"
42 #include "IMB_imbuf.h"
43 #include "IMB_allocimbuf.h"
51 1 - zoek een overgang in een kolom
52 2 - kijk wat de relatie met links en rechts is,
54 Is pixel boven overgang links of rechts ervan gelijk aan bovenste kleur,
55 zoek dan naar beneden.
57 Is pixel onder overgang links of rechts ervan gelijk aan onderste kleur,
63 /* er moet een functie * komen die aan kan geven of twee kleuren nu
64 * wel of niet gelijk zijn.
65 * Voor nu maar een define
70 zipfork "cc -g anti.c util.o -lgl_s -limbuf -limage -lm -o anti > /dev/console"
71 zipfork "anti /data/rt > /dev/console"
72 zipfork "anti /pics/martin/03.01.ChambFinal/0001 > /dev/console"
75 static unsigned int anti_mask = 0xffffffff;
76 static int anti_a, anti_b, anti_g, anti_r;
78 #define compare(x, y) ((x ^ y) & anti_mask)
82 struct Edge * next, * prev;
87 static void anti_free_listarray(int count, ListBase * listarray)
91 if (listarray == 0) return;
93 for (i = 0; i < count; i++) BLI_freelistN(listarray + i);
97 static ListBase * scanimage(struct ImBuf * ibuf, int dir)
99 int step, pixels, lines, nextline, x, y, col1, col2;
101 ListBase * listarray, * curlist;
107 step = 1; nextline = ibuf->x;
108 pixels = ibuf->x; lines = ibuf->y;
111 step = ibuf->x; nextline = 1;
112 pixels = ibuf->y; lines = ibuf->x;
115 listarray = (ListBase*)MEM_callocN((lines)* sizeof(ListBase), "listarray");
116 for (y = 0; y < lines; y++){
118 rect += y * nextline;
119 curlist = listarray + y;
124 for (x = 0; x < pixels; x++) {
126 if (compare(col1, col2)) {
131 BLI_addtail(curlist, edge);
135 printf("\n\n%s: Aborting antialias !\n", ibuf->name);
136 printf("To many transitions.\nIs this a natural image ?\n\n"),
137 anti_free_listarray(lines, listarray);
149 static Edge * findmatch(Edge * first, Edge * edge)
152 int in = 0, out = 65535;
154 if (edge->prev) in = edge->prev->position;
155 if (edge->next) out = edge->next->position;
158 if (first->position < edge->position) {
159 if (first->col1 == edge->col1) {
160 if (first->position >= in) match = first;
161 } else if (first->col2 == edge->col2) {
162 if (first->next == 0) match = first;
163 else if (first->next->position >= edge->position) match = first;
164 } else if (first->col2 == edge->col1) {
165 match = 0; /* bij zigzagjes kan deze al 'ns foutief gezet zijn */
167 } else if (first->position == edge->position) {
168 if (first->col1 == edge->col1 || first->col2 == edge->col2) match = first;
170 if (match) break; /* er is er al een */
172 if (first->col1 == edge->col1) {
173 if (first->prev == 0) match = first;
174 else if (first->prev->position <= edge->position) match = first;
175 } else if (first->col2 == edge->col2) {
176 if (first->position <= out) match = first;
187 static void filterdraw(unsigned int * ldest, unsigned int * lsrce, int zero, int half, int step)
193 /* we filteren de pixels op ldest tussen in en out met pixels van lsrce
194 * Het gewicht loopt ondertussen van 0 naar 1
199 if (count < 0) count = -count;
200 if (count <= 1) return;
203 src = (uchar *) (lsrce + (step * zero));
204 dst = (uchar *) (ldest + (step * zero));
207 src = (uchar *) (lsrce + (step * zero));
208 dst = (uchar *) (ldest + (step * zero));
214 dst += step * (count >> 1);
215 src += step * (count >> 1);
217 count = (count + 1) >> 1;
221 /* dit moet natuurlijk gamma gecorrigeerd */
223 for(; count > 0; count --) {
224 if (anti_a) dst[0] += weight * (src[0] - dst[0]);
225 if (anti_b) dst[1] += weight * (src[1] - dst[1]);
226 if (anti_g) dst[2] += weight * (src[2] - dst[2]);
227 if (anti_r) dst[3] += weight * (src[3] - dst[3]);
234 static void filterimage(struct ImBuf * ibuf, struct ImBuf * cbuf, ListBase * listarray, int dir)
236 int step, pixels, lines, nextline, y, pos, drawboth;
237 unsigned int * irect, * crect;
238 Edge * left, * middle, * right, temp, * any;
242 step = 1; nextline = ibuf->x;
243 pixels = ibuf->x; lines = ibuf->y;
246 step = ibuf->x; nextline = 1;
247 pixels = ibuf->y; lines = ibuf->x;
250 for (y = 1; y < lines - 1; y++){
252 irect += y * nextline;
254 crect += y * nextline;
256 middle = listarray[y].first;
258 left = findmatch(listarray[y - 1].first, middle);
259 right = findmatch(listarray[y + 1].first, middle);
262 if (left == 0 || right == 0) {
265 if (right) any = right;
268 pos = 2 * middle->position - any->position;
270 if (any->position < middle->position) {
271 if (pos > pixels - 1) pos = pixels - 1;
273 if (pos > middle->next->position) pos = middle->next->position;
276 if (pos > any->next->position) pos = any->next->position;
279 if (pos < 0) pos = 0;
281 if (pos < middle->prev->position) pos = middle->prev->position;
284 if (pos < any->prev->position) pos = any->prev->position;
288 if (left) right = &temp;
292 } else if (left->position == middle->position || right->position == middle->position) {
294 /* klein hoekje, met een van de twee op afstand 2 (ander is toch op afstand 0) ? */
296 if (abs(left->position - right->position) == 2) drawboth = TRUE;
297 } else if (left->position < middle->position && right->position > middle->position){
300 } else if (left->position > middle->position && right->position < middle->position){
309 filterdraw(irect, crect - nextline, left->position, middle->position, step);
310 filterdraw(irect, crect + nextline, right->position, middle->position, step);
313 middle = middle->next;
319 void IMB_antialias(struct ImBuf * ibuf)
322 ListBase * listarray;
324 if (ibuf == 0) return;
325 cbuf = IMB_dupImBuf(ibuf);
327 anti_a = (anti_mask >> 24) & 0xff;
328 anti_b = (anti_mask >> 16) & 0xff;
329 anti_g = (anti_mask >> 8) & 0xff;
330 anti_r = (anti_mask >> 0) & 0xff;
332 listarray = scanimage(cbuf, 'h');
334 filterimage(ibuf, cbuf, listarray, 'h');
335 anti_free_listarray(ibuf->y, listarray);
337 listarray = scanimage(cbuf, 'v');
339 filterimage(ibuf, cbuf, listarray, 'v');
340 anti_free_listarray(ibuf->x, listarray);
348 /* intelligente scaling */
350 static void _intel_scale(struct ImBuf * ibuf, ListBase * listarray, int dir)
352 int step, lines, nextline, x, y, col;
353 unsigned int * irect, * trect;
355 Edge * left, * right;
360 step = 1; nextline = ibuf->x;
362 tbuf = IMB_double_fast_y(ibuf);
365 step = 2 * ibuf->x; nextline = 1;
367 tbuf = IMB_double_fast_x(ibuf);
373 imb_freerectImBuf(ibuf);
374 ibuf->rect = tbuf->rect;
375 ibuf->mall |= IB_rect;
383 for (y = 0; y < lines - 2; y++){
385 irect += ((2 * y) + 1) * nextline;
387 left = listarray[y].first;
389 right = findmatch(listarray[y + 1].first, left);
391 if (left->col2 == right->col2) {
392 if (left->next && right->next) {
393 if (left->next->position >= right->position) {
394 start = ((left->position + right->position) >> 1);
395 end = ((left->next->position + right->next->position) >> 1);
397 trect = irect + (start * step);
398 for (x = start; x < end; x++) {
406 if (left->col1 == right->col1) {
407 if (left->prev && right->prev) {
408 if (left->prev->position <= right->position) {
409 end = ((left->position + right->position) >> 1);
410 start = ((left->prev->position + right->prev->position) >> 1);
412 trect = irect + (start * step);
413 for (x = start; x < end; x++) {
428 void IMB_clever_double(struct ImBuf * ibuf)
430 ListBase * listarray, * curlist;
435 if (ibuf == 0) return;
438 listarray = scanimage(ibuf, 'v');
440 for (i = 0; i < size; i++) {
441 curlist = listarray + i;
442 new = (Edge*)MEM_callocN(sizeof(Edge),"Edge");
443 new->col2 = ibuf->rect[i]; /* bovenste pixel */
444 new->col1 = new->col2 - 1;
445 BLI_addhead(curlist, new);
446 new = (Edge*)MEM_callocN(sizeof(Edge),"Edge");
447 new->position = ibuf->y - 1;
448 new->col1 = ibuf->rect[i + ((ibuf->y -1) * ibuf->x)]; /* onderste pixel */
449 new->col2 = new->col1 - 1;
450 BLI_addtail(curlist, new);
452 _intel_scale(ibuf, listarray, 'v');
453 anti_free_listarray(size, listarray);
456 listarray = scanimage(ibuf, 'h');
458 for (i = 0; i < size; i++) {
459 curlist = listarray + i;
460 new = (Edge*)MEM_callocN(sizeof(Edge),"Edge");
461 new->col2 = ibuf->rect[i * ibuf->x]; /* linkse pixel */
462 new->col1 = new->col2 - 1;
463 BLI_addhead(curlist, new);
464 new = (Edge*)MEM_callocN(sizeof(Edge),"Edge");
465 new->position = ibuf->x - 1;
466 new->col1 = ibuf->rect[((i + 1) * ibuf->x) - 1]; /* rechtse pixel */
467 new->col2 = new->col1 - 1;
468 BLI_addtail(curlist, new);
470 _intel_scale(ibuf, listarray, 'h');
471 anti_free_listarray(size, listarray);