use 'const char *' for imbuf and file ops.
[blender.git] / source / blender / imbuf / intern / dds / dds_api.cpp
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * Contributors: Amorilia (amorilia@gamebox.net)
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 #include <stddef.h>
26 #include <dds_api.h>
27 #include <Stream.h>
28 #include <DirectDrawSurface.h>
29 #include <stdio.h> // printf
30 #include <fstream>
31
32 extern "C" {
33
34 #include "imbuf.h"
35 #include "IMB_imbuf_types.h"
36 #include "IMB_imbuf.h"
37 #include "IMB_allocimbuf.h"
38
39
40 int imb_save_dds(struct ImBuf * ibuf, const char *name, int flags)
41 {
42         return(0); /* todo: finish this function */
43
44         /* check image buffer */
45         if (ibuf == 0) return (0);
46         if (ibuf->rect == 0) return (0);
47
48         /* open file for writing */
49         std::ofstream fildes(name);
50
51         /* write header */
52         fildes << "DDS ";
53         fildes.close();
54
55         return(1);
56 }
57
58 int imb_is_a_dds(unsigned char *mem) // note: use at most first 32 bytes
59 {
60         /* heuristic check to see if mem contains a DDS file */
61         /* header.fourcc == FOURCC_DDS */
62         if ((mem[0] != 'D') || (mem[1] != 'D') || (mem[2] != 'S') || (mem[3] != ' ')) return(0);
63         /* header.size == 124 */
64         if ((mem[4] != 124) || mem[5] || mem[6] || mem[7]) return(0);
65         return(1);
66 }
67
68 struct ImBuf *imb_load_dds(unsigned char *mem, size_t size, int flags)
69 {
70         struct ImBuf * ibuf = 0;
71         DirectDrawSurface dds(mem, size); /* reads header */
72         unsigned char bits_per_pixel;
73         unsigned int *rect;
74         Image img;
75         unsigned int numpixels = 0;
76         int col;
77         unsigned char *cp = (unsigned char *) &col;
78         Color32 pixel;
79         Color32 *pixels = 0;
80
81         if(!imb_is_a_dds(mem))
82                 return (0);
83
84         /* check if DDS is valid and supported */
85         if (!dds.isValid()) {
86                 /* no need to print error here, just testing if it is a DDS */
87                 if(flags & IB_test)
88                         return (0);
89
90                 printf("DDS: not valid; header follows\n");
91                 dds.printInfo();
92                 return(0);
93         }
94         if (!dds.isSupported()) {
95                 printf("DDS: format not supported\n");
96                 return(0);
97         }
98         if ((dds.width() > 65535) || (dds.height() > 65535)) {
99                 printf("DDS: dimensions too large\n");
100                 return(0);
101         }
102
103         /* convert DDS into ImBuf */
104         // TODO use the image RGB or RGBA tag to determine the bits per pixel
105         if (dds.hasAlpha()) bits_per_pixel = 32;
106         else bits_per_pixel = 24;
107         ibuf = IMB_allocImBuf(dds.width(), dds.height(), bits_per_pixel, 0);
108         if (ibuf == 0) return(0); /* memory allocation failed */
109
110         ibuf->ftype = DDS;
111         ibuf->profile = IB_PROFILE_SRGB;
112
113         if ((flags & IB_test) == 0) {
114                 if (!imb_addrectImBuf(ibuf)) return(ibuf);
115                 if (ibuf->rect == 0) return(ibuf);
116
117                 rect = ibuf->rect;
118                 dds.mipmap(&img, 0, 0); /* load first face, first mipmap */
119                 pixels = img.pixels();
120                 numpixels = dds.width() * dds.height();
121                 cp[3] = 0xff; /* default alpha if alpha channel is not present */
122
123                 for (unsigned int i = 0; i < numpixels; i++) {
124                         pixel = pixels[i];
125                         cp[0] = pixel.r; /* set R component of col */
126                         cp[1] = pixel.g; /* set G component of col */
127                         cp[2] = pixel.b; /* set B component of col */
128                         if (bits_per_pixel == 32)
129                                 cp[3] = pixel.a; /* set A component of col */
130                         rect[i] = col;
131                 }
132                 IMB_flipy(ibuf);
133         }
134
135         return(ibuf);
136 }
137
138 } // extern "C"