imagex-optimize: --recompress
authorEric Biggers <ebiggers3@gmail.com>
Tue, 20 Nov 2012 05:56:12 +0000 (23:56 -0600)
committerEric Biggers <ebiggers3@gmail.com>
Tue, 20 Nov 2012 05:56:12 +0000 (23:56 -0600)
Implemented with a new flag WIMLIB_WRITE_FLAG_RECOMPRESS

doc/imagex-optimize.1.in
programs/imagex.c
src/wimlib.h
src/wimlib_internal.h
src/write.c

index 40a91ad3f79254c3599c10c476a8885e83df4aac..a0ce30d108e01ffcb989e2b96616034ba8b09091 100644 (file)
@@ -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
 
index 0b7c96b0b7556f9aa72471e100583b3d307814a2..4e5765f649b2b650da84dfd1b47fd0b9ad199dd2 100644 (file)
@@ -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;
index abbdb70301726853a55443744a0d764676ff3639..6c99ffdbda1128e848d18a4f9dfd6dbb15a330e9 100644 (file)
@@ -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
 
index 6c45ca38185b1c6b0125e5ecef1c1e490a3482c0..be3dc32c342459329474c5c25f7a6d6b186ba03d 100644 (file)
@@ -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 {
index 96d6676729aaa307acb4f340326e2ce37de48c2d..a9cb6aecaa6c6da0db11b159014e192ad29fac67 100644 (file)
@@ -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,
-                                        &lte->output_resource_entry, 0);
+                                        &lte->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;