mirror of
https://github.com/vasi/pixz
synced 2024-11-10 19:10:43 +00:00
List blocks of a .xz file
This commit is contained in:
parent
dbe600a7e7
commit
7e02b87f68
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
pixz
|
pixz
|
||||||
|
pixzlist
|
||||||
*.o
|
*.o
|
||||||
test.out
|
test.out
|
||||||
test.base
|
test.base
|
||||||
|
22
Makefile
22
Makefile
@ -1,13 +1,27 @@
|
|||||||
LDFLAGS = -L/Library/Fink/sl64/lib -llzma -Wall
|
LDFLAGS = -L/Library/Fink/sl64/lib -llzma -Wall
|
||||||
CFLAGS = -I/Library/Fink/sl64/include -g -O0 -std=c99 -Wall
|
CFLAGS = -I/Library/Fink/sl64/include -g -O0 -std=c99 -Wall
|
||||||
|
|
||||||
PIXZ_OBJS: pixz.o encode.o block.o
|
CC = gcc $(CFLAGS) -c -o
|
||||||
|
LD = gcc $(LDFLAGS) -o
|
||||||
|
|
||||||
|
|
||||||
|
PIXZ_OBJS = pixz.o encode.o block.o
|
||||||
|
|
||||||
|
all: pixz
|
||||||
|
|
||||||
pixz: $(PIXZ_OBJS)
|
pixz: $(PIXZ_OBJS)
|
||||||
gcc $(LDFLAGS) -o $@ $^
|
$(LD) $@ $^
|
||||||
|
|
||||||
$(PIXZ_OBJS): %.o: %.c pixz.h
|
$(PIXZ_OBJS): %.o: %.c pixz.h
|
||||||
gcc $(CFLAGS) -c -o $@ $<
|
$(CC) $@ $<
|
||||||
|
|
||||||
|
|
||||||
|
pixzlist: pixzlist.o
|
||||||
|
$(LD) $@ $^
|
||||||
|
|
||||||
|
pixzlist.o: pixzlist.c
|
||||||
|
$(CC) $@ $<
|
||||||
|
|
||||||
|
|
||||||
run: pixz
|
run: pixz
|
||||||
time ./$< < test.in > test.out
|
time ./$< < test.in > test.out
|
||||||
@ -17,4 +31,4 @@ run: pixz
|
|||||||
clean:
|
clean:
|
||||||
rm -f *.o pixz test.out
|
rm -f *.o pixz test.out
|
||||||
|
|
||||||
.PHONY: run clean
|
.PHONY: all run clean
|
||||||
|
2
encode.c
2
encode.c
@ -53,7 +53,7 @@ fixme_err pixz_encode_options_default(pixz_encode_options *opts) {
|
|||||||
const size_t k = 1024, m = 1024 * k;
|
const size_t k = 1024, m = 1024 * k;
|
||||||
|
|
||||||
// Set defaults
|
// Set defaults
|
||||||
opts->blocksize = 8 * m;
|
opts->blocksize = 1 * m;
|
||||||
opts->chunksize = 64 * k;
|
opts->chunksize = 64 * k;
|
||||||
opts->filters[0].id = LZMA_FILTER_LZMA2;
|
opts->filters[0].id = LZMA_FILTER_LZMA2;
|
||||||
opts->check = LZMA_CHECK_CRC32;
|
opts->check = LZMA_CHECK_CRC32;
|
||||||
|
132
pixzlist.c
Normal file
132
pixzlist.c
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#include <lzma.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
|
|
||||||
|
#define Err(fmt, ...) fprintf(stderr, fmt ".\n", ##__VA_ARGS__)
|
||||||
|
#define fErr(fmt, ...) Err(fmt, fname, ##__VA_ARGS__)
|
||||||
|
#define feErr(fmt, ...) fErr(fmt ": %s", strerror(errno), ##__VA_ARGS__)
|
||||||
|
#define cfErr(code, fmt, ...) Err(fmt, code, fname, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define R(ret, ...) ({ __VA_ARGS__; return ret; })
|
||||||
|
#define P(pred, ...) ({ if (pred) { __VA_ARGS__; } })
|
||||||
|
|
||||||
|
#define feRErr(ret, ...) R(ret, feErr(__VA_ARGS__))
|
||||||
|
#define fPRErr(pred, ret, ...) P(pred, R(ret, fErr(__VA_ARGS__)))
|
||||||
|
#define cfPRErr(code, ret, ...) P(code != LZMA_OK, R(ret, cfErr(code, __VA_ARGS__)))
|
||||||
|
|
||||||
|
#define CHUNKSIZE 4096
|
||||||
|
#define MEMLIMIT (32 * 1024 * 1204)
|
||||||
|
|
||||||
|
void pixzlist_listfile(char *fname, FILE *f);
|
||||||
|
lzma_index *pixzlist_index(char *fname, FILE *f);
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
char *fname = argv[i];
|
||||||
|
FILE *f = fopen(fname, "r");
|
||||||
|
if (f == NULL) {
|
||||||
|
fprintf(stderr, "Can't open file '%s': %s.\n", fname, strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pixzlist_listfile(fname, f);
|
||||||
|
fclose(f);
|
||||||
|
if (i != argc - 1)
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pixzlist_listfile(char *fname, FILE *f) {
|
||||||
|
lzma_index *index = pixzlist_index(fname, f);
|
||||||
|
if (!index)
|
||||||
|
return;
|
||||||
|
|
||||||
|
printf("%s:\n", fname);
|
||||||
|
|
||||||
|
lzma_index_record rec;
|
||||||
|
while (!lzma_index_read(index, &rec)) {
|
||||||
|
printf("%llu / %llu\n", rec.unpadded_size, rec.uncompressed_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
lzma_index_end(index, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
lzma_index *pixzlist_index(char *fname, FILE *f) {
|
||||||
|
// Seek to footer
|
||||||
|
if (fseek(f, -LZMA_STREAM_HEADER_SIZE, SEEK_END) == -1) {
|
||||||
|
fprintf(stderr, "Can't seek to footer in '%s': %s.\n",
|
||||||
|
fname, strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read footer
|
||||||
|
uint8_t header[LZMA_STREAM_HEADER_SIZE];
|
||||||
|
if (fread(header, LZMA_STREAM_HEADER_SIZE, 1, f) != 1) {
|
||||||
|
fprintf(stderr, "Can't read footer from '%s': %s.\n",
|
||||||
|
fname, strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode footer
|
||||||
|
lzma_stream_flags flags;
|
||||||
|
lzma_ret lerr = lzma_stream_footer_decode(&flags, header);
|
||||||
|
if (lerr != LZMA_OK) {
|
||||||
|
if (lerr == LZMA_FORMAT_ERROR)
|
||||||
|
fprintf(stderr, "'%s' isn't an LZMA file.\n", fname);
|
||||||
|
else if (lerr == LZMA_DATA_ERROR)
|
||||||
|
fprintf(stderr, "CRC mismatch in '%s' footer.\n", fname);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "Error #%d decoding footer of '%s'.\n", lerr, fname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seek to index
|
||||||
|
if (fseek(f, -LZMA_STREAM_HEADER_SIZE - flags.backward_size, SEEK_END) == -1) {
|
||||||
|
fprintf(stderr, "Can't seek to index in '%s': %s.\n",
|
||||||
|
fname, strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create index decoder
|
||||||
|
uint8_t chunk[CHUNKSIZE];
|
||||||
|
lzma_stream stream = LZMA_STREAM_INIT;
|
||||||
|
lzma_index *index = NULL;
|
||||||
|
lerr = lzma_index_decoder(&stream, &index, MEMLIMIT);
|
||||||
|
if (lerr != LZMA_OK) {
|
||||||
|
fprintf(stderr, "Error #%d starting decoding index of '%s'.\n",
|
||||||
|
lerr, fname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode index
|
||||||
|
while (lerr != LZMA_STREAM_END) {
|
||||||
|
size_t rd = fread(chunk, 1, CHUNKSIZE, f);
|
||||||
|
if (rd == 0) {
|
||||||
|
fprintf(stderr, "Error reading index from '%s': %s.\n",
|
||||||
|
fname, strerror(errno));
|
||||||
|
goto index_err;
|
||||||
|
}
|
||||||
|
stream.next_in = chunk;
|
||||||
|
stream.avail_in = rd;
|
||||||
|
|
||||||
|
while (stream.avail_in != 0 && lerr != LZMA_STREAM_END) {
|
||||||
|
lerr = lzma_code(&stream, LZMA_RUN);
|
||||||
|
if (lerr != LZMA_OK && lerr != LZMA_STREAM_END) {
|
||||||
|
fprintf(stderr, "Error #%d starting decoding index of '%s'.\n",
|
||||||
|
lerr, fname);
|
||||||
|
goto index_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lzma_end(&stream);
|
||||||
|
return index;
|
||||||
|
|
||||||
|
index_err:
|
||||||
|
lzma_end(&stream);
|
||||||
|
lzma_index_end(index, NULL);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user