Addes libopenjpeg (jpeg2000) support to the Makefiles
[blender.git] / source / blender / imbuf / intern / iff.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  * iff.c
28  *
29  * $Id$
30  */
31
32 #ifdef WIN32
33 #include <io.h>
34 #endif
35 #include "BLI_blenlib.h"
36 #include "imbuf.h"
37 #include "imbuf_patch.h"
38 #include "IMB_imbuf_types.h"
39 #include "IMB_iff.h"
40
41 unsigned short imb_start_iff(struct ImBuf *ibuf, int file)
42 {
43         unsigned int *point, size, *buf;
44         
45         if ((point=buf=(unsigned int *)malloc(32768))==0) return FALSE;
46
47         *point++ = FORM;                                /* FORMxxxxILBM in buffer */
48         *point++ = 0;
49
50         if (IS_amiga(ibuf)){
51                 struct BitMapHeader *bmhd;
52
53                 *point++ = ILBM;
54                 *point++ = CAMG;
55                 *point++ = 4;
56                 *point++ = (ibuf->ftype & 0xffff);
57
58                 *point++=BMHD;
59                 *point++=sizeof(struct BitMapHeader);
60
61                 bmhd=(struct BitMapHeader *)point;              /* bmhd points to location where bmhd will be */
62                 point=(unsigned int *)((char *)point+sizeof(struct BitMapHeader));      /* advance pointer already */
63
64                 bmhd->w=ibuf->x;
65                 bmhd->h=ibuf->y;
66                 bmhd->pageWidth=ibuf->x;
67                 bmhd->pageHeight=ibuf->y;
68                 bmhd->x=0;
69                 bmhd->y=0;
70                 bmhd->nPlanes=ibuf->depth;
71                 bmhd->masking=0;
72                 if (ibuf->flags & IB_vert){
73                         bmhd->compression=2;
74                 }
75                 else{
76                         bmhd->compression=1;
77                 }
78                 bmhd->pad1=0;
79                 bmhd->transparentColor=0;
80                 bmhd->xAspect=1;
81                 bmhd->yAspect=1;
82         } else if (IS_anim(ibuf)){
83                 struct Adat *adat;
84                 extern float adat_gamma;
85                 extern float adat_distort;
86                 
87                 *point++ = ANIM;
88                 *point++ = ADAT;
89                 *point++ = BIG_LONG(sizeof(struct Adat));
90
91                 adat = (struct Adat *)point;
92                 point = (unsigned int *)((char *)point+sizeof(struct Adat));    /* advance pointer already */
93
94                 adat->w = BIG_SHORT(ibuf->x);
95                 adat->h = BIG_SHORT(ibuf->y);
96
97                 adat->type = BIG_SHORT(ibuf->ftype);
98                 adat->xorig = BIG_SHORT(ibuf->xorig);
99                 adat->yorig = BIG_SHORT(ibuf->yorig);
100                 adat->pad = 0;
101                 adat->gamma = adat_gamma;
102                 adat->distort = adat_distort;
103         }
104
105         size=((uchar *)point-(uchar *)buf);
106         if (write(file,buf,size)!=size){
107                 free(buf);
108                 return (FALSE);
109         }
110
111         if (ibuf->cmap){
112                 if (IS_anim(ibuf)){
113                         size = ibuf->maxcol * sizeof(int);
114                         buf[0] = CMAP;
115                         buf[1] = BIG_LONG(size);
116                         if (write(file,buf,8) != 8){
117                                 free(buf);
118                                 return (FALSE);
119                         }
120                         if (write(file,ibuf->cmap,size) != size){
121                                 free(buf);
122                                 return (FALSE);
123                         }
124                 } else{
125                         uchar *cpoint,*cols;
126                         unsigned int i,bits;
127
128                         point = buf;
129                         if (IS_amiga(ibuf)){
130                                 *(point++) = CMAP;
131                                 *(point++) = BIG_LONG(3*ibuf->maxcol);
132                         }
133
134                         cpoint = (uchar *) point;
135                         cols = (uchar *)ibuf->cmap;
136                         if ((ibuf->cbits > 0) && (ibuf->cbits < 8)){
137                                 bits = ~((1 << (8-ibuf->cbits)) - 1);
138                         } else bits = -1;
139
140                         if (IS_ham(ibuf)) bits = -1;
141                         
142                         for (i=0 ; i<ibuf->maxcol ; i++){
143                                 *(cpoint++) = cols[0] & bits;
144                                 *(cpoint++) = cols[1] & bits;
145                                 *(cpoint++) = cols[2] & bits;
146                                 cols += 4;
147                         }
148                         if (ibuf->maxcol & 1) *(cpoint++)=0;
149
150                         size=(cpoint-(uchar *)buf);
151                         if (write(file,buf,size)!=size){
152                                 free(buf);
153                                 return (FALSE);
154                         }
155                 }
156         }
157
158         if (IS_amiga(ibuf)) buf[0] = BODY;
159         if (IS_anim(ibuf)) buf[0] = BODY;
160         buf[1]=0;
161
162         if (write(file,buf,8)!=8){
163                 free(buf);
164                 return(FALSE);
165         }
166
167         free(buf);
168         return (TRUE);
169 }
170
171
172 unsigned short imb_update_iff(int file, int code)
173 {
174         int     buf[2], filelen, skip;
175         uchar nop;
176
177         if (file<=0) return (FALSE);
178
179         filelen = BLI_filesize(file)-8;                 /* calc filelength  */
180
181         lseek(file,0L,2);               /* seek end */
182
183         if (filelen & 1){                                               /* make length 'even' */
184                 switch(code){
185                 case BODY:
186                         nop = IFFNOP;
187                         break;
188                 }
189                 if (write(file,&nop,1)!=1) return (FALSE);
190                 filelen++;
191         }
192         lseek(file,4L,0);
193
194         buf[0] = BIG_LONG(filelen);
195         
196         if (write(file, buf, 4) != 4) return (FALSE);
197         if (code == 0) return (TRUE);
198
199         filelen-=4;
200         lseek(file,4L,1);
201
202         while (filelen>0){              /* seek BODY */
203                 read(file, buf, 8);
204                 filelen -= 8;
205                 if (buf[0] == code) break;
206                 
207                 skip = (BIG_LONG(buf[1]) + 1) & ~1;
208                 filelen -= skip;
209                 lseek(file, skip, 1);
210         }
211         if (filelen <= 0) {
212                 printf("update_iff: couldn't find chunk\n");
213                 return (FALSE);
214         }
215
216         lseek(file, -4L, 1);
217         
218         buf[0] = BIG_LONG(filelen);
219         
220         if (write(file, buf, 4)!=4) return (FALSE);
221
222         return (TRUE);
223 }