1 /*********************************************************************
2   Blosc - Blocked Shuffling and Compression Library
3 
4   Copyright (C) 2021  The Blosc Developers <blosc@blosc.org>
5   https://blosc.org
6   License: BSD 3-Clause (see LICENSE.txt)
7 
8   See LICENSE.txt for details about copyright and rights to use.
9 **********************************************************************/
10 
11 #ifndef BLOSC_FRAME_H
12 #define BLOSC_FRAME_H
13 
14 #include <stdio.h>
15 #include <stdint.h>
16 
17 // Different types of frames
18 #define FRAME_CONTIGUOUS_TYPE 0
19 #define FRAME_DIRECTORY_TYPE 1
20 
21 
22 // Constants for metadata placement in header
23 #define FRAME_HEADER_MAGIC 2
24 #define FRAME_HEADER_LEN (FRAME_HEADER_MAGIC + 8 + 1)  // 11
25 #define FRAME_LEN (FRAME_HEADER_LEN + 4 + 1)  // 16
26 #define FRAME_FLAGS (FRAME_LEN + 8 + 1)  // 25
27 #define FRAME_TYPE (FRAME_FLAGS + 1)  // 26
28 #define FRAME_CODECS (FRAME_FLAGS + 2)  // 27
29 #define FRAME_NBYTES (FRAME_FLAGS + 4 + 1)  // 30
30 #define FRAME_CBYTES (FRAME_NBYTES + 8 + 1)  // 39
31 #define FRAME_TYPESIZE (FRAME_CBYTES + 8 + 1) // 48
32 #define FRAME_BLOCKSIZE (FRAME_TYPESIZE + 4 + 1)  // 53
33 #define FRAME_CHUNKSIZE (FRAME_BLOCKSIZE + 4 + 1)  // 58
34 #define FRAME_NTHREADS_C (FRAME_CHUNKSIZE + 4 + 1)  // 63
35 #define FRAME_NTHREADS_D (FRAME_NTHREADS_C + 2 + 1)  // 66
36 #define FRAME_HAS_VLMETALAYERS (FRAME_NTHREADS_D + 2)  // 68
37 #define FRAME_FILTER_PIPELINE (FRAME_HAS_VLMETALAYERS + 1 + 1) // 70
38 #define FRAME_UDCODEC (FRAME_FILTER_PIPELINE + 1 + 6) // 77
39 #define FRAME_CODEC_META (FRAME_FILTER_PIPELINE + 1 + 7) // 78
40 #define FRAME_HEADER_MINLEN (FRAME_FILTER_PIPELINE + 1 + 16)  // 87 <- minimum length
41 #define FRAME_METALAYERS (FRAME_HEADER_MINLEN)  // 87
42 #define FRAME_IDX_SIZE (FRAME_METALAYERS + 1 + 1)  // 89
43 
44 #define FRAME_FILTER_PIPELINE_MAX (8)  // the maximum number of filters that can be stored in header
45 
46 #define FRAME_TRAILER_VERSION_BETA2 (0U)  // for beta.2 and former
47 #define FRAME_TRAILER_VERSION (1U)        // can be up to 127
48 
49 #define FRAME_TRAILER_MINLEN (25)  // minimum length for the trailer (msgpack overhead)
50 #define FRAME_TRAILER_LEN_OFFSET (22)  // offset to trailer length (counting from the end)
51 #define FRAME_TRAILER_VLMETALAYERS (2)
52 
53 
54 typedef struct {
55   char* urlpath;            //!< The name of the file or directory if it's an sframe; if NULL, this is in-memory
56   uint8_t* cframe;          //!< The in-memory, contiguous frame buffer
57   bool avoid_cframe_free;   //!< Whether the cframe can be freed (false) or not (true).
58   uint8_t* coffsets;        //!< Pointers to the (compressed, on-disk) chunk offsets
59   int64_t len;              //!< The current length of the frame in (compressed) bytes
60   int64_t maxlen;           //!< The maximum length of the frame; if 0, there is no maximum
61   uint32_t trailer_len;     //!< The current length of the trailer in (compressed) bytes
62   bool sframe;              //!< Whether the frame is sparse (true) or not
63   blosc2_schunk *schunk;    //!< The schunk associated
64 } blosc2_frame_s;
65 
66 
67 /*********************************************************************
68   Frame struct related functions.
69   These are rather low-level and the blosc2_schunk interface is
70   recommended instead.
71 *********************************************************************/
72 
73 /**
74  * @brief Create a new frame.
75  *
76  * @param urlpath The filename of the frame.  If not persistent, pass NULL.
77  *
78  * @return The new frame.
79  */
80 blosc2_frame_s* frame_new(const char* urlpath);
81 
82 /**
83  * @brief Create a frame from a super-chunk.
84  *
85  * @param schunk The super-chunk from where the frame will be created.
86  * @param frame The pointer for the frame that will be populated.
87  *
88  * @note If frame->urlpath is NULL, a frame is created in-memory; else it is created
89  * on-disk.
90  *
91  * @return The size in bytes of the frame. If an error occurs it returns a negative value.
92  */
93 int64_t frame_from_schunk(blosc2_schunk* schunk, blosc2_frame_s* frame);
94 
95 /**
96  * @brief Free all memory from a frame.
97  *
98  * @param frame The frame to be freed.
99  *
100  * @return 0 if succeeds.
101  */
102 int frame_free(blosc2_frame_s *frame);
103 
104 /**
105  * @brief Initialize a frame out of a file.
106  *
107  * @param urlpath The file name.
108  *
109  * @return The frame created from the file.
110  */
111 blosc2_frame_s* frame_from_file(const char *urlpath, const blosc2_io *io_cb);
112 
113 /**
114  * @brief Initialize a frame out of a frame buffer.
115  *
116  * @param buffer The buffer for the frame.
117  * @param len The length of buffer for the frame.
118  * @param copy Whether the frame buffer should be copied internally or not.
119  *
120  * @return The frame created from the frame buffer.
121  */
122 blosc2_frame_s* frame_from_cframe(uint8_t *cframe, int64_t len, bool copy);
123 
124 /**
125  * @brief Create a super-chunk from a frame.
126  *
127  * @param frame The frame from which the super-chunk will be created.
128  * @param copy If true, a new frame buffer is created
129  * internally to serve as storage for the super-chunk. Else, the
130  * super-chunk will be backed by @p frame (i.e. no copies are made).
131  *
132  * @return The super-chunk corresponding to the frame.
133  */
134 blosc2_schunk* frame_to_schunk(blosc2_frame_s* frame, bool copy, const blosc2_io *udio);
135 
136 blosc2_storage *
137 get_new_storage(const blosc2_storage *storage, const blosc2_cparams *cdefaults, const blosc2_dparams *ddefaults,
138                 const blosc2_io *iodefaults);
139 
140 void* frame_append_chunk(blosc2_frame_s* frame, void* chunk, blosc2_schunk* schunk);
141 void* frame_insert_chunk(blosc2_frame_s* frame, int nchunk, void* chunk, blosc2_schunk* schunk);
142 void* frame_update_chunk(blosc2_frame_s* frame, int nchunk, void* chunk, blosc2_schunk* schunk);
143 void* frame_delete_chunk(blosc2_frame_s* frame, int nchunk, blosc2_schunk* schunk);
144 int frame_reorder_offsets(blosc2_frame_s *frame, const int *offsets_order, blosc2_schunk* schunk);
145 
146 int frame_get_chunk(blosc2_frame_s* frame, int nchunk, uint8_t **chunk, bool *needs_free);
147 int frame_get_lazychunk(blosc2_frame_s* frame, int nchunk, uint8_t **chunk, bool *needs_free);
148 int frame_decompress_chunk(blosc2_context* dctx, blosc2_frame_s* frame, int nchunk,
149                            void *dest, int32_t nbytes);
150 
151 int frame_update_header(blosc2_frame_s* frame, blosc2_schunk* schunk, bool new);
152 int frame_update_trailer(blosc2_frame_s* frame, blosc2_schunk* schunk);
153 
154 int frame_fill_special(blosc2_frame_s* frame, int64_t nitems, int special_value,
155                        int32_t chunksize, blosc2_schunk* schunk);
156 
157 #endif //BLOSC_FRAME_H
158