File: | backend/djvu/djvu-links.c |
Warning: | line 329, column 2 Value stored to 'iter' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ |
2 | /* |
3 | * Implements hyperlink functionality for Djvu files. |
4 | * Copyright (C) 2006 Pauli Virtanen <pav@iki.fi> |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2, or (at your option) |
9 | * 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 |
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
19 | */ |
20 | |
21 | #include <config.h> |
22 | #include <string.h> |
23 | #include <glib.h> |
24 | #include <libdjvu/miniexp.h> |
25 | #include "djvu-document.h" |
26 | #include "djvu-links.h" |
27 | #include "djvu-document-private.h" |
28 | #include "ev-document-links.h" |
29 | #include "ev-mapping-list.h" |
30 | |
31 | static gboolean number_from_miniexp(miniexp_t sexp, int *number) |
32 | { |
33 | if (miniexp_numberp (sexp)) { |
34 | *number = miniexp_to_int (sexp); |
35 | return TRUE(!(0)); |
36 | } else { |
37 | return FALSE(0); |
38 | } |
39 | } |
40 | |
41 | static gboolean string_from_miniexp(miniexp_t sexp, const char **str) |
42 | { |
43 | if (miniexp_stringp (sexp)) { |
44 | *str = miniexp_to_str (sexp); |
45 | return TRUE(!(0)); |
46 | } else { |
47 | return FALSE(0); |
48 | } |
49 | } |
50 | |
51 | static gboolean number_from_string_10(const gchar *str, guint64 *number) |
52 | { |
53 | gchar *end_ptr; |
54 | |
55 | *number = g_ascii_strtoull(str, &end_ptr, 10); |
56 | if (*end_ptr == '\0') { |
57 | return TRUE(!(0)); |
58 | } else { |
59 | return FALSE(0); |
60 | } |
61 | } |
62 | |
63 | static guint64 |
64 | get_djvu_link_page (const DjvuDocument *djvu_document, const gchar *link_name, int base_page) |
65 | { |
66 | guint64 page_num = 0; |
67 | |
68 | /* #pagenum, #+pageoffset, #-pageoffset */ |
69 | if (g_str_has_prefix (link_name, "#")(__builtin_constant_p ("#")? __extension__ ({ const char * const __str = (link_name); const char * const __prefix = ("#"); gboolean __result = (0); if (__str == ((void*)0) || __prefix == ((void *)0)) __result = (g_str_has_prefix) (__str, __prefix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix))); if (__str_len >= __prefix_len) __result = memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0; } __result; }) : (g_str_has_prefix) (link_name, "#") )) { |
70 | if (base_page > 0 && g_str_has_prefix (link_name+1, "+")(__builtin_constant_p ("+")? __extension__ ({ const char * const __str = (link_name+1); const char * const __prefix = ("+"); gboolean __result = (0); if (__str == ((void*)0) || __prefix == ((void *)0)) __result = (g_str_has_prefix) (__str, __prefix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix))); if (__str_len >= __prefix_len) __result = memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0; } __result; }) : (g_str_has_prefix) (link_name+1, "+") )) { |
71 | if (number_from_string_10 (link_name + 2, &page_num)) { |
72 | return base_page + page_num; |
73 | } |
74 | } else if (base_page > 0 && g_str_has_prefix (link_name+1, "-")(__builtin_constant_p ("-")? __extension__ ({ const char * const __str = (link_name+1); const char * const __prefix = ("-"); gboolean __result = (0); if (__str == ((void*)0) || __prefix == ((void *)0)) __result = (g_str_has_prefix) (__str, __prefix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix))); if (__str_len >= __prefix_len) __result = memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0; } __result; }) : (g_str_has_prefix) (link_name+1, "-") )) { |
75 | if (number_from_string_10 (link_name + 2, &page_num)) { |
76 | return base_page - page_num; |
77 | } |
78 | } else { |
79 | if (number_from_string_10 (link_name + 1, &page_num)) { |
80 | return page_num - 1; |
81 | } |
82 | } |
83 | } else { |
84 | /* FIXME: component file identifiers */ |
85 | } |
86 | |
87 | return page_num; |
88 | } |
89 | |
90 | static EvLinkDest * |
91 | get_djvu_link_dest (const DjvuDocument *djvu_document, const gchar *link_name, int base_page) |
92 | { |
93 | return ev_link_dest_new_page (get_djvu_link_page (djvu_document, link_name, base_page)); |
94 | } |
95 | |
96 | static EvLinkAction * |
97 | get_djvu_link_action (const DjvuDocument *djvu_document, const gchar *link_name, int base_page) |
98 | { |
99 | EvLinkDest *ev_dest = NULL((void*)0); |
100 | EvLinkAction *ev_action = NULL((void*)0); |
101 | |
102 | ev_dest = get_djvu_link_dest (djvu_document, link_name, base_page); |
103 | |
104 | if (ev_dest) { |
105 | ev_action = ev_link_action_new_dest (ev_dest); |
106 | } else if (strstr(link_name, "://") != NULL((void*)0)) { |
107 | /* It's probably an URI */ |
108 | ev_action = ev_link_action_new_external_uri (link_name); |
109 | } else { |
110 | /* FIXME: component file identifiers */ |
111 | } |
112 | |
113 | return ev_action; |
114 | } |
115 | |
116 | static gchar * |
117 | str_to_utf8 (const gchar *text) |
118 | { |
119 | static const gchar *encodings_to_try[2]; |
120 | static gint n_encodings_to_try = 0; |
121 | gchar *utf8_text = NULL((void*)0); |
122 | gint i; |
123 | |
124 | if (n_encodings_to_try == 0) { |
125 | const gchar *charset; |
126 | gboolean charset_is_utf8; |
127 | |
128 | charset_is_utf8 = g_get_charset (&charset); |
129 | if (!charset_is_utf8) { |
130 | encodings_to_try[n_encodings_to_try++] = charset; |
131 | } |
132 | |
133 | if (g_ascii_strcasecmp (charset, "ISO-8859-1") != 0) { |
134 | encodings_to_try[n_encodings_to_try++] = "ISO-8859-1"; |
135 | } |
136 | } |
137 | |
138 | for (i = 0; i < n_encodings_to_try; i++) { |
139 | utf8_text = g_convert (text, -1, "UTF-8", |
140 | encodings_to_try[i], |
141 | NULL((void*)0), NULL((void*)0), NULL((void*)0)); |
142 | if (utf8_text) |
143 | break; |
144 | } |
145 | |
146 | return utf8_text; |
147 | } |
148 | |
149 | /** |
150 | * Builds the index CtkTreeModel from DjVu s-expr |
151 | * |
152 | * (bookmarks |
153 | * ("title1" "dest1" |
154 | * ("title12" "dest12" |
155 | * ... ) |
156 | * ... ) |
157 | * ("title2" "dest2" |
158 | * ... ) |
159 | * ... ) |
160 | */ |
161 | static void |
162 | build_tree (const DjvuDocument *djvu_document, |
163 | CtkTreeModel *model, |
164 | CtkTreeIter *parent, |
165 | miniexp_t iter) |
166 | { |
167 | const char *title, *link_dest; |
168 | char *title_markup; |
169 | |
170 | EvLinkAction *ev_action = NULL((void*)0); |
171 | EvLink *ev_link = NULL((void*)0); |
172 | CtkTreeIter tree_iter; |
173 | |
174 | if (miniexp_car (iter) == miniexp_symbol ("bookmarks")) { |
175 | /* The (bookmarks) cons */ |
176 | iter = miniexp_cdr (iter); |
177 | } else if ( miniexp_length (iter) >= 2 ) { |
178 | gchar *utf8_title = NULL((void*)0); |
179 | |
180 | /* An entry */ |
181 | if (!string_from_miniexp (miniexp_car (iter), &title)) goto unknown_entry; |
182 | if (!string_from_miniexp (miniexp_cadr (iter), &link_dest)) goto unknown_entry; |
183 | |
184 | |
185 | if (!g_utf8_validate (title, -1, NULL((void*)0))) { |
186 | utf8_title = str_to_utf8 (title); |
187 | title_markup = g_markup_escape_text (utf8_title, -1); |
188 | } else { |
189 | title_markup = g_markup_escape_text (title, -1); |
190 | } |
191 | |
192 | ev_action = get_djvu_link_action (djvu_document, link_dest, -1); |
193 | |
194 | if (g_str_has_suffix (link_dest, ".djvu")(__builtin_constant_p (".djvu")? __extension__ ({ const char * const __str = (link_dest); const char * const __suffix = (".djvu" ); gboolean __result = (0); if (__str == ((void*)0) || __suffix == ((void*)0)) __result = (g_str_has_suffix) (__str, __suffix ); else { const size_t __str_len = strlen (((__str) + !(__str ))); const size_t __suffix_len = strlen (((__suffix) + !(__suffix ))); if (__str_len >= __suffix_len) __result = memcmp (__str + __str_len - __suffix_len, ((__suffix) + !(__suffix)), __suffix_len ) == 0; } __result; }) : (g_str_has_suffix) (link_dest, ".djvu" ) )) { |
195 | /* FIXME: component file identifiers */ |
196 | } else if (ev_action) { |
197 | ev_link = ev_link_new (utf8_title ? utf8_title : title, ev_action); |
198 | ctk_tree_store_append (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_store_get_type ())))))), &tree_iter, parent); |
199 | ctk_tree_store_set (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_store_get_type ())))))), &tree_iter, |
200 | EV_DOCUMENT_LINKS_COLUMN_MARKUP, title_markup, |
201 | EV_DOCUMENT_LINKS_COLUMN_LINK, ev_link, |
202 | EV_DOCUMENT_LINKS_COLUMN_EXPAND, FALSE(0), |
203 | -1); |
204 | g_object_unref (ev_link); |
205 | } else { |
206 | ctk_tree_store_append (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_store_get_type ())))))), &tree_iter, parent); |
207 | ctk_tree_store_set (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_store_get_type ())))))), &tree_iter, |
208 | EV_DOCUMENT_LINKS_COLUMN_MARKUP, title_markup, |
209 | EV_DOCUMENT_LINKS_COLUMN_EXPAND, FALSE(0), |
210 | -1); |
211 | } |
212 | |
213 | g_free (title_markup); |
214 | g_free (utf8_title); |
215 | iter = miniexp_cddr (iter); |
216 | parent = &tree_iter; |
217 | } else { |
218 | goto unknown_entry; |
219 | } |
220 | |
221 | for (; iter != miniexp_nil((miniexp_t)(size_t)0); iter = miniexp_cdr (iter)) { |
222 | build_tree (djvu_document, model, parent, miniexp_car (iter)); |
223 | } |
224 | return; |
225 | |
226 | unknown_entry: |
227 | g_warning ("DjvuLibre error: Unknown entry in bookmarks"); |
228 | return; |
229 | } |
230 | |
231 | static gboolean |
232 | get_djvu_hyperlink_area (ddjvu_pageinfo_t *page_info, |
233 | miniexp_t sexp, |
234 | EvMapping *ev_link_mapping) |
235 | { |
236 | miniexp_t iter; |
237 | |
238 | iter = sexp; |
239 | |
240 | if ((miniexp_car (iter) == miniexp_symbol ("rect") || miniexp_car (iter) == miniexp_symbol ("oval")) |
241 | && miniexp_length (iter) == 5) { |
242 | /* FIXME: get bounding box for (oval) since Lector doesn't support shaped links */ |
243 | int minx, miny, width, height; |
244 | |
245 | iter = miniexp_cdr (iter); |
246 | if (!number_from_miniexp (miniexp_car (iter), &minx)) goto unknown_link; |
247 | iter = miniexp_cdr (iter); |
248 | if (!number_from_miniexp (miniexp_car (iter), &miny)) goto unknown_link; |
249 | iter = miniexp_cdr (iter); |
250 | if (!number_from_miniexp (miniexp_car (iter), &width)) goto unknown_link; |
251 | iter = miniexp_cdr (iter); |
252 | if (!number_from_miniexp (miniexp_car (iter), &height)) goto unknown_link; |
253 | |
254 | ev_link_mapping->area.x1 = minx; |
255 | ev_link_mapping->area.x2 = (minx + width); |
256 | ev_link_mapping->area.y1 = (page_info->height - (miny + height)); |
257 | ev_link_mapping->area.y2 = (page_info->height - miny); |
258 | } else if (miniexp_car (iter) == miniexp_symbol ("poly") |
259 | && miniexp_length (iter) >= 5 && miniexp_length (iter) % 2 == 1) { |
260 | |
261 | /* FIXME: get bounding box since Lector doesn't support shaped links */ |
262 | int minx = G_MAXINT2147483647, miny = G_MAXINT2147483647; |
263 | int maxx = G_MININT(-2147483647 -1), maxy = G_MININT(-2147483647 -1); |
264 | |
265 | iter = miniexp_cdr(iter); |
266 | while (iter != miniexp_nil((miniexp_t)(size_t)0)) { |
267 | int x, y; |
268 | |
269 | if (!number_from_miniexp (miniexp_car(iter), &x)) goto unknown_link; |
270 | iter = miniexp_cdr (iter); |
271 | if (!number_from_miniexp (miniexp_car(iter), &y)) goto unknown_link; |
272 | iter = miniexp_cdr (iter); |
273 | |
274 | minx = MIN (minx, x)(((minx) < (x)) ? (minx) : (x)); |
275 | miny = MIN (miny, y)(((miny) < (y)) ? (miny) : (y)); |
276 | maxx = MAX (maxx, x)(((maxx) > (x)) ? (maxx) : (x)); |
277 | maxy = MAX (maxy, y)(((maxy) > (y)) ? (maxy) : (y)); |
278 | } |
279 | |
280 | ev_link_mapping->area.x1 = minx; |
281 | ev_link_mapping->area.x2 = maxx; |
282 | ev_link_mapping->area.y1 = (page_info->height - maxy); |
283 | ev_link_mapping->area.y2 = (page_info->height - miny); |
284 | } else { |
285 | /* unknown */ |
286 | goto unknown_link; |
287 | } |
288 | |
289 | return TRUE(!(0)); |
290 | |
291 | unknown_link: |
292 | g_warning("DjvuLibre error: Unknown hyperlink area %s", miniexp_to_name(miniexp_car(sexp))); |
293 | return FALSE(0); |
294 | } |
295 | |
296 | static EvMapping * |
297 | get_djvu_hyperlink_mapping (DjvuDocument *djvu_document, |
298 | int page, |
299 | ddjvu_pageinfo_t *page_info, |
300 | miniexp_t sexp) |
301 | { |
302 | EvMapping *ev_link_mapping = NULL((void*)0); |
303 | EvLinkAction *ev_action = NULL((void*)0); |
304 | miniexp_t iter; |
305 | const char *url, *url_target, *comment; |
306 | |
307 | ev_link_mapping = g_new (EvMapping, 1)((EvMapping *) g_malloc_n ((1), sizeof (EvMapping))); |
308 | |
309 | iter = sexp; |
310 | |
311 | if (miniexp_car (iter) != miniexp_symbol ("maparea")) goto unknown_mapping; |
312 | |
313 | iter = miniexp_cdr(iter); |
314 | |
315 | if (miniexp_caar(iter) == miniexp_symbol("url")) { |
316 | if (!string_from_miniexp (miniexp_cadr (miniexp_car (iter)), &url)) goto unknown_mapping; |
317 | if (!string_from_miniexp (miniexp_caddr (miniexp_car (iter)), &url_target)) goto unknown_mapping; |
318 | } else { |
319 | if (!string_from_miniexp (miniexp_car(iter), &url)) goto unknown_mapping; |
320 | url_target = NULL((void*)0); |
321 | } |
322 | |
323 | iter = miniexp_cdr (iter); |
324 | if (!string_from_miniexp (miniexp_car(iter), &comment)) goto unknown_mapping; |
325 | |
326 | iter = miniexp_cdr (iter); |
327 | if (!get_djvu_hyperlink_area (page_info, miniexp_car(iter), ev_link_mapping)) goto unknown_mapping; |
328 | |
329 | iter = miniexp_cdr (iter); |
Value stored to 'iter' is never read | |
330 | /* FIXME: DjVu hyperlink attributes are ignored */ |
331 | |
332 | ev_action = get_djvu_link_action (djvu_document, url, page); |
333 | if (!ev_action) goto unknown_mapping; |
334 | |
335 | ev_link_mapping->data = ev_link_new (comment, ev_action); |
336 | |
337 | return ev_link_mapping; |
338 | |
339 | unknown_mapping: |
340 | if (ev_link_mapping) g_free(ev_link_mapping); |
341 | g_warning("DjvuLibre error: Unknown hyperlink %s", miniexp_to_name(miniexp_car(sexp))); |
342 | return NULL((void*)0); |
343 | } |
344 | |
345 | |
346 | gboolean |
347 | djvu_links_has_document_links (EvDocumentLinks *document_links) |
348 | { |
349 | DjvuDocument *djvu_document = DJVU_DOCUMENT (document_links)((((DjvuDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document_links)), ((djvu_document_get_type ())))))); |
350 | miniexp_t outline; |
351 | |
352 | while ((outline = ddjvu_document_get_outline (djvu_document->d_document)) == miniexp_dummy((miniexp_t)(size_t)2)) |
353 | djvu_handle_events (djvu_document, TRUE(!(0)), NULL((void*)0)); |
354 | |
355 | if (outline) { |
356 | ddjvu_miniexp_release (djvu_document->d_document, outline); |
357 | return TRUE(!(0)); |
358 | } |
359 | |
360 | return FALSE(0); |
361 | } |
362 | |
363 | EvMappingList * |
364 | djvu_links_get_links (EvDocumentLinks *document_links, |
365 | gint page, |
366 | double scale_factor) |
367 | { |
368 | DjvuDocument *djvu_document = DJVU_DOCUMENT (document_links)((((DjvuDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document_links)), ((djvu_document_get_type ())))))); |
369 | GList *retval = NULL((void*)0); |
370 | miniexp_t page_annotations = miniexp_nil((miniexp_t)(size_t)0); |
371 | miniexp_t *hyperlinks = NULL((void*)0), *iter = NULL((void*)0); |
372 | EvMapping *ev_link_mapping; |
373 | ddjvu_pageinfo_t page_info; |
374 | |
375 | while ((page_annotations = ddjvu_document_get_pageanno (djvu_document->d_document, page)) == miniexp_dummy((miniexp_t)(size_t)2)) |
376 | djvu_handle_events (djvu_document, TRUE(!(0)), NULL((void*)0)); |
377 | |
378 | while (ddjvu_document_get_pageinfo (djvu_document->d_document, page, &page_info)ddjvu_document_get_pageinfo_imp(djvu_document->d_document, page,&page_info,sizeof(ddjvu_pageinfo_t)) < DDJVU_JOB_OK) |
379 | djvu_handle_events(djvu_document, TRUE(!(0)), NULL((void*)0)); |
380 | |
381 | if (page_annotations) { |
382 | hyperlinks = ddjvu_anno_get_hyperlinks (page_annotations); |
383 | if (hyperlinks) { |
384 | for (iter = hyperlinks; *iter; ++iter) { |
385 | ev_link_mapping = get_djvu_hyperlink_mapping (djvu_document, page, &page_info, *iter); |
386 | if (ev_link_mapping) { |
387 | ev_link_mapping->area.x1 *= scale_factor; |
388 | ev_link_mapping->area.x2 *= scale_factor; |
389 | ev_link_mapping->area.y1 *= scale_factor; |
390 | ev_link_mapping->area.y2 *= scale_factor; |
391 | retval = g_list_prepend (retval, ev_link_mapping); |
392 | } |
393 | } |
394 | free (hyperlinks); |
395 | } |
396 | ddjvu_miniexp_release (djvu_document->d_document, page_annotations); |
397 | } |
398 | |
399 | return ev_mapping_list_new (page, retval, (GDestroyNotify)g_object_unref); |
400 | } |
401 | |
402 | EvLinkDest * |
403 | djvu_links_find_link_dest (EvDocumentLinks *document_links, |
404 | const gchar *link_name) |
405 | { |
406 | DjvuDocument *djvu_document = DJVU_DOCUMENT (document_links)((((DjvuDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document_links)), ((djvu_document_get_type ())))))); |
407 | EvLinkDest *ev_dest = NULL((void*)0); |
408 | |
409 | ev_dest = get_djvu_link_dest (djvu_document, link_name, -1); |
410 | |
411 | if (!ev_dest) { |
412 | g_warning ("DjvuLibre error: unknown link destination %s", link_name); |
413 | } |
414 | |
415 | return ev_dest; |
416 | } |
417 | |
418 | gint |
419 | djvu_links_find_link_page (EvDocumentLinks *document_links, |
420 | const gchar *link_name) |
421 | { |
422 | DjvuDocument *djvu_document = DJVU_DOCUMENT (document_links)((((DjvuDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document_links)), ((djvu_document_get_type ())))))); |
423 | gint page; |
424 | |
425 | page = get_djvu_link_page (djvu_document, link_name, -1); |
426 | |
427 | if (page == -1) { |
428 | g_warning ("DjvuLibre error: unknown link destination %s", link_name); |
429 | } |
430 | |
431 | return page; |
432 | } |
433 | |
434 | CtkTreeModel * |
435 | djvu_links_get_links_model (EvDocumentLinks *document_links) |
436 | { |
437 | DjvuDocument *djvu_document = DJVU_DOCUMENT (document_links)((((DjvuDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document_links)), ((djvu_document_get_type ())))))); |
438 | CtkTreeModel *model = NULL((void*)0); |
439 | miniexp_t outline = miniexp_nil((miniexp_t)(size_t)0); |
440 | |
441 | while ((outline = ddjvu_document_get_outline (djvu_document->d_document)) == miniexp_dummy((miniexp_t)(size_t)2)) |
442 | djvu_handle_events (djvu_document, TRUE(!(0)), NULL((void*)0)); |
443 | |
444 | if (outline) { |
445 | model = (CtkTreeModel *) ctk_tree_store_new (EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS, |
446 | G_TYPE_STRING((GType) ((16) << (2))), |
447 | G_TYPE_OBJECT((GType) ((20) << (2))), |
448 | G_TYPE_BOOLEAN((GType) ((5) << (2))), |
449 | G_TYPE_STRING((GType) ((16) << (2)))); |
450 | build_tree (djvu_document, model, NULL((void*)0), outline); |
451 | |
452 | ddjvu_miniexp_release (djvu_document->d_document, outline); |
453 | } |
454 | |
455 | return model; |
456 | } |