+
+static int
+xpress_create_compressor(size_t max_window_size,
+ const struct wimlib_compressor_params_header *params,
+ void **c_ret)
+{
+ struct xpress_compressor *c;
+
+ if (max_window_size == 0 || max_window_size > (1U << 26))
+ return WIMLIB_ERR_INVALID_PARAM;
+
+ c = CALLOC(1, sizeof(struct xpress_compressor));
+ if (c == NULL)
+ goto oom;
+
+ c->window = MALLOC(max_window_size + 8);
+ if (c->window == NULL)
+ goto oom;
+
+ c->max_window_size = max_window_size;
+
+ c->matches = MALLOC(max_window_size * sizeof(c->matches[0]));
+ if (c->matches == NULL)
+ goto oom;
+
+ c->prev_tab = MALLOC(max_window_size * sizeof(c->prev_tab[0]));
+ if (c->prev_tab == NULL)
+ goto oom;
+
+ *c_ret = c;
+ return 0;
+
+oom:
+ xpress_free_compressor(c);
+ return WIMLIB_ERR_NOMEM;
+}
+
+static u64
+xpress_get_needed_memory(size_t max_window_size,
+ const struct wimlib_compressor_params_header *params)
+{
+ u64 size = 0;
+
+ size += sizeof(struct xpress_compressor);
+ size += max_window_size + 8;
+ size += max_window_size * sizeof(((struct xpress_compressor*)0)->matches[0]);
+ size += max_window_size * sizeof(((struct xpress_compressor*)0)->prev_tab[0]);
+
+ return size;
+}
+
+const struct compressor_ops xpress_compressor_ops = {
+ .get_needed_memory = xpress_get_needed_memory,
+ .create_compressor = xpress_create_compressor,
+ .compress = xpress_compress,
+ .free_compressor = xpress_free_compressor,
+};