This is patch# 19017 16bit SGI image loading
[blender.git] / source / blender / imbuf / intern / cspace.c
1 /**
2  *
3  * $Id$
4  *
5  * ***** BEGIN GPL LICENSE BLOCK *****
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20  *
21  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
22  * All rights reserved.
23  *
24  * The Original Code is: all of this file.
25  *
26  * Contributor(s): none yet.
27  *
28  * ***** END GPL LICENSE BLOCK *****
29  */
30
31 #include "BLI_blenlib.h"
32
33 #include "imbuf.h"
34 #include "imbuf_patch.h"
35 #include "IMB_imbuf_types.h"
36
37 void IMB_cspace(struct ImBuf *ibuf, float mat[][4]);
38
39 /************************************************************************/
40 /*                              COLORSPACE                              */
41 /************************************************************************/
42
43 static void fillmattab(double val, unsigned short *mattab)
44 {
45         int tot,ival;
46         int i;
47
48         val *= (1 << 22);
49         ival = val;
50         tot = 32767; /* een half */
51
52         for(i = 256; i > 0; i--){
53                 *(mattab) = (tot >> 16);
54                 mattab += 3;
55                 tot += ival;
56         }
57 }
58
59
60 static void cspfill(short *buf, unsigned short *fill, int x)
61 {
62         unsigned short r,g,b;
63
64         b = fill[0];
65         g = fill[1];
66         r = fill[2];
67         for (;x>0;x--){
68                 buf[0] = b;
69                 buf[1] = g;
70                 buf[2] = r;
71                 buf += 3;
72         }
73 }
74
75
76 static void cspadd(short *buf, unsigned short *cont, unsigned char *rect, int x)
77 {
78         short i;
79         for (;x>0;x--){
80                 i = *(rect);
81                 rect += 4;
82                 buf[0] += cont[i*3];
83                 buf[1] += cont[i*3 + 1];
84                 buf[2] += cont[i*3 + 2];
85                 buf += 3;
86         }
87 }
88
89
90 static void cspret(short *buf, unsigned char *rect, int x)
91 {
92         int r,g,b;
93         
94         for(; x > 0; x--){
95                 b = buf[0];
96                 g = buf[1];
97                 r = buf[2];
98
99                 if (b & 0x4000){
100                         if (b<0) rect[2]=0;
101                         else rect[2]=255;
102                 } else rect[2] = b >> 6;
103
104                 if (g & 0x4000){
105                         if (g<0) rect[1]=0;
106                         else rect[1]=255;
107                 } else rect[1] = g >> 6;
108
109                 if (r & 0x4000){
110                         if (r<0) rect[0]=0;
111                         else rect[0]=255;
112                 } else rect[0] = r >> 6;
113
114                 buf += 3;
115                 rect += 4;
116         }
117 }
118
119
120 static void rotcspace(struct ImBuf *ibuf, unsigned short *cont_1, unsigned short *cont_2, unsigned short *cont_3, unsigned short *add)
121 {
122         short x,y,*buf;
123         uchar *rect;
124
125         x=ibuf->x;
126         rect= (uchar *)ibuf->rect;
127
128         buf=(short *)malloc(x*3*sizeof(short));
129         if (buf){
130                 for(y=ibuf->y;y>0;y--){
131                         cspfill(buf,add,x);
132                         cspadd(buf,cont_1,rect+0,x);
133                         cspadd(buf,cont_2,rect+1,x);
134                         cspadd(buf,cont_3,rect+2,x);
135                         cspret(buf,rect,x);
136                         rect += x<<2;
137                 }
138                 free(buf);
139         }
140 }
141
142
143 void IMB_cspace(struct ImBuf *ibuf, float mat[][4])
144 {
145         unsigned short *cont_1,*cont_2,*cont_3,add[3];
146
147         cont_1=(unsigned short *)malloc(256*3*sizeof(short));
148         cont_2=(unsigned short *)malloc(256*3*sizeof(short));
149         cont_3=(unsigned short *)malloc(256*3*sizeof(short));
150
151         if (cont_1 && cont_2 && cont_3){
152
153                 fillmattab(mat[0][0],cont_1);
154                 fillmattab(mat[0][1],cont_1+1);
155                 fillmattab(mat[0][2],cont_1+2);
156
157                 fillmattab(mat[1][0],cont_2);
158                 fillmattab(mat[1][1],cont_2+1);
159                 fillmattab(mat[1][2],cont_2+2);
160
161                 fillmattab(mat[2][0],cont_3);
162                 fillmattab(mat[2][1],cont_3+1);
163                 fillmattab(mat[2][2],cont_3+2);
164
165                 add[0] = (mat[3][0] * 64.0) + .5;
166                 add[1] = (mat[3][1] * 64.0) + .5;
167                 add[2] = (mat[3][2] * 64.0) + .5;
168
169                 rotcspace(ibuf, cont_1, cont_2, cont_3, add);
170         }
171
172         if (cont_1) free(cont_1);
173         if (cont_2) free(cont_2);
174         if (cont_3) free(cont_3);
175 }
176