From 5bae0e225874077fe8aa06a5649aa7bc45d9ef8f Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 19 Nov 2012 23:56:12 -0600 Subject: [PATCH] imagex-optimize: --recompress Implemented with a new flag WIMLIB_WRITE_FLAG_RECOMPRESS --- doc/imagex-optimize.1.in | 11 ++++++++++- programs/imagex.c | 8 ++++++-- src/wimlib.h | 4 ++++ src/wimlib_internal.h | 1 + src/write.c | 28 +++++++++++++++++----------- 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/doc/imagex-optimize.1.in b/doc/imagex-optimize.1.in index 40a91ad3..a0ce30d1 100644 --- a/doc/imagex-optimize.1.in +++ b/doc/imagex-optimize.1.in @@ -3,7 +3,7 @@ imagex-optimize \- Optimize a WIM archive .SH SYNOPSIS -\fBimagex optimize\fR \fIWIMFILE\fR [--check] +\fBimagex optimize\fR \fIWIMFILE\fR [--check] [--recompress] .SH DESCRIPTION .PP @@ -16,10 +16,19 @@ In addition, some errors in the original WIM may be fixed by re-writing it .SH OPTIONS .TP 6 +\fB--check\fR 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). .SH NOTES diff --git a/programs/imagex.c b/programs/imagex.c index 0b7c96b0..4e5765f6 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -99,7 +99,7 @@ static const char *usage_strings[] = { "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] = @@ -172,7 +172,8 @@ static const struct option mount_options[] = { }; static const struct option optimize_options[] = { - {"check", no_argument, NULL, 'c'}, + {"check", no_argument, NULL, 'c'}, + {"recompress", no_argument, NULL, 'r'}, {NULL, 0, NULL, 0}, }; @@ -1364,6 +1365,9 @@ static int imagex_optimize(int argc, const char **argv) 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; diff --git a/src/wimlib.h b/src/wimlib.h index abbdb703..6c99ffdb 100644 --- a/src/wimlib.h +++ b/src/wimlib.h @@ -280,6 +280,10 @@ enum wim_compression_type { * (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 diff --git a/src/wimlib_internal.h b/src/wimlib_internal.h index 6c45ca38..be3dc32c 100644 --- a/src/wimlib_internal.h +++ b/src/wimlib_internal.h @@ -254,6 +254,7 @@ struct image_metadata { #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 { diff --git a/src/write.c b/src/write.c index 96d66767..a9cb6aec 100644 --- a/src/write.c +++ b/src/write.c @@ -382,7 +382,8 @@ int write_wim_resource(struct lookup_table_entry *lte, /* 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; @@ -685,6 +686,10 @@ static int write_stream_list_serial(struct list_head *stream_list, 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) { @@ -693,7 +698,8 @@ static int write_stream_list_serial(struct list_head *stream_list, &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; } @@ -748,7 +754,6 @@ static int main_writer_thread_proc(struct list_head *stream_list, { int ret; - struct message msgs[queue_size]; ZERO_ARRAY(msgs); @@ -942,8 +947,9 @@ static int main_writer_thread_proc(struct list_head *stream_list, 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, @@ -1238,7 +1244,7 @@ static int write_stream_list_parallel(struct list_head *stream_list, } 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); } @@ -1291,9 +1297,11 @@ static int write_stream_list(struct list_head *stream_list, FILE *out_fp, 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; } @@ -1562,8 +1570,6 @@ WIMLIBAPI int wimlib_write(WIMStruct *w, const char *path, 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; -- 2.43.0