zip: Better parsing of Info-ZIP type 1 extra field
[deark.git] / modules / autocad.c
blob51fb6a6a45d7f94cdb301b5cd3e23f6a5137be64
1 // This file is part of Deark.
2 // Copyright (C) 2017 Jason Summers
3 // See the file COPYING for terms of use.
5 // AutoCAD Slide Library (.slb)
7 #include <deark-config.h>
8 #include <deark-private.h>
9 DE_DECLARE_MODULE(de_module_autocad_slb);
11 static void de_run_autocad_slb(deark *c, de_module_params *mparams)
13 i64 pos;
14 i64 nslides = 0;
15 i64 k;
16 struct slideinfo {
17 i64 pos;
18 i64 len;
20 i64 si_numalloc;
21 struct slideinfo *si = NULL;
22 de_ucstring *slidename = NULL;
24 de_dbg(c, "[pass 1: recording addresses]");
25 si_numalloc = 64;
26 si = de_mallocarray(c, si_numalloc, sizeof(struct slideinfo));
27 pos = 32;
28 while(1) {
29 i64 k;
31 if(pos > (c->infile->len-36)) {
32 de_err(c, "Unterminated directory");
33 goto done;
35 if(de_getbyte(pos)==0) {
36 break;
39 k = nslides; // Index of the new slide
40 nslides++;
42 if(nslides > si_numalloc) {
43 i64 old_numalloc, new_numalloc;
45 if(!de_good_image_count(c, nslides)) {
46 de_err(c, "Too many slides");
47 goto done;
49 old_numalloc = si_numalloc;
50 new_numalloc = old_numalloc*2;
51 si = de_reallocarray(c, si, old_numalloc, sizeof(struct slideinfo),
52 new_numalloc);
53 si_numalloc *= new_numalloc;
56 si[k].pos = de_getu32le(pos+32);
58 if(si[k].pos > c->infile->len) {
59 de_err(c, "Invalid directory");
60 goto done;
62 if(k>0) {
63 if(si[k].pos < si[k-1].pos) {
64 de_err(c, "Invalid directory");
65 goto done;
69 if(k>0) {
70 // Set the previous slide's length.
71 si[k-1].len = si[k].pos - si[k-1].pos;
73 // Start by assuming this slide ends at the end of the file. If this
74 // turns out not to be the last slide, this value will be changed later.
75 si[k].len = c->infile->len - si[k].pos;
77 pos += 36;
80 de_dbg(c, "[pass 2: extracting slides]");
81 pos = 32;
82 slidename = ucstring_create(c);
83 for(k=0; k<nslides; k++) {
84 de_finfo *fi = NULL;
86 de_dbg(c, "slide dir entry at %d", (int)pos);
87 de_dbg_indent(c, 1);
89 ucstring_empty(slidename);
90 dbuf_read_to_ucstring(c->infile, pos, 31, slidename,
91 DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII);
93 de_dbg(c, "address: %u", (unsigned int)si[k].pos);
94 de_dbg(c, "calculated len: %u", (unsigned int)si[k].len);
96 fi = de_finfo_create(c);
97 de_finfo_set_name_from_ucstring(c, fi, slidename, 0);
98 dbuf_create_file_from_slice(c->infile, si[k].pos, si[k].len, "sld", fi, 0);
99 de_finfo_destroy(c, fi);
101 de_dbg_indent(c, -1);
102 pos += 36;
105 done:
106 ucstring_destroy(slidename);
107 de_free(c, si);
110 static int de_identify_autocad_slb(deark *c)
112 if(!dbuf_memcmp(c->infile, 0, "AutoCAD Slide Library 1.0\r\n\x1a", 28))
113 return 100;
114 return 0;
117 void de_module_autocad_slb(deark *c, struct deark_module_info *mi)
119 mi->id = "autocad_slb";
120 mi->desc = "AutoCAD Slide Library";
121 mi->run_fn = de_run_autocad_slb;
122 mi->identify_fn = de_identify_autocad_slb;