+
+/* Extract the first @size bytes of the specified blob to the specified file
+ * descriptor. This does *not* check the SHA-1 message digest. */
+int
+extract_blob_prefix_to_fd(struct blob_descriptor *blob, u64 size,
+ struct filedes *fd)
+{
+ struct read_blob_callbacks cbs = {
+ .consume_chunk = extract_chunk_to_fd,
+ .ctx = fd,
+ };
+ return read_blob_prefix(blob, size, &cbs);
+}
+
+/* Extract the full uncompressed contents of the specified blob to the specified
+ * file descriptor. This checks the SHA-1 message digest. */
+int
+extract_blob_to_fd(struct blob_descriptor *blob, struct filedes *fd)
+{
+ struct read_blob_callbacks cbs = {
+ .consume_chunk = extract_chunk_to_fd,
+ .ctx = fd,
+ };
+ return read_blob_with_sha1(blob, &cbs);
+}
+
+/* Calculate the SHA-1 message digest of a blob and store it in @blob->hash. */
+int
+sha1_blob(struct blob_descriptor *blob)
+{
+ struct read_blob_callbacks cbs = {
+ };
+ return read_blob_with_sha1(blob, &cbs);
+}
+
+/*
+ * Convert a short WIM resource header to a stand-alone WIM resource descriptor.
+ *
+ * Note: for solid resources some fields still need to be overridden.
+ */
+void
+wim_reshdr_to_desc(const struct wim_reshdr *reshdr, WIMStruct *wim,
+ struct wim_resource_descriptor *rdesc)
+{
+ rdesc->wim = wim;
+ rdesc->offset_in_wim = reshdr->offset_in_wim;
+ rdesc->size_in_wim = reshdr->size_in_wim;
+ rdesc->uncompressed_size = reshdr->uncompressed_size;
+ INIT_LIST_HEAD(&rdesc->blob_list);
+ rdesc->flags = reshdr->flags;
+ rdesc->is_pipable = wim_is_pipable(wim);
+ if (rdesc->flags & WIM_RESHDR_FLAG_COMPRESSED) {
+ rdesc->compression_type = wim->compression_type;
+ rdesc->chunk_size = wim->chunk_size;
+ } else {
+ rdesc->compression_type = WIMLIB_COMPRESSION_TYPE_NONE;
+ rdesc->chunk_size = 0;
+ }
+}
+
+/*
+ * Convert the short WIM resource header @reshdr to a stand-alone WIM resource
+ * descriptor @rdesc, then set @blob to consist of that entire resource. This
+ * should only be used for non-solid resources!
+ */
+void
+wim_reshdr_to_desc_and_blob(const struct wim_reshdr *reshdr, WIMStruct *wim,
+ struct wim_resource_descriptor *rdesc,
+ struct blob_descriptor *blob)
+{
+ wim_reshdr_to_desc(reshdr, wim, rdesc);
+ blob->size = rdesc->uncompressed_size;
+ blob_set_is_located_in_wim_resource(blob, rdesc, 0);
+}
+
+/* Import a WIM resource header from the on-disk format. */
+void
+get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr,
+ struct wim_reshdr *reshdr)
+{
+ 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;
+}
+
+/* Export a WIM resource header to the on-disk format. */
+void
+put_wim_reshdr(const struct wim_reshdr *reshdr,
+ struct wim_reshdr_disk *disk_reshdr)
+{
+ 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);
+}