diff options
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_skp/imp_skp.c')
-rw-r--r-- | src/others/mimesh/libg3d-0.0.8/plugins/import/imp_skp/imp_skp.c | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_skp/imp_skp.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_skp/imp_skp.c new file mode 100644 index 0000000..64b74c8 --- /dev/null +++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_skp/imp_skp.c | |||
@@ -0,0 +1,218 @@ | |||
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 <string.h> | ||
24 | |||
25 | #include <g3d/types.h> | ||
26 | #include <g3d/context.h> | ||
27 | #include <g3d/read.h> | ||
28 | #include <g3d/stream.h> | ||
29 | |||
30 | #include "imp_skp.h" | ||
31 | #include "imp_skp_read.h" | ||
32 | #include "imp_skp_chunks.h" | ||
33 | |||
34 | static gboolean skp_parse_version_map(G3DStream *stream, guint32 *max_nlen, | ||
35 | guint32 *max_version); | ||
36 | static gchar *skp_find_section(G3DStream *stream, guint32 max_nlen, | ||
37 | guint32 max_version, guint32 *version); | ||
38 | static SkpChunkDesc *skp_get_chunk_desc(gchar *cname); | ||
39 | |||
40 | EAPI | ||
41 | gboolean plugin_load_model_from_stream(G3DContext *context, G3DStream *stream, | ||
42 | G3DModel *model, gpointer user_data) | ||
43 | { | ||
44 | gchar *smagic, *sversion, *stmp, *ssection; | ||
45 | guint32 max_nlen = 0, max_version = 0, version = 0; | ||
46 | SkpChunkDesc *desc; | ||
47 | SkpGlobalData *global; | ||
48 | SkpLocalData *local; | ||
49 | |||
50 | smagic = skp_read_wchar(stream); | ||
51 | if(smagic == NULL) { | ||
52 | g_warning("not a valid .skp file: '%s'", stream->uri); | ||
53 | return FALSE; | ||
54 | } | ||
55 | sversion = skp_read_wchar(stream); | ||
56 | if(sversion == NULL) { | ||
57 | g_warning("failed to read version from '%s'", stream->uri); | ||
58 | g_free(smagic); | ||
59 | return FALSE; | ||
60 | } | ||
61 | |||
62 | g_debug("SKP: magic: '%s', version: '%s'", smagic, sversion); | ||
63 | g_free(smagic); | ||
64 | g_free(sversion); | ||
65 | |||
66 | g3d_stream_seek(stream, 16, G_SEEK_CUR); | ||
67 | stmp = skp_read_wchar(stream); | ||
68 | if(stmp != NULL) | ||
69 | g_free(stmp); | ||
70 | g3d_stream_read_int32_le(stream); | ||
71 | |||
72 | ssection = skp_read_char(stream); | ||
73 | if(ssection) { | ||
74 | if(strcmp(ssection, "CVersionMap") == 0) | ||
75 | g_debug("\\CVersionMap"); | ||
76 | skp_parse_version_map(stream, &max_nlen, &max_version); | ||
77 | g_free(ssection); | ||
78 | } | ||
79 | |||
80 | global = g_new0(SkpGlobalData, 1); | ||
81 | global->context = context; | ||
82 | global->model = model; | ||
83 | global->stream = stream; | ||
84 | |||
85 | ssection = skp_find_section(stream, max_nlen, max_version, &version); | ||
86 | while(ssection != NULL) { | ||
87 | desc = skp_get_chunk_desc(ssection); | ||
88 | if(desc == NULL) { | ||
89 | g_warning("SKP: unknown chunk type '%s'", ssection); | ||
90 | } else { | ||
91 | if((version > desc->max_ver) || (version < desc->min_ver)) { | ||
92 | g_warning("SKP: %s: unhandled version %u (%u - %u)", | ||
93 | ssection, version, desc->min_ver, desc->max_ver); | ||
94 | } else { | ||
95 | if(desc->callback) { | ||
96 | local = g_new0(SkpLocalData, 1); | ||
97 | local->id = desc->id; | ||
98 | local->version = version; | ||
99 | |||
100 | desc->callback(global, local); | ||
101 | |||
102 | g_free(local); | ||
103 | } | ||
104 | } /* version check */ | ||
105 | } /* has desc */ | ||
106 | |||
107 | ssection = skp_find_section(stream, max_nlen, max_version, &version); | ||
108 | } /* sections */ | ||
109 | |||
110 | /* clean up */ | ||
111 | g_free(global); | ||
112 | |||
113 | return TRUE; | ||
114 | } | ||
115 | |||
116 | EAPI | ||
117 | gchar *plugin_description(void) | ||
118 | { | ||
119 | return g_strdup("SketchUp models."); | ||
120 | } | ||
121 | |||
122 | EAPI | ||
123 | gchar **plugin_extensions(void) | ||
124 | { | ||
125 | return g_strsplit("skp", ":", 0); | ||
126 | } | ||
127 | |||
128 | |||
129 | /*****************************************************************************/ | ||
130 | |||
131 | static gboolean skp_parse_version_map(G3DStream *stream, guint32 *max_nlen, | ||
132 | guint32 *max_version) | ||
133 | { | ||
134 | gchar *part; | ||
135 | guint32 version; | ||
136 | |||
137 | while(TRUE) { | ||
138 | part = skp_read_wchar(stream); | ||
139 | if(part == NULL) | ||
140 | return FALSE; | ||
141 | version = g3d_stream_read_int32_le(stream); | ||
142 | #if DEBUG > 1 | ||
143 | g_debug("\t%-30s %u", part, version); | ||
144 | #endif | ||
145 | if(strcmp(part, "End-Of-Version-Map") == 0) { | ||
146 | g_free(part); | ||
147 | return TRUE; | ||
148 | } | ||
149 | |||
150 | if(version > *max_version) | ||
151 | *max_version = version; | ||
152 | if(strlen(part) > *max_nlen) | ||
153 | *max_nlen = strlen(part); | ||
154 | |||
155 | g_free(part); | ||
156 | } | ||
157 | return FALSE; | ||
158 | } | ||
159 | |||
160 | static gchar *skp_find_section(G3DStream *stream, guint32 max_nlen, | ||
161 | guint32 max_version, guint32 *version) | ||
162 | { | ||
163 | goffset offset; | ||
164 | guint32 ver, nlen; | ||
165 | guint16 w1; | ||
166 | gchar *name; | ||
167 | |||
168 | while(!g3d_stream_eof(stream) && (g3d_stream_read_int8(stream) != 0xFF)); | ||
169 | |||
170 | if(g3d_stream_eof(stream)) | ||
171 | return NULL; | ||
172 | |||
173 | offset = g3d_stream_tell(stream); | ||
174 | if(g3d_stream_read_int8(stream) != 0xFF) { | ||
175 | g3d_stream_seek(stream, offset, G_SEEK_SET); | ||
176 | return skp_find_section(stream, max_nlen, max_version, version); | ||
177 | } | ||
178 | |||
179 | ver = g3d_stream_read_int16_le(stream); | ||
180 | if(ver > max_version) { | ||
181 | g3d_stream_seek(stream, offset, G_SEEK_SET); | ||
182 | return skp_find_section(stream, max_nlen, max_version, version); | ||
183 | } | ||
184 | |||
185 | nlen = g3d_stream_read_int16_le(stream); | ||
186 | if(nlen > max_nlen) { | ||
187 | g3d_stream_seek(stream, offset, G_SEEK_SET); | ||
188 | return skp_find_section(stream, max_nlen, max_version, version); | ||
189 | } | ||
190 | |||
191 | name = g_new0(gchar, nlen + 1); | ||
192 | g3d_stream_read(stream, name, nlen); | ||
193 | if(name[0] != 'C') { | ||
194 | g_free(name); | ||
195 | g3d_stream_seek(stream, offset, G_SEEK_SET); | ||
196 | return skp_find_section(stream, max_nlen, max_version, version); | ||
197 | } | ||
198 | *version = ver; | ||
199 | |||
200 | w1 = g3d_stream_read_int16_le(stream); | ||
201 | g3d_stream_seek(stream, -2, G_SEEK_CUR); | ||
202 | |||
203 | g_debug("\\%-30s v%-2u @ 0x%08x (0x%04x)", name, ver, | ||
204 | (guint32)g3d_stream_tell(stream), w1); | ||
205 | |||
206 | return name; | ||
207 | } | ||
208 | |||
209 | static SkpChunkDesc *skp_get_chunk_desc(gchar *cname) | ||
210 | { | ||
211 | guint32 i; | ||
212 | |||
213 | for(i = 0; skp_chunks[i].id != NULL; i ++) { | ||
214 | if(strcmp(cname, skp_chunks[i].id) == 0) | ||
215 | return &(skp_chunks[i]); | ||
216 | } | ||
217 | return NULL; | ||
218 | } | ||