svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r22625:22668
[blender.git] / source / blender / imbuf / intern / bitplanes.c
1 /**
2  * bitplanes.c
3  *
4  * $Id$
5  *
6  * ***** BEGIN GPL 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.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL LICENSE BLOCK *****
30  */
31
32 #include "imbuf.h"
33 #include "BLI_blenlib.h"
34
35 #include "imbuf_patch.h"
36
37 #include "IMB_imbuf_types.h"
38 #include "IMB_imbuf.h"
39 #include "IMB_allocimbuf.h"
40 #include "IMB_bitplanes.h"
41
42 unsigned int **imb_copyplanelist(struct ImBuf *ibuf)
43 {
44         int nobp,i;
45         unsigned int **listn,**listo;
46
47         nobp=ibuf->depth;
48         listn= malloc(nobp*sizeof(int *));                      /* make copy of bitmap */
49         if (listn==0) return (0);
50
51         listo=ibuf->planes;
52         for (i=nobp;i>0;i--){
53                 *(listn++) = *(listo++);
54         }
55         listn -= nobp;
56
57         return (listn);
58 }
59
60 static void bptolscanl(unsigned int *buf, int size, unsigned int **list, int nobp, int offset)
61 {
62         /*      converts bitplanes to a buffer with ints
63         by 4 dividiable amount of bitplanes,
64         the width of bitplanes is rounded at ints       */
65
66         list += nobp;
67
68         for (;nobp>0;)
69         {
70                 int todo,i;
71                 register int bp1, bp2, bp3, bp4, data;
72                 register unsigned int *point;
73                 int loffset;
74                 /*register unsigned int bp1, bp2, bp3, bp4;*/
75
76                 bp1 = bp2 = bp3 = bp4 = todo = 0;
77                 point = buf;
78                 loffset = offset;
79
80                 if (nobp & 1){
81                         list -= 1;
82                         nobp -= 1;
83                         for(i=size;i>0;i--)
84                         {
85                                 if (todo==0)
86                                 {
87                                         bp1 = BIG_LONG((list[0])[loffset]);
88                                         loffset++;
89                                         todo=32;
90                                 }
91
92                                 data = *point;
93                                 data<<=1;
94
95                                 if (bp1<0) data+=1;
96                                 bp1<<=1;
97
98                                 /*              data += (bp1 >> 31);
99                                         bp1 <<= 1;
100                                 */
101                                 *(point++)=data;
102                                 todo--;
103                         }
104                 } else if (nobp & 2){
105                         list -= 2;
106                         nobp -= 2;
107                         for(i=size;i>0;i--)
108                         {
109                                 if (todo==0)
110                                 {
111                                         bp1 = BIG_LONG((list[0])[loffset]);
112                                         bp2 = BIG_LONG((list[1])[loffset]);
113                                         loffset++;
114                                         todo=32;
115                                 }
116
117                                 data = *point;
118                                 data<<=2;
119
120                                 if (bp1<0) data+=1;
121                                 bp1<<=1;
122                                 if (bp2<0) data+=2;
123                                 bp2<<=1;
124
125                                 /*              data += (bp1 >> 31) + ((bp2 & 0x80000000) >> 30);
126                                 bp1 <<= 1; bp2 <<= 1;
127                                 */
128                                 *(point++)=data;
129                                 todo--;
130                         }
131                 } else{
132                         list -= 4;
133                         nobp -= 4;
134                         for(i=size;i>0;i--)
135                         {
136                                 if (todo==0) {
137                                         bp1 = BIG_LONG((list[0])[loffset]);
138                                         bp2 = BIG_LONG((list[1])[loffset]);
139                                         bp3 = BIG_LONG((list[2])[loffset]);
140                                         bp4 = BIG_LONG((list[3])[loffset]);
141                                         loffset++;
142                                         todo=32;
143                                 }
144
145                                 data = *point;
146                                 data<<=4;
147
148                                 if (bp1<0) data+=1;
149                                 bp1<<=1;
150                                 if (bp2<0) data+=2;
151                                 bp2<<=1;
152                                 if (bp3<0) data+=4;
153                                 bp3<<=1;
154                                 if (bp4<0) data+=8;
155                                 bp4<<=1;
156
157                                 /*              data += (bp1 >> 31) \
158                                 + ((bp2 & 0x80000000) >> 30) \
159                                 + ((bp3 & 0x80000000) >> 29) \
160                                 + ((bp4 & 0x80000000) >> 28);
161                 
162                                 bp1 <<= 1; bp2 <<= 1;
163                                 bp3 <<= 1; bp4 <<= 1;
164                                 */
165                                 
166                                 *(point++)=data;
167                                 todo--;
168                         }
169                 }
170         }
171 }
172
173
174 void imb_bptolong(struct ImBuf *ibuf)
175 {
176         int nobp,i,x;
177         unsigned int *rect,offset;
178         float black[4] = {0.0,0.0,0.0,1.0};
179         float clear[4] = {0.0,0.0,0.0,0.0};
180
181         /* first clear all ints */
182
183         if (ibuf == 0) return;
184         if (ibuf->planes == 0) return;
185         if (ibuf->rect == 0) imb_addrectImBuf(ibuf);
186
187         nobp=ibuf->depth;
188         if (nobp != 32){
189                 if (nobp == 24) IMB_rectfill(ibuf, black); /* set alpha */
190                 else IMB_rectfill(ibuf, clear);
191         }
192
193         rect= ibuf->rect;
194         x= ibuf->x;
195         offset=0;
196
197         for (i= ibuf->y; i>0; i--){
198                 bptolscanl(rect, x, ibuf->planes, nobp, offset);
199                 rect += x;
200                 offset += ibuf->skipx;
201         }
202 }
203
204
205 static void ltobpscanl(unsigned int *rect, int x, unsigned int **list, int nobp, int offset)
206 {
207         /* converts a buffer with ints to bitplanes. Take care, buffer 
208                 will be destroyed !*/
209
210         if (nobp != 32)
211         {
212                 int *rect2;
213                 int todo,j;
214
215                 rect2 = (int*)rect;
216
217                 todo = 32-nobp;
218                 for (j = x;j>0;j--){
219                         *(rect2++) <<= todo;
220                 }
221         }
222
223         list += nobp;
224         for (;nobp>0;){
225                 register int bp1=0, bp2=0, bp3=0, data;
226                 register unsigned int *point;
227                 int i,todo;
228                 int bp4=0,loffset;
229
230                 point = rect;
231                 todo=32;
232                 loffset=offset;
233
234                 if (nobp & 1){
235                         list -= 1;
236                         nobp -= 1;
237
238                         for(i=x;i>0;i--){
239                                 data = *point;
240
241                                 bp1 <<= 1;
242                                 if (data<0) bp1 += 1;
243                                 data <<= 1;
244
245                                 *(point++) = data;
246
247                                 todo--;
248                                 if (todo == 0){
249                                         (list[0])[loffset] = bp1;
250                                         loffset++;
251                                         todo=32;
252                                 }
253                         }
254                         if (todo != 32)
255                         {
256                                 bp1 <<= todo;
257                                 (list[0])[loffset] = bp1;
258                         }
259                 } else if (nobp & 2){
260                         list -= 2;
261                         nobp -= 2;
262                         for(i=x;i>0;i--){
263                                 data = *point;
264
265                                 bp2 <<= 1;
266                                 if (data<0) bp2 += 1;
267                                 data <<= 1;
268                                 bp1 <<= 1;
269                                 if (data<0) bp1 += 1;
270                                 data <<= 1;
271
272                                 *(point++) = data;
273
274                                 todo--;
275                                 if (todo == 0){
276                                         (list[0])[loffset] = bp1;
277                                         (list[1])[loffset] = bp2;
278                                         loffset++;
279                                         todo=32;
280                                 }
281                         }
282                         if (todo != 32){
283                                 bp1 <<= todo;
284                                 bp2 <<= todo;
285                                 (list[0])[loffset] = bp1;
286                                 (list[1])[loffset] = bp2;
287                         }
288                 } else{
289                         list -= 4;
290                         nobp -= 4;
291                         for(i=x;i>0;i--){
292                                 data = *point;
293
294                                 bp4 <<= 1;
295                                 if (data<0) bp4 += 1;
296                                 data <<= 1;
297                                 bp3 <<= 1;
298                                 if (data<0) bp3 += 1;
299                                 data <<= 1;
300                                 bp2 <<= 1;
301                                 if (data<0) bp2 += 1;
302                                 data <<= 1;
303                                 bp1 <<= 1;
304                                 if (data<0) bp1 += 1;
305                                 data <<= 1;
306
307                                 *(point++) = data;
308
309                                 todo--;
310                                 if (todo == 0){
311                                         (list[0])[loffset] = bp1;
312                                         (list[1])[loffset] = bp2;
313                                         (list[2])[loffset] = bp3;
314                                         (list[3])[loffset] = bp4;
315                                         loffset++;
316                                         todo=32;
317                                 }
318                         }
319                         if (todo != 32){
320                                 bp1 <<= todo;
321                                 bp2 <<= todo;
322                                 bp3 <<= todo;
323                                 bp4 <<= todo;
324                                 (list[0])[loffset] = bp1;
325                                 (list[1])[loffset] = bp2;
326                                 (list[2])[loffset] = bp3;
327                                 (list[3])[loffset] = bp4;
328                         }
329                 }
330         }
331 }
332
333
334 void imb_longtobp(struct ImBuf *ibuf)
335 {
336         /* converts a buffer with ints to bitplanes. Take care, buffer
337         will be destroyed !*/
338
339         int nobp,i,x;
340         unsigned int *rect,offset,*buf;
341         ;
342
343         nobp = ibuf->depth;
344         rect=ibuf->rect;
345         x=ibuf->x;
346         offset=0;
347         if ((buf=malloc(x*sizeof(int)))==0) return;
348
349         for (i=ibuf->y;i>0;i--){
350                 memcpy(buf, rect, x*sizeof(int));
351                 rect +=x ;
352                 ltobpscanl(buf, x, ibuf->planes, nobp, offset);
353                 offset += ibuf->skipx;
354         }
355         free(buf);
356 }