fpga_compress: allow decompression routine to deinterleave output in multiple files

This commit is contained in:
Philippe Teuwen 2021-06-07 22:40:42 +02:00
commit 339fd909c6

View file

@ -26,8 +26,8 @@ static void usage(void) {
fprintf(stdout, " Combine n FPGA bitstream files and compress them into one.\n\n"); fprintf(stdout, " Combine n FPGA bitstream files and compress them into one.\n\n");
fprintf(stdout, " fpga_compress -v <infile1> <infile2> ... <infile_n> <outfile>\n"); fprintf(stdout, " fpga_compress -v <infile1> <infile2> ... <infile_n> <outfile>\n");
fprintf(stdout, " Extract Version Information from FPGA bitstream files and write it to <outfile>\n\n"); fprintf(stdout, " Extract Version Information from FPGA bitstream files and write it to <outfile>\n\n");
fprintf(stdout, " fpga_compress -d <infile> <outfile>\n"); fprintf(stdout, " fpga_compress -d <infile> <outfile(s)>\n");
fprintf(stdout, " Decompress <infile>. Write result to <outfile>\n\n"); fprintf(stdout, " Decompress <infile>. Write result to <outfile(s)>\n\n");
} }
static bool all_feof(FILE *infile[], uint8_t num_infiles) { static bool all_feof(FILE *infile[], uint8_t num_infiles) {
@ -140,7 +140,10 @@ typedef struct lz4_stream_s {
int avail_in; int avail_in;
} lz4_stream; } lz4_stream;
static int zlib_decompress(FILE *infile, FILE *outfile) {
// Call it either with opened infile + outsize=0
// or with opened infile, opened outfiles, num_outfiles and valid outsize
static int zlib_decompress(FILE *infile, FILE *outfiles[], uint8_t num_outfiles, long *outsize) {
LZ4_streamDecode_t lz4StreamDecode_body = {{ 0 }}; LZ4_streamDecode_t lz4StreamDecode_body = {{ 0 }};
char outbuf[FPGA_RING_BUFFER_BYTES]; char outbuf[FPGA_RING_BUFFER_BYTES];
@ -151,17 +154,29 @@ static int zlib_decompress(FILE *infile, FILE *outfile) {
if (infile_size <= 0) { if (infile_size <= 0) {
printf("error, when getting filesize"); printf("error, when getting filesize");
fclose(outfile); if (*outsize > 0) {
fclose(infile); fclose(infile);
for (uint16_t j = 0; j < num_outfiles; j++) {
fclose(outfiles[j]);
}
}
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
char *outbufall = NULL;
if (*outsize > 0) {
outbufall = calloc(*outsize, sizeof(char));
}
char *inbuf = calloc(infile_size, sizeof(char)); char *inbuf = calloc(infile_size, sizeof(char));
size_t num_read = fread(inbuf, sizeof(char), infile_size, infile); size_t num_read = fread(inbuf, sizeof(char), infile_size, infile);
if (num_read != infile_size) { if (num_read != infile_size) {
fclose(outfile); if (*outsize > 0) {
fclose(infile); fclose(infile);
for (uint16_t j = 0; j < num_outfiles; j++) {
fclose(outfiles[j]);
}
}
free(inbuf); free(inbuf);
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
@ -182,14 +197,32 @@ static int zlib_decompress(FILE *infile, FILE *outfile) {
if (decBytes <= 0) { if (decBytes <= 0) {
break; break;
} }
fwrite(outbuf, decBytes, sizeof(char), outfile); if (outbufall != NULL) {
memcpy(outbufall + total_size, outbuf, decBytes);
}
total_size += decBytes; total_size += decBytes;
compressed_fpga_stream.next_in += cmp_bytes; compressed_fpga_stream.next_in += cmp_bytes;
} }
printf("uncompressed %li input bytes to %i output bytes\n", infile_size, total_size); if (outbufall == NULL) {
fclose(outfile); *outsize = total_size;
fclose(infile); fseek(infile, 0L, SEEK_SET);
free(inbuf); return EXIT_SUCCESS;
} else {
fclose(infile);
total_size = 0;
for (uint16_t k = 0; k < *outsize / (FPGA_INTERLEAVE_SIZE * num_outfiles); k++) {
for (uint16_t j = 0; j < num_outfiles; j++) {
fwrite(outbufall + total_size, FPGA_INTERLEAVE_SIZE, sizeof(char), outfiles[j]);
total_size += FPGA_INTERLEAVE_SIZE;
}
}
printf("uncompressed %li input bytes to %i output bytes\n", infile_size, total_size);
}
if (*outsize > 0) {
for (uint16_t j = 0; j < num_outfiles; j++) {
fclose(outfiles[j]);
}
}
return (EXIT_SUCCESS); return (EXIT_SUCCESS);
} }
@ -362,29 +395,42 @@ int main(int argc, char **argv) {
if (!strcmp(argv[1], "-d")) { // Decompress if (!strcmp(argv[1], "-d")) { // Decompress
FILE **infiles = calloc(1, sizeof(FILE *)); if (argc < 4) {
if (argc != 4) {
usage(); usage();
free(infiles);
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
infiles[0] = fopen(argv[2], "rb"); int num_output_files = argc - 3;
if (infiles[0] == NULL) { FILE **outfiles = calloc(num_output_files, sizeof(FILE *));
char **outfile_names = calloc(num_output_files, sizeof(char *));
for (uint16_t i = 0; i < num_output_files; i++) {
outfile_names[i] = argv[i + 3];
outfiles[i] = fopen(outfile_names[i], "wb");
if (outfiles[i] == NULL) {
fprintf(stderr, "Error. Cannot open output file %s\n\n", outfile_names[i]);
free(outfile_names);
free(outfiles);
return (EXIT_FAILURE);
}
}
FILE *infile = fopen(argv[2], "rb");
if (infile == NULL) {
fprintf(stderr, "Error. Cannot open input file %s\n\n", argv[2]); fprintf(stderr, "Error. Cannot open input file %s\n\n", argv[2]);
free(infiles); free(outfile_names);
return (EXIT_FAILURE); free(outfiles);
}
FILE *outfile = fopen(argv[3], "wb");
if (outfile == NULL) {
fprintf(stderr, "Error. Cannot open output file %s\n\n", argv[3]);
free(infiles);
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
int ret = zlib_decompress(infiles[0], outfile); long outsize = 0;
free(infiles); int ret = 0;
// First call to estimate output size
ret = zlib_decompress(infile, outfiles, num_output_files, &outsize);
if (ret == EXIT_SUCCESS) {
// Second call to create files
ret = zlib_decompress(infile, outfiles, num_output_files, &outsize);
}
free(outfile_names);
free(outfiles);
return (ret); return (ret);
} else { // Compress or generate version info } else { // Compress or generate version info
bool generate_version_file = false; bool generate_version_file = false;