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