+
+ blob = lookup_blob(blob_table, hash);
+ if (blob)
+ return blob;
+
+ blob = new_blob_descriptor();
+ if (!blob)
+ return NULL;
+
+ buffer_copy = memdup(buffer, size);
+ if (!buffer_copy) {
+ free_blob_descriptor(blob);
+ return NULL;
+ }
+ blob_set_is_located_in_attached_buffer(blob, buffer_copy, size);
+ copy_hash(blob->hash, hash);
+ blob_table_insert(blob_table, blob);
+ return blob;
+}
+
+struct blob_descriptor *
+after_blob_hashed(struct blob_descriptor *blob,
+ struct blob_descriptor **back_ptr,
+ struct blob_table *blob_table)
+{
+ struct blob_descriptor *duplicate_blob;
+
+ list_del(&blob->unhashed_list);
+ blob->unhashed = 0;
+
+ /* Look for a duplicate blob */
+ duplicate_blob = lookup_blob(blob_table, blob->hash);
+ if (duplicate_blob) {
+ /* We have a duplicate blob. Transfer the reference counts from
+ * this blob to the duplicate and update the reference to this
+ * blob (from a stream) to point to the duplicate. The caller
+ * is responsible for freeing @blob if needed. */
+ wimlib_assert(duplicate_blob->size == blob->size);
+ duplicate_blob->refcnt += blob->refcnt;
+ blob->refcnt = 0;
+ *back_ptr = duplicate_blob;
+ return duplicate_blob;