+static int
+cmp_streams_by_out_rspec(const void *p1, const void *p2)
+{
+ const struct wim_lookup_table_entry *lte1, *lte2;
+
+ lte1 = *(const struct wim_lookup_table_entry**)p1;
+ lte2 = *(const struct wim_lookup_table_entry**)p2;
+
+ if (lte1->out_reshdr.flags & WIM_RESHDR_FLAG_PACKED_STREAMS) {
+ if (lte2->out_reshdr.flags & WIM_RESHDR_FLAG_PACKED_STREAMS) {
+ if (lte1->out_res_offset_in_wim != lte2->out_res_offset_in_wim)
+ return cmp_u64(lte1->out_res_offset_in_wim,
+ lte2->out_res_offset_in_wim);
+ } else {
+ return 1;
+ }
+ } else {
+ if (lte2->out_reshdr.flags & WIM_RESHDR_FLAG_PACKED_STREAMS)
+ return -1;
+ }
+ return cmp_u64(lte1->out_reshdr.offset_in_wim,
+ lte2->out_reshdr.offset_in_wim);
+}
+
+static int
+write_wim_lookup_table(WIMStruct *wim, int image, int write_flags,
+ struct wim_reshdr *out_reshdr,
+ struct list_head *lookup_table_list)
+{
+ int ret;
+
+ /* Set output resource metadata for streams already present in WIM. */
+ if (write_flags & WIMLIB_WRITE_FLAG_OVERWRITE) {
+ struct wim_lookup_table_entry *lte;
+ list_for_each_entry(lte, lookup_table_list, lookup_table_list)
+ {
+ if (lte->resource_location == RESOURCE_IN_WIM &&
+ lte->rspec->wim == wim)
+ {
+ stream_set_out_reshdr_for_reuse(lte);
+ }
+ }
+ }
+
+ ret = sort_stream_list(lookup_table_list,
+ offsetof(struct wim_lookup_table_entry, lookup_table_list),
+ cmp_streams_by_out_rspec);
+ if (ret)
+ return ret;
+
+ /* Add entries for metadata resources. */
+ if (!(write_flags & WIMLIB_WRITE_FLAG_NO_METADATA)) {
+ int start_image;
+ int end_image;
+
+ if (image == WIMLIB_ALL_IMAGES) {
+ start_image = 1;
+ end_image = wim->hdr.image_count;
+ } else {
+ start_image = image;
+ end_image = image;
+ }
+
+ /* Push metadata resource lookup table entries onto the front of
+ * the list in reverse order, so that they're written in order.
+ */
+ for (int i = end_image; i >= start_image; i--) {
+ struct wim_lookup_table_entry *metadata_lte;
+
+ metadata_lte = wim->image_metadata[i - 1]->metadata_lte;
+ wimlib_assert(metadata_lte->out_reshdr.flags & WIM_RESHDR_FLAG_METADATA);
+ metadata_lte->out_refcnt = 1;
+ list_add(&metadata_lte->lookup_table_list, lookup_table_list);
+ }
+ }
+
+ return write_wim_lookup_table_from_stream_list(lookup_table_list,
+ &wim->out_fd,
+ wim->hdr.part_number,
+ out_reshdr,
+ write_flags_to_resource_flags(write_flags),
+ &wim->lzx_context);
+}
+