Minor refactoring of the IFF and box-format parsers
[deark.git] / technical.md
blob568a1dff3e33f8a3feb4598ef826a27b1ee4b804
1 # Technical information about Deark #
3 This document is a supplement to the information in the [readme.md](readme.md)
4 file.
6 ## Mission statement ##
8 Deark has several related purposes:
10 * To find interesting things that are stored in files, but usually ignored,
11 such as thumbnail images and comments.
13 * To rescue data from uncommon file formats, and to be a convenient way to
14 decode many different formats.
16 * The "-d" option is a core feature, and can help to learn about a file and its
17 format, whether or not anything is extracted from it.
19 * Digital preservation of information about file formats. Its source code
20 encapsulates information about some formats that might otherwise be hard to
21 find.
23 There's not much rhyme or reason to the formats Deark supports, or to its
24 features. It exists mainly because I've written too many one-off programs to
25 decode file formats, and wanted to put everything in one place. Part of the
26 goal is to support (mainly old) formats that are under-served by other
27 open-source software. Many of the formats it currently supports are related to
28 graphics, but it is not limited to graphics formats.
30 One guideline is that any image format supported by the XnView image viewer,
31 and not by any well-maintained open source software, is a candidate for being
32 supported, no matter how obscure it may be.
34 ## Security ##
36 Deark is intended to be safe to use with untrusted input files, but there are
37 no promises. It is written in C, and vulnerabilities very likely exist.
39 A strategically-designed input file can definitely cause Deark to use a
40 disproportionate amount of system resources, such as disk space or CPU time.
41 Deark does enforce some resource limits, but not consistently. This is a
42 difficult problem to solve.
44 ## The filename problem ##
46 When Deark writes a file, it has to decide what to name it. This can be a very
47 difficult problem. For one thing, what is and is not a valid filename depends
48 on the user's platform, and the relevant filesystem type. For another thing,
49 there are security hazards everywhere. Deark should not try to write a file
50 named "/etc/passwd", for example.
52 Also, there are a near-limitless number of reasonable ways to construct an
53 output filename, with an elaborate decision tree to select the best behavior
54 in various circumstances.
56 Deark essentially throws up its hands and gives up. By default, it names all
57 output filenames to start with "output.". It overwrites existing files with no
58 warning (unless you use -n). It bans all ASCII characters that could
59 conceivably be problematical, as well as any non-ASCII characters that don't
60 appear on its whitelist.
62 When Deark writes to a ZIP or tar file (the "-zip"/"-tar" option), it doesn't
63 have to worry about what to name the internal files. It can palm that problem
64 off onto your unzip/untar program. It is more tolerant in this case.
66 Directory paths are only maintained as such if you use -zip/-tar (and you don't
67 use "-opt archive:subdirs=0"). Deark generally does not write a file anywhere
68 other than the current directory, though you can tell it to do so with -od, or
69 with other options such as -arcfn or -k3.
71 ## The "Is this one format or two?" problem ##
73 It's often hard to decide whether a format should get its own module, or be a
74 part of some other module. Deark has some guidelines for this, but doesn't
75 always follow them consistently.
77 Modules are not supposed to make use of the input filename, except during
78 format detection. So if two formats can't be distinguished in any other way,
79 they generally have to be placed in separate modules. 
81 ## Format detection ##
83 If the user does not use the "-m" option, then Deark will try to guess the best
84 module to use. It prefers to do this using only the contents of the file, but
85 unfortunately, there are many file formats that cannot realistically be
86 identified in such a way. So, in some cases, Deark also uses the filename,
87 especially the filename extension.
89 It does not use any other file attributes, such as the last-modified time or
90 the executable-flag; though this could change in future versions.
92 The filename is only used for format detection, and not for any other purpose.
93 This helps make its behavior safe and predictable. The options -m, -start, and
94 -fromstdin are among those that might need special cases added, if that were
95 not the case.
97 This behavior *might* be changed in the future (as an option?), because some
98 formats store important information in the filename, and having a separate
99 module for each possibility isn't always feasible. For example, with Unix
100 compress format, there is no other way to construct a good output filename, so
101 Deark has to settle for a generic name like "output.000.bin".
103 ## Character encoding (console) ##
105 The "-d" option prints a lot of textual information to the console, some of
106 which is not ASCII-compatible. Non-ASCII text can sometimes cause problems.
108 On Windows, Deark generally does the right thing automatically. However, if you
109 are redirecting the output to a file or a pipe, there are cases where the
110 "-enc" option can be helpful. 
112 On Unix-like platforms, UTF-8 output will be written to the terminal,
113 regardless of your LANG (etc.) environment variable. You can use "-enc ascii"
114 to print only ASCII. (This is not ideal, but seriously, it's time to switch to
115 UTF-8 if at all possible.)
117 On Unix-like platforms, command-line parameters are assumed to be in UTF-8.
119 ## Character encoding (output files) ##
121 When Deark generates a text file, its preferred encoding is UTF-8, with a BOM
122 (unless you use "-nobom"). But there are many cases where it can't do that,
123 because the original encoding is undefined, unsupported, or incompatible with
124 Unicode. In such cases, it just writes out the original bytes as they are.
126 If the text was already encoded in UTF-8, Deark does not behave perfectly
127 consistently. Some modules copy the bytes as they are, while other sanitize
128 them first.
130 Deark keeps the end-of-line characters as they are in the original file. If it
131 has to generate end-of-line characters of its own, it uses Unix-style line-feed
132 characters.
134 ## Executable output files ##
136 Most file attributes (such as file ownership) are ignored when extracting
137 files, but Deark does try to maintain the "executable" status of output
138 files, for formats which store this attribute. The Windows version of Deark
139 does not use this information, except when writing to a ZIP/tar file.
141 This is a simple yes/no flag. It does not distinguish between
142 owner-executable and world-executable, for example.
144 ## Directory "files" and empty directories ##
146 Some archive formats contain independent representations of subdirectores,
147 allowing empty directories, and directory attributes, to be stored. By default,
148 Deark retains these entries when writing to a ZIP/tar file, and otherwise
149 ignores them. This behavior can be changed with "-opt keepdirentries". Even so,
150 Deark never creates directories directly. Instead, it may create marker files
151 with a ".dir" extension.
153 Note that this means the -zip/-tar option can affect the numbering of output
154 files used by, e.g., the -get option.
156 ## Modification times ##
158 In certain cases, Deark tries to maintain the modification time (and to a
159 lesser degree, other timestamps) of the original file. This only happens with
160 timestamps contained inside the input file.
162 If a timestamp does not include a time zone, the time will be assumed to be in
163 Universal Time (UTC), unless the -intz option was used. Deark is expected to be
164 used with files that were created long ago and far away, so it never assumes
165 that the Deark user's time zone is relevant.
167 Note that if you are extracting to a system that does not store file times in
168 UTC (often the case on Windows), the timestamps may not be very accurate.
170 ## Modification times and thumbnails ##
172 Some thumbnail image formats store the last-modified time of the original file.
173 This raises the question of whether Deark should use this as the last-modified
174 time of the extracted thumbnail file. Currently, Deark *does* do this, but it
175 must be acknowledged that there's something not quite right about it, because
176 the thumbnail may have been created much later than the original image.
178 ## The .iptctiff and .8bimtiff formats ##
180 In some cases, Deark saves IPTC-IIM metadata, or Photoshop Resources (also
181 semi-incorrectly known as "8BIM"), to a file. These data formats don't have a
182 good *file* format to use, so Deark wraps them in a minimal TIFF-based
183 container. You can reprocess this container file with Deark, and it may decode
184 the data (use -d), or extract the raw data to a file.
186 ## AppleDouble format ##
188 In most cases, Deark writes Macintosh resource forks to AppleDouble format. It
189 considers this to be its preferred format for resource forks. You have to use
190 an option, if you want it to write the fork in raw form.
192 It gives AppleDouble output files an ".adf" file extension. Although this is
193 one of the conventions suggested in the AppleDouble specification, it is not
194 commonly used. The other naming conventions don't play well with Deark's naming
195 conventions.
197 Another problem is that, because Deark gives each output file a unique prefix
198 like "output.NNN", the AppleDouble file and its associated data fork will not
199 have the same base filename, further reducing the chance that other systems
200 will treat them as a unit. There's no good fix for this, though you may be able
201 to avoid it by using the -zip option.
203 ## PNG htSP chunks ##
205 When decoding mouse cursor graphics, Deark sometimes records the cursor's
206 "hotspot" in the resulting PNG image, in a custom "htSP" chunk. The htSP
207 chunk's format is explained here.
209 The chunk type is "htSP": hex [68 74 53 50].
211 The chunk data field length is 24 or more bytes. Encoders must write exactly 24
212 bytes. Decoders must ignore any bytes after the first 24.
214 The first 16 bytes of the data field are an arbitrary signature UUID: hex [b9
215 fe 4f 3d 8f 32 45 6f aa 02 dc d7 9c ce 0e 24]. This represents the UUID
216 b9fe4f3d-8f32-456f-aa02-dcd79cce0e24. If the first 16 bytes are not exactly
217 this signature, the chunk does not conform to this specification.
219 At most one htSP chunk with this signature may appear in a PNG file. The chunk
220 must appear before the IDAT chunks.
222 After the signature are two 4-byte fields: The X coordinate at offset 16, then
223 the Y coordinate at offset 20. Each is stored as a "PNG four-byte signed
224 integer" (big-endian, two's complement).
226 The X coordinate is the number of pixels the hotspot is to the right of the
227 image's leftmost column of pixels. (If the hotspot is in the leftmost column,
228 then its coordinate is 0). The Y coordinate is the number of pixels the hotspot
229 is below the image's topmost row of pixels. It is legal for the hotspot to be
230 beyond the bounds of the image.
232 The hotspot is conceptually an entire pixel (or virtual pixel), not a specific
233 point in some coordinate system. If more precision is needed, assume the
234 hotspot is the center of that pixel. This means that if a 16x16-pixel image
235 with hotspot (0,0) were to be mirrored left-right, the new hotspot would be
236 (15,0), not (16,0) as it would be if the hotspot were the upper-left corner of
237 the pixel.
239 ## I've never heard of that format! ##
241 For the identities of the formats supported by Deark, see
243 - [File format wiki: Electronic File Formats](http://fileformats.archiveteam.org/wiki/Electronic_File_Formats)
244 - [File format wiki: Graphics](http://fileformats.archiveteam.org/wiki/Graphics)
246 ## Other information ##
248 By design, Deark does not look at any files that don't explicitly appear on the
249 command line. In the future, there might be an option to change this behavior,
250 and automatically try to find related files.
252 Bitmap fonts are converted to images. Someday, there might be an option to
253 convert them to some portable font format, but that is difficult to do well.
255 ## How to build ##
257 Deark is written in C. On a Unix-like system, typing "make" from a shell prompt
258 will (hopefully) be sufficient:
260     $ make
262 This will build an executable file named "deark". Deark has no dependencies,
263 other than the standard C libraries.
265 One way to configure the build is by setting certain environment variables. See
266 the scripts at scripts/example-build-* for examples.
268 Another way is to create Makefile fragment files named local1.mk and/or
269 local2.mk.
271 Some C-language-level configuration can be done by creating a file named
272 src/deark-config2.h, and adding -DDE_USE_CONFIG2_H to the CFLAGS variable in
273 the Makefile.
275 It is safe to build Deark using "parallel make", i.e. "make -j". This will
276 speed up the build, in most cases.
278 If you want to install it in a convenient location, just copy the "deark" file.
279 For example:
281     $ sudo cp deark /usr/local/bin/
283     $ sudo make install
285 For Microsoft Windows, the project files in proj/vs2019 should work for
286 sufficiently new versions of Microsoft Visual Studio. Alternatively, you can
287 use Cygwin.
289 When doing a Windows (Win32 API) build, the Makefile is not intended to be used
290 directly (without configuration). For MinGW and similar compilers, it is
291 recommended to use a script (e.g. scripts/example-build-mingw.sh) or local*.mk
292 files.
294 Note that for Windows, Deark unconditionally uses Unicode API functions like
295 fputws() and GetFileAttributesW(), so it's not possible to do a "non-Unicode"
296 build.
298 ## Developer notes ##
300 ### Coding style and C language ###
302 The C language version that Deark uses is not rigidly defined, but it should
303 be compatible with most modern compilers, without special options.
305 It is mostly compatible with a rather old version of C, almost C89 but with
306 "//" comments. But that's subject to change. For instance, putting declarations
307 only at the beginning of functions is no longer required (Deark used to be
308 tested on a compiler that required it), though it is still often done out of
309 habit.
311 ### Other notes ###
313 Maximizing execution speed is not a goal of Deark. This is a deliberate
314 concession. The focus is on making the code easy to write, easy to read, and to
315 minimize the chance of bugs. (Serious performace issues will still be
316 addressed, though.)
318 The Deark executable size is a consideration. A suggested feature might be
319 declined if it would involve too much bloat.
321 Deark is intended to be compiled as a 64-bit application. It uses 64-bit
322 integers pervasively. It can be compiled as a 32-bit app (provided the compiler
323 has a 64-bit integer type), and it will operate correctly. But it will be very
324 inefficient, and might run at less than half the 64-bit speed.
326 The Deark source code is structured like a library, but it's not intended to be
327 used as such. The error handling methods, and error messages, are not really
328 suitable for use in a library.
330 A regression test suite does exist for Deark, but is not available publicly at
331 this time.