diff options
Diffstat (limited to '')
-rw-r--r-- | src/others/mimesh/libg3d-0.0.8/plugins/image/img_dds.c | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/image/img_dds.c b/src/others/mimesh/libg3d-0.0.8/plugins/image/img_dds.c new file mode 100644 index 0000000..cf6c58f --- /dev/null +++ b/src/others/mimesh/libg3d-0.0.8/plugins/image/img_dds.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* $Id$ */ | ||
2 | |||
3 | /* | ||
4 | libg3d - 3D object loading library | ||
5 | |||
6 | Copyright (C) 2005-2009 Markus Dahms <mad@automagically.de> | ||
7 | |||
8 | This library is free software; you can redistribute it and/or | ||
9 | modify it under the terms of the GNU Lesser General Public | ||
10 | License as published by the Free Software Foundation; either | ||
11 | version 2.1 of the License, or (at your option) any later version. | ||
12 | |||
13 | This library is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | Lesser General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU Lesser General Public | ||
19 | License along with this library; if not, write to the Free Software | ||
20 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
21 | */ | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <string.h> | ||
25 | |||
26 | #include <g3d/types.h> | ||
27 | #include <g3d/stream.h> | ||
28 | #include <g3d/iff.h> | ||
29 | |||
30 | static gboolean decode_dxt1(G3DImage *image, G3DStream *stream); | ||
31 | |||
32 | EAPI | ||
33 | gboolean plugin_load_image_from_stream(G3DContext *context, G3DStream *stream, | ||
34 | G3DImage *image, gpointer user_data) | ||
35 | { | ||
36 | guint32 magic, size, flags, depth; | ||
37 | guint32 pfsize, pfflags, pffourcc, pfbpp; | ||
38 | guint32 pfrmask, pfgmask, pfbmask, pfamask; | ||
39 | guint32 caps1, caps2; | ||
40 | gchar *sfourcc; | ||
41 | |||
42 | magic = g3d_stream_read_int32_be(stream); | ||
43 | if(magic != G3D_IFF_MKID('D','D','S',' ')) { | ||
44 | g_warning("%s is not a DDS file", stream->uri); | ||
45 | return FALSE; | ||
46 | } | ||
47 | image->name = g_strdup(stream->uri); | ||
48 | |||
49 | size = g3d_stream_read_int32_le(stream); | ||
50 | flags = g3d_stream_read_int32_le(stream); | ||
51 | image->height = g3d_stream_read_int32_le(stream); | ||
52 | image->width = g3d_stream_read_int32_le(stream); | ||
53 | g3d_stream_read_int32_le(stream); /* pitch or linesize */ | ||
54 | depth = g3d_stream_read_int32_le(stream); | ||
55 | g3d_stream_read_int32_le(stream); /* num mipmaps */ | ||
56 | |||
57 | g3d_stream_skip(stream, 44); | ||
58 | |||
59 | pfsize = g3d_stream_read_int32_le(stream); | ||
60 | pfflags = g3d_stream_read_int32_le(stream); | ||
61 | |||
62 | pffourcc = g3d_stream_read_int32_be(stream); | ||
63 | sfourcc = g3d_iff_id_to_text(pffourcc); | ||
64 | |||
65 | pfbpp = g3d_stream_read_int32_le(stream); | ||
66 | pfrmask = g3d_stream_read_int32_le(stream); | ||
67 | pfgmask = g3d_stream_read_int32_le(stream); | ||
68 | pfbmask = g3d_stream_read_int32_le(stream); | ||
69 | pfamask = g3d_stream_read_int32_le(stream); | ||
70 | caps1 = g3d_stream_read_int32_le(stream); | ||
71 | caps2 = g3d_stream_read_int32_le(stream); | ||
72 | |||
73 | g3d_stream_skip(stream, 12); | ||
74 | |||
75 | #if DEBUG > 0 | ||
76 | g_debug("DDS: %ux%u %s 0x%08x", image->width, image->height, | ||
77 | sfourcc, pfflags); | ||
78 | g_debug("DDS: masks: 0x%04x, 0x%04x, 0x%04x, 0x%04x", | ||
79 | pfrmask, pfgmask, pfbmask, pfamask); | ||
80 | #endif | ||
81 | |||
82 | image->pixeldata = g_new0(guint8, image->width * image->height * 4); | ||
83 | |||
84 | switch(pffourcc) { | ||
85 | case G3D_IFF_MKID('D','X','T','1'): | ||
86 | decode_dxt1(image, stream); | ||
87 | break; | ||
88 | default: | ||
89 | g_warning("DDS: unsupported FOURCC: %s", sfourcc); | ||
90 | } | ||
91 | |||
92 | g_free(sfourcc); | ||
93 | return TRUE; | ||
94 | } | ||
95 | |||
96 | EAPI | ||
97 | gchar *plugin_description(G3DContext *context) | ||
98 | { | ||
99 | return g_strdup("DDS textures.\n" | ||
100 | "Author: Markus Dahms"); | ||
101 | } | ||
102 | |||
103 | EAPI | ||
104 | gchar **plugin_extensions(G3DContext *context) | ||
105 | { | ||
106 | return g_strsplit("dds", ":", 0); | ||
107 | } | ||
108 | |||
109 | /*****************************************************************************/ | ||
110 | |||
111 | static void decode_rgb565(guint16 c, G3DFloat *r, G3DFloat *g, G3DFloat *b) | ||
112 | { | ||
113 | *r = ((c & 0xF800) >> 11) / 32.0; | ||
114 | *g = ((c & 0x07E0) >> 5) / 64.0; | ||
115 | *b = (c & 0x001F) / 32.0; | ||
116 | } | ||
117 | |||
118 | static gboolean decode_dxt1(G3DImage *image, G3DStream *stream) | ||
119 | { | ||
120 | gint32 x, y, i, j; | ||
121 | guint32 index; | ||
122 | G3DFloat r, g, b, r1, r2, g1, g2, b1, b2; | ||
123 | guint8 line, v2; | ||
124 | |||
125 | for(y = 0; y < image->height; y += 4) { | ||
126 | for(x = 0; x < image->width; x += 4) { | ||
127 | decode_rgb565(g3d_stream_read_int16_le(stream), &r1, &g1, &b1); | ||
128 | decode_rgb565(g3d_stream_read_int16_le(stream), &r2, &g2, &b2); | ||
129 | for(j = 0; j < 4; j ++) { | ||
130 | line = g3d_stream_read_int8(stream); | ||
131 | for(i = 0; i < 4; i ++) { | ||
132 | v2 = line & 0x3; | ||
133 | line >>= 2; | ||
134 | r = r1 + ((r2 - r1) / 3.0) * v2; | ||
135 | g = g1 + ((g2 - g1) / 3.0) * v2; | ||
136 | b = b1 + ((b2 - b1) / 3.0) * v2; | ||
137 | index = ((image->height - 4) - y + j) * | ||
138 | image->width + x + i; | ||
139 | image->pixeldata[index * 4 + 0] = r * 255.0; | ||
140 | image->pixeldata[index * 4 + 1] = g * 255.0; | ||
141 | image->pixeldata[index * 4 + 2] = b * 255.0; | ||
142 | image->pixeldata[index * 4 + 3] = 0xFF; | ||
143 | } | ||
144 | } | ||
145 | } | ||
146 | } | ||
147 | |||
148 | return TRUE; | ||
149 | } | ||