+ return ret;
+}
+
+/* Convert a WIM resource header to a stand-alone resource specification. */
+void
+wim_res_hdr_to_spec(const struct wim_reshdr *reshdr, WIMStruct *wim,
+ struct wim_resource_spec *spec)
+{
+ spec->wim = wim;
+ spec->offset_in_wim = reshdr->offset_in_wim;
+ spec->size_in_wim = reshdr->size_in_wim;
+ spec->uncompressed_size = reshdr->uncompressed_size;
+ INIT_LIST_HEAD(&spec->lte_list);
+ spec->flags = reshdr->flags;
+ spec->is_pipable = wim_is_pipable(wim);
+ if (spec->flags & (WIM_RESHDR_FLAG_COMPRESSED | WIM_RESHDR_FLAG_CONCAT)) {
+ spec->ctype = wim->compression_type;
+ spec->cchunk_size = wim->chunk_size;
+ } else {
+ spec->ctype = WIMLIB_COMPRESSION_TYPE_NONE;
+ spec->cchunk_size = 0;
+ }
+}
+
+/* Convert a stand-alone resource specification to a WIM resource header. */
+void
+wim_res_spec_to_hdr(const struct wim_resource_spec *rspec,
+ struct wim_reshdr *reshdr)
+{
+ reshdr->offset_in_wim = rspec->offset_in_wim;
+ reshdr->size_in_wim = rspec->size_in_wim;
+ reshdr->flags = rspec->flags;
+ reshdr->uncompressed_size = rspec->uncompressed_size;
+}
+
+/* Translates a WIM resource header from the on-disk format into an in-memory
+ * format. */
+void
+get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr,
+ struct wim_reshdr *reshdr)
+{
+ /* Note: disk_reshdr may not be 8 byte aligned--- in that case, the
+ * offset and original_size members will be unaligned. (This is okay
+ * since `struct resource_reshdr_disk' is declared as packed.) */
+
+ reshdr->offset_in_wim = le64_to_cpu(disk_reshdr->offset_in_wim);
+ reshdr->size_in_wim = (((u64)disk_reshdr->size_in_wim[0] << 0) |
+ ((u64)disk_reshdr->size_in_wim[1] << 8) |
+ ((u64)disk_reshdr->size_in_wim[2] << 16) |
+ ((u64)disk_reshdr->size_in_wim[3] << 24) |
+ ((u64)disk_reshdr->size_in_wim[4] << 32) |
+ ((u64)disk_reshdr->size_in_wim[5] << 40) |
+ ((u64)disk_reshdr->size_in_wim[6] << 48));
+ reshdr->uncompressed_size = le64_to_cpu(disk_reshdr->uncompressed_size);
+ reshdr->flags = disk_reshdr->flags;
+
+ /* Truncate numbers to 62 bits to avoid possible overflows. */
+ if (reshdr->offset_in_wim & 0xc000000000000000ULL) {
+ WARNING("Truncating offset in resource reshdr");
+ reshdr->offset_in_wim &= 0x3fffffffffffffffULL;
+ }
+ if (reshdr->uncompressed_size & 0xc000000000000000ULL) {
+ WARNING("Truncating original_size in resource reshdr");
+ reshdr->uncompressed_size &= 0x3fffffffffffffffULL;
+ }
+}
+
+/* Translates a WIM resource header from an in-memory format into the on-disk
+ * format. */
+void
+put_wim_reshdr(const struct wim_reshdr *reshdr,
+ struct wim_reshdr_disk *disk_reshdr)
+{
+ /* Note: disk_reshdr may not be 8 byte aligned--- in that case, the
+ * offset and original_size members will be unaligned. (This is okay
+ * since `struct resource_reshdr_disk' is declared as packed.) */
+ disk_reshdr->size_in_wim[0] = reshdr->size_in_wim >> 0;
+ disk_reshdr->size_in_wim[1] = reshdr->size_in_wim >> 8;
+ disk_reshdr->size_in_wim[2] = reshdr->size_in_wim >> 16;
+ disk_reshdr->size_in_wim[3] = reshdr->size_in_wim >> 24;
+ disk_reshdr->size_in_wim[4] = reshdr->size_in_wim >> 32;
+ disk_reshdr->size_in_wim[5] = reshdr->size_in_wim >> 40;
+ disk_reshdr->size_in_wim[6] = reshdr->size_in_wim >> 48;
+ disk_reshdr->flags = reshdr->flags;
+ disk_reshdr->offset_in_wim = cpu_to_le64(reshdr->offset_in_wim);
+ disk_reshdr->uncompressed_size = cpu_to_le64(reshdr->uncompressed_size);