Initial revision
[blender.git] / source / blender / imbuf / intern / bitplanes.c
1 /**
2  * bitplanes.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 "imbuf.h"
36 #include "BLI_blenlib.h"
37
38 #include "imbuf_patch.h"
39
40 #include "IMB_imbuf_types.h"
41 #include "IMB_imbuf.h"
42
43 #include "IMB_allocimbuf.h"
44 #include "IMB_bitplanes.h"
45
46
47 unsigned int **imb_copyplanelist(struct ImBuf *ibuf)
48 {
49         int nobp,i;
50         unsigned int **listn,**listo;
51
52         nobp=ibuf->depth;
53         listn= malloc(nobp*sizeof(int *));                      /* kopie van bitmap maken */
54         if (listn==0) return (0);
55
56         listo=ibuf->planes;
57         for (i=nobp;i>0;i--){
58                 *(listn++) = *(listo++);
59         }
60         listn -= nobp;
61
62         return (listn);
63 }
64
65 static void bptolscanl(unsigned int *buf, int size, unsigned int **list, int nobp, int offset)
66 {
67         /*      zet bitplanes om in een buffer met ints
68         door 4 deelbare hoeveelheid bitplanes,
69         breedte bitplanes op    ints afgrond    */
70
71         list += nobp;
72
73         for (;nobp>0;)
74         {
75                 int todo,i;
76                 register int bp1, bp2, bp3, data;
77                 register unsigned int *point;
78                 int  bp4, loffset;
79                 /*register unsigned int bp1, bp2, bp3, bp4;*/
80
81                 todo = 0;
82                 point = buf;
83                 loffset = offset;
84
85                 if (nobp & 1){
86                         list -= 1;
87                         nobp -= 1;
88                         for(i=size;i>0;i--)
89                         {
90                                 if (todo==0)
91                                 {
92                                         bp1 = BIG_LONG((list[0])[loffset]);
93                                         loffset++;
94                                         todo=32;
95                                 }
96
97                                 data = *point;
98                                 data<<=1;
99
100                                 if (bp1<0) data+=1;
101                                 bp1<<=1;
102
103                                 /*              data += (bp1 >> 31);
104                                         bp1 <<= 1;
105                                 */
106                                 *(point++)=data;
107                                 todo--;
108                         }
109                 } else if (nobp & 2){
110                         list -= 2;
111                         nobp -= 2;
112                         for(i=size;i>0;i--)
113                         {
114                                 if (todo==0)
115                                 {
116                                         bp1 = BIG_LONG((list[0])[loffset]);
117                                         bp2 = BIG_LONG((list[1])[loffset]);
118                                         loffset++;
119                                         todo=32;
120                                 }
121
122                                 data = *point;
123                                 data<<=2;
124
125                                 if (bp1<0) data+=1;
126                                 bp1<<=1;
127                                 if (bp2<0) data+=2;
128                                 bp2<<=1;
129
130                                 /*              data += (bp1 >> 31) + ((bp2 & 0x80000000) >> 30);
131                                 bp1 <<= 1; bp2 <<= 1;
132                                 */
133                                 *(point++)=data;
134                                 todo--;
135                         }
136                 } else{
137                         list -= 4;
138                         nobp -= 4;
139                         for(i=size;i>0;i--)
140                         {
141                                 if (todo==0) {
142                                         bp1 = BIG_LONG((list[0])[loffset]);
143                                         bp2 = BIG_LONG((list[1])[loffset]);
144                                         bp3 = BIG_LONG((list[2])[loffset]);
145                                         bp4 = BIG_LONG((list[3])[loffset]);
146                                         loffset++;
147                                         todo=32;
148                                 }
149
150                                 data = *point;
151                                 data<<=4;
152
153                                 if (bp1<0) data+=1;
154                                 bp1<<=1;
155                                 if (bp2<0) data+=2;
156                                 bp2<<=1;
157                                 if (bp3<0) data+=4;
158                                 bp3<<=1;
159                                 if (bp4<0) data+=8;
160                                 bp4<<=1;
161
162                                 /*              data += (bp1 >> 31) \
163                                 + ((bp2 & 0x80000000) >> 30) \
164                                 + ((bp3 & 0x80000000) >> 29) \
165                                 + ((bp4 & 0x80000000) >> 28);
166                 
167                                 bp1 <<= 1; bp2 <<= 1;
168                                 bp3 <<= 1; bp4 <<= 1;
169                                 */
170                                 
171                                 *(point++)=data;
172                                 todo--;
173                         }
174                 }
175         }
176 }
177
178
179 void imb_bptolong(struct ImBuf *ibuf)
180 {
181         int nobp,i,x;
182         unsigned int *rect,offset;
183
184         /* eerst alle ints wissen */
185
186         if (ibuf == 0) return;
187         if (ibuf->planes == 0) return;
188         if (ibuf->rect == 0) imb_addrectImBuf(ibuf);
189
190         nobp=ibuf->depth;
191         if (nobp != 32){
192                 if (nobp == 24) IMB_rectoptot(ibuf, 0, IMB_rectfill, 0xff000000); /* alpha zetten */
193                 else IMB_rectoptot(ibuf, 0, IMB_rectfill, 0);
194         }
195
196         rect= ibuf->rect;
197         x= ibuf->x;
198         offset=0;
199
200         for (i= ibuf->y; i>0; i--){
201                 bptolscanl(rect, x, ibuf->planes, nobp, offset);
202                 rect += x;
203                 offset += ibuf->skipx;
204         }
205 }
206
207
208 static void ltobpscanl(unsigned int *rect, int x, unsigned int **list, int nobp, int offset)
209 {
210         /* zet een buffer met ints, om in bitplanes. Opgepast, buffer 
211                 wordt vernietigd !*/
212
213         if (nobp != 32)
214         {
215                 int *rect2;
216                 int todo,j;
217
218                 rect2 = (int*)rect;
219
220                 todo = 32-nobp;
221                 for (j = x;j>0;j--){
222                         *(rect2++) <<= todo;
223                 }
224         }
225
226         list += nobp;
227         for (;nobp>0;){
228                 register int bp1=0, bp2=0, bp3=0, data;
229                 register unsigned int *point;
230                 int i,todo;
231                 int bp4=0,loffset;
232
233                 point = rect;
234                 todo=32;
235                 loffset=offset;
236
237                 if (nobp & 1){
238                         list -= 1;
239                         nobp -= 1;
240
241                         for(i=x;i>0;i--){
242                                 data = *point;
243
244                                 bp1 <<= 1;
245                                 if (data<0) bp1 += 1;
246                                 data <<= 1;
247
248                                 *(point++) = data;
249
250                                 todo--;
251                                 if (todo == 0){
252                                         (list[0])[loffset] = bp1;
253                                         loffset++;
254                                         todo=32;
255                                 }
256                         }
257                         if (todo != 32)
258                         {
259                                 bp1 <<= todo;
260                                 (list[0])[loffset] = bp1;
261                         }
262                 } else if (nobp & 2){
263                         list -= 2;
264                         nobp -= 2;
265                         for(i=x;i>0;i--){
266                                 data = *point;
267
268                                 bp2 <<= 1;
269                                 if (data<0) bp2 += 1;
270                                 data <<= 1;
271                                 bp1 <<= 1;
272                                 if (data<0) bp1 += 1;
273                                 data <<= 1;
274
275                                 *(point++) = data;
276
277                                 todo--;
278                                 if (todo == 0){
279                                         (list[0])[loffset] = bp1;
280                                         (list[1])[loffset] = bp2;
281                                         loffset++;
282                                         todo=32;
283                                 }
284                         }
285                         if (todo != 32){
286                                 bp1 <<= todo;
287                                 bp2 <<= todo;
288                                 (list[0])[loffset] = bp1;
289                                 (list[1])[loffset] = bp2;
290                         }
291                 } else{
292                         list -= 4;
293                         nobp -= 4;
294                         for(i=x;i>0;i--){
295                                 data = *point;
296
297                                 bp4 <<= 1;
298                                 if (data<0) bp4 += 1;
299                                 data <<= 1;
300                                 bp3 <<= 1;
301                                 if (data<0) bp3 += 1;
302                                 data <<= 1;
303                                 bp2 <<= 1;
304                                 if (data<0) bp2 += 1;
305                                 data <<= 1;
306                                 bp1 <<= 1;
307                                 if (data<0) bp1 += 1;
308                                 data <<= 1;
309
310                                 *(point++) = data;
311
312                                 todo--;
313                                 if (todo == 0){
314                                         (list[0])[loffset] = bp1;
315                                         (list[1])[loffset] = bp2;
316                                         (list[2])[loffset] = bp3;
317                                         (list[3])[loffset] = bp4;
318                                         loffset++;
319                                         todo=32;
320                                 }
321                         }
322                         if (todo != 32){
323                                 bp1 <<= todo;
324                                 bp2 <<= todo;
325                                 bp3 <<= todo;
326                                 bp4 <<= todo;
327                                 (list[0])[loffset] = bp1;
328                                 (list[1])[loffset] = bp2;
329                                 (list[2])[loffset] = bp3;
330                                 (list[3])[loffset] = bp4;
331                         }
332                 }
333         }
334 }
335
336
337 void imb_longtobp(struct ImBuf *ibuf)
338 {
339         /* zet een buffer met ints, om in bitplanes. Opgepast, buffer 
340                 wordt vernietigd !*/
341
342         int nobp,i,x;
343         unsigned int *rect,offset,*buf;
344         ;
345
346         nobp = ibuf->depth;
347         rect=ibuf->rect;
348         x=ibuf->x;
349         offset=0;
350         if ((buf=malloc(x*sizeof(int)))==0) return;
351
352         for (i=ibuf->y;i>0;i--){
353                 memcpy(buf, rect, x*sizeof(int));
354                 rect +=x ;
355                 ltobpscanl(buf, x, ibuf->planes, nobp, offset);
356                 offset += ibuf->skipx;
357         }
358         free(buf);
359 }