1 /* cbfs-compression-tool, CLI utility for dealing with CBFS compressed data */
2 /* SPDX-License-Identifier: GPL-2.0-only */
13 const char *usage_text
= "cbfs-compression-tool benchmark\n"
14 " runs benchmarks for all implemented algorithms\n"
15 "cbfs-compression-tool compress inFile outFile algo\n"
16 " compresses inFile with algo and stores in outFile\n"
18 "'compress' file format:\n"
19 " 4 bytes little endian: algorithm ID (as used in CBFS)\n"
20 " 4 bytes little endian: uncompressed size\n"
21 " ...: compressed data stream\n";
23 static void usage(void)
28 static int benchmark(void)
30 const int bufsize
= 10*1024*1024;
31 char *data
= malloc(bufsize
);
33 fprintf(stderr
, "out of memory\n");
36 char *compressed_data
= malloc(bufsize
);
37 if (!compressed_data
) {
39 fprintf(stderr
, "out of memory\n");
42 int i
, l
= strlen(usage_text
) + 1;
43 for (i
= 0; i
+ l
< bufsize
; i
+= l
) {
44 memcpy(data
+ i
, usage_text
, l
);
46 memset(data
+ i
, 0, bufsize
- i
);
47 const struct typedesc_t
*algo
;
48 for (algo
= &types_cbfs_compression
[0]; algo
->name
!= NULL
; algo
++) {
49 int outsize
= bufsize
;
50 printf("measuring '%s'\n", algo
->name
);
51 comp_func_ptr comp
= compression_function(algo
->type
);
53 printf("no handler associated with algorithm\n");
55 free(compressed_data
);
59 struct timespec t_s
, t_e
;
60 clock_gettime(CLOCK_MONOTONIC
, &t_s
);
62 if (comp(data
, bufsize
, compressed_data
, &outsize
)) {
63 printf("compression failed");
67 clock_gettime(CLOCK_MONOTONIC
, &t_e
);
68 printf("compressing %d bytes to %d took %ld seconds\n",
70 (long)(t_e
.tv_sec
- t_s
.tv_sec
));
73 free(compressed_data
);
77 static int compress(char *infile
, char *outfile
, char *algoname
,
85 const struct typedesc_t
*algo
= &types_cbfs_compression
[0];
86 while (algo
->name
!= NULL
) {
87 if (strcasecmp(algo
->name
, algoname
) == 0) break;
90 if (algo
->name
== NULL
) {
91 fprintf(stderr
, "algo '%s' is not supported.\n", algoname
);
95 comp_func_ptr comp
= compression_function(algo
->type
);
97 printf("no handler associated with algorithm\n");
101 fin
= fopen(infile
, "rb");
103 fprintf(stderr
, "could not open '%s'\n", infile
);
106 fout
= fopen(outfile
, "wb");
108 fprintf(stderr
, "could not open '%s' for writing\n", outfile
);
112 if (fseek(fin
, 0, SEEK_END
) != 0) {
113 fprintf(stderr
, "could not seek in input\n");
116 long insize
= ftell(fin
);
118 fprintf(stderr
, "could not determine input size\n");
123 indata
= malloc(insize
);
125 fprintf(stderr
, "out of memory\n");
129 void *outdata
= malloc(insize
);
131 fprintf(stderr
, "out of memory\n");
136 int remsize
= insize
;
137 while (remsize
> 0) {
138 int readsz
= fread(indata
, 1, remsize
, fin
);
140 fprintf(stderr
, "failed to read input with %d bytes left\n", remsize
);
146 if (comp(indata
, insize
, outdata
, &outsize
) == -1) {
150 algo
= &types_cbfs_compression
[0];
155 header
[0] = algo
->type
& 0xff;
156 header
[1] = (algo
->type
>> 8) & 0xff;
157 header
[2] = (algo
->type
>> 16) & 0xff;
158 header
[3] = (algo
->type
>> 24) & 0xff;
159 header
[4] = insize
& 0xff;
160 header
[5] = (insize
>> 8) & 0xff;
161 header
[6] = (insize
>> 16) & 0xff;
162 header
[7] = (insize
>> 24) & 0xff;
163 if (fwrite(header
, 8, 1, fout
) != 1) {
164 fprintf(stderr
, "failed writing header\n");
168 if (fwrite(outdata
, outsize
, 1, fout
) != 1) {
169 fprintf(stderr
, "failed writing compressed data\n");
175 if (fin
) fclose(fin
);
176 if (fout
) fclose(fout
);
177 if (indata
) free(indata
);
181 int main(int argc
, char **argv
)
183 if ((argc
== 2) && (strcmp(argv
[1], "benchmark") == 0))
185 if ((argc
== 5) && (strcmp(argv
[1], "compress") == 0))
186 return compress(argv
[2], argv
[3], argv
[4], 1);
187 if ((argc
== 5) && (strcmp(argv
[1], "rawcompress") == 0))
188 return compress(argv
[2], argv
[3], argv
[4], 0);