Implemented with a new flag WIMLIB_WRITE_FLAG_RECOMPRESS
imagex-optimize \- Optimize a WIM archive
.SH SYNOPSIS
imagex-optimize \- Optimize a WIM archive
.SH SYNOPSIS
-\fBimagex optimize\fR \fIWIMFILE\fR [--check]
+\fBimagex optimize\fR \fIWIMFILE\fR [--check] [--recompress]
When reading \fIWIMFILE\fR, verify its integrity if the integrity table is
present; include an integrity table in the optimized WIM. If this option is not
specified and \fIWIMFILE\fR, no integrity table is included in the optimized
WIM, even if there was one before.
When reading \fIWIMFILE\fR, verify its integrity if the integrity table is
present; include an integrity table in the optimized WIM. If this option is not
specified and \fIWIMFILE\fR, no integrity table is included in the optimized
WIM, even if there was one before.
+.TP 6
+\fB--recompress\fR
+Recompress all compressed streams in \fIWIMFILE\fR when rebuilding it. This
+will increase the time needed to rebuild the WIM,unless the WIM is uncompressed,
+but it may result in a better compression ratio if wimlib can do a better job
+than the program that wrote the original file. A side effect of this is that
+every stream in the original WIM will be checksummed, so this can help verify
+that the WIM is intact (equivalent to applying all the images from it).
"imagex mountrw WIMFILE [IMAGE_NUM | IMAGE_NAME] DIRECTORY\n"
" [--check] [--debug] [--streams-interface=INTERFACE]\n",
[OPTIMIZE] =
"imagex mountrw WIMFILE [IMAGE_NUM | IMAGE_NAME] DIRECTORY\n"
" [--check] [--debug] [--streams-interface=INTERFACE]\n",
[OPTIMIZE] =
-"imagex optimize WIMFILE [--check]\n",
+"imagex optimize WIMFILE [--check] [--recompress]\n",
[SPLIT] =
"imagex split WIMFILE SPLIT_WIMFILE PART_SIZE_MB [--check]\n",
[UNMOUNT] =
[SPLIT] =
"imagex split WIMFILE SPLIT_WIMFILE PART_SIZE_MB [--check]\n",
[UNMOUNT] =
};
static const struct option optimize_options[] = {
};
static const struct option optimize_options[] = {
- {"check", no_argument, NULL, 'c'},
+ {"check", no_argument, NULL, 'c'},
+ {"recompress", no_argument, NULL, 'r'},
open_flags |= WIMLIB_OPEN_FLAG_CHECK_INTEGRITY;
write_flags |= WIMLIB_WRITE_FLAG_CHECK_INTEGRITY;
break;
open_flags |= WIMLIB_OPEN_FLAG_CHECK_INTEGRITY;
write_flags |= WIMLIB_WRITE_FLAG_CHECK_INTEGRITY;
break;
+ case 'r':
+ write_flags |= WIMLIB_WRITE_FLAG_RECOMPRESS;
+ break;
default:
usage(OPTIMIZE);
return -1;
default:
usage(OPTIMIZE);
return -1;
* (Applies to wimlib_overwrite(), not wimlib_write()). */
#define WIMLIB_WRITE_FLAG_REBUILD 0x00000010
* (Applies to wimlib_overwrite(), not wimlib_write()). */
#define WIMLIB_WRITE_FLAG_REBUILD 0x00000010
+/** Do not copy compressed resources between WIMs if the compression type is the
+ * same. Instead, recompress them. */
+#define WIMLIB_WRITE_FLAG_RECOMPRESS 0x00000020
+
/** Mark the image being added as the bootable image of the WIM. */
#define WIMLIB_ADD_IMAGE_FLAG_BOOT 0x00000001
/** Mark the image being added as the bootable image of the WIM. */
#define WIMLIB_ADD_IMAGE_FLAG_BOOT 0x00000001
#define WIMLIB_RESOURCE_FLAG_RAW 0x1
#define WIMLIB_RESOURCE_FLAG_MULTITHREADED 0x2
#define WIMLIB_RESOURCE_FLAG_RAW 0x1
#define WIMLIB_RESOURCE_FLAG_MULTITHREADED 0x2
+#define WIMLIB_RESOURCE_FLAG_RECOMPRESS 0x4
/* The opaque structure exposed to the wimlib API. */
typedef struct WIMStruct {
/* The opaque structure exposed to the wimlib API. */
typedef struct WIMStruct {
/* Are the compression types the same? If so, do a raw copy (copy
* without decompressing and recompressing the data). */
raw = (wim_resource_compression_type(lte) == out_ctype
/* Are the compression types the same? If so, do a raw copy (copy
* without decompressing and recompressing the data). */
raw = (wim_resource_compression_type(lte) == out_ctype
- && out_ctype != WIM_COMPRESSION_TYPE_NONE);
+ && out_ctype != WIM_COMPRESSION_TYPE_NONE
+ && !(flags & WIMLIB_RESOURCE_FLAG_RECOMPRESS));
if (raw) {
flags |= WIMLIB_RESOURCE_FLAG_RAW;
if (raw) {
flags |= WIMLIB_RESOURCE_FLAG_RAW;
u64 cur_size = 0;
u64 next_size = 0;
unsigned cur_percent = 0;
u64 cur_size = 0;
u64 next_size = 0;
unsigned cur_percent = 0;
+ int write_resource_flags = 0;
+
+ if (write_flags & WIMLIB_WRITE_FLAG_RECOMPRESS)
+ write_resource_flags |= WIMLIB_RESOURCE_FLAG_RECOMPRESS;
list_for_each_entry(lte, stream_list, staging_list) {
if (write_flags & WIMLIB_WRITE_FLAG_SHOW_PROGRESS) {
list_for_each_entry(lte, stream_list, staging_list) {
if (write_flags & WIMLIB_WRITE_FLAG_SHOW_PROGRESS) {
&cur_percent, lte);
}
ret = write_wim_resource(lte, out_fp, out_ctype,
&cur_percent, lte);
}
ret = write_wim_resource(lte, out_fp, out_ctype,
- <e->output_resource_entry, 0);
+ <e->output_resource_entry,
+ write_resource_flags);
if (ret != 0)
return ret;
}
if (ret != 0)
return ret;
}
struct message msgs[queue_size];
ZERO_ARRAY(msgs);
struct message msgs[queue_size];
ZERO_ARRAY(msgs);
struct lookup_table_entry,
staging_list);
next_resource = next_resource->next;
struct lookup_table_entry,
staging_list);
next_resource = next_resource->next;
- if ((next_lte->resource_location == RESOURCE_IN_WIM
- && wimlib_get_compression_type(next_lte->wim) == out_ctype)
+ if ((!(write_flags & WIMLIB_WRITE_FLAG_RECOMPRESS)
+ && next_lte->resource_location == RESOURCE_IN_WIM
+ && wimlib_get_compression_type(next_lte->wim) == out_ctype)
|| wim_resource_size(next_lte) == 0)
{
list_add_tail(&next_lte->staging_list,
|| wim_resource_size(next_lte) == 0)
{
list_add_tail(&next_lte->staging_list,
}
if (write_flags & WIMLIB_WRITE_FLAG_SHOW_PROGRESS) {
}
if (write_flags & WIMLIB_WRITE_FLAG_SHOW_PROGRESS) {
- printf("Writing %s compressed data using %u threads...\n",
+ printf("Writing %s data using %u threads...\n",
get_data_type(out_ctype), num_threads);
}
get_data_type(out_ctype), num_threads);
}
num_streams++;
total_size += wim_resource_size(lte);
if (!compression_needed
num_streams++;
total_size += wim_resource_size(lte);
if (!compression_needed
- && out_ctype != WIM_COMPRESSION_TYPE_NONE
- && (lte->resource_location != RESOURCE_IN_WIM
- || wimlib_get_compression_type(lte->wim) != out_ctype)
+ &&
+ (out_ctype != WIM_COMPRESSION_TYPE_NONE
+ && (lte->resource_location != RESOURCE_IN_WIM
+ || wimlib_get_compression_type(lte->wim) != out_ctype
+ || (write_flags & WIMLIB_WRITE_FLAG_REBUILD)))
&& wim_resource_size(lte) != 0)
compression_needed = true;
}
&& wim_resource_size(lte) != 0)
compression_needed = true;
}
if (!w || !path)
return WIMLIB_ERR_INVALID_PARAM;
if (!w || !path)
return WIMLIB_ERR_INVALID_PARAM;
- write_flags &= WIMLIB_WRITE_MASK_PUBLIC;
-
if (image != WIM_ALL_IMAGES &&
(image < 1 || image > w->hdr.image_count))
return WIMLIB_ERR_INVALID_IMAGE;
if (image != WIM_ALL_IMAGES &&
(image < 1 || image > w->hdr.image_count))
return WIMLIB_ERR_INVALID_IMAGE;