svn merge -r 12937:13095 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.git] / source / blender / imbuf / intern / cmap.c
1 /**
2  * cmap.c
3  *
4  * $Id$
5  *
6  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
7  *
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
14  * about this.
15  *
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.
20  *
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.
24  *
25  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
26  * All rights reserved.
27  *
28  * The Original Code is: all of this file.
29  *
30  * Contributor(s): none yet.
31  *
32  * ***** END GPL/BL DUAL LICENSE BLOCK *****
33  */
34
35 #include <ctype.h>
36 #include "BLI_blenlib.h"
37
38 #include "imbuf.h"
39 #include "imbuf_patch.h"
40 #include "IMB_imbuf_types.h"
41 #include "IMB_imbuf.h"
42
43 #include "IMB_cmap.h"
44
45 static short *lastcube = 0;
46 static uchar *lastcoltab = 0;
47 static short lastmaxcol;
48 static short lastmincol;
49 static short lastcbits;
50 short alpha_col0 = FALSE;
51
52 extern void IMB_free_cache_limiter();
53
54 /*
55  * there still is a bug here. If you want to convert an image to a 1 bit colormap you get
56  * a black image. All conversion to less than 4 bits is too dark anyway.
57  */
58
59 void IMB_freeImBufdata(void)
60 {
61         if (lastcube) free(lastcube);
62         lastcube= 0;
63         if (lastcoltab) free(lastcoltab);
64         lastcoltab= 0;
65         IMB_free_cache_limiter();
66 }
67
68
69 int IMB_alpha_to_col0(int value)
70 {
71         int old;
72         
73         old = alpha_col0;
74         alpha_col0 = value;
75         return (old);
76 }
77
78
79 void imb_losecmapbits(struct ImBuf *ibuf, unsigned int *coltab)
80 {
81         int i,bits;
82         unsigned int col, and1, and2, *rect;
83
84         if (ibuf == 0) return;
85         if (ibuf->rect == 0) return;
86         if (ibuf->cbits == 0) return;
87         if (ibuf->cbits >= 8) return;
88
89 /*
90         bij cbits = 5:
91         and1 = 11100000;
92         bij cbits = 6:
93         and1 = 11000000;
94 */
95
96         bits = ibuf->cbits;
97         and1 = ((1 << (8-bits)) - 1) & 0xff;
98         and1 |= (and1 << 24) + (and1 << 16) + (and1 << 8);
99         and2 = ~and1;
100         and1 <<= bits;
101
102         rect = ibuf->rect;
103         for (i = ibuf->x * ibuf->y ; i > 0; i--) {
104                 col = rect[0]; 
105                 *rect++ = col - ((col & and1) >> bits);
106         }
107         
108         if (coltab){
109                 for (i = 0 ; i < ibuf->maxcol ; i++) {
110                         col = coltab[i];
111                         coltab[i] = (col - ((col & and1) >> bits)) & and2;
112                 }
113         }
114 }
115
116
117 static void addcmapbits(struct ImBuf *ibuf)
118 {
119         int i,bits;
120         int div,mul;
121         uchar * cmap;
122         
123         if (ibuf == 0) return;
124         if (ibuf->cmap == 0) return;
125         if (ibuf->cbits == 0) return;
126         if (ibuf->cbits >= 8) return;
127
128         bits = ibuf->cbits;
129
130         /* bits = 4 -> div = 0xf0
131          * bits = 5 -> div = 0xf8
132          */
133          
134         div = ((1 << bits) - 1) << (8 - bits);
135         mul = 0xffff / div;
136         
137         if (ibuf->cmap){
138                 cmap = (uchar *) ibuf->cmap;
139                 for (i = 0 ; i < ibuf->maxcol ; i++){
140                         cmap[1] = (mul * cmap[1]) >> 8;
141                         cmap[2] = (mul * cmap[2]) >> 8;
142                         cmap[3] = (mul * cmap[3]) >> 8;
143                         cmap += 4;
144                 }
145         }
146 }
147
148
149 static short addplanetocube(short *cube, short *plane, int minx, int miny, int sizep, int addcx, int addcy, int sizec, int col)
150 {
151         short done = FALSE;
152         int x, numx, numy, skipc, skipp, temp;
153
154         /* clip first */
155
156         numx = numy = sizep;
157
158         temp = minx + sizep - 1;
159         if (temp > sizec) numx -= temp - sizec;
160
161         temp = miny + sizep - 1;
162         if (temp > sizec) numy -= temp - sizec;
163
164         if (minx < 0){
165                 plane -= minx;
166                 cube -= minx * addcx;
167                 numx += minx;
168         }
169
170         if (miny < 0){
171                 plane -= miny * sizep;
172                 cube -= miny * addcy;
173                 numy += miny;
174         }
175
176         skipc = addcy - (numx * addcx);
177         skipp = sizep - numx;
178
179         for (; numy > 0 ; numy--){
180                 for (x = numx ; x > 0; x--) {
181                         
182                         if (plane[0] < cube[1]) {
183                         
184                                 cube[0] = col;
185                                 cube[1] = plane[0];
186                                 done = TRUE;
187                         }
188                         plane ++;
189                         cube += addcx;
190                 }
191                 plane += skipp;
192                 cube += skipc;
193         }
194
195         return (done);
196 }
197
198
199
200 short *imb_coldeltatab(unsigned char *coltab, short mincol, short maxcol, short cbits)
201 {
202         short max, *quadr, *_quadr, *_cube, *cube, *_plane, done, nocol;
203         unsigned int addcb, addcg, addcr, sizep;
204         uchar *_colp, *colp, *col;
205         int i, j, k, addcube;
206         int r, g, b;
207
208         max = (1 << cbits) - 1;
209         nocol = maxcol - mincol;
210         coltab += 4 * mincol;
211         
212         /* reduce colors to the right amount of bits */
213
214         {
215                 unsigned int * lctab, and;
216
217                 lctab = (unsigned int *) coltab;
218                 and = max << (8 - cbits);
219                 and = and + (and << 8) + (and << 16) + (and << 24);
220                 for (i=nocol-1 ; i >= 0 ; i--) lctab[i] = (lctab[i] & and) >> (8 - cbits);
221         }
222
223         /* is this data the same as previous ? */
224
225         if (lastcube){
226                 if (mincol == lastmincol && maxcol == lastmaxcol && cbits == lastcbits){
227                         if (lastcoltab){
228                                 if (memcmp(lastcoltab, coltab, 4 * nocol) == 0) return(lastcube);
229                         }
230                 }
231         }
232         if (lastcube) free(lastcube);
233         if (lastcoltab) free(lastcoltab);
234
235         lastcube = 0; 
236         lastcoltab = 0;
237         _cube = malloc(2 * (1 << (3 * cbits)) * sizeof(short));
238         _plane = malloc((2 * max + 1) * (2 * max + 1) * sizeof(short));
239         _quadr = malloc((2 * max + 1) * sizeof(short));
240         _colp = malloc(6 * nocol);
241
242         if (_cube == 0 || _plane == 0 || _quadr == 0 || _colp == 0){
243                 if (_cube) free(_cube);
244                 if (_plane) free(_plane);
245                 if (_quadr) free(_quadr);
246                 if (_colp) free(_colp);
247                 return(0);
248         }
249
250         lastcoltab = malloc(4 * nocol);
251         if (lastcoltab) memcpy(lastcoltab, coltab, 4 * nocol);
252         lastcube = _cube;
253         lastmincol = mincol;
254         lastmaxcol = maxcol;
255         lastcbits = cbits;
256
257         /* cube initialise */
258
259         cube = _cube;
260         for (i = (1 << (3 * cbits)); i > 0 ; i--){
261                 cube[0] = 0;
262                 cube[1] = 32767;
263                 cube += 2;
264         }
265
266         /* mak error look up table */
267
268         {
269                 unsigned int delta;
270
271                 quadr = _quadr + max + 1;
272                 quadr[0] = 0;
273                 delta = 3;
274                 for (i = 1 ; i <= max ; i++){
275                         quadr[i] = quadr[-i] = delta;
276                         delta += i + 3;
277                 }
278         }
279
280         /* colorplane initialise */
281
282         for (i = 6 * nocol - 1; i >= 0; i--) _colp[i] = 1;
283
284         addcr = 2;
285         addcg = (addcr << cbits);
286         addcb = (addcg << cbits);
287
288         /* fill in first round */
289
290         {
291                 unsigned int ofs;
292
293                 col = coltab;
294                 cube = _cube;
295
296                 for (i = 0 ; i < nocol ; i++){
297                         ofs = (col[3] * addcr) + (col[2] * addcg) + (col[1] * addcb);
298                         /* color been filled in -> then skip */
299                         if (cube[ofs + 1]) cube[ofs] = i + mincol;
300                         cube[ofs + 1] = 0;
301                         col += 4;
302                 }
303         }
304
305         for (i = 1; i <= max ; i++){
306                 colp = _colp;
307                 col = coltab;
308                 done = FALSE;
309                 sizep = 2*i +1;
310
311                 /* plane initialise */
312                 {
313                         unsigned int delta;
314                         short *plane;
315
316                         plane = _plane;
317                         for (j = -i ; j <= i; j++){
318                                 delta = quadr[i] + quadr[j];
319                                 for (k = -i; k <= i; k++){
320                                         *plane++ = delta + quadr[k];
321                                 }
322                         }
323                 }
324
325                 for (j = mincol; j < maxcol; j++){
326                         b = col[1] - i;
327                         g = col[2] - i;
328                         r = col[3] - i;
329                         
330                         addcube= (addcr * r) + (addcg * g) + (addcb * b);
331                         /* PRINT4(d, d, d, d, addcube, r, g, b); */
332                         /* if(addcube >= 2 * (1 << (3 * cbits))) { */
333                         /*      printf("maxerror: %d %d\n", addcube, 2 * (1 << (3 * cbits))); */
334                                 /* add_cube= 2 * (1 << (3 * cbits)) -1; */
335                         /* } */
336                         cube = _cube + addcube;
337
338                         if (colp[0]){
339                                 if (b < 0) colp[0] = 0;
340                                 else done |= colp[0] = addplanetocube(cube, _plane, r, g, sizep, addcr, addcg, max, j);
341                         }
342                         if (colp[1]){
343                                 if (g < 0) colp[1] = 0;
344                                 else done |= colp[1] = addplanetocube(cube, _plane, r, b, sizep, addcr, addcb, max, j);
345                         }
346                         if (colp[2]){
347                                 if (r < 0) colp[2] = 0;
348                                 else done |= colp[2] = addplanetocube(cube, _plane, b, g, sizep, addcb, addcg, max, j);
349                         }
350                         if (colp[3]){
351                                 if ((b + sizep - 1) > max) colp[3] = 0;
352                                 else done |= colp[3] = addplanetocube(cube + (sizep -1) * addcb, _plane, r, g, sizep, addcr,
353                                         addcg, max, j);
354                         }
355                         if (colp[4]){
356                                 if ((g + sizep - 1) > max) colp[4] = 0;
357                                 else done |= colp[4] = addplanetocube(cube + (sizep -1) * addcg, _plane, r, b, sizep, addcr,
358                                         addcb, max, j);
359                         }
360                         if (colp[5]){
361                                 if ((r + sizep - 1) > max) colp[5] = 0;
362                                 else done |= colp[5] = addplanetocube(cube + (sizep -1) * addcr, _plane, b, g, sizep, addcb,
363                                         addcg, max, j);
364                         }
365
366                         colp += 6;
367                         col += 4;
368                 }
369                 if (done == 0) break;
370         }
371
372         free(_quadr);
373         free(_plane);
374         free(_colp);
375         return(_cube);
376 }
377
378
379 static void convcmap(struct ImBuf* ibuf, short *deltab, short cbits)
380 {
381         unsigned int *rect;
382         short x,y;
383         unsigned int col;
384         unsigned int bbits,gbits,rbits;
385         unsigned int bmask,gmask,rmask;
386
387         bbits = 24 - 3 * cbits - 1;
388         gbits = 16 - 2 * cbits - 1;
389         rbits = 8 - cbits - 1;
390
391         rmask = ((1 << cbits) - 1) << (8 - cbits);
392         gmask = rmask << 8;
393         bmask = gmask << 8;
394
395         rect =(unsigned int *)ibuf->rect;
396
397         for(y=ibuf->y;y>0;y--){
398                 for(x=ibuf->x;x>0;x--){
399                         col = *rect;
400                         col = ((col & bmask) >> bbits) + ((col & gmask) >> gbits) + ((col & rmask) >> rbits);
401                         *rect++ = deltab[col];
402                 }
403         }
404 }
405
406 short IMB_converttocmap(struct ImBuf *ibuf)
407 {
408         unsigned int *coltab;
409         short *deltab=0, cbits;
410         int i;
411         int mincol, mask = 0;
412         struct ImBuf * abuf = 0;
413         unsigned int * rect, * arect;
414         
415         cbits = 5;
416         if (ibuf->cmap == 0) return(0);
417         
418         if ((ibuf->cbits > 0) && (ibuf->cbits <8)) cbits = ibuf->cbits;
419
420         coltab = calloc(ibuf->maxcol, sizeof(unsigned int));
421         if (coltab == 0) return(0);
422         memcpy(coltab, ibuf->cmap, ibuf->maxcol * sizeof(unsigned int));
423         
424         mincol = ibuf->mincol;  
425         if (alpha_col0) {
426                 if (mincol == 0) mincol = 1;
427                 abuf = IMB_dupImBuf(ibuf);
428         }
429         
430         imb_losecmapbits(ibuf, coltab);
431         deltab = imb_coldeltatab((uchar *) coltab, mincol ,ibuf->maxcol, cbits);
432         
433         if (deltab == 0) {
434                 free(coltab);
435                 if (abuf) IMB_freeImBuf(abuf);
436                 return(0);
437         }
438
439
440         IMB_dit0(ibuf,1,cbits);
441         IMB_dit0(ibuf,2,cbits);
442         IMB_dit0(ibuf,3,cbits);
443         convcmap(ibuf, deltab, cbits);
444         
445         if (abuf) {
446                 /* convert alpha to color 0 */
447                 rect = ibuf->rect;
448                 arect = abuf->rect;
449                 
450                 if (alpha_col0 == 1) mask = 0xff000000; /* alpha ==  0 -> 0 */
451                 if (alpha_col0 == 2) mask = 0x80000000; /* alpha < 128 -> 0 */
452                 
453                 for (i = ibuf->x * ibuf->y; i > 0; i--) {
454                         if ((*arect++ & mask) == 0) rect[0] = 0;
455                         rect++;
456                 }
457                 
458                 IMB_freeImBuf(abuf);
459         }
460
461         free(coltab);
462         
463         return (TRUE);
464 }
465
466
467 void imb_makecolarray(struct ImBuf *ibuf, unsigned char *mem, short nocols)
468 {
469         short i,bits = 0;
470         uchar *cmap;
471
472         /* what's the theory behind this? */
473         
474         nocols = ibuf->maxcol;
475
476         if (ibuf->cmap){
477                 cmap = (uchar *) ibuf->cmap;
478                 for (i = 0; i < nocols; i++){
479                         cmap[3] = mem[0];
480                         cmap[2] = mem[1];
481                         cmap[1] = mem[2];
482                         cmap[0] = 0;
483                         
484                         bits |= mem[0] | mem[1] | mem[2];
485                         mem += 3;
486                         cmap += 4;
487                 }
488
489                 /* patch voor AdPro II */
490                 if (IS_ham(ibuf)){
491                         i = ibuf->depth - 2;
492                         bits = ((1 << i) - 1) << (8 - i);
493                         for (i=0 ; i<nocols ; i++) ibuf->cmap[i] &= (bits << 24) + (bits << 16) + (bits << 8) + bits;
494                 }
495
496                 if ((bits & 0x1f) == 0){
497                         ibuf->cbits = 3;
498                 } else if ((bits & 0x0f) == 0){
499                         ibuf->cbits = 4;
500                 } else if ((bits & 0x07) == 0){
501                         ibuf->cbits = 5;
502                 } else if ((bits & 0x03) == 0){
503                         ibuf->cbits = 6;
504                 } else ibuf->cbits = 8;
505
506                 addcmapbits(ibuf);
507
508                 if (IS_hbrite(ibuf)){
509                         for (i=31;i>=0;i--){
510                                 ibuf->cmap[i+32] =  (ibuf->cmap[i]  & 0xfefefefe) >> 1;
511                         }
512                 }
513                 
514                 if (IS_amiga(ibuf)){
515                         cmap = (uchar * ) (ibuf->cmap + 1);
516                         for (i = 1; i < nocols; i++){
517                                 cmap[0] = 0xff;
518                                 cmap += 4;
519                         }
520                 }
521         }
522 }
523
524 /* temporal... rects now are rgba, cmaps are abgr */
525 #define SWITCH_INT(a)   {char s_i, *p_i; p_i= (char *)&(a); s_i= p_i[0]; p_i[0]= p_i[3]; p_i[3]= s_i; s_i= p_i[1]; p_i[1]= p_i[2]; p_i[2]= s_i; }
526
527 void IMB_applycmap(struct ImBuf *ibuf)
528 {
529         unsigned int *rect, *cmap;
530         int x, y, i, col, code;
531         int *mask = 0;
532         
533         if (ibuf == 0) return;
534         if (ibuf->rect == 0 || ibuf->cmap == 0) return;
535         
536         rect = ibuf->rect;
537         cmap = ibuf->cmap;
538
539         if (IS_ham(ibuf)){
540                 
541                 /* generate mask of max (8 + 2) bits */
542                 mask = malloc(1024 * 2 * sizeof(int));
543
544                 x = 1 << (ibuf->depth - 2);
545                 y = 65535 / (x - 1);
546                 
547                 for (i = 0; i < x; i++){
548                         mask[i] = 0;
549                         mask[i + x]     = 0x00ffff;
550                         mask[i + x + x] = 0xffff00;
551                         mask[i + x + x + x] = 0xff00ff;
552
553                         col = (y * i) >> 8;
554                         
555                         mask[i + 1024] = 0xff000000 | ibuf->cmap[i];
556                         mask[i + x + 1024] = 0xff000000 | col << 16;
557                         mask[i + x + x + 1024] = 0xff000000 | col;
558                         mask[i + x + x + x + 1024] = 0xff000000 | col << 8;
559                 }
560                 
561                 /* only color 0 transparant */
562                 mask[0+1024] =ibuf->cmap[0];
563                 
564                 for (y = ibuf->y ; y>0 ; y--){
565                         col = cmap[0];
566                         for (x=ibuf->x ; x>0 ; x--){
567                                 code = *rect;
568                                 *rect++ = col = (col & mask[code]) | mask[code + 1024];
569                         }
570                 }
571                 free(mask);
572         } else {
573         
574                 for(i = ibuf->x * ibuf->y; i>0; i--){
575                         col = *rect;
576                         if (col >= 0 && col < ibuf->maxcol) *rect = cmap[col];
577                         rect++;
578
579                         /* *(rect++) = cmap[*rect]; */
580                 }
581         }
582 }
583