aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_skp/imp_skp.c
diff options
context:
space:
mode:
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.c218
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
34static gboolean skp_parse_version_map(G3DStream *stream, guint32 *max_nlen,
35 guint32 *max_version);
36static gchar *skp_find_section(G3DStream *stream, guint32 max_nlen,
37 guint32 max_version, guint32 *version);
38static SkpChunkDesc *skp_get_chunk_desc(gchar *cname);
39
40EAPI
41gboolean 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
116EAPI
117gchar *plugin_description(void)
118{
119 return g_strdup("SketchUp models.");
120}
121
122EAPI
123gchar **plugin_extensions(void)
124{
125 return g_strsplit("skp", ":", 0);
126}
127
128
129/*****************************************************************************/
130
131static 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
160static 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
209static 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}