+ * A compressed resource in a WIM consists of a number of consecutive LZX or
+ * XPRESS-compressed chunks, each of which decompresses to 32768 bytes of data,
+ * except possibly the last, which always decompresses to any remaining bytes.
+ * In addition, immediately before the chunks, a table (the "chunk table")
+ * provides the offset, in bytes relative to the end of the chunk table, of the
+ * start of each compressed chunk, except for the first chunk which is omitted
+ * as it always has an offset of 0. Therefore, a compressed resource with N
+ * chunks will have a chunk table with N - 1 entries.
+ *
+ * Additional information:
+ *
+ * - Entries in the chunk table are 4 bytes each, except if the uncompressed
+ * size of the resource is greater than 4 GiB, in which case the entries in
+ * the chunk table are 8 bytes each. In either case, the entries are unsigned
+ * little-endian integers.
+ *
+ * - The chunk table is included in the compressed size of the resource provided
+ * in the corresponding entry in the WIM's stream lookup table.
+ *
+ * - The compressed size of a chunk is never greater than the uncompressed size.
+ * From the compressor's point of view, chunks that would have compressed to a
+ * size greater than or equal to their original size are in fact stored
+ * uncompressed. From the decompresser's point of view, chunks with
+ * compressed size equal to their uncompressed size are in fact uncompressed.
+ *
+ * Furthermore, wimlib supports its own "pipable" WIM format, and for this the
+ * structure of compressed resources was modified to allow piped reading and
+ * writing. To make sequential writing possible, the chunk table is placed
+ * after the chunks rather than before the chunks, and to make sequential
+ * reading possible, each chunk is prefixed with a 4-byte header giving its
+ * compressed size as a 32-bit, unsigned, little-endian integer (less than or
+ * equal to 32768). Otherwise the details are the same.
+ */
+
+typedef int (*decompress_func_t)(const void *, unsigned, void *, unsigned);
+
+static decompress_func_t
+get_decompress_func(int ctype)
+{
+ if (ctype == WIMLIB_COMPRESSION_TYPE_LZX)
+ return wimlib_lzx_decompress;
+ else
+ return wimlib_xpress_decompress;
+}
+
+/*
+ * read_compressed_resource()-
+ *
+ * Read data from a compressed resource being read from a seekable WIM file.
+ * The resource may be either pipable or non-pipable.
+ *
+ * @flags may be:
+ *
+ * 0:
+ * Just do a normal read, decompressing the data if necessary.
+ *
+ * WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS:
+ * Read the raw contents of the compressed chunks of the compressed
+ * resource. For pipable resources, this does *not* include the chunk
+ * headers. If a callback function is being used, it will be called once
+ * for each compressed chunk. For non-pipable resources, this mode
+ * excludes the chunk table. For pipable resources, this mode excludes the
+ * stream and chunk headers.