| /* zran.h -- example of deflated stream indexing and random access |
| * Copyright (C) 2005, 2012, 2018, 2023 Mark Adler |
| * For conditions of distribution and use, see copyright notice in zlib.h |
| * Version 1.3 18 Feb 2023 Mark Adler */ |
| |
| #include <stdio.h> |
| #include "zlib.h" |
| |
| // Access point. |
| typedef struct point { |
| off_t out; // offset in uncompressed data |
| off_t in; // offset in compressed file of first full byte |
| int bits; // 0, or number of bits (1-7) from byte at in-1 |
| unsigned char window[32768]; // preceding 32K of uncompressed data |
| } point_t; |
| |
| // Access point list. |
| struct deflate_index { |
| int have; // number of access points in list |
| int mode; // -15 for raw, 15 for zlib, or 31 for gzip |
| off_t length; // total length of uncompressed data |
| point_t *list; // allocated list of access points |
| }; |
| |
| // Make one pass through a zlib, gzip, or raw deflate compressed stream and |
| // build an index, with access points about every span bytes of uncompressed |
| // output. gzip files with multiple members are fully indexed. span should be |
| // chosen to balance the speed of random access against the memory requirements |
| // of the list, which is about 32K bytes per access point. The return value is |
| // the number of access points on success (>= 1), Z_MEM_ERROR for out of |
| // memory, Z_BUF_ERROR for a premature end of input, Z_DATA_ERROR for a format |
| // or verification error in the input file, or Z_ERRNO for a file read error. |
| // On success, *built points to the resulting index. |
| int deflate_index_build(FILE *in, off_t span, struct deflate_index **built); |
| |
| // Use the index to read len bytes from offset into buf. Return the number of |
| // bytes read or a negative error code. If data is requested past the end of |
| // the uncompressed data, then deflate_index_extract() will return a value less |
| // than len, indicating how much was actually read into buf. If given a valid |
| // index, this function should not return an error unless the file was modified |
| // somehow since the index was generated, given that deflate_index_build() had |
| // validated all of the input. If nevertheless there is a failure, Z_BUF_ERROR |
| // is returned if the compressed data ends prematurely, Z_DATA_ERROR if the |
| // deflate compressed data is not valid, Z_MEM_ERROR if out of memory, |
| // Z_STREAM_ERROR if the index is not valid, or Z_ERRNO if there is an error |
| // reading or seeking on the input file. |
| ptrdiff_t deflate_index_extract(FILE *in, struct deflate_index *index, |
| off_t offset, unsigned char *buf, size_t len); |
| |
| // Deallocate an index built by deflate_index_build(). |
| void deflate_index_free(struct deflate_index *index); |