84588b52573a1bfa31d34c78c3c6fe972e6d150b
[blender.git] / source / blender / imbuf / intern / divers.c
1 /**
2  *
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  * allocimbuf.c
28  *
29  * $Id$
30  */
31
32 #include "BLI_blenlib.h"
33 #include "BLI_rand.h"
34
35 #include "imbuf.h"
36 #include "imbuf_patch.h"
37 #include "IMB_imbuf_types.h"
38 #include "IMB_imbuf.h"
39 #include "IMB_allocimbuf.h"
40 #include "IMB_divers.h"
41
42 void imb_checkncols(struct ImBuf *ibuf)
43 {
44         unsigned int i;
45
46         if (ibuf==0) return;
47         
48         if (IS_amiga(ibuf)){
49                 if (IS_ham(ibuf)){
50                         if (ibuf->depth == 0) ibuf->depth = 6;
51                         ibuf->mincol = 0;
52                         ibuf->maxcol = 1 << (ibuf->depth - 2);
53                         /*printf("%d %d\n", ibuf->maxcol, ibuf->depth);*/
54                         return;
55                 } else if (IS_hbrite(ibuf)){
56                         ibuf->mincol = 0;
57                         ibuf->maxcol = 64;
58                         ibuf->depth = 6;
59                         return;
60                 }
61         }
62
63         if (ibuf->maxcol == 0){
64                 if (ibuf->depth <= 8){
65                         ibuf->mincol = 0;
66                         ibuf->maxcol = (1 << ibuf->depth);
67                         return;
68                 } else if (ibuf->depth == 0){
69                         ibuf->depth = 5;
70                         ibuf->mincol = 0;
71                         ibuf->maxcol = 32;
72                 }
73                 return;
74         } else {
75                 /* ibuf->maxcol defines the depth */
76                 for (i=1 ; ibuf->maxcol > (1 << i); i++);
77                 ibuf->depth = i;
78                 return;
79         }
80 }
81
82
83 void IMB_de_interlace(struct ImBuf *ibuf)
84 {
85         struct ImBuf * tbuf1, * tbuf2;
86         
87         if (ibuf == 0) return;
88         if (ibuf->flags & IB_fields) return;
89         ibuf->flags |= IB_fields;
90         
91         if (ibuf->rect) {
92                 /* make copies */
93                 tbuf1 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 32, IB_rect, 0);
94                 tbuf2 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 32, IB_rect, 0);
95                 
96                 ibuf->x *= 2;   
97                 IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
98                 IMB_rectcpy(tbuf2, ibuf, 0, 0, tbuf2->x, 0, ibuf->x, ibuf->y);
99         
100                 ibuf->x /= 2;
101                 IMB_rectcpy(ibuf, tbuf1, 0, 0, 0, 0, tbuf1->x, tbuf1->y);
102                 IMB_rectcpy(ibuf, tbuf2, 0, tbuf2->y, 0, 0, tbuf2->x, tbuf2->y);
103                 
104                 IMB_freeImBuf(tbuf1);
105                 IMB_freeImBuf(tbuf2);
106         }
107         ibuf->y /= 2;
108 }
109
110 void IMB_interlace(struct ImBuf *ibuf)
111 {
112         struct ImBuf * tbuf1, * tbuf2;
113
114         if (ibuf == 0) return;
115         ibuf->flags &= ~IB_fields;
116
117         ibuf->y *= 2;
118
119         if (ibuf->rect) {
120                 /* make copies */
121                 tbuf1 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 32, IB_rect, 0);
122                 tbuf2 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 32, IB_rect, 0);
123
124                 IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
125                 IMB_rectcpy(tbuf2, ibuf, 0, 0, 0, tbuf2->y, ibuf->x, ibuf->y);
126
127                 ibuf->x *= 2;
128                 IMB_rectcpy(ibuf, tbuf1, 0, 0, 0, 0, tbuf1->x, tbuf1->y);
129                 IMB_rectcpy(ibuf, tbuf2, tbuf2->x, 0, 0, 0, tbuf2->x, tbuf2->y);
130                 ibuf->x /= 2;
131
132                 IMB_freeImBuf(tbuf1);
133                 IMB_freeImBuf(tbuf2);
134         }
135 }
136
137
138 void IMB_gamwarp(struct ImBuf *ibuf, double gamma)
139 {
140         uchar gam[256];
141         int i;
142         uchar *rect;
143         float *rectf;
144
145         if (ibuf == 0) return;
146         if (gamma == 1.0) return;
147
148         rect = (uchar *) ibuf->rect;
149         rectf = ibuf->rect_float;
150
151         gamma = 1.0 / gamma;
152
153         if (rect) {
154                 for (i = 255 ; i >= 0 ; i--) 
155                         gam[i] = (255.0 * pow(i / 255.0 ,
156                                               gamma))  + 0.5;
157
158                 for (i = ibuf->x * ibuf->y ; i>0 ; i--, rect+=4){
159                         rect[0] = gam[rect[0]];
160                         rect[1] = gam[rect[1]];
161                         rect[2] = gam[rect[2]];
162                 }
163         }
164
165         if (rectf) {
166                 for (i = ibuf->x * ibuf->y ; i>0 ; i--, rectf+=4){
167                         rectf[0] = pow(rectf[0] / 255.0, gamma);
168                         rectf[1] = pow(rectf[1] / 255.0, gamma);
169                         rectf[2] = pow(rectf[2] / 255.0, gamma);
170                 }
171         }
172 }
173
174 #define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.99f*val))
175
176 void IMB_rect_from_float(struct ImBuf *ibuf)
177 {
178         /* quick method to convert floatbuf to byte */
179         float *tof = ibuf->rect_float;
180         float dither= ibuf->dither;
181         int i, channels= ibuf->channels;
182         unsigned char *to = (unsigned char *) ibuf->rect;
183         
184         if(tof==NULL) return;
185         if(to==NULL) {
186                 imb_addrectImBuf(ibuf);
187                 to = (unsigned char *) ibuf->rect;
188         }
189         
190         if(dither==0.0f || channels!=4) {
191                 if(channels==1) {
192                         for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof++)
193                                 to[1]= to[2]= to[3]= to[0] = FTOCHAR(tof[0]);
194                 }
195                 else if(channels==3) {
196                         for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=3) {
197                                 to[0] = FTOCHAR(tof[0]);
198                                 to[1] = FTOCHAR(tof[1]);
199                                 to[2] = FTOCHAR(tof[2]);
200                                 to[3] = 255;
201                         }
202                 }
203                 else {
204                         for (i = ibuf->x * ibuf->y; i > 0; i--, to+=4, tof+=4) {
205                                 to[0] = FTOCHAR(tof[0]);
206                                 to[1] = FTOCHAR(tof[1]);
207                                 to[2] = FTOCHAR(tof[2]);
208                                 to[3] = FTOCHAR(tof[3]);
209                         }
210                 }
211         }
212         else {
213                 float dither_value, col;
214                 dither= dither/255.0f;
215                 for (i = ibuf->x * ibuf->y; i > 0; i--) {
216                         dither_value = (BLI_frand()-0.5)*dither; 
217                         col= tof[0] + dither_value;
218                         to[0] = FTOCHAR(col);
219                         col= tof[1] + dither_value;
220                         to[1] = FTOCHAR(col);
221                         col= tof[2] + dither_value;
222                         to[2] = FTOCHAR(col);
223                         col= tof[3] + dither_value;
224                         to[3] = FTOCHAR(col);
225
226                         to += 4; 
227                         tof += 4;
228                 }
229         }
230 }
231
232 void IMB_float_from_rect(struct ImBuf *ibuf)
233 {
234         /* quick method to convert byte to floatbuf */
235         float *tof = ibuf->rect_float;
236         int i;
237         unsigned char *to = (unsigned char *) ibuf->rect;
238         
239         if(to==NULL) return;
240         if(tof==NULL) {
241                 imb_addrectfloatImBuf(ibuf);
242                 tof = ibuf->rect_float;
243         }
244         
245         for (i = ibuf->x * ibuf->y; i > 0; i--) 
246         {
247                 tof[0] = ((float)to[0])*(1.0f/255.0f);
248                 tof[1] = ((float)to[1])*(1.0f/255.0f);
249                 tof[2] = ((float)to[2])*(1.0f/255.0f);
250                 tof[3] = ((float)to[3])*(1.0f/255.0f);
251                 to += 4; 
252                 tof += 4;
253         }
254 }
255