blosc2.c:is_little_endian:
   35|     32|static bool is_little_endian(void) {
   36|     32|  static const int i = 1;
   37|     32|  char* p = (char*)&i;
   38|       |
   39|     32|  if (p[0] == 1) {
  ------------------
  |  Branch (39:7): [True: 32, False: 0]
  ------------------
   40|     32|    return true;
   41|     32|  }
   42|      0|  else {
   43|      0|    return false;
   44|      0|  }
   45|     32|}
blosc2.c:sw32_:
   89|      8|static inline int32_t sw32_(const void* pa) {
   90|      8|  int32_t idest;
   91|       |
   92|      8|  bool little_endian = is_little_endian();
   93|      8|  if (little_endian) {
  ------------------
  |  Branch (93:7): [True: 8, False: 0]
  ------------------
   94|      8|    idest = *(int32_t *)pa;
   95|      8|  }
   96|      0|  else {
   97|      0|#if defined (__GNUC__)
   98|      0|    return __builtin_bswap32(*(unsigned int *)pa);
   99|       |#elif defined (_MSC_VER) /* Visual Studio */
  100|       |    return _byteswap_ulong(*(unsigned int *)pa);
  101|       |#else
  102|       |    uint8_t *dest = (uint8_t *)&idest;
  103|       |    dest[0] = pa_[3];
  104|       |    dest[1] = pa_[2];
  105|       |    dest[2] = pa_[1];
  106|       |    dest[3] = pa_[0];
  107|       |#endif
  108|      0|  }
  109|      8|  return idest;
  110|      8|}
frame.c:endian_handler:
   49|     63|{
   50|     63|  bool little_endian = is_little_endian();
   51|     63|  if (little_endian == little) {
  ------------------
  |  Branch (51:7): [True: 0, False: 63]
  ------------------
   52|      0|    memcpy(dest, pa, size);
   53|      0|  }
   54|     63|  else {
   55|     63|    uint8_t* pa_ = (uint8_t*)pa;
   56|     63|    uint8_t pa2_[8];
   57|     63|    switch (size) {
   58|     28|      case 8:
  ------------------
  |  Branch (58:7): [True: 28, False: 35]
  ------------------
   59|     28|        pa2_[0] = pa_[7];
   60|     28|        pa2_[1] = pa_[6];
   61|     28|        pa2_[2] = pa_[5];
   62|     28|        pa2_[3] = pa_[4];
   63|     28|        pa2_[4] = pa_[3];
   64|     28|        pa2_[5] = pa_[2];
   65|     28|        pa2_[6] = pa_[1];
   66|     28|        pa2_[7] = pa_[0];
   67|     28|        break;
   68|     29|      case 4:
  ------------------
  |  Branch (68:7): [True: 29, False: 34]
  ------------------
   69|     29|        pa2_[0] = pa_[3];
   70|     29|        pa2_[1] = pa_[2];
   71|     29|        pa2_[2] = pa_[1];
   72|     29|        pa2_[3] = pa_[0];
   73|     29|        break;
   74|      4|      case 2:
  ------------------
  |  Branch (74:7): [True: 4, False: 59]
  ------------------
   75|      4|        pa2_[0] = pa_[1];
   76|      4|        pa2_[1] = pa_[0];
   77|      4|        break;
   78|      2|      case 1:
  ------------------
  |  Branch (78:7): [True: 2, False: 61]
  ------------------
   79|      2|        pa2_[0] = pa_[0];
   80|      2|        break;
   81|      0|      default:
  ------------------
  |  Branch (81:7): [True: 0, False: 63]
  ------------------
   82|      0|        BLOSC_TRACE_ERROR("Unhandled size: %d.", size);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   83|     63|    }
   84|     63|    memcpy(dest, pa2_, size);
   85|     63|  }
   86|     63|}
frame.c:is_little_endian:
   35|     63|static bool is_little_endian(void) {
   36|     63|  static const int i = 1;
   37|     63|  char* p = (char*)&i;
   38|       |
   39|     63|  if (p[0] == 1) {
  ------------------
  |  Branch (39:7): [True: 63, False: 0]
  ------------------
   40|     63|    return true;
   41|     63|  }
   42|      0|  else {
   43|      0|    return false;
   44|      0|  }
   45|     63|}

blosc2_stdio_destroy:
   87|      1|int blosc2_stdio_destroy(void* params) {
   88|      1|  BLOSC_UNUSED_PARAM(params);
  ------------------
  |  |   28|      1|#define BLOSC_UNUSED_PARAM(x) ((void)(x))
  ------------------
   89|      1|  return 0;
   90|      1|}

do_nothing:
  566|     28|int do_nothing(uint8_t filter, char cmode) {
  567|     28|  if (cmode == 'c') {
  ------------------
  |  Branch (567:7): [True: 0, False: 28]
  ------------------
  568|      0|    return (filter == BLOSC_NOFILTER);
  569|     28|  } else {
  570|       |    // TRUNC_PREC do not have to be applied during decompression
  571|     28|    return ((filter == BLOSC_NOFILTER) || (filter == BLOSC_TRUNC_PREC));
  ------------------
  |  Branch (571:13): [True: 20, False: 8]
  |  Branch (571:43): [True: 0, False: 8]
  ------------------
  572|     28|  }
  573|     28|}
next_filter:
  576|      4|int next_filter(const uint8_t* filters, int current_filter, char cmode) {
  577|      4|  for (int i = current_filter - 1; i >= 0; i--) {
  ------------------
  |  Branch (577:36): [True: 4, False: 0]
  ------------------
  578|      4|    if (!do_nothing(filters[i], cmode)) {
  ------------------
  |  Branch (578:9): [True: 4, False: 0]
  ------------------
  579|      4|      return filters[i];
  580|      4|    }
  581|      4|  }
  582|      0|  return BLOSC_NOFILTER;
  583|      4|}
last_filter:
  586|      4|int last_filter(const uint8_t* filters, char cmode) {
  587|      4|  int last_index = -1;
  588|     28|  for (int i = BLOSC2_MAX_FILTERS - 1; i >= 0; i--) {
  ------------------
  |  Branch (588:40): [True: 24, False: 4]
  ------------------
  589|     24|    if (!do_nothing(filters[i], cmode))  {
  ------------------
  |  Branch (589:9): [True: 4, False: 20]
  ------------------
  590|      4|      last_index = i;
  591|      4|    }
  592|     24|  }
  593|      4|  return last_index;
  594|      4|}
read_chunk_header:
  673|     24|{
  674|     24|  memset(header, 0, sizeof(blosc_header));
  675|       |
  676|     24|  if (srcsize < BLOSC_MIN_HEADER_LENGTH) {
  ------------------
  |  Branch (676:7): [True: 0, False: 24]
  ------------------
  677|      0|    BLOSC_TRACE_ERROR("Not enough space to read Blosc header.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  678|      0|    return BLOSC2_ERROR_READ_BUFFER;
  679|      0|  }
  680|       |
  681|     24|  memcpy(header, src, BLOSC_MIN_HEADER_LENGTH);
  682|       |
  683|     24|  bool little_endian = is_little_endian();
  684|       |
  685|     24|  if (!little_endian) {
  ------------------
  |  Branch (685:7): [True: 0, False: 24]
  ------------------
  686|      0|    header->nbytes = bswap32_(header->nbytes);
  687|      0|    header->blocksize = bswap32_(header->blocksize);
  688|      0|    header->cbytes = bswap32_(header->cbytes);
  689|      0|  }
  690|       |
  691|     24|  if (header->version > BLOSC2_VERSION_FORMAT) {
  ------------------
  |  Branch (691:7): [True: 0, False: 24]
  ------------------
  692|       |    /* Version from future */
  693|      0|    return BLOSC2_ERROR_VERSION_SUPPORT;
  694|      0|  }
  695|     24|  if (header->cbytes < BLOSC_MIN_HEADER_LENGTH) {
  ------------------
  |  Branch (695:7): [True: 0, False: 24]
  ------------------
  696|      0|    BLOSC_TRACE_ERROR("`cbytes` is too small to read min header.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  697|      0|    return BLOSC2_ERROR_INVALID_HEADER;
  698|      0|  }
  699|     24|  if (header->blocksize <= 0 || (header->nbytes > 0 && (header->blocksize > header->nbytes))) {
  ------------------
  |  Branch (699:7): [True: 0, False: 24]
  |  Branch (699:34): [True: 24, False: 0]
  |  Branch (699:56): [True: 0, False: 24]
  ------------------
  700|      0|    BLOSC_TRACE_ERROR("`blocksize` is zero or greater than uncompressed size");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  701|      0|    return BLOSC2_ERROR_INVALID_HEADER;
  702|      0|  }
  703|     24|  if (header->blocksize > BLOSC2_MAXBLOCKSIZE) {
  ------------------
  |  Branch (703:7): [True: 0, False: 24]
  ------------------
  704|      0|    BLOSC_TRACE_ERROR("`blocksize` greater than maximum allowed");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  705|      0|    return BLOSC2_ERROR_INVALID_HEADER;
  706|      0|  }
  707|     24|  if (header->typesize == 0) {
  ------------------
  |  Branch (707:7): [True: 0, False: 24]
  ------------------
  708|      0|    BLOSC_TRACE_ERROR("`typesize` is zero.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  709|      0|    return BLOSC2_ERROR_INVALID_HEADER;
  710|      0|  }
  711|       |
  712|       |  /* Read extended header if it is wanted */
  713|     24|  if ((extended_header) && (header->flags & BLOSC_DOSHUFFLE) && (header->flags & BLOSC_DOBITSHUFFLE)) {
  ------------------
  |  Branch (713:7): [True: 8, False: 16]
  |  Branch (713:28): [True: 8, False: 0]
  |  Branch (713:65): [True: 8, False: 0]
  ------------------
  714|      8|    if (header->cbytes < BLOSC_EXTENDED_HEADER_LENGTH) {
  ------------------
  |  Branch (714:9): [True: 0, False: 8]
  ------------------
  715|      0|      BLOSC_TRACE_ERROR("`cbytes` is too small to read extended header.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  716|      0|      return BLOSC2_ERROR_INVALID_HEADER;
  717|      0|    }
  718|      8|    if (srcsize < BLOSC_EXTENDED_HEADER_LENGTH) {
  ------------------
  |  Branch (718:9): [True: 0, False: 8]
  ------------------
  719|      0|      BLOSC_TRACE_ERROR("Not enough space to read Blosc extended header.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  720|      0|      return BLOSC2_ERROR_READ_BUFFER;
  721|      0|    }
  722|       |
  723|      8|    memcpy((uint8_t *)header + BLOSC_MIN_HEADER_LENGTH, src + BLOSC_MIN_HEADER_LENGTH,
  724|      8|      BLOSC_EXTENDED_HEADER_LENGTH - BLOSC_MIN_HEADER_LENGTH);
  725|       |
  726|      8|    int32_t special_type = (header->blosc2_flags >> 4) & BLOSC2_SPECIAL_MASK;
  727|      8|    if (special_type != 0) {
  ------------------
  |  Branch (727:9): [True: 1, False: 7]
  ------------------
  728|      1|      if (header->nbytes % header->typesize != 0) {
  ------------------
  |  Branch (728:11): [True: 0, False: 1]
  ------------------
  729|      0|        BLOSC_TRACE_ERROR("`nbytes` is not a multiple of typesize");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  730|      0|        return BLOSC2_ERROR_INVALID_HEADER;
  731|      0|      }
  732|      1|      if (special_type == BLOSC2_SPECIAL_VALUE) {
  ------------------
  |  Branch (732:11): [True: 0, False: 1]
  ------------------
  733|      0|        if (header->cbytes < BLOSC_EXTENDED_HEADER_LENGTH + header->typesize) {
  ------------------
  |  Branch (733:13): [True: 0, False: 0]
  ------------------
  734|      0|          BLOSC_TRACE_ERROR("`cbytes` is too small for run length encoding");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  735|      0|          return BLOSC2_ERROR_READ_BUFFER;
  736|      0|        }
  737|      0|      }
  738|      1|    }
  739|       |    // The number of filters depends on the version of the header. Blosc2 alpha series
  740|       |    // did not initialize filters to zero beyond the max supported.
  741|      8|    if (header->version == BLOSC2_VERSION_FORMAT_ALPHA) {
  ------------------
  |  Branch (741:9): [True: 0, False: 8]
  ------------------
  742|      0|      header->filters[5] = 0;
  743|      0|      header->filters_meta[5] = 0;
  744|      0|    }
  745|      8|  }
  746|     16|  else {
  747|     16|    flags_to_filters(header->flags, header->filters);
  748|     16|  }
  749|     24|  return 0;
  750|     24|}
_cycle_buffers:
  917|      4|void _cycle_buffers(uint8_t **src, uint8_t **dest, uint8_t **tmp) {
  918|      4|  uint8_t *tmp2 = *src;
  919|      4|  *src = *dest;
  920|      4|  *dest = *tmp;
  921|      4|  *tmp = tmp2;
  922|      4|}
pipeline_backward:
 1322|      4|                      uint8_t* tmp2, int last_filter_index, int32_t nblock) {
 1323|      4|  blosc2_context* context = thread_context->parent_context;
 1324|      4|  int32_t typesize = context->typesize;
 1325|      4|  uint8_t* filters = context->filters;
 1326|      4|  uint8_t* filters_meta = context->filters_meta;
 1327|      4|  uint8_t* _src = src;
 1328|      4|  uint8_t* _dest = tmp;
 1329|      4|  uint8_t* _tmp = tmp2;
 1330|      4|  int errcode = 0;
 1331|       |
 1332|      4|  for (int i = BLOSC2_MAX_FILTERS - 1; i >= 0; i--) {
  ------------------
  |  Branch (1332:40): [True: 4, False: 0]
  ------------------
 1333|       |    // Delta filter requires the whole chunk ready
 1334|      4|    int last_copy_filter = (last_filter_index == i) || (next_filter(filters, i, 'd') == BLOSC_DELTA);
  ------------------
  |  Branch (1334:28): [True: 4, False: 0]
  |  Branch (1334:56): [True: 0, False: 0]
  ------------------
 1335|      4|    if (last_copy_filter && context->postfilter == NULL) {
  ------------------
  |  Branch (1335:9): [True: 4, False: 0]
  |  Branch (1335:29): [True: 4, False: 0]
  ------------------
 1336|      4|      _dest = dest + offset;
 1337|      4|    }
 1338|      4|    int rc = BLOSC2_ERROR_SUCCESS;
 1339|      4|    if (filters[i] <= BLOSC2_DEFINED_FILTERS_STOP) {
  ------------------
  |  Branch (1339:9): [True: 4, False: 0]
  ------------------
 1340|      4|      switch (filters[i]) {
 1341|      4|        case BLOSC_SHUFFLE:
  ------------------
  |  Branch (1341:9): [True: 4, False: 0]
  ------------------
 1342|      4|          unshuffle(typesize, bsize, _src, _dest);
 1343|      4|          break;
 1344|      0|        case BLOSC_BITSHUFFLE:
  ------------------
  |  Branch (1344:9): [True: 0, False: 4]
  ------------------
 1345|      0|          if (bitunshuffle(typesize, bsize, _src, _dest, context->src[BLOSC2_CHUNK_VERSION]) < 0) {
  ------------------
  |  Branch (1345:15): [True: 0, False: 0]
  ------------------
 1346|      0|            return BLOSC2_ERROR_FILTER_PIPELINE;
 1347|      0|          }
 1348|      0|          break;
 1349|      0|        case BLOSC_DELTA:
  ------------------
  |  Branch (1349:9): [True: 0, False: 4]
  ------------------
 1350|      0|          if (context->nthreads == 1) {
  ------------------
  |  Branch (1350:15): [True: 0, False: 0]
  ------------------
 1351|       |            /* Serial mode */
 1352|      0|            delta_decoder(dest, offset, bsize, typesize, _dest);
 1353|      0|          } else {
 1354|       |            /* Force the thread in charge of the block 0 to go first */
 1355|      0|            pthread_mutex_lock(&context->delta_mutex);
 1356|      0|            if (context->dref_not_init) {
  ------------------
  |  Branch (1356:17): [True: 0, False: 0]
  ------------------
 1357|      0|              if (offset != 0) {
  ------------------
  |  Branch (1357:19): [True: 0, False: 0]
  ------------------
 1358|      0|                pthread_cond_wait(&context->delta_cv, &context->delta_mutex);
 1359|      0|              } else {
 1360|      0|                delta_decoder(dest, offset, bsize, typesize, _dest);
 1361|      0|                context->dref_not_init = 0;
 1362|      0|                pthread_cond_broadcast(&context->delta_cv);
 1363|      0|              }
 1364|      0|            }
 1365|      0|            pthread_mutex_unlock(&context->delta_mutex);
 1366|      0|            if (offset != 0) {
  ------------------
  |  Branch (1366:17): [True: 0, False: 0]
  ------------------
 1367|      0|              delta_decoder(dest, offset, bsize, typesize, _dest);
 1368|      0|            }
 1369|      0|          }
 1370|      0|          break;
 1371|      0|        case BLOSC_TRUNC_PREC:
  ------------------
  |  Branch (1371:9): [True: 0, False: 4]
  ------------------
 1372|       |          // TRUNC_PREC filter does not need to be undone
 1373|      0|          break;
 1374|      0|        default:
  ------------------
  |  Branch (1374:9): [True: 0, False: 4]
  ------------------
 1375|      0|          if (filters[i] != BLOSC_NOFILTER) {
  ------------------
  |  Branch (1375:15): [True: 0, False: 0]
  ------------------
 1376|      0|            BLOSC_TRACE_ERROR("Filter %d not handled during decompression.",
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1377|      0|                              filters[i]);
 1378|      0|            errcode = -1;
 1379|      0|          }
 1380|      4|      }
 1381|      4|    } else {
 1382|       |        // Look for the filters_meta in user filters and run it
 1383|      0|        for (uint64_t j = 0; j < g_nfilters; ++j) {
  ------------------
  |  Branch (1383:30): [True: 0, False: 0]
  ------------------
 1384|      0|          if (g_filters[j].id == filters[i]) {
  ------------------
  |  Branch (1384:15): [True: 0, False: 0]
  ------------------
 1385|      0|            if (g_filters[j].backward == NULL) {
  ------------------
  |  Branch (1385:17): [True: 0, False: 0]
  ------------------
 1386|       |              // Dynamically load filter
 1387|      0|              if (fill_filter(&g_filters[j]) < 0) {
  ------------------
  |  Branch (1387:19): [True: 0, False: 0]
  ------------------
 1388|      0|                BLOSC_TRACE_ERROR("Could not load filter %d.", g_filters[j].id);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1389|      0|                return BLOSC2_ERROR_FILTER_PIPELINE;
 1390|      0|              }
 1391|      0|            }
 1392|      0|            if (g_filters[j].backward != NULL) {
  ------------------
  |  Branch (1392:17): [True: 0, False: 0]
  ------------------
 1393|      0|              blosc2_dparams dparams;
 1394|      0|              blosc2_ctx_get_dparams(context, &dparams);
 1395|      0|              rc = g_filters[j].backward(_src, _dest, bsize, filters_meta[i], &dparams, g_filters[j].id);
 1396|      0|            } else {
 1397|      0|              BLOSC_TRACE_ERROR("Backward function is NULL");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1398|      0|              return BLOSC2_ERROR_FILTER_PIPELINE;
 1399|      0|            }
 1400|      0|            if (rc != BLOSC2_ERROR_SUCCESS) {
  ------------------
  |  Branch (1400:17): [True: 0, False: 0]
  ------------------
 1401|      0|              BLOSC_TRACE_ERROR("User-defined filter %d failed during decompression.", filters[i]);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1402|      0|              return rc;
 1403|      0|            }
 1404|      0|            goto urfiltersuccess;
 1405|      0|          }
 1406|      0|        }
 1407|      0|      BLOSC_TRACE_ERROR("User-defined filter %d not found during decompression.", filters[i]);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1408|      0|      return BLOSC2_ERROR_FILTER_PIPELINE;
 1409|      0|      urfiltersuccess:;
 1410|      0|    }
 1411|       |
 1412|       |    // Cycle buffers when required
 1413|      4|    if ((filters[i] != BLOSC_NOFILTER) && (filters[i] != BLOSC_TRUNC_PREC)) {
  ------------------
  |  Branch (1413:9): [True: 4, False: 0]
  |  Branch (1413:43): [True: 4, False: 0]
  ------------------
 1414|      4|      _cycle_buffers(&_src, &_dest, &_tmp);
 1415|      4|    }
 1416|      4|    if (last_filter_index == i) {
  ------------------
  |  Branch (1416:9): [True: 4, False: 0]
  ------------------
 1417|      4|      break;
 1418|      4|    }
 1419|      4|  }
 1420|       |
 1421|       |  /* Postfilter function */
 1422|      4|  if (context->postfilter != NULL) {
  ------------------
  |  Branch (1422:7): [True: 0, False: 4]
  ------------------
 1423|       |    // Create new postfilter parameters for this block (must be private for each thread)
 1424|      0|    blosc2_postfilter_params postparams;
 1425|      0|    memcpy(&postparams, context->postparams, sizeof(postparams));
 1426|      0|    postparams.input = _src;
 1427|      0|    postparams.output = dest + offset;
 1428|      0|    postparams.size = bsize;
 1429|      0|    postparams.typesize = typesize;
 1430|      0|    postparams.offset = nblock * context->blocksize;
 1431|      0|    postparams.nchunk = context->schunk != NULL ? context->schunk->current_nchunk : -1;
  ------------------
  |  Branch (1431:25): [True: 0, False: 0]
  ------------------
 1432|      0|    postparams.nblock = nblock;
 1433|      0|    postparams.tid = thread_context->tid;
 1434|      0|    postparams.ttmp = thread_context->tmp;
 1435|      0|    postparams.ttmp_nbytes = thread_context->tmp_nbytes;
 1436|      0|    postparams.ctx = context;
 1437|       |
 1438|      0|    if (context->postfilter(&postparams) != 0) {
  ------------------
  |  Branch (1438:9): [True: 0, False: 0]
  ------------------
 1439|      0|      BLOSC_TRACE_ERROR("Execution of postfilter function failed");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1440|      0|      return BLOSC2_ERROR_POSTFILTER;
 1441|      0|    }
 1442|      0|  }
 1443|       |
 1444|      4|  return errcode;
 1445|      4|}
free_thread_context:
 2088|      6|void free_thread_context(struct thread_context* thread_context) {
 2089|      6|  destroy_thread_context(thread_context);
 2090|      6|  my_free(thread_context);
 2091|      6|}
check_nthreads:
 2094|      3|int check_nthreads(blosc2_context* context) {
 2095|      3|  if (context->nthreads <= 0) {
  ------------------
  |  Branch (2095:7): [True: 0, False: 3]
  ------------------
 2096|      0|    BLOSC_TRACE_ERROR("nthreads must be >= 1 and <= %d", INT16_MAX);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  | 2096|      0|    BLOSC_TRACE_ERROR("nthreads must be >= 1 and <= %d", INT16_MAX);
  |  |  |  |  ------------------
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2097|      0|    return BLOSC2_ERROR_INVALID_PARAM;
 2098|      0|  }
 2099|       |
 2100|      3|  if (context->new_nthreads != context->nthreads) {
  ------------------
  |  Branch (2100:7): [True: 0, False: 3]
  ------------------
 2101|      0|    if (context->nthreads > 1) {
  ------------------
  |  Branch (2101:9): [True: 0, False: 0]
  ------------------
 2102|      0|      release_threadpool(context);
 2103|      0|    }
 2104|      0|    context->nthreads = context->new_nthreads;
 2105|      0|  }
 2106|      3|  if (context->new_nthreads > 1 && context->threads_started == 0) {
  ------------------
  |  Branch (2106:7): [True: 0, False: 3]
  |  Branch (2106:36): [True: 0, False: 0]
  ------------------
 2107|      0|    init_threadpool(context);
 2108|      0|  }
 2109|       |
 2110|      3|  return context->nthreads;
 2111|      3|}
build_filters:
 2677|      2|                   const int32_t typesize, uint8_t* filters) {
 2678|       |
 2679|       |  /* Fill the end part of the filter pipeline */
 2680|      2|  if ((doshuffle == BLOSC_SHUFFLE) && (typesize > 1))
  ------------------
  |  Branch (2680:7): [True: 0, False: 2]
  |  Branch (2680:39): [True: 0, False: 0]
  ------------------
 2681|      0|    filters[BLOSC2_MAX_FILTERS - 1] = BLOSC_SHUFFLE;
 2682|      2|  if (doshuffle == BLOSC_BITSHUFFLE)
  ------------------
  |  Branch (2682:7): [True: 0, False: 2]
  ------------------
 2683|      0|    filters[BLOSC2_MAX_FILTERS - 1] = BLOSC_BITSHUFFLE;
 2684|      2|  if (doshuffle == BLOSC_NOSHUFFLE)
  ------------------
  |  Branch (2684:7): [True: 0, False: 2]
  ------------------
 2685|      0|    filters[BLOSC2_MAX_FILTERS - 1] = BLOSC_NOSHUFFLE;
 2686|      2|  if (delta)
  ------------------
  |  Branch (2686:7): [True: 0, False: 2]
  ------------------
 2687|      0|    filters[BLOSC2_MAX_FILTERS - 2] = BLOSC_DELTA;
 2688|      2|}
blosc2_decompress_ctx:
 2930|      4|                          void* dest, int32_t destsize) {
 2931|      4|  int result;
 2932|       |
 2933|      4|  if (context->do_compress != 0) {
  ------------------
  |  Branch (2933:7): [True: 0, False: 4]
  ------------------
 2934|      0|    BLOSC_TRACE_ERROR("Context is not meant for decompression.  Giving up.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2935|      0|    return BLOSC2_ERROR_INVALID_PARAM;
 2936|      0|  }
 2937|       |
 2938|      4|  result = blosc_run_decompression_with_context(context, src, srcsize, dest, destsize);
 2939|       |
 2940|       |  // Reset a possible block_maskout
 2941|      4|  if (context->block_maskout != NULL) {
  ------------------
  |  Branch (2941:7): [True: 0, False: 4]
  ------------------
 2942|      0|    free(context->block_maskout);
 2943|      0|    context->block_maskout = NULL;
 2944|      0|  }
 2945|      4|  context->block_maskout_nitems = 0;
 2946|       |
 2947|      4|  return result;
 2948|      4|}
_blosc_getitem:
 3015|      4|                   int start, int nitems, void* dest, int32_t destsize) {
 3016|      4|  uint8_t* _src = (uint8_t*)(src);  /* current pos for source buffer */
 3017|      4|  uint8_t* _dest = (uint8_t*)(dest);
 3018|      4|  int32_t ntbytes = 0;              /* the number of uncompressed bytes */
 3019|      4|  int32_t bsize, bsize2, ebsize, leftoverblock;
 3020|      4|  int32_t startb, stopb;
 3021|      4|  int32_t stop = start + nitems;
 3022|      4|  int j, rc;
 3023|       |
 3024|      4|  if (nitems == 0) {
  ------------------
  |  Branch (3024:7): [True: 0, False: 4]
  ------------------
 3025|       |    // We have nothing to do
 3026|      0|    return 0;
 3027|      0|  }
 3028|      4|  if (nitems * header->typesize > destsize) {
  ------------------
  |  Branch (3028:7): [True: 0, False: 4]
  ------------------
 3029|      0|    BLOSC_TRACE_ERROR("`nitems`*`typesize` out of dest bounds.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3030|      0|    return BLOSC2_ERROR_WRITE_BUFFER;
 3031|      0|  }
 3032|       |
 3033|      4|  context->bstarts = (int32_t*)(_src + context->header_overhead);
 3034|       |
 3035|       |  /* Check region boundaries */
 3036|      4|  if ((start < 0) || (start * header->typesize > header->nbytes)) {
  ------------------
  |  Branch (3036:7): [True: 0, False: 4]
  |  Branch (3036:22): [True: 0, False: 4]
  ------------------
 3037|      0|    BLOSC_TRACE_ERROR("`start` out of bounds.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3038|      0|    return BLOSC2_ERROR_INVALID_PARAM;
 3039|      0|  }
 3040|       |
 3041|      4|  if ((stop < 0) || (stop * header->typesize > header->nbytes)) {
  ------------------
  |  Branch (3041:7): [True: 0, False: 4]
  |  Branch (3041:21): [True: 0, False: 4]
  ------------------
 3042|      0|    BLOSC_TRACE_ERROR("`start`+`nitems` out of bounds.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3043|      0|    return BLOSC2_ERROR_INVALID_PARAM;
 3044|      0|  }
 3045|       |
 3046|      4|  int chunk_memcpy = header->flags & 0x1;
 3047|      4|  if (!context->special_type && !chunk_memcpy &&
  ------------------
  |  Branch (3047:7): [True: 4, False: 0]
  |  Branch (3047:33): [True: 0, False: 4]
  ------------------
 3048|      4|      ((uint8_t *)(_src + srcsize) < (uint8_t *)(context->bstarts + context->nblocks))) {
  ------------------
  |  Branch (3048:7): [True: 0, False: 0]
  ------------------
 3049|      0|    BLOSC_TRACE_ERROR("`bstarts` out of bounds.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3050|      0|    return BLOSC2_ERROR_READ_BUFFER;
 3051|      0|  }
 3052|       |
 3053|      4|  bool memcpyed = header->flags & (uint8_t)BLOSC_MEMCPYED;
 3054|      4|  if (context->special_type) {
  ------------------
  |  Branch (3054:7): [True: 0, False: 4]
  ------------------
 3055|       |    // Fake a runlen as if its a memcpyed chunk
 3056|      0|    memcpyed = true;
 3057|      0|  }
 3058|       |
 3059|      4|  bool is_lazy = ((context->header_overhead == BLOSC_EXTENDED_HEADER_LENGTH) &&
  ------------------
  |  Branch (3059:19): [True: 4, False: 0]
  ------------------
 3060|      4|                  (context->blosc2_flags & 0x08u) && !context->special_type);
  ------------------
  |  Branch (3060:19): [True: 0, False: 4]
  |  Branch (3060:54): [True: 0, False: 0]
  ------------------
 3061|      4|  if (memcpyed && !is_lazy && !context->postfilter) {
  ------------------
  |  Branch (3061:7): [True: 4, False: 0]
  |  Branch (3061:19): [True: 4, False: 0]
  |  Branch (3061:31): [True: 4, False: 0]
  ------------------
 3062|       |    // Short-circuit for (non-lazy) memcpyed or special values
 3063|      4|    ntbytes = nitems * header->typesize;
 3064|      4|    switch (context->special_type) {
 3065|      0|      case BLOSC2_SPECIAL_VALUE:
  ------------------
  |  Branch (3065:7): [True: 0, False: 4]
  ------------------
 3066|       |        // All repeated values
 3067|      0|        rc = set_values(context->typesize, _src, _dest, ntbytes);
 3068|      0|        if (rc < 0) {
  ------------------
  |  Branch (3068:13): [True: 0, False: 0]
  ------------------
 3069|      0|          BLOSC_TRACE_ERROR("set_values failed");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3070|      0|          return BLOSC2_ERROR_DATA;
 3071|      0|        }
 3072|      0|        break;
 3073|      0|      case BLOSC2_SPECIAL_NAN:
  ------------------
  |  Branch (3073:7): [True: 0, False: 4]
  ------------------
 3074|      0|        rc = set_nans(context->typesize, _dest, ntbytes);
 3075|      0|        if (rc < 0) {
  ------------------
  |  Branch (3075:13): [True: 0, False: 0]
  ------------------
 3076|      0|          BLOSC_TRACE_ERROR("set_nans failed");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3077|      0|          return BLOSC2_ERROR_DATA;
 3078|      0|        }
 3079|      0|        break;
 3080|      0|      case BLOSC2_SPECIAL_ZERO:
  ------------------
  |  Branch (3080:7): [True: 0, False: 4]
  ------------------
 3081|      0|        memset(_dest, 0, ntbytes);
 3082|      0|        break;
 3083|      0|      case BLOSC2_SPECIAL_UNINIT:
  ------------------
  |  Branch (3083:7): [True: 0, False: 4]
  ------------------
 3084|       |        // We do nothing here
 3085|      0|        break;
 3086|      4|      case BLOSC2_NO_SPECIAL:
  ------------------
  |  Branch (3086:7): [True: 4, False: 0]
  ------------------
 3087|      4|        _src += context->header_overhead + start * context->typesize;
 3088|      4|        memcpy(_dest, _src, ntbytes);
 3089|      4|        break;
 3090|      0|      default:
  ------------------
  |  Branch (3090:7): [True: 0, False: 4]
  ------------------
 3091|      0|        BLOSC_TRACE_ERROR("Unhandled special value case");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3092|      0|        BLOSC_ERROR(BLOSC2_ERROR_SCHUNK_SPECIAL);
  ------------------
  |  |  115|      0|    do {                                            \
  |  |  116|      0|        int rc_ = (rc);                             \
  |  |  117|      0|        if (rc_ < BLOSC2_ERROR_SUCCESS) {           \
  |  |  ------------------
  |  |  |  Branch (117:13): [True: 0, False: 0]
  |  |  ------------------
  |  |  118|      0|            char *error_msg = print_error(rc_);     \
  |  |  119|      0|            BLOSC_TRACE_ERROR("%s", error_msg);     \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  120|      0|            return rc_;                             \
  |  |  121|      0|        }                                           \
  |  |  122|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (122:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3093|      4|    }
 3094|      4|    return ntbytes;
 3095|      4|  }
 3096|       |
 3097|      0|  ebsize = header->blocksize + header->typesize * (signed)sizeof(int32_t);
 3098|      0|  struct thread_context* scontext = context->serial_context;
 3099|       |  /* Resize the temporaries in serial context if needed */
 3100|      0|  if (header->blocksize > scontext->tmp_blocksize) {
  ------------------
  |  Branch (3100:7): [True: 0, False: 0]
  ------------------
 3101|      0|    my_free(scontext->tmp);
 3102|      0|    scontext->tmp_nbytes = (size_t)4 * ebsize;
 3103|      0|    scontext->tmp = my_malloc(scontext->tmp_nbytes);
 3104|      0|    BLOSC_ERROR_NULL(scontext->tmp, BLOSC2_ERROR_MEMORY_ALLOC);
  ------------------
  |  |  108|      0|    do {                                            \
  |  |  109|      0|        if ((pointer) == NULL) {                    \
  |  |  ------------------
  |  |  |  Branch (109:13): [True: 0, False: 0]
  |  |  ------------------
  |  |  110|      0|            BLOSC_TRACE_ERROR("Pointer is null");   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  111|      0|            return (rc);                            \
  |  |  112|      0|        }                                           \
  |  |  113|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3105|      0|    scontext->tmp2 = scontext->tmp + ebsize;
 3106|      0|    scontext->tmp3 = scontext->tmp2 + ebsize;
 3107|      0|    scontext->tmp4 = scontext->tmp3 + ebsize;
 3108|      0|    scontext->tmp_blocksize = (int32_t)header->blocksize;
 3109|      0|  }
 3110|       |
 3111|      0|  for (j = 0; j < context->nblocks; j++) {
  ------------------
  |  Branch (3111:15): [True: 0, False: 0]
  ------------------
 3112|      0|    bsize = header->blocksize;
 3113|      0|    leftoverblock = 0;
 3114|      0|    if ((j == context->nblocks - 1) && (context->leftover > 0)) {
  ------------------
  |  Branch (3114:9): [True: 0, False: 0]
  |  Branch (3114:40): [True: 0, False: 0]
  ------------------
 3115|      0|      bsize = context->leftover;
 3116|      0|      leftoverblock = 1;
 3117|      0|    }
 3118|       |
 3119|       |    /* Compute start & stop for each block */
 3120|      0|    startb = start * header->typesize - j * header->blocksize;
 3121|      0|    stopb = stop * header->typesize - j * header->blocksize;
 3122|      0|    if (stopb <= 0) {
  ------------------
  |  Branch (3122:9): [True: 0, False: 0]
  ------------------
 3123|       |      // We can exit as soon as this block is beyond stop
 3124|      0|      break;
 3125|      0|    }
 3126|      0|    if (startb >= header->blocksize) {
  ------------------
  |  Branch (3126:9): [True: 0, False: 0]
  ------------------
 3127|      0|      continue;
 3128|      0|    }
 3129|      0|    if (startb < 0) {
  ------------------
  |  Branch (3129:9): [True: 0, False: 0]
  ------------------
 3130|      0|      startb = 0;
 3131|      0|    }
 3132|      0|    if (stopb > header->blocksize) {
  ------------------
  |  Branch (3132:9): [True: 0, False: 0]
  ------------------
 3133|      0|      stopb = header->blocksize;
 3134|      0|    }
 3135|      0|    bsize2 = stopb - startb;
 3136|       |
 3137|      0|#if defined(HAVE_PLUGINS)
 3138|      0|    if (context->compcode == BLOSC_CODEC_ZFP_FIXED_RATE) {
  ------------------
  |  Branch (3138:9): [True: 0, False: 0]
  ------------------
 3139|      0|      scontext->zfp_cell_start = startb / context->typesize;
 3140|      0|      scontext->zfp_cell_nitems = nitems;
 3141|      0|    }
 3142|      0|#endif /* HAVE_PLUGINS */
 3143|       |
 3144|       |    /* Do the actual data copy */
 3145|       |    // Regular decompression.  Put results in tmp2.
 3146|       |    // If the block is aligned and the worst case fits in destination, let's avoid a copy
 3147|      0|    bool get_single_block = ((startb == 0) && (bsize == nitems * header->typesize));
  ------------------
  |  Branch (3147:30): [True: 0, False: 0]
  |  Branch (3147:47): [True: 0, False: 0]
  ------------------
 3148|      0|    uint8_t* tmp2 = get_single_block ? dest : scontext->tmp2;
  ------------------
  |  Branch (3148:21): [True: 0, False: 0]
  ------------------
 3149|       |
 3150|       |    // If memcpyed we don't have a bstarts section (because it is not needed)
 3151|      0|    int32_t src_offset = memcpyed ?
  ------------------
  |  Branch (3151:26): [True: 0, False: 0]
  ------------------
 3152|      0|      context->header_overhead + j * header->blocksize : sw32_(context->bstarts + j);
 3153|       |
 3154|      0|    int32_t cbytes = blosc_d(context->serial_context, bsize, leftoverblock, memcpyed,
 3155|      0|                             src, srcsize, src_offset, j,
 3156|      0|                             tmp2, 0, scontext->tmp, scontext->tmp3);
 3157|      0|    if (cbytes < 0) {
  ------------------
  |  Branch (3157:9): [True: 0, False: 0]
  ------------------
 3158|      0|      ntbytes = cbytes;
 3159|      0|      break;
 3160|      0|    }
 3161|      0|    if (scontext->zfp_cell_nitems > 0) {
  ------------------
  |  Branch (3161:9): [True: 0, False: 0]
  ------------------
 3162|      0|      if (cbytes == bsize2) {
  ------------------
  |  Branch (3162:11): [True: 0, False: 0]
  ------------------
 3163|      0|        memcpy((uint8_t *) dest, tmp2, (unsigned int) bsize2);
 3164|      0|      } else if (cbytes == context->blocksize) {
  ------------------
  |  Branch (3164:18): [True: 0, False: 0]
  ------------------
 3165|      0|        memcpy((uint8_t *) dest, tmp2 + scontext->zfp_cell_start * context->typesize, (unsigned int) bsize2);
 3166|      0|        cbytes = bsize2;
 3167|      0|      }
 3168|      0|    } else if (!get_single_block) {
  ------------------
  |  Branch (3168:16): [True: 0, False: 0]
  ------------------
 3169|       |      /* Copy to destination */
 3170|      0|      memcpy((uint8_t *) dest + ntbytes, tmp2 + startb, (unsigned int) bsize2);
 3171|      0|    }
 3172|      0|    ntbytes += bsize2;
 3173|      0|  }
 3174|       |
 3175|      0|  scontext->zfp_cell_nitems = 0;
 3176|       |
 3177|      0|  return ntbytes;
 3178|      0|}
blosc2_getitem:
 3180|      4|int blosc2_getitem(const void* src, int32_t srcsize, int start, int nitems, void* dest, int32_t destsize) {
 3181|      4|  blosc2_context context;
 3182|      4|  int result;
 3183|       |
 3184|       |  /* Minimally populate the context */
 3185|      4|  memset(&context, 0, sizeof(blosc2_context));
 3186|       |
 3187|      4|  context.schunk = g_schunk;
 3188|      4|  context.nthreads = 1;  // force a serial decompression; fixes #95
 3189|       |
 3190|       |  /* Call the actual getitem function */
 3191|      4|  result = blosc2_getitem_ctx(&context, src, srcsize, start, nitems, dest, destsize);
 3192|       |
 3193|       |  /* Release resources */
 3194|      4|  if (context.serial_context != NULL) {
  ------------------
  |  Branch (3194:7): [True: 4, False: 0]
  ------------------
 3195|      4|    free_thread_context(context.serial_context);
 3196|      4|  }
 3197|      4|  return result;
 3198|      4|}
blosc2_getitem_ctx:
 3207|      4|    int start, int nitems, void* dest, int32_t destsize) {
 3208|      4|  blosc_header header;
 3209|      4|  int result;
 3210|       |
 3211|       |  /* Minimally populate the context */
 3212|      4|  result = read_chunk_header((uint8_t *) src, srcsize, true, &header);
 3213|      4|  if (result < 0) {
  ------------------
  |  Branch (3213:7): [True: 0, False: 4]
  ------------------
 3214|      0|    return result;
 3215|      0|  }
 3216|       |
 3217|      4|  context->src = src;
 3218|      4|  context->srcsize = srcsize;
 3219|      4|  context->dest = dest;
 3220|      4|  context->destsize = destsize;
 3221|       |
 3222|      4|  result = blosc2_initialize_context_from_header(context, &header);
 3223|      4|  if (result < 0) {
  ------------------
  |  Branch (3223:7): [True: 0, False: 4]
  ------------------
 3224|      0|    return result;
 3225|      0|  }
 3226|       |
 3227|      4|  if (context->serial_context == NULL) {
  ------------------
  |  Branch (3227:7): [True: 4, False: 0]
  ------------------
 3228|      4|    context->serial_context = create_thread_context(context, 0);
 3229|      4|  }
 3230|      4|  BLOSC_ERROR_NULL(context->serial_context, BLOSC2_ERROR_THREAD_CREATE);
  ------------------
  |  |  108|      4|    do {                                            \
  |  |  109|      4|        if ((pointer) == NULL) {                    \
  |  |  ------------------
  |  |  |  Branch (109:13): [True: 0, False: 4]
  |  |  ------------------
  |  |  110|      0|            BLOSC_TRACE_ERROR("Pointer is null");   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  111|      0|            return (rc);                            \
  |  |  112|      0|        }                                           \
  |  |  113|      4|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3231|       |  /* Call the actual getitem function */
 3232|      4|  result = _blosc_getitem(context, &header, src, srcsize, start, nitems, dest, destsize);
 3233|       |
 3234|      4|  return result;
 3235|      4|}
blosc2_get_nthreads:
 3531|      2|{
 3532|      2|  return g_nthreads;
 3533|      2|}
blosc2_set_nthreads:
 3535|      7|int16_t blosc2_set_nthreads(int16_t nthreads) {
 3536|      7|  int16_t ret = g_nthreads;          /* the previous number of threads */
 3537|       |
 3538|       |  /* Check whether the library should be initialized */
 3539|      7|  if (!g_initlib) blosc2_init();
  ------------------
  |  Branch (3539:7): [True: 0, False: 7]
  ------------------
 3540|       |
 3541|      7| if (nthreads != ret) {
  ------------------
  |  Branch (3541:6): [True: 0, False: 7]
  ------------------
 3542|      0|   g_nthreads = nthreads;
 3543|      0|   g_global_context->new_nthreads = nthreads;
 3544|      0|   int16_t ret2 = check_nthreads(g_global_context);
 3545|      0|   if (ret2 < 0) {
  ------------------
  |  Branch (3545:8): [True: 0, False: 0]
  ------------------
 3546|      0|     return ret2;
 3547|      0|   }
 3548|      0| }
 3549|       |
 3550|      7|  return ret;
 3551|      7|}
blosc2_cbuffer_sizes:
 3670|     16|int blosc2_cbuffer_sizes(const void* cbuffer, int32_t* nbytes, int32_t* cbytes, int32_t* blocksize) {
 3671|     16|  blosc_header header;
 3672|     16|  int rc = read_chunk_header((uint8_t *) cbuffer, BLOSC_MIN_HEADER_LENGTH, false, &header);
 3673|     16|  if (rc < 0) {
  ------------------
  |  Branch (3673:7): [True: 0, False: 16]
  ------------------
 3674|       |    /* Return zeros if error reading header */
 3675|      0|    memset(&header, 0, sizeof(header));
 3676|      0|  }
 3677|       |
 3678|       |  /* Read the interesting values */
 3679|     16|  if (nbytes != NULL)
  ------------------
  |  Branch (3679:7): [True: 13, False: 3]
  ------------------
 3680|     13|    *nbytes = header.nbytes;
 3681|     16|  if (cbytes != NULL)
  ------------------
  |  Branch (3681:7): [True: 16, False: 0]
  ------------------
 3682|     16|    *cbytes = header.cbytes;
 3683|     16|  if (blocksize != NULL)
  ------------------
  |  Branch (3683:7): [True: 4, False: 12]
  ------------------
 3684|      4|    *blocksize = header.blocksize;
 3685|     16|  return rc;
 3686|     16|}
blosc2_init:
 3795|      7|void blosc2_init(void) {
 3796|       |  /* Return if Blosc is already initialized */
 3797|      7|  if (g_initlib) return;
  ------------------
  |  Branch (3797:7): [True: 0, False: 7]
  ------------------
 3798|       |
 3799|      7|  BLOSC2_IO_CB_DEFAULTS.id = BLOSC2_IO_FILESYSTEM;
 3800|      7|  BLOSC2_IO_CB_DEFAULTS.name = "filesystem";
 3801|      7|  BLOSC2_IO_CB_DEFAULTS.is_allocation_necessary = true;
 3802|      7|  BLOSC2_IO_CB_DEFAULTS.open = (blosc2_open_cb) blosc2_stdio_open;
 3803|      7|  BLOSC2_IO_CB_DEFAULTS.close = (blosc2_close_cb) blosc2_stdio_close;
 3804|      7|  BLOSC2_IO_CB_DEFAULTS.size = (blosc2_size_cb) blosc2_stdio_size;
 3805|      7|  BLOSC2_IO_CB_DEFAULTS.write = (blosc2_write_cb) blosc2_stdio_write;
 3806|      7|  BLOSC2_IO_CB_DEFAULTS.read = (blosc2_read_cb) blosc2_stdio_read;
 3807|      7|  BLOSC2_IO_CB_DEFAULTS.truncate = (blosc2_truncate_cb) blosc2_stdio_truncate;
 3808|      7|  BLOSC2_IO_CB_DEFAULTS.destroy = (blosc2_destroy_cb) blosc2_stdio_destroy;
 3809|       |
 3810|      7|  BLOSC2_IO_CB_MMAP.id = BLOSC2_IO_FILESYSTEM_MMAP;
 3811|      7|  BLOSC2_IO_CB_MMAP.name = "filesystem_mmap";
 3812|      7|  BLOSC2_IO_CB_MMAP.is_allocation_necessary = false;
 3813|      7|  BLOSC2_IO_CB_MMAP.open = (blosc2_open_cb) blosc2_stdio_mmap_open;
 3814|      7|  BLOSC2_IO_CB_MMAP.close = (blosc2_close_cb) blosc2_stdio_mmap_close;
 3815|      7|  BLOSC2_IO_CB_MMAP.read = (blosc2_read_cb) blosc2_stdio_mmap_read;
 3816|      7|  BLOSC2_IO_CB_MMAP.size = (blosc2_size_cb) blosc2_stdio_mmap_size;
 3817|      7|  BLOSC2_IO_CB_MMAP.write = (blosc2_write_cb) blosc2_stdio_mmap_write;
 3818|      7|  BLOSC2_IO_CB_MMAP.truncate = (blosc2_truncate_cb) blosc2_stdio_mmap_truncate;
 3819|      7|  BLOSC2_IO_CB_MMAP.destroy = (blosc2_destroy_cb) blosc2_stdio_mmap_destroy;
 3820|       |
 3821|      7|  g_ncodecs = 0;
 3822|      7|  g_nfilters = 0;
 3823|      7|  g_ntuners = 0;
 3824|       |
 3825|      7|#if defined(HAVE_PLUGINS)
 3826|      7|  #include "blosc2/blosc2-common.h"
 3827|      7|  #include "blosc2/blosc2-stdio.h"
 3828|      7|  register_codecs();
 3829|      7|  register_filters();
 3830|      7|  register_tuners();
 3831|      7|#endif
 3832|      7|  pthread_mutex_init(&global_comp_mutex, NULL);
 3833|       |  /* Create a global context */
 3834|      7|  g_global_context = (blosc2_context*)my_malloc(sizeof(blosc2_context));
 3835|      7|  memset(g_global_context, 0, sizeof(blosc2_context));
 3836|      7|  g_global_context->nthreads = g_nthreads;
 3837|      7|  g_global_context->new_nthreads = g_nthreads;
 3838|      7|  g_initlib = 1;
 3839|      7|}
blosc2_free_resources:
 3842|      7|int blosc2_free_resources(void) {
 3843|       |  /* Return if Blosc is not initialized */
 3844|      7|  if (!g_initlib) return BLOSC2_ERROR_FAILURE;
  ------------------
  |  Branch (3844:7): [True: 0, False: 7]
  ------------------
 3845|       |
 3846|      7|  return release_threadpool(g_global_context);
 3847|      7|}
blosc2_destroy:
 3850|      7|void blosc2_destroy(void) {
 3851|       |  /* Return if Blosc is not initialized */
 3852|      7|  if (!g_initlib) return;
  ------------------
  |  Branch (3852:7): [True: 0, False: 7]
  ------------------
 3853|       |
 3854|      7|  blosc2_free_resources();
 3855|      7|  g_initlib = 0;
 3856|      7|  blosc2_free_ctx(g_global_context);
 3857|       |
 3858|      7|  pthread_mutex_destroy(&global_comp_mutex);
 3859|       |
 3860|      7|}
release_threadpool:
 3863|     17|int release_threadpool(blosc2_context *context) {
 3864|     17|  int32_t t;
 3865|     17|  void* status;
 3866|     17|  int rc;
 3867|       |
 3868|     17|  if (context->threads_started > 0) {
  ------------------
  |  Branch (3868:7): [True: 0, False: 17]
  ------------------
 3869|      0|    if (threads_callback) {
  ------------------
  |  Branch (3869:9): [True: 0, False: 0]
  ------------------
 3870|       |      /* free context data for user-managed threads */
 3871|      0|      for (t=0; t<context->threads_started; t++)
  ------------------
  |  Branch (3871:17): [True: 0, False: 0]
  ------------------
 3872|      0|        destroy_thread_context(context->thread_contexts + t);
 3873|      0|      my_free(context->thread_contexts);
 3874|      0|    }
 3875|      0|    else {
 3876|       |      /* Tell all existing threads to finish */
 3877|      0|      context->end_threads = 1;
 3878|      0|      WAIT_INIT(-1, context);
  ------------------
  |  |  113|      0|  do {                                                                 \
  |  |  114|      0|    rc = pthread_barrier_wait(&(CONTEXT_PTR)->barr_init);              \
  |  |  115|      0|    if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {              \
  |  |  ------------------
  |  |  |  Branch (115:9): [True: 0, False: 0]
  |  |  |  Branch (115:20): [True: 0, False: 0]
  |  |  ------------------
  |  |  116|      0|      BLOSC_TRACE_ERROR("Could not wait on barrier (init): %d", rc);   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  117|      0|      return((RET_VAL));                                               \
  |  |  118|      0|    }                                                                  \
  |  |  119|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (119:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3879|       |
 3880|       |      /* Join exiting threads */
 3881|      0|      for (t = 0; t < context->threads_started; t++) {
  ------------------
  |  Branch (3881:19): [True: 0, False: 0]
  ------------------
 3882|      0|        rc = pthread_join(context->threads[t], &status);
 3883|      0|        if (rc) {
  ------------------
  |  Branch (3883:13): [True: 0, False: 0]
  ------------------
 3884|      0|          BLOSC_TRACE_ERROR("Return code from pthread_join() is %d\n"
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3885|      0|                            "\tError detail: %s.", rc, strerror(rc));
 3886|      0|        }
 3887|      0|      }
 3888|       |
 3889|       |      /* Thread attributes */
 3890|      0|      #if !defined(_WIN32)
 3891|      0|        pthread_attr_destroy(&context->ct_attr);
 3892|      0|      #endif
 3893|       |
 3894|       |      /* Release thread handlers */
 3895|      0|      my_free(context->threads);
 3896|      0|    }
 3897|       |
 3898|       |    /* Release mutex and condition variable objects */
 3899|      0|    pthread_mutex_destroy(&context->count_mutex);
 3900|      0|    pthread_mutex_destroy(&context->delta_mutex);
 3901|      0|    pthread_mutex_destroy(&context->nchunk_mutex);
 3902|      0|    pthread_cond_destroy(&context->delta_cv);
 3903|       |
 3904|       |    /* Barriers */
 3905|      0|  #ifdef BLOSC_POSIX_BARRIERS
 3906|      0|    pthread_barrier_destroy(&context->barr_init);
 3907|      0|    pthread_barrier_destroy(&context->barr_finish);
 3908|       |  #else
 3909|       |    pthread_mutex_destroy(&context->count_threads_mutex);
 3910|       |    pthread_cond_destroy(&context->count_threads_cv);
 3911|       |    context->count_threads = 0;      /* Reset threads counter */
 3912|       |  #endif
 3913|       |
 3914|       |    /* Reset flags and counters */
 3915|      0|    context->end_threads = 0;
 3916|      0|    context->threads_started = 0;
 3917|      0|  }
 3918|       |
 3919|       |
 3920|     17|  return 0;
 3921|     17|}
blosc2_create_cctx:
 3927|      2|blosc2_context* blosc2_create_cctx(blosc2_cparams cparams) {
 3928|      2|  blosc2_context* context = (blosc2_context*)my_malloc(sizeof(blosc2_context));
 3929|      2|  BLOSC_ERROR_NULL(context, NULL);
  ------------------
  |  |  108|      2|    do {                                            \
  |  |  109|      2|        if ((pointer) == NULL) {                    \
  |  |  ------------------
  |  |  |  Branch (109:13): [True: 0, False: 2]
  |  |  ------------------
  |  |  110|      0|            BLOSC_TRACE_ERROR("Pointer is null");   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  111|      0|            return (rc);                            \
  |  |  112|      0|        }                                           \
  |  |  113|      2|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3930|       |
 3931|       |  /* Populate the context, using zeros as default values */
 3932|      2|  memset(context, 0, sizeof(blosc2_context));
 3933|      2|  context->do_compress = 1;   /* meant for compression */
 3934|      2|  context->use_dict = cparams.use_dict;
 3935|      2|  if (cparams.instr_codec) {
  ------------------
  |  Branch (3935:7): [True: 0, False: 2]
  ------------------
 3936|      0|    context->blosc2_flags = BLOSC2_INSTR_CODEC;
 3937|      0|  }
 3938|       |
 3939|     14|  for (int i = 0; i < BLOSC2_MAX_FILTERS; i++) {
  ------------------
  |  Branch (3939:19): [True: 12, False: 2]
  ------------------
 3940|     12|    context->filters[i] = cparams.filters[i];
 3941|     12|    context->filters_meta[i] = cparams.filters_meta[i];
 3942|       |
 3943|     12|    if (context->filters[i] >= BLOSC_LAST_FILTER && context->filters[i] <= BLOSC2_DEFINED_FILTERS_STOP) {
  ------------------
  |  Branch (3943:9): [True: 0, False: 12]
  |  Branch (3943:53): [True: 0, False: 0]
  ------------------
 3944|      0|      BLOSC_TRACE_ERROR("filter (%d) is not yet defined",
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3945|      0|                        context->filters[i]);
 3946|      0|      free(context);
 3947|      0|      return NULL;
 3948|      0|    }
 3949|     12|    if (context->filters[i] > BLOSC_LAST_REGISTERED_FILTER && context->filters[i] <= BLOSC2_GLOBAL_REGISTERED_FILTERS_STOP) {
  ------------------
  |  Branch (3949:9): [True: 0, False: 12]
  |  Branch (3949:63): [True: 0, False: 0]
  ------------------
 3950|      0|      BLOSC_TRACE_ERROR("filter (%d) is not yet defined",
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3951|      0|                        context->filters[i]);
 3952|      0|      free(context);
 3953|      0|      return NULL;
 3954|      0|    }
 3955|     12|  }
 3956|       |
 3957|      2|#if defined(HAVE_PLUGINS)
 3958|      2|#include "blosc2/codecs-registry.h"
 3959|      2|  if ((context->compcode >= BLOSC_CODEC_ZFP_FIXED_ACCURACY) && (context->compcode <= BLOSC_CODEC_ZFP_FIXED_RATE)) {
  ------------------
  |  Branch (3959:7): [True: 0, False: 2]
  |  Branch (3959:64): [True: 0, False: 0]
  ------------------
 3960|      0|    for (int i = 0; i < BLOSC2_MAX_FILTERS; ++i) {
  ------------------
  |  Branch (3960:21): [True: 0, False: 0]
  ------------------
 3961|      0|      if ((context->filters[i] == BLOSC_SHUFFLE) || (context->filters[i] == BLOSC_BITSHUFFLE)) {
  ------------------
  |  Branch (3961:11): [True: 0, False: 0]
  |  Branch (3961:53): [True: 0, False: 0]
  ------------------
 3962|      0|        BLOSC_TRACE_ERROR("ZFP cannot be run in presence of SHUFFLE / BITSHUFFLE");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3963|      0|        return NULL;
 3964|      0|      }
 3965|      0|    }
 3966|      0|  }
 3967|      2|#endif /* HAVE_PLUGINS */
 3968|       |
 3969|       |  /* Check for a BLOSC_SHUFFLE environment variable */
 3970|      2|  int doshuffle = -1;
 3971|      2|  char* envvar = getenv("BLOSC_SHUFFLE");
 3972|      2|  if (envvar != NULL) {
  ------------------
  |  Branch (3972:7): [True: 0, False: 2]
  ------------------
 3973|      0|    if (strcmp(envvar, "NOSHUFFLE") == 0) {
  ------------------
  |  Branch (3973:9): [True: 0, False: 0]
  ------------------
 3974|      0|      doshuffle = BLOSC_NOSHUFFLE;
 3975|      0|    }
 3976|      0|    else if (strcmp(envvar, "SHUFFLE") == 0) {
  ------------------
  |  Branch (3976:14): [True: 0, False: 0]
  ------------------
 3977|      0|      doshuffle = BLOSC_SHUFFLE;
 3978|      0|    }
 3979|      0|    else if (strcmp(envvar, "BITSHUFFLE") == 0) {
  ------------------
  |  Branch (3979:14): [True: 0, False: 0]
  ------------------
 3980|      0|      doshuffle = BLOSC_BITSHUFFLE;
 3981|      0|    }
 3982|      0|    else {
 3983|      0|      BLOSC_TRACE_WARNING("BLOSC_SHUFFLE environment variable '%s' not recognized\n", envvar);
  ------------------
  |  |   98|      0|#define BLOSC_TRACE_WARNING(msg, ...) BLOSC_TRACE(warning, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3984|      0|    }
 3985|      0|  }
 3986|       |  /* Check for a BLOSC_DELTA environment variable */
 3987|      0|  int dodelta = BLOSC_NOFILTER;
 3988|      2|  envvar = getenv("BLOSC_DELTA");
 3989|      2|  if (envvar != NULL) {
  ------------------
  |  Branch (3989:7): [True: 0, False: 2]
  ------------------
 3990|      0|    if (strcmp(envvar, "1") == 0) {
  ------------------
  |  Branch (3990:9): [True: 0, False: 0]
  ------------------
 3991|      0|      dodelta = BLOSC_DELTA;
 3992|      0|    } else if (strcmp(envvar, "0") == 0){
  ------------------
  |  Branch (3992:16): [True: 0, False: 0]
  ------------------
 3993|      0|      dodelta = BLOSC_NOFILTER;
 3994|      0|    }
 3995|      0|    else {
 3996|      0|      BLOSC_TRACE_WARNING("BLOSC_DELTA environment variable '%s' not recognized\n", envvar);
  ------------------
  |  |   98|      0|#define BLOSC_TRACE_WARNING(msg, ...) BLOSC_TRACE(warning, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3997|      0|    }
 3998|      0|  }
 3999|       |  /* Check for a BLOSC_TYPESIZE environment variable */
 4000|      0|  context->typesize = cparams.typesize;
 4001|      2|  envvar = getenv("BLOSC_TYPESIZE");
 4002|      2|  if (envvar != NULL) {
  ------------------
  |  Branch (4002:7): [True: 0, False: 2]
  ------------------
 4003|      0|    int32_t value;
 4004|      0|    value = (int32_t) strtol(envvar, NULL, 10);
 4005|      0|    if ((errno != EINVAL) && (value > 0)) {
  ------------------
  |  Branch (4005:9): [True: 0, False: 0]
  |  Branch (4005:30): [True: 0, False: 0]
  ------------------
 4006|      0|      context->typesize = value;
 4007|      0|    }
 4008|      0|    else {
 4009|      0|      BLOSC_TRACE_WARNING("BLOSC_TYPESIZE environment variable '%s' not recognized\n", envvar);
  ------------------
  |  |   98|      0|#define BLOSC_TRACE_WARNING(msg, ...) BLOSC_TRACE(warning, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4010|      0|    }
 4011|      0|  }
 4012|      0|  build_filters(doshuffle, dodelta, context->typesize, context->filters);
 4013|       |
 4014|      2|  context->clevel = cparams.clevel;
 4015|       |  /* Check for a BLOSC_CLEVEL environment variable */
 4016|      2|  envvar = getenv("BLOSC_CLEVEL");
 4017|      2|  if (envvar != NULL) {
  ------------------
  |  Branch (4017:7): [True: 0, False: 2]
  ------------------
 4018|      0|    int value;
 4019|      0|    value = (int)strtol(envvar, NULL, 10);
 4020|      0|    if ((errno != EINVAL) && (value >= 0)) {
  ------------------
  |  Branch (4020:9): [True: 0, False: 0]
  |  Branch (4020:30): [True: 0, False: 0]
  ------------------
 4021|      0|      context->clevel = value;
 4022|      0|    }
 4023|      0|    else {
 4024|      0|      BLOSC_TRACE_WARNING("BLOSC_CLEVEL environment variable '%s' not recognized\n", envvar);
  ------------------
  |  |   98|      0|#define BLOSC_TRACE_WARNING(msg, ...) BLOSC_TRACE(warning, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4025|      0|    }
 4026|      0|  }
 4027|       |
 4028|      0|  context->compcode = cparams.compcode;
 4029|       |  /* Check for a BLOSC_COMPRESSOR environment variable */
 4030|      2|  envvar = getenv("BLOSC_COMPRESSOR");
 4031|      2|  if (envvar != NULL) {
  ------------------
  |  Branch (4031:7): [True: 0, False: 2]
  ------------------
 4032|      0|    int codec = blosc2_compname_to_compcode(envvar);
 4033|      0|    if (codec >= BLOSC_LAST_CODEC) {
  ------------------
  |  Branch (4033:9): [True: 0, False: 0]
  ------------------
 4034|      0|      BLOSC_TRACE_ERROR("User defined codecs cannot be set here. Use Blosc2 mechanism instead.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4035|      0|      return NULL;
 4036|      0|    }
 4037|      0|    context->compcode = codec;
 4038|      0|  }
 4039|      2|  context->compcode_meta = cparams.compcode_meta;
 4040|       |
 4041|      2|  context->blocksize = cparams.blocksize;
 4042|       |  /* Check for a BLOSC_BLOCKSIZE environment variable */
 4043|      2|  envvar = getenv("BLOSC_BLOCKSIZE");
 4044|      2|  if (envvar != NULL) {
  ------------------
  |  Branch (4044:7): [True: 0, False: 2]
  ------------------
 4045|      0|    int32_t blocksize;
 4046|      0|    blocksize = (int32_t) strtol(envvar, NULL, 10);
 4047|      0|    if ((errno != EINVAL) && (blocksize > 0)) {
  ------------------
  |  Branch (4047:9): [True: 0, False: 0]
  |  Branch (4047:30): [True: 0, False: 0]
  ------------------
 4048|      0|      context->blocksize = blocksize;
 4049|      0|    }
 4050|      0|    else {
 4051|      0|      BLOSC_TRACE_WARNING("BLOSC_BLOCKSIZE environment variable '%s' not recognized\n", envvar);
  ------------------
  |  |   98|      0|#define BLOSC_TRACE_WARNING(msg, ...) BLOSC_TRACE(warning, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4052|      0|    }
 4053|      0|  }
 4054|       |
 4055|      0|  context->nthreads = cparams.nthreads;
 4056|       |  /* Check for a BLOSC_NTHREADS environment variable */
 4057|      2|  envvar = getenv("BLOSC_NTHREADS");
 4058|      2|  if (envvar != NULL) {
  ------------------
  |  Branch (4058:7): [True: 0, False: 2]
  ------------------
 4059|      0|    int16_t nthreads = (int16_t) strtol(envvar, NULL, 10);
 4060|      0|    if ((errno != EINVAL) && (nthreads > 0)) {
  ------------------
  |  Branch (4060:9): [True: 0, False: 0]
  |  Branch (4060:30): [True: 0, False: 0]
  ------------------
 4061|      0|      context->nthreads = nthreads;
 4062|      0|    }
 4063|      0|    else {
 4064|      0|      BLOSC_TRACE_WARNING("BLOSC_NTHREADS environment variable '%s' not recognized\n", envvar);
  ------------------
  |  |   98|      0|#define BLOSC_TRACE_WARNING(msg, ...) BLOSC_TRACE(warning, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4065|      0|    }
 4066|      0|  }
 4067|      0|  context->new_nthreads = context->nthreads;
 4068|       |
 4069|      2|  context->splitmode = cparams.splitmode;
 4070|       |  /* Check for a BLOSC_SPLITMODE environment variable */
 4071|      2|  envvar = getenv("BLOSC_SPLITMODE");
 4072|      2|  if (envvar != NULL) {
  ------------------
  |  Branch (4072:7): [True: 0, False: 2]
  ------------------
 4073|      0|    int32_t splitmode = -1;
 4074|      0|    if (strcmp(envvar, "ALWAYS") == 0) {
  ------------------
  |  Branch (4074:9): [True: 0, False: 0]
  ------------------
 4075|      0|      splitmode = BLOSC_ALWAYS_SPLIT;
 4076|      0|    }
 4077|      0|    else if (strcmp(envvar, "NEVER") == 0) {
  ------------------
  |  Branch (4077:14): [True: 0, False: 0]
  ------------------
 4078|      0|      splitmode = BLOSC_NEVER_SPLIT;
 4079|      0|    }
 4080|      0|    else if (strcmp(envvar, "AUTO") == 0) {
  ------------------
  |  Branch (4080:14): [True: 0, False: 0]
  ------------------
 4081|      0|      splitmode = BLOSC_AUTO_SPLIT;
 4082|      0|    }
 4083|      0|    else if (strcmp(envvar, "FORWARD_COMPAT") == 0) {
  ------------------
  |  Branch (4083:14): [True: 0, False: 0]
  ------------------
 4084|      0|      splitmode = BLOSC_FORWARD_COMPAT_SPLIT;
 4085|      0|    }
 4086|      0|    else {
 4087|      0|      BLOSC_TRACE_WARNING("BLOSC_SPLITMODE environment variable '%s' not recognized\n", envvar);
  ------------------
  |  |   98|      0|#define BLOSC_TRACE_WARNING(msg, ...) BLOSC_TRACE(warning, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4088|      0|    }
 4089|      0|    if (splitmode >= 0) {
  ------------------
  |  Branch (4089:9): [True: 0, False: 0]
  ------------------
 4090|      0|      context->splitmode = splitmode;
 4091|      0|    }
 4092|      0|  }
 4093|       |
 4094|      0|  context->threads_started = 0;
 4095|      2|  context->schunk = cparams.schunk;
 4096|       |
 4097|      2|  if (cparams.prefilter != NULL) {
  ------------------
  |  Branch (4097:7): [True: 0, False: 2]
  ------------------
 4098|      0|    context->prefilter = cparams.prefilter;
 4099|      0|    context->preparams = (blosc2_prefilter_params*)my_malloc(sizeof(blosc2_prefilter_params));
 4100|      0|    BLOSC_ERROR_NULL(context->preparams, NULL);
  ------------------
  |  |  108|      0|    do {                                            \
  |  |  109|      0|        if ((pointer) == NULL) {                    \
  |  |  ------------------
  |  |  |  Branch (109:13): [True: 0, False: 0]
  |  |  ------------------
  |  |  110|      0|            BLOSC_TRACE_ERROR("Pointer is null");   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  111|      0|            return (rc);                            \
  |  |  112|      0|        }                                           \
  |  |  113|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 4101|      0|    memcpy(context->preparams, cparams.preparams, sizeof(blosc2_prefilter_params));
 4102|      0|  }
 4103|       |
 4104|      2|  if (cparams.tuner_id <= 0) {
  ------------------
  |  Branch (4104:7): [True: 2, False: 0]
  ------------------
 4105|      2|    cparams.tuner_id = g_tuner;
 4106|      2|  } else {
 4107|      0|    for (int i = 0; i < g_ntuners; ++i) {
  ------------------
  |  Branch (4107:21): [True: 0, False: 0]
  ------------------
 4108|      0|      if (g_tuners[i].id == cparams.tuner_id) {
  ------------------
  |  Branch (4108:11): [True: 0, False: 0]
  ------------------
 4109|      0|        if (g_tuners[i].init == NULL) {
  ------------------
  |  Branch (4109:13): [True: 0, False: 0]
  ------------------
 4110|      0|          if (fill_tuner(&g_tuners[i]) < 0) {
  ------------------
  |  Branch (4110:15): [True: 0, False: 0]
  ------------------
 4111|      0|            BLOSC_TRACE_ERROR("Could not load tuner %d.", g_tuners[i].id);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4112|      0|            return NULL;
 4113|      0|          }
 4114|      0|        }
 4115|      0|        if (g_tuners[i].init(cparams.tuner_params, context, NULL) < 0) {
  ------------------
  |  Branch (4115:13): [True: 0, False: 0]
  ------------------
 4116|      0|          BLOSC_TRACE_ERROR("Error in user-defined tuner %d init function\n", cparams.tuner_id);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4117|      0|          return NULL;
 4118|      0|        }
 4119|      0|        goto urtunersuccess;
 4120|      0|      }
 4121|      0|    }
 4122|      0|    BLOSC_TRACE_ERROR("User-defined tuner %d not found\n", cparams.tuner_id);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4123|      0|    return NULL;
 4124|      0|  }
 4125|      2|  urtunersuccess:;
 4126|       |
 4127|      2|  context->tuner_id = cparams.tuner_id;
 4128|       |
 4129|      2|  context->codec_params = cparams.codec_params;
 4130|      2|  memcpy(context->filter_params, cparams.filter_params, BLOSC2_MAX_FILTERS * sizeof(void*));
 4131|       |
 4132|      2|  return context;
 4133|      2|}
blosc2_create_dctx:
 4136|      1|blosc2_context* blosc2_create_dctx(blosc2_dparams dparams) {
 4137|      1|  blosc2_context* context = (blosc2_context*)my_malloc(sizeof(blosc2_context));
 4138|      1|  BLOSC_ERROR_NULL(context, NULL);
  ------------------
  |  |  108|      1|    do {                                            \
  |  |  109|      1|        if ((pointer) == NULL) {                    \
  |  |  ------------------
  |  |  |  Branch (109:13): [True: 0, False: 1]
  |  |  ------------------
  |  |  110|      0|            BLOSC_TRACE_ERROR("Pointer is null");   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  111|      0|            return (rc);                            \
  |  |  112|      0|        }                                           \
  |  |  113|      1|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 4139|       |
 4140|       |  /* Populate the context, using zeros as default values */
 4141|      1|  memset(context, 0, sizeof(blosc2_context));
 4142|      1|  context->do_compress = 0;   /* Meant for decompression */
 4143|       |
 4144|      1|  context->nthreads = dparams.nthreads;
 4145|      1|  char* envvar = getenv("BLOSC_NTHREADS");
 4146|      1|  if (envvar != NULL) {
  ------------------
  |  Branch (4146:7): [True: 0, False: 1]
  ------------------
 4147|      0|    long nthreads = strtol(envvar, NULL, 10);
 4148|      0|    if ((errno != EINVAL) && (nthreads > 0)) {
  ------------------
  |  Branch (4148:9): [True: 0, False: 0]
  |  Branch (4148:30): [True: 0, False: 0]
  ------------------
 4149|      0|      context->nthreads = (int16_t) nthreads;
 4150|      0|    }
 4151|      0|  }
 4152|      1|  context->new_nthreads = context->nthreads;
 4153|       |
 4154|      1|  context->threads_started = 0;
 4155|      1|  context->block_maskout = NULL;
 4156|      1|  context->block_maskout_nitems = 0;
 4157|      1|  context->schunk = dparams.schunk;
 4158|       |
 4159|      1|  if (dparams.postfilter != NULL) {
  ------------------
  |  Branch (4159:7): [True: 0, False: 1]
  ------------------
 4160|      0|    context->postfilter = dparams.postfilter;
 4161|      0|    context->postparams = (blosc2_postfilter_params*)my_malloc(sizeof(blosc2_postfilter_params));
 4162|      0|    BLOSC_ERROR_NULL(context->postparams, NULL);
  ------------------
  |  |  108|      0|    do {                                            \
  |  |  109|      0|        if ((pointer) == NULL) {                    \
  |  |  ------------------
  |  |  |  Branch (109:13): [True: 0, False: 0]
  |  |  ------------------
  |  |  110|      0|            BLOSC_TRACE_ERROR("Pointer is null");   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  111|      0|            return (rc);                            \
  |  |  112|      0|        }                                           \
  |  |  113|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 4163|      0|    memcpy(context->postparams, dparams.postparams, sizeof(blosc2_postfilter_params));
 4164|      0|  }
 4165|       |
 4166|      1|  return context;
 4167|      1|}
blosc2_free_ctx:
 4170|     10|void blosc2_free_ctx(blosc2_context* context) {
 4171|     10|  release_threadpool(context);
 4172|     10|  if (context->serial_context != NULL) {
  ------------------
  |  Branch (4172:7): [True: 1, False: 9]
  ------------------
 4173|      1|    free_thread_context(context->serial_context);
 4174|      1|  }
 4175|     10|  if (context->dict_cdict != NULL) {
  ------------------
  |  Branch (4175:7): [True: 0, False: 10]
  ------------------
 4176|      0|#ifdef HAVE_ZSTD
 4177|      0|    ZSTD_freeCDict(context->dict_cdict);
 4178|      0|#endif
 4179|      0|  }
 4180|     10|  if (context->dict_ddict != NULL) {
  ------------------
  |  Branch (4180:7): [True: 0, False: 10]
  ------------------
 4181|      0|#ifdef HAVE_ZSTD
 4182|      0|    ZSTD_freeDDict(context->dict_ddict);
 4183|      0|#endif
 4184|      0|  }
 4185|     10|  if (context->tuner_params != NULL) {
  ------------------
  |  Branch (4185:7): [True: 0, False: 10]
  ------------------
 4186|      0|    int rc;
 4187|      0|    if (context->tuner_id < BLOSC_LAST_TUNER && context->tuner_id == BLOSC_STUNE) {
  ------------------
  |  |   26|      0|#define BLOSC_STUNE 0
  ------------------
  |  Branch (4187:9): [True: 0, False: 0]
  |  Branch (4187:49): [True: 0, False: 0]
  ------------------
 4188|      0|      rc = blosc_stune_free(context);
 4189|      0|    } else {
 4190|      0|      for (int i = 0; i < g_ntuners; ++i) {
  ------------------
  |  Branch (4190:23): [True: 0, False: 0]
  ------------------
 4191|      0|        if (g_tuners[i].id == context->tuner_id) {
  ------------------
  |  Branch (4191:13): [True: 0, False: 0]
  ------------------
 4192|      0|          if (g_tuners[i].free == NULL) {
  ------------------
  |  Branch (4192:15): [True: 0, False: 0]
  ------------------
 4193|      0|            if (fill_tuner(&g_tuners[i]) < 0) {
  ------------------
  |  Branch (4193:17): [True: 0, False: 0]
  ------------------
 4194|      0|              BLOSC_TRACE_ERROR("Could not load tuner %d.", g_tuners[i].id);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4195|      0|              return;
 4196|      0|            }
 4197|      0|          }
 4198|      0|          rc = g_tuners[i].free(context);
 4199|      0|          goto urtunersuccess;
 4200|      0|        }
 4201|      0|      }
 4202|      0|      BLOSC_TRACE_ERROR("User-defined tuner %d not found\n", context->tuner_id);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4203|      0|      return;
 4204|      0|      urtunersuccess:;
 4205|      0|    }
 4206|      0|    if (rc < 0) {
  ------------------
  |  Branch (4206:9): [True: 0, False: 0]
  ------------------
 4207|      0|      BLOSC_TRACE_ERROR("Error in user-defined tuner free function\n");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4208|      0|      return;
 4209|      0|    }
 4210|      0|  }
 4211|     10|  if (context->prefilter != NULL) {
  ------------------
  |  Branch (4211:7): [True: 0, False: 10]
  ------------------
 4212|      0|    my_free(context->preparams);
 4213|      0|  }
 4214|     10|  if (context->postfilter != NULL) {
  ------------------
  |  Branch (4214:7): [True: 0, False: 10]
  ------------------
 4215|      0|    my_free(context->postparams);
 4216|      0|  }
 4217|       |
 4218|     10|  if (context->block_maskout != NULL) {
  ------------------
  |  Branch (4218:7): [True: 0, False: 10]
  ------------------
 4219|      0|    free(context->block_maskout);
 4220|      0|  }
 4221|     10|  my_free(context);
 4222|     10|}
blosc2_chunk_zeros:
 4278|      1|int blosc2_chunk_zeros(blosc2_cparams cparams, const int32_t nbytes, void* dest, int32_t destsize) {
 4279|      1|  if (destsize < BLOSC_EXTENDED_HEADER_LENGTH) {
  ------------------
  |  Branch (4279:7): [True: 0, False: 1]
  ------------------
 4280|      0|    BLOSC_TRACE_ERROR("dest buffer is not long enough");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4281|      0|    return BLOSC2_ERROR_DATA;
 4282|      0|  }
 4283|       |
 4284|      1|  if (nbytes % cparams.typesize) {
  ------------------
  |  Branch (4284:7): [True: 0, False: 1]
  ------------------
 4285|      0|    BLOSC_TRACE_ERROR("nbytes must be a multiple of typesize");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4286|      0|    return BLOSC2_ERROR_DATA;
 4287|      0|  }
 4288|       |
 4289|      1|  blosc_header header;
 4290|      1|  blosc2_context* context = blosc2_create_cctx(cparams);
 4291|      1|  if (context == NULL) {
  ------------------
  |  Branch (4291:7): [True: 0, False: 1]
  ------------------
 4292|      0|    BLOSC_TRACE_ERROR("Error while creating the compression context");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4293|      0|    return BLOSC2_ERROR_NULL_POINTER;
 4294|      0|  }
 4295|       |
 4296|      1|  int error = initialize_context_compression(
 4297|      1|          context, NULL, nbytes, dest, destsize,
 4298|      1|          context->clevel, context->filters, context->filters_meta,
 4299|      1|          context->typesize, context->compcode, context->blocksize,
 4300|      1|          context->new_nthreads, context->nthreads, context->splitmode,
 4301|      1|          context->tuner_id, context->tuner_params, context->schunk);
 4302|      1|  if (error <= 0) {
  ------------------
  |  Branch (4302:7): [True: 0, False: 1]
  ------------------
 4303|      0|    blosc2_free_ctx(context);
 4304|      0|    return error;
 4305|      0|  }
 4306|       |
 4307|      1|  memset(&header, 0, sizeof(header));
 4308|      1|  header.version = BLOSC2_VERSION_FORMAT;
 4309|      1|  header.versionlz = BLOSC_BLOSCLZ_VERSION_FORMAT;
 4310|      1|  header.flags = BLOSC_DOSHUFFLE | BLOSC_DOBITSHUFFLE;  // extended header
 4311|      1|  header.typesize = context->typesize;
 4312|      1|  header.nbytes = (int32_t)nbytes;
 4313|      1|  header.blocksize = context->blocksize;
 4314|      1|  header.cbytes = BLOSC_EXTENDED_HEADER_LENGTH;
 4315|      1|  header.blosc2_flags = BLOSC2_SPECIAL_ZERO << 4;  // mark chunk as all zeros
 4316|      1|  memcpy((uint8_t *)dest, &header, sizeof(header));
 4317|       |
 4318|      1|  blosc2_free_ctx(context);
 4319|       |
 4320|      1|  return BLOSC_EXTENDED_HEADER_LENGTH;
 4321|      1|}
register_filter_private:
 4469|     35|int register_filter_private(blosc2_filter *filter) {
 4470|     35|    BLOSC_ERROR_NULL(filter, BLOSC2_ERROR_INVALID_PARAM);
  ------------------
  |  |  108|     35|    do {                                            \
  |  |  109|     35|        if ((pointer) == NULL) {                    \
  |  |  ------------------
  |  |  |  Branch (109:13): [True: 0, False: 35]
  |  |  ------------------
  |  |  110|      0|            BLOSC_TRACE_ERROR("Pointer is null");   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  111|      0|            return (rc);                            \
  |  |  112|      0|        }                                           \
  |  |  113|     35|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 4471|     35|    if (g_nfilters == UINT8_MAX) {
  ------------------
  |  Branch (4471:9): [True: 0, False: 35]
  ------------------
 4472|      0|        BLOSC_TRACE_ERROR("Can not register more filters");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4473|      0|        return BLOSC2_ERROR_CODEC_SUPPORT;
 4474|      0|    }
 4475|     35|    if (filter->id < BLOSC2_GLOBAL_REGISTERED_FILTERS_START) {
  ------------------
  |  Branch (4475:9): [True: 0, False: 35]
  ------------------
 4476|      0|        BLOSC_TRACE_ERROR("The id must be greater or equal than %d", BLOSC2_GLOBAL_REGISTERED_FILTERS_START);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4477|      0|        return BLOSC2_ERROR_FAILURE;
 4478|      0|    }
 4479|       |    /* This condition can never be fulfilled
 4480|       |    if (filter->id > BLOSC2_USER_REGISTERED_FILTERS_STOP) {
 4481|       |        BLOSC_TRACE_ERROR("The id must be less than or equal to %d", BLOSC2_USER_REGISTERED_FILTERS_STOP);
 4482|       |        return BLOSC2_ERROR_FAILURE;
 4483|       |    }
 4484|       |    */
 4485|       |
 4486|    105|    for (uint64_t i = 0; i < g_nfilters; ++i) {
  ------------------
  |  Branch (4486:26): [True: 70, False: 35]
  ------------------
 4487|     70|      if (g_filters[i].id == filter->id) {
  ------------------
  |  Branch (4487:11): [True: 0, False: 70]
  ------------------
 4488|      0|        if (strcmp(g_filters[i].name, filter->name) != 0) {
  ------------------
  |  Branch (4488:13): [True: 0, False: 0]
  ------------------
 4489|      0|          BLOSC_TRACE_ERROR("The filter (ID: %d) plugin is already registered with name: %s."
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4490|      0|                            "  Choose another one !", filter->id, g_filters[i].name);
 4491|      0|          return BLOSC2_ERROR_FAILURE;
 4492|      0|        }
 4493|      0|        else {
 4494|       |          // Already registered, so no more actions needed
 4495|      0|          return BLOSC2_ERROR_SUCCESS;
 4496|      0|        }
 4497|      0|      }
 4498|     70|    }
 4499|       |
 4500|     35|    blosc2_filter *filter_new = &g_filters[g_nfilters++];
 4501|     35|    memcpy(filter_new, filter, sizeof(blosc2_filter));
 4502|       |
 4503|     35|    return BLOSC2_ERROR_SUCCESS;
 4504|     35|}
register_codec_private:
 4519|     42|int register_codec_private(blosc2_codec *codec) {
 4520|     42|    BLOSC_ERROR_NULL(codec, BLOSC2_ERROR_INVALID_PARAM);
  ------------------
  |  |  108|     42|    do {                                            \
  |  |  109|     42|        if ((pointer) == NULL) {                    \
  |  |  ------------------
  |  |  |  Branch (109:13): [True: 0, False: 42]
  |  |  ------------------
  |  |  110|      0|            BLOSC_TRACE_ERROR("Pointer is null");   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  111|      0|            return (rc);                            \
  |  |  112|      0|        }                                           \
  |  |  113|     42|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 4521|     42|    if (g_ncodecs == UINT8_MAX) {
  ------------------
  |  Branch (4521:9): [True: 0, False: 42]
  ------------------
 4522|      0|      BLOSC_TRACE_ERROR("Can not register more codecs");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4523|      0|      return BLOSC2_ERROR_CODEC_SUPPORT;
 4524|      0|    }
 4525|     42|    if (codec->compcode < BLOSC2_GLOBAL_REGISTERED_CODECS_START) {
  ------------------
  |  Branch (4525:9): [True: 0, False: 42]
  ------------------
 4526|      0|      BLOSC_TRACE_ERROR("The id must be greater or equal than %d", BLOSC2_GLOBAL_REGISTERED_CODECS_START);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4527|      0|      return BLOSC2_ERROR_FAILURE;
 4528|      0|    }
 4529|       |    /* This condition can never be fulfilled
 4530|       |    if (codec->compcode > BLOSC2_USER_REGISTERED_CODECS_STOP) {
 4531|       |      BLOSC_TRACE_ERROR("The id must be less or equal to %d", BLOSC2_USER_REGISTERED_CODECS_STOP);
 4532|       |      return BLOSC2_ERROR_FAILURE;
 4533|       |    }
 4534|       |     */
 4535|       |
 4536|    147|    for (int i = 0; i < g_ncodecs; ++i) {
  ------------------
  |  Branch (4536:21): [True: 105, False: 42]
  ------------------
 4537|    105|      if (g_codecs[i].compcode == codec->compcode) {
  ------------------
  |  Branch (4537:11): [True: 0, False: 105]
  ------------------
 4538|      0|        if (strcmp(g_codecs[i].compname, codec->compname) != 0) {
  ------------------
  |  Branch (4538:13): [True: 0, False: 0]
  ------------------
 4539|      0|          BLOSC_TRACE_ERROR("The codec (ID: %d) plugin is already registered with name: %s."
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4540|      0|                            "  Choose another one !", codec->compcode, codec->compname);
 4541|      0|          return BLOSC2_ERROR_CODEC_PARAM;
 4542|      0|        }
 4543|      0|        else {
 4544|       |          // Already registered, so no more actions needed
 4545|      0|          return BLOSC2_ERROR_SUCCESS;
 4546|      0|        }
 4547|      0|      }
 4548|    105|    }
 4549|       |
 4550|     42|    blosc2_codec *codec_new = &g_codecs[g_ncodecs++];
 4551|     42|    memcpy(codec_new, codec, sizeof(blosc2_codec));
 4552|       |
 4553|     42|    return BLOSC2_ERROR_SUCCESS;
 4554|     42|}
register_tuner_private:
 4569|      7|int register_tuner_private(blosc2_tuner *tuner) {
 4570|      7|  BLOSC_ERROR_NULL(tuner, BLOSC2_ERROR_INVALID_PARAM);
  ------------------
  |  |  108|      7|    do {                                            \
  |  |  109|      7|        if ((pointer) == NULL) {                    \
  |  |  ------------------
  |  |  |  Branch (109:13): [True: 0, False: 7]
  |  |  ------------------
  |  |  110|      0|            BLOSC_TRACE_ERROR("Pointer is null");   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  111|      0|            return (rc);                            \
  |  |  112|      0|        }                                           \
  |  |  113|      7|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 4571|      7|  if (g_ntuners == UINT8_MAX) {
  ------------------
  |  Branch (4571:7): [True: 0, False: 7]
  ------------------
 4572|      0|    BLOSC_TRACE_ERROR("Can not register more tuners");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4573|      0|    return BLOSC2_ERROR_CODEC_SUPPORT;
 4574|      0|  }
 4575|      7|  if (tuner->id < BLOSC2_GLOBAL_REGISTERED_TUNER_START) {
  ------------------
  |  Branch (4575:7): [True: 0, False: 7]
  ------------------
 4576|      0|    BLOSC_TRACE_ERROR("The id must be greater or equal than %d", BLOSC2_GLOBAL_REGISTERED_TUNER_START);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4577|      0|    return BLOSC2_ERROR_FAILURE;
 4578|      0|  }
 4579|       |
 4580|      7|  for (int i = 0; i < g_ntuners; ++i) {
  ------------------
  |  Branch (4580:19): [True: 0, False: 7]
  ------------------
 4581|      0|    if (g_tuners[i].id == tuner->id) {
  ------------------
  |  Branch (4581:9): [True: 0, False: 0]
  ------------------
 4582|      0|      if (strcmp(g_tuners[i].name, tuner->name) != 0) {
  ------------------
  |  Branch (4582:11): [True: 0, False: 0]
  ------------------
 4583|      0|        BLOSC_TRACE_ERROR("The tuner (ID: %d) plugin is already registered with name: %s."
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4584|      0|                          "  Choose another one !", tuner->id, g_tuners[i].name);
 4585|      0|        return BLOSC2_ERROR_FAILURE;
 4586|      0|      }
 4587|      0|      else {
 4588|       |        // Already registered, so no more actions needed
 4589|      0|        return BLOSC2_ERROR_SUCCESS;
 4590|      0|      }
 4591|      0|    }
 4592|      0|  }
 4593|       |
 4594|      7|  blosc2_tuner *tuner_new = &g_tuners[g_ntuners++];
 4595|      7|  memcpy(tuner_new, tuner, sizeof(blosc2_tuner));
 4596|       |
 4597|      7|  return BLOSC2_ERROR_SUCCESS;
 4598|      7|}
_blosc2_register_io_cb:
 4611|      1|int _blosc2_register_io_cb(const blosc2_io_cb *io) {
 4612|       |
 4613|      1|  for (uint64_t i = 0; i < g_nio; ++i) {
  ------------------
  |  Branch (4613:24): [True: 0, False: 1]
  ------------------
 4614|      0|    if (g_ios[i].id == io->id) {
  ------------------
  |  Branch (4614:9): [True: 0, False: 0]
  ------------------
 4615|      0|      if (strcmp(g_ios[i].name, io->name) != 0) {
  ------------------
  |  Branch (4615:11): [True: 0, False: 0]
  ------------------
 4616|      0|        BLOSC_TRACE_ERROR("The IO (ID: %d) plugin is already registered with name: %s."
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4617|      0|                          "  Choose another one !", io->id, g_ios[i].name);
 4618|      0|        return BLOSC2_ERROR_PLUGIN_IO;
 4619|      0|      }
 4620|      0|      else {
 4621|       |        // Already registered, so no more actions needed
 4622|      0|        return BLOSC2_ERROR_SUCCESS;
 4623|      0|      }
 4624|      0|    }
 4625|      0|  }
 4626|       |
 4627|      1|  blosc2_io_cb *io_new = &g_ios[g_nio++];
 4628|      1|  memcpy(io_new, io, sizeof(blosc2_io_cb));
 4629|       |
 4630|      1|  return BLOSC2_ERROR_SUCCESS;
 4631|      1|}
blosc2_get_io_cb:
 4648|     12|blosc2_io_cb *blosc2_get_io_cb(uint8_t id) {
 4649|     12|  for (uint64_t i = 0; i < g_nio; ++i) {
  ------------------
  |  Branch (4649:24): [True: 11, False: 1]
  ------------------
 4650|     11|    if (g_ios[i].id == id) {
  ------------------
  |  Branch (4650:9): [True: 11, False: 0]
  ------------------
 4651|     11|      return &g_ios[i];
 4652|     11|    }
 4653|     11|  }
 4654|      1|  if (id == BLOSC2_IO_FILESYSTEM) {
  ------------------
  |  Branch (4654:7): [True: 1, False: 0]
  ------------------
 4655|      1|    if (_blosc2_register_io_cb(&BLOSC2_IO_CB_DEFAULTS) < 0) {
  ------------------
  |  Branch (4655:9): [True: 0, False: 1]
  ------------------
 4656|      0|      BLOSC_TRACE_ERROR("Error registering the default IO API");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4657|      0|      return NULL;
 4658|      0|    }
 4659|      1|    return blosc2_get_io_cb(id);
 4660|      1|  }
 4661|      0|  else if (id == BLOSC2_IO_FILESYSTEM_MMAP) {
  ------------------
  |  Branch (4661:12): [True: 0, False: 0]
  ------------------
 4662|      0|    if (_blosc2_register_io_cb(&BLOSC2_IO_CB_MMAP) < 0) {
  ------------------
  |  Branch (4662:9): [True: 0, False: 0]
  ------------------
 4663|      0|      BLOSC_TRACE_ERROR("Error registering the mmap IO API");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4664|      0|      return NULL;
 4665|      0|    }
 4666|      0|    return blosc2_get_io_cb(id);
 4667|      0|  }
 4668|      0|  return NULL;
 4669|      1|}
blosc2.c:flags_to_filters:
  621|     16|static void flags_to_filters(const uint8_t flags, uint8_t* filters) {
  622|       |  /* Initialize the filter pipeline */
  623|     16|  memset(filters, 0, BLOSC2_MAX_FILTERS);
  624|       |  /* Fill the filter pipeline */
  625|     16|  if (flags & BLOSC_DOSHUFFLE)
  ------------------
  |  Branch (625:7): [True: 16, False: 0]
  ------------------
  626|     16|    filters[BLOSC2_MAX_FILTERS - 1] = BLOSC_SHUFFLE;
  627|     16|  if (flags & BLOSC_DOBITSHUFFLE)
  ------------------
  |  Branch (627:7): [True: 16, False: 0]
  ------------------
  628|     16|    filters[BLOSC2_MAX_FILTERS - 1] = BLOSC_BITSHUFFLE;
  629|     16|  if (flags & BLOSC_DODELTA)
  ------------------
  |  Branch (629:7): [True: 0, False: 16]
  ------------------
  630|      0|    filters[BLOSC2_MAX_FILTERS - 2] = BLOSC_DELTA;
  631|     16|}
blosc2.c:destroy_thread_context:
 2071|      6|static void destroy_thread_context(struct thread_context* thread_context) {
 2072|      6|  my_free(thread_context->tmp);
 2073|      6|#if defined(HAVE_ZSTD)
 2074|      6|  if (thread_context->zstd_cctx != NULL) {
  ------------------
  |  Branch (2074:7): [True: 0, False: 6]
  ------------------
 2075|      0|    ZSTD_freeCCtx(thread_context->zstd_cctx);
 2076|      0|  }
 2077|      6|  if (thread_context->zstd_dctx != NULL) {
  ------------------
  |  Branch (2077:7): [True: 0, False: 6]
  ------------------
 2078|      0|    ZSTD_freeDCtx(thread_context->zstd_dctx);
 2079|      0|  }
 2080|      6|#endif
 2081|       |#ifdef HAVE_IPP
 2082|       |  if (thread_context->lz4_hash_table != NULL) {
 2083|       |    ippsFree(thread_context->lz4_hash_table);
 2084|       |  }
 2085|       |#endif
 2086|      6|}
blosc2.c:my_free:
  203|     22|static void my_free(void* block) {
  204|       |#if defined(_WIN32)
  205|       |  _aligned_free(block);
  206|       |#else
  207|     22|  free(block);
  208|     22|#endif  /* _WIN32 */
  209|     22|}
blosc2.c:initialize_context_compression:
 2153|      1|        blosc2_schunk* schunk) {
 2154|       |
 2155|       |  /* Set parameters */
 2156|      1|  context->do_compress = 1;
 2157|      1|  context->src = (const uint8_t*)src;
 2158|      1|  context->srcsize = srcsize;
 2159|      1|  context->dest = (uint8_t*)dest;
 2160|      1|  context->output_bytes = 0;
 2161|      1|  context->destsize = destsize;
 2162|      1|  context->sourcesize = srcsize;
 2163|      1|  context->typesize = (int32_t)typesize;
 2164|      1|  context->filter_flags = filters_to_flags(filters);
 2165|      7|  for (int i = 0; i < BLOSC2_MAX_FILTERS; i++) {
  ------------------
  |  Branch (2165:19): [True: 6, False: 1]
  ------------------
 2166|      6|    context->filters[i] = filters[i];
 2167|      6|    context->filters_meta[i] = filters_meta[i];
 2168|      6|  }
 2169|      1|  context->compcode = compressor;
 2170|      1|  context->nthreads = nthreads;
 2171|      1|  context->new_nthreads = new_nthreads;
 2172|      1|  context->end_threads = 0;
 2173|      1|  context->clevel = clevel;
 2174|      1|  context->schunk = schunk;
 2175|      1|  context->tuner_params = tuner_params;
 2176|      1|  context->tuner_id = tuner_id;
 2177|      1|  context->splitmode = splitmode;
 2178|       |  /* tuner some compression parameters */
 2179|      1|  context->blocksize = (int32_t)blocksize;
 2180|      1|  int rc = 0;
 2181|      1|  if (context->tuner_params != NULL) {
  ------------------
  |  Branch (2181:7): [True: 0, False: 1]
  ------------------
 2182|      0|    if (context->tuner_id < BLOSC_LAST_TUNER && context->tuner_id == BLOSC_STUNE) {
  ------------------
  |  |   26|      0|#define BLOSC_STUNE 0
  ------------------
  |  Branch (2182:9): [True: 0, False: 0]
  |  Branch (2182:49): [True: 0, False: 0]
  ------------------
 2183|      0|      if (blosc_stune_next_cparams(context) < 0) {
  ------------------
  |  Branch (2183:11): [True: 0, False: 0]
  ------------------
 2184|      0|        BLOSC_TRACE_ERROR("Error in stune next_cparams func\n");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2185|      0|        return BLOSC2_ERROR_TUNER;
 2186|      0|      }
 2187|      0|    } else {
 2188|      0|      for (int i = 0; i < g_ntuners; ++i) {
  ------------------
  |  Branch (2188:23): [True: 0, False: 0]
  ------------------
 2189|      0|        if (g_tuners[i].id == context->tuner_id) {
  ------------------
  |  Branch (2189:13): [True: 0, False: 0]
  ------------------
 2190|      0|          if (g_tuners[i].next_cparams == NULL) {
  ------------------
  |  Branch (2190:15): [True: 0, False: 0]
  ------------------
 2191|      0|            if (fill_tuner(&g_tuners[i]) < 0) {
  ------------------
  |  Branch (2191:17): [True: 0, False: 0]
  ------------------
 2192|      0|              BLOSC_TRACE_ERROR("Could not load tuner %d.", g_tuners[i].id);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2193|      0|              return BLOSC2_ERROR_FAILURE;
 2194|      0|            }
 2195|      0|          }
 2196|      0|          if (g_tuners[i].next_cparams(context) < 0) {
  ------------------
  |  Branch (2196:15): [True: 0, False: 0]
  ------------------
 2197|      0|            BLOSC_TRACE_ERROR("Error in tuner %d next_cparams func\n", context->tuner_id);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2198|      0|            return BLOSC2_ERROR_TUNER;
 2199|      0|          }
 2200|      0|          if (g_tuners[i].id == BLOSC_BTUNE && context->blocksize == 0) {
  ------------------
  |  Branch (2200:15): [True: 0, False: 0]
  |  Branch (2200:48): [True: 0, False: 0]
  ------------------
 2201|       |            // Call stune for initializing blocksize
 2202|      0|            if (blosc_stune_next_blocksize(context) < 0) {
  ------------------
  |  Branch (2202:17): [True: 0, False: 0]
  ------------------
 2203|      0|              BLOSC_TRACE_ERROR("Error in stune next_blocksize func\n");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2204|      0|              return BLOSC2_ERROR_TUNER;
 2205|      0|            }
 2206|      0|          }
 2207|      0|          goto urtunersuccess;
 2208|      0|        }
 2209|      0|      }
 2210|      0|      BLOSC_TRACE_ERROR("User-defined tuner %d not found\n", context->tuner_id);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2211|      0|      return BLOSC2_ERROR_INVALID_PARAM;
 2212|      0|    }
 2213|      1|  } else {
 2214|      1|    if (context->tuner_id < BLOSC_LAST_TUNER && context->tuner_id == BLOSC_STUNE) {
  ------------------
  |  |   26|      1|#define BLOSC_STUNE 0
  ------------------
  |  Branch (2214:9): [True: 1, False: 0]
  |  Branch (2214:49): [True: 1, False: 0]
  ------------------
 2215|      1|      rc = blosc_stune_next_blocksize(context);
 2216|      1|    } else {
 2217|      0|      for (int i = 0; i < g_ntuners; ++i) {
  ------------------
  |  Branch (2217:23): [True: 0, False: 0]
  ------------------
 2218|      0|        if (g_tuners[i].id == context->tuner_id) {
  ------------------
  |  Branch (2218:13): [True: 0, False: 0]
  ------------------
 2219|      0|          if (g_tuners[i].next_blocksize == NULL) {
  ------------------
  |  Branch (2219:15): [True: 0, False: 0]
  ------------------
 2220|      0|            if (fill_tuner(&g_tuners[i]) < 0) {
  ------------------
  |  Branch (2220:17): [True: 0, False: 0]
  ------------------
 2221|      0|              BLOSC_TRACE_ERROR("Could not load tuner %d.", g_tuners[i].id);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2222|      0|              return BLOSC2_ERROR_FAILURE;
 2223|      0|            }
 2224|      0|          }
 2225|      0|          rc = g_tuners[i].next_blocksize(context);
 2226|      0|          goto urtunersuccess;
 2227|      0|        }
 2228|      0|      }
 2229|      0|      BLOSC_TRACE_ERROR("User-defined tuner %d not found\n", context->tuner_id);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2230|      0|      return BLOSC2_ERROR_INVALID_PARAM;
 2231|      0|    }
 2232|      1|  }
 2233|      1|  urtunersuccess:;
 2234|      1|  if (rc < 0) {
  ------------------
  |  Branch (2234:7): [True: 0, False: 1]
  ------------------
 2235|      0|    BLOSC_TRACE_ERROR("Error in tuner next_blocksize func\n");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2236|      0|    return BLOSC2_ERROR_TUNER;
 2237|      0|  }
 2238|       |
 2239|       |
 2240|       |  /* Check buffer size limits */
 2241|      1|  if (srcsize > BLOSC2_MAX_BUFFERSIZE) {
  ------------------
  |  Branch (2241:7): [True: 0, False: 1]
  ------------------
 2242|      0|    BLOSC_TRACE_ERROR("Input buffer size cannot exceed %d bytes.",
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2243|      0|                      BLOSC2_MAX_BUFFERSIZE);
 2244|      0|    return BLOSC2_ERROR_MAX_BUFSIZE_EXCEEDED;
 2245|      0|  }
 2246|       |
 2247|      1|  if (destsize < BLOSC2_MAX_OVERHEAD) {
  ------------------
  |  Branch (2247:7): [True: 0, False: 1]
  ------------------
 2248|      0|    BLOSC_TRACE_ERROR("Output buffer size should be larger than %d bytes.",
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2249|      0|                      BLOSC2_MAX_OVERHEAD);
 2250|      0|    return BLOSC2_ERROR_MAX_BUFSIZE_EXCEEDED;
 2251|      0|  }
 2252|       |
 2253|       |  /* Compression level */
 2254|      1|  if (clevel < 0 || clevel > 9) {
  ------------------
  |  Branch (2254:7): [True: 0, False: 1]
  |  Branch (2254:21): [True: 0, False: 1]
  ------------------
 2255|       |    /* If clevel not in 0..9, print an error */
 2256|      0|    BLOSC_TRACE_ERROR("`clevel` parameter must be between 0 and 9!.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2257|      0|    return BLOSC2_ERROR_CODEC_PARAM;
 2258|      0|  }
 2259|       |
 2260|       |  /* Check typesize limits */
 2261|      1|  if (context->typesize > BLOSC_MAX_TYPESIZE) {
  ------------------
  |  Branch (2261:7): [True: 0, False: 1]
  ------------------
 2262|       |    /* If typesize is too large, treat buffer as an 1-byte stream. */
 2263|      0|    context->typesize = 1;
 2264|      0|  }
 2265|       |
 2266|      1|  blosc2_calculate_blocks(context);
 2267|       |
 2268|      1|  return 1;
 2269|      1|}
blosc2.c:filters_to_flags:
  598|      9|static uint8_t filters_to_flags(const uint8_t* filters) {
  599|      9|  uint8_t flags = 0;
  600|       |
  601|     63|  for (int i = 0; i < BLOSC2_MAX_FILTERS; i++) {
  ------------------
  |  Branch (601:19): [True: 54, False: 9]
  ------------------
  602|     54|    switch (filters[i]) {
  603|      8|      case BLOSC_SHUFFLE:
  ------------------
  |  Branch (603:7): [True: 8, False: 46]
  ------------------
  604|      8|        flags |= BLOSC_DOSHUFFLE;
  605|      8|        break;
  606|      0|      case BLOSC_BITSHUFFLE:
  ------------------
  |  Branch (606:7): [True: 0, False: 54]
  ------------------
  607|      0|        flags |= BLOSC_DOBITSHUFFLE;
  608|      0|        break;
  609|      0|      case BLOSC_DELTA:
  ------------------
  |  Branch (609:7): [True: 0, False: 54]
  ------------------
  610|      0|        flags |= BLOSC_DODELTA;
  611|      0|        break;
  612|     46|      default :
  ------------------
  |  Branch (612:7): [True: 46, False: 8]
  ------------------
  613|     46|        break;
  614|     54|    }
  615|     54|  }
  616|      9|  return flags;
  617|      9|}
blosc2.c:blosc2_calculate_blocks:
  752|      9|static inline void blosc2_calculate_blocks(blosc2_context* context) {
  753|       |  /* Compute number of blocks in buffer */
  754|      9|  context->nblocks = context->sourcesize / context->blocksize;
  755|      9|  context->leftover = context->sourcesize % context->blocksize;
  756|      9|  context->nblocks = (context->leftover > 0) ?
  ------------------
  |  Branch (756:22): [True: 3, False: 6]
  ------------------
  757|      6|                     (context->nblocks + 1) : context->nblocks;
  758|      9|}
blosc2.c:do_job:
 2115|      3|static int do_job(blosc2_context* context) {
 2116|      3|  int32_t ntbytes;
 2117|       |
 2118|       |  /* Set sentinels */
 2119|      3|  context->dref_not_init = 1;
 2120|       |
 2121|       |  /* Check whether we need to restart threads */
 2122|      3|  check_nthreads(context);
 2123|       |
 2124|       |  /* Run the serial version when nthreads is 1 or when the buffers are
 2125|       |     not larger than blocksize */
 2126|      3|  if (context->nthreads == 1 || (context->sourcesize / context->blocksize) <= 1) {
  ------------------
  |  Branch (2126:7): [True: 3, False: 0]
  |  Branch (2126:33): [True: 0, False: 0]
  ------------------
 2127|       |    /* The context for this 'thread' has no been initialized yet */
 2128|      3|    if (context->serial_context == NULL) {
  ------------------
  |  Branch (2128:9): [True: 1, False: 2]
  ------------------
 2129|      1|      context->serial_context = create_thread_context(context, 0);
 2130|      1|    }
 2131|      2|    else if (context->blocksize != context->serial_context->tmp_blocksize) {
  ------------------
  |  Branch (2131:14): [True: 1, False: 1]
  ------------------
 2132|      1|      free_thread_context(context->serial_context);
 2133|      1|      context->serial_context = create_thread_context(context, 0);
 2134|      1|    }
 2135|      3|    BLOSC_ERROR_NULL(context->serial_context, BLOSC2_ERROR_THREAD_CREATE);
  ------------------
  |  |  108|      3|    do {                                            \
  |  |  109|      3|        if ((pointer) == NULL) {                    \
  |  |  ------------------
  |  |  |  Branch (109:13): [True: 0, False: 3]
  |  |  ------------------
  |  |  110|      0|            BLOSC_TRACE_ERROR("Pointer is null");   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  111|      0|            return (rc);                            \
  |  |  112|      0|        }                                           \
  |  |  113|      3|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 2136|      3|    ntbytes = serial_blosc(context->serial_context);
 2137|      3|  }
 2138|      0|  else {
 2139|      0|    ntbytes = parallel_blosc(context);
 2140|      0|  }
 2141|       |
 2142|      3|  return ntbytes;
 2143|      3|}
blosc2.c:serial_blosc:
 1921|      3|static int serial_blosc(struct thread_context* thread_context) {
 1922|      3|  blosc2_context* context = thread_context->parent_context;
 1923|      3|  int32_t j, bsize, leftoverblock;
 1924|      3|  int32_t cbytes;
 1925|      3|  int32_t ntbytes = context->output_bytes;
 1926|      3|  int32_t* bstarts = context->bstarts;
 1927|      3|  uint8_t* tmp = thread_context->tmp;
 1928|      3|  uint8_t* tmp2 = thread_context->tmp2;
 1929|      3|  int dict_training = context->use_dict && (context->dict_cdict == NULL);
  ------------------
  |  Branch (1929:23): [True: 0, False: 3]
  |  Branch (1929:44): [True: 0, False: 0]
  ------------------
 1930|      3|  bool memcpyed = context->header_flags & (uint8_t)BLOSC_MEMCPYED;
 1931|      3|  if (!context->do_compress && context->special_type) {
  ------------------
  |  Branch (1931:7): [True: 3, False: 0]
  |  Branch (1931:32): [True: 1, False: 2]
  ------------------
 1932|       |    // Fake a runlen as if it was a memcpyed chunk
 1933|      1|    memcpyed = true;
 1934|      1|  }
 1935|       |
 1936|      8|  for (j = 0; j < context->nblocks; j++) {
  ------------------
  |  Branch (1936:15): [True: 5, False: 3]
  ------------------
 1937|      5|    if (context->do_compress && !memcpyed && !dict_training) {
  ------------------
  |  Branch (1937:9): [True: 0, False: 5]
  |  Branch (1937:33): [True: 0, False: 0]
  |  Branch (1937:46): [True: 0, False: 0]
  ------------------
 1938|      0|      _sw32(bstarts + j, ntbytes);
 1939|      0|    }
 1940|      5|    bsize = context->blocksize;
 1941|      5|    leftoverblock = 0;
 1942|      5|    if ((j == context->nblocks - 1) && (context->leftover > 0)) {
  ------------------
  |  Branch (1942:9): [True: 3, False: 2]
  |  Branch (1942:40): [True: 2, False: 1]
  ------------------
 1943|      2|      bsize = context->leftover;
 1944|      2|      leftoverblock = 1;
 1945|      2|    }
 1946|      5|    if (context->do_compress) {
  ------------------
  |  Branch (1946:9): [True: 0, False: 5]
  ------------------
 1947|      0|      if (memcpyed && !context->prefilter) {
  ------------------
  |  Branch (1947:11): [True: 0, False: 0]
  |  Branch (1947:23): [True: 0, False: 0]
  ------------------
 1948|       |        /* We want to memcpy only */
 1949|      0|        memcpy(context->dest + context->header_overhead + j * context->blocksize,
 1950|      0|               context->src + j * context->blocksize, (unsigned int)bsize);
 1951|      0|        cbytes = (int32_t)bsize;
 1952|      0|      }
 1953|      0|      else {
 1954|       |        /* Regular compression */
 1955|      0|        cbytes = blosc_c(thread_context, bsize, leftoverblock, ntbytes,
 1956|      0|                         context->destsize, context->src, j * context->blocksize,
 1957|      0|                         context->dest + ntbytes, tmp, tmp2);
 1958|      0|        if (cbytes == 0) {
  ------------------
  |  Branch (1958:13): [True: 0, False: 0]
  ------------------
 1959|      0|          ntbytes = 0;              /* incompressible data */
 1960|      0|          break;
 1961|      0|        }
 1962|      0|      }
 1963|      0|    }
 1964|      5|    else {
 1965|       |      /* Regular decompression */
 1966|       |      // If memcpyed we don't have a bstarts section (because it is not needed)
 1967|      5|      int32_t src_offset = memcpyed ?
  ------------------
  |  Branch (1967:28): [True: 1, False: 4]
  ------------------
 1968|      4|          context->header_overhead + j * context->blocksize : sw32_(bstarts + j);
 1969|      5|      cbytes = blosc_d(thread_context, bsize, leftoverblock, memcpyed,
 1970|      5|                       context->src, context->srcsize, src_offset, j,
 1971|      5|                       context->dest, j * context->blocksize, tmp, tmp2);
 1972|      5|    }
 1973|       |
 1974|      5|    if (cbytes < 0) {
  ------------------
  |  Branch (1974:9): [True: 0, False: 5]
  ------------------
 1975|      0|      ntbytes = cbytes;         /* error in blosc_c or blosc_d */
 1976|      0|      break;
 1977|      0|    }
 1978|      5|    ntbytes += cbytes;
 1979|      5|  }
 1980|       |
 1981|      3|  return ntbytes;
 1982|      3|}
blosc2.c:blosc_run_decompression_with_context:
 2897|      4|                                                void* dest, int32_t destsize) {
 2898|      4|  blosc_header header;
 2899|      4|  int32_t ntbytes;
 2900|      4|  int rc;
 2901|       |
 2902|      4|  rc = read_chunk_header(src, srcsize, true, &header);
 2903|      4|  if (rc < 0) {
  ------------------
  |  Branch (2903:7): [True: 0, False: 4]
  ------------------
 2904|      0|    return rc;
 2905|      0|  }
 2906|       |
 2907|      4|  if (header.nbytes > destsize) {
  ------------------
  |  Branch (2907:7): [True: 0, False: 4]
  ------------------
 2908|       |    // Not enough space for writing into the destination
 2909|      0|    return BLOSC2_ERROR_WRITE_BUFFER;
 2910|      0|  }
 2911|       |
 2912|      4|  rc = initialize_context_decompression(context, &header, src, srcsize, dest, destsize);
 2913|      4|  if (rc < 0) {
  ------------------
  |  Branch (2913:7): [True: 1, False: 3]
  ------------------
 2914|      1|    return rc;
 2915|      1|  }
 2916|       |
 2917|       |  /* Do the actual decompression */
 2918|      3|  ntbytes = do_job(context);
 2919|      3|  if (ntbytes < 0) {
  ------------------
  |  Branch (2919:7): [True: 0, False: 3]
  ------------------
 2920|      0|    return ntbytes;
 2921|      0|  }
 2922|       |
 2923|      3|  assert(ntbytes <= (int32_t)destsize);
 2924|      3|  return ntbytes;
 2925|      3|}
blosc2.c:initialize_context_decompression:
 2273|      4|                                            int32_t srcsize, void* dest, int32_t destsize) {
 2274|      4|  int32_t bstarts_end;
 2275|       |
 2276|      4|  context->do_compress = 0;
 2277|      4|  context->src = (const uint8_t*)src;
 2278|      4|  context->srcsize = srcsize;
 2279|      4|  context->dest = (uint8_t*)dest;
 2280|      4|  context->destsize = destsize;
 2281|      4|  context->output_bytes = 0;
 2282|      4|  context->end_threads = 0;
 2283|       |
 2284|      4|  int rc = blosc2_initialize_context_from_header(context, header);
 2285|      4|  if (rc < 0) {
  ------------------
  |  Branch (2285:7): [True: 0, False: 4]
  ------------------
 2286|      0|    return rc;
 2287|      0|  }
 2288|       |
 2289|       |  /* Check that we have enough space to decompress */
 2290|      4|  if (context->sourcesize > (int32_t)context->destsize) {
  ------------------
  |  Branch (2290:7): [True: 0, False: 4]
  ------------------
 2291|      0|    return BLOSC2_ERROR_WRITE_BUFFER;
 2292|      0|  }
 2293|       |
 2294|      4|  if (context->block_maskout != NULL && context->block_maskout_nitems != context->nblocks) {
  ------------------
  |  Branch (2294:7): [True: 0, False: 4]
  |  Branch (2294:41): [True: 0, False: 0]
  ------------------
 2295|      0|    BLOSC_TRACE_ERROR("The number of items in block_maskout (%d) must match the number"
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2296|      0|                      " of blocks in chunk (%d).",
 2297|      0|                      context->block_maskout_nitems, context->nblocks);
 2298|      0|    return BLOSC2_ERROR_DATA;
 2299|      0|  }
 2300|       |
 2301|      4|  context->special_type = (header->blosc2_flags >> 4) & BLOSC2_SPECIAL_MASK;
 2302|      4|  if (context->special_type > BLOSC2_SPECIAL_LASTID) {
  ------------------
  |  Branch (2302:7): [True: 0, False: 4]
  ------------------
 2303|      0|    BLOSC_TRACE_ERROR("Unknown special values ID (%d) ",
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2304|      0|                      context->special_type);
 2305|      0|    return BLOSC2_ERROR_DATA;
 2306|      0|  }
 2307|       |
 2308|      4|  int memcpyed = (context->header_flags & (uint8_t) BLOSC_MEMCPYED);
 2309|      4|  if (memcpyed && (header->cbytes != header->nbytes + context->header_overhead)) {
  ------------------
  |  Branch (2309:7): [True: 1, False: 3]
  |  Branch (2309:19): [True: 1, False: 0]
  ------------------
 2310|      1|    BLOSC_TRACE_ERROR("Wrong header info for this memcpyed chunk");
  ------------------
  |  |   97|      1|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      1|    do {                                            \
  |  |  |  |  102|      1|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      1|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 1, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      1|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2311|      0|    return BLOSC2_ERROR_DATA;
 2312|      1|  }
 2313|       |
 2314|      3|  if ((header->nbytes == 0) && (header->cbytes == context->header_overhead) &&
  ------------------
  |  Branch (2314:7): [True: 0, False: 3]
  |  Branch (2314:32): [True: 0, False: 0]
  ------------------
 2315|      3|      !context->special_type) {
  ------------------
  |  Branch (2315:7): [True: 0, False: 0]
  ------------------
 2316|       |    // A compressed buffer with only a header can only contain a zero-length buffer
 2317|      0|    return 0;
 2318|      0|  }
 2319|       |
 2320|      3|  context->bstarts = (int32_t *) (context->src + context->header_overhead);
 2321|      3|  bstarts_end = context->header_overhead;
 2322|      3|  if (!context->special_type && !memcpyed) {
  ------------------
  |  Branch (2322:7): [True: 2, False: 1]
  |  Branch (2322:33): [True: 2, False: 0]
  ------------------
 2323|       |    /* If chunk is not special or a memcpyed, we do have a bstarts section */
 2324|      2|    bstarts_end = (int32_t)(context->header_overhead + (context->nblocks * sizeof(int32_t)));
 2325|      2|  }
 2326|       |
 2327|      3|  if (srcsize < bstarts_end) {
  ------------------
  |  Branch (2327:7): [True: 0, False: 3]
  ------------------
 2328|      0|    BLOSC_TRACE_ERROR("`bstarts` exceeds length of source buffer.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2329|      0|    return BLOSC2_ERROR_READ_BUFFER;
 2330|      0|  }
 2331|      3|  srcsize -= bstarts_end;
 2332|       |
 2333|       |  /* Read optional dictionary if flag set */
 2334|      3|  if (context->blosc2_flags & BLOSC2_USEDICT) {
  ------------------
  |  Branch (2334:7): [True: 0, False: 3]
  ------------------
 2335|      0|#if defined(HAVE_ZSTD)
 2336|      0|    context->use_dict = 1;
 2337|      0|    if (context->dict_ddict != NULL) {
  ------------------
  |  Branch (2337:9): [True: 0, False: 0]
  ------------------
 2338|       |      // Free the existing dictionary (probably from another chunk)
 2339|      0|      ZSTD_freeDDict(context->dict_ddict);
 2340|      0|    }
 2341|       |    // The trained dictionary is after the bstarts block
 2342|      0|    if (srcsize < (signed)sizeof(int32_t)) {
  ------------------
  |  Branch (2342:9): [True: 0, False: 0]
  ------------------
 2343|      0|      BLOSC_TRACE_ERROR("Not enough space to read size of dictionary.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2344|      0|      return BLOSC2_ERROR_READ_BUFFER;
 2345|      0|    }
 2346|      0|    srcsize -= sizeof(int32_t);
 2347|       |    // Read dictionary size
 2348|      0|    context->dict_size = sw32_(context->src + bstarts_end);
 2349|      0|    if (context->dict_size <= 0 || context->dict_size > BLOSC2_MAXDICTSIZE) {
  ------------------
  |  Branch (2349:9): [True: 0, False: 0]
  |  Branch (2349:36): [True: 0, False: 0]
  ------------------
 2350|      0|      BLOSC_TRACE_ERROR("Dictionary size is smaller than minimum or larger than maximum allowed.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2351|      0|      return BLOSC2_ERROR_CODEC_DICT;
 2352|      0|    }
 2353|      0|    if (srcsize < (int32_t)context->dict_size) {
  ------------------
  |  Branch (2353:9): [True: 0, False: 0]
  ------------------
 2354|      0|      BLOSC_TRACE_ERROR("Not enough space to read entire dictionary.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2355|      0|      return BLOSC2_ERROR_READ_BUFFER;
 2356|      0|    }
 2357|      0|    srcsize -= context->dict_size;
 2358|       |    // Read dictionary
 2359|      0|    context->dict_buffer = (void*)(context->src + bstarts_end + sizeof(int32_t));
 2360|      0|    context->dict_ddict = ZSTD_createDDict(context->dict_buffer, context->dict_size);
 2361|      0|#endif   // HAVE_ZSTD
 2362|      0|  }
 2363|       |
 2364|      3|  return 0;
 2365|      3|}
blosc2.c:my_malloc:
  178|     22|static uint8_t* my_malloc(size_t size) {
  179|     22|  void* block = NULL;
  180|     22|  int res = 0;
  181|       |
  182|       |/* Do an alignment to 32 bytes because AVX2 is supported */
  183|       |#if defined(_WIN32)
  184|       |  /* A (void *) cast needed for avoiding a warning with MINGW :-/ */
  185|       |  block = (void *)_aligned_malloc(size, 32);
  186|       |#elif _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
  187|       |  /* Platform does have an implementation of posix_memalign */
  188|     22|  res = posix_memalign(&block, 32, size);
  189|       |#else
  190|       |  block = malloc(size);
  191|       |#endif  /* _WIN32 */
  192|       |
  193|     22|  if (block == NULL || res != 0) {
  ------------------
  |  Branch (193:7): [True: 0, False: 22]
  |  Branch (193:24): [True: 0, False: 22]
  ------------------
  194|      0|    BLOSC_TRACE_ERROR("Error allocating memory!");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  195|      0|    return NULL;
  196|      0|  }
  197|       |
  198|     22|  return (uint8_t*)block;
  199|     22|}
blosc2.c:blosc_d:
 1555|      5|    int32_t nblock, uint8_t* dest, int32_t dest_offset, uint8_t* tmp, uint8_t* tmp2) {
 1556|      5|  blosc2_context* context = thread_context->parent_context;
 1557|      5|  uint8_t* filters = context->filters;
 1558|      5|  uint8_t *tmp3 = thread_context->tmp4;
 1559|      5|  int32_t compformat = (context->header_flags & (uint8_t)0xe0) >> 5u;
 1560|      5|  int dont_split = (context->header_flags & 0x10) >> 4;
 1561|      5|  int32_t chunk_nbytes;
 1562|      5|  int32_t chunk_cbytes;
 1563|      5|  int nstreams;
 1564|      5|  int32_t neblock;
 1565|      5|  int32_t nbytes;                /* number of decompressed bytes in split */
 1566|      5|  int32_t cbytes;                /* number of compressed bytes in split */
 1567|       |  // int32_t ctbytes = 0;           /* number of compressed bytes in block */
 1568|      5|  int32_t ntbytes = 0;           /* number of uncompressed bytes in block */
 1569|      5|  uint8_t* _dest;
 1570|      5|  int32_t typesize = context->typesize;
 1571|      5|  bool instr_codec = context->blosc2_flags & BLOSC2_INSTR_CODEC;
 1572|      5|  const char* compname;
 1573|      5|  int rc;
 1574|       |
 1575|      5|  if (context->block_maskout != NULL && context->block_maskout[nblock]) {
  ------------------
  |  Branch (1575:7): [True: 0, False: 5]
  |  Branch (1575:41): [True: 0, False: 0]
  ------------------
 1576|       |    // Do not decompress, but act as if we successfully decompressed everything
 1577|      0|    return bsize;
 1578|      0|  }
 1579|       |
 1580|      5|  rc = blosc2_cbuffer_sizes(src, &chunk_nbytes, &chunk_cbytes, NULL);
 1581|      5|  if (rc < 0) {
  ------------------
  |  Branch (1581:7): [True: 0, False: 5]
  ------------------
 1582|      0|    return rc;
 1583|      0|  }
 1584|       |
 1585|       |  // In some situations (lazychunks) the context can arrive uninitialized
 1586|       |  // (but BITSHUFFLE needs it for accessing the format of the chunk)
 1587|      5|  if (context->src == NULL) {
  ------------------
  |  Branch (1587:7): [True: 0, False: 5]
  ------------------
 1588|      0|    context->src = src;
 1589|      0|  }
 1590|       |
 1591|       |  // Chunks with special values cannot be lazy
 1592|      5|  bool is_lazy = ((context->header_overhead == BLOSC_EXTENDED_HEADER_LENGTH) &&
  ------------------
  |  Branch (1592:19): [True: 5, False: 0]
  ------------------
 1593|      5|          (context->blosc2_flags & 0x08u) && !context->special_type);
  ------------------
  |  Branch (1593:11): [True: 0, False: 5]
  |  Branch (1593:46): [True: 0, False: 0]
  ------------------
 1594|      5|  if (is_lazy) {
  ------------------
  |  Branch (1594:7): [True: 0, False: 5]
  ------------------
 1595|       |    // The chunk is on disk, so just lazily load the block
 1596|      0|    if (context->schunk == NULL) {
  ------------------
  |  Branch (1596:9): [True: 0, False: 0]
  ------------------
 1597|      0|      BLOSC_TRACE_ERROR("Lazy chunk needs an associated super-chunk.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1598|      0|      return BLOSC2_ERROR_INVALID_PARAM;
 1599|      0|    }
 1600|      0|    if (context->schunk->frame == NULL) {
  ------------------
  |  Branch (1600:9): [True: 0, False: 0]
  ------------------
 1601|      0|      BLOSC_TRACE_ERROR("Lazy chunk needs an associated frame.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1602|      0|      return BLOSC2_ERROR_INVALID_PARAM;
 1603|      0|    }
 1604|      0|    blosc2_frame_s* frame = (blosc2_frame_s*)context->schunk->frame;
 1605|      0|    char* urlpath = frame->urlpath;
 1606|      0|    size_t trailer_offset = BLOSC_EXTENDED_HEADER_LENGTH + context->nblocks * sizeof(int32_t);
 1607|      0|    int32_t nchunk;
 1608|      0|    int64_t chunk_offset;
 1609|       |    // The nchunk and the offset of the current chunk are in the trailer
 1610|      0|    nchunk = *(int32_t*)(src + trailer_offset);
 1611|      0|    chunk_offset = *(int64_t*)(src + trailer_offset + sizeof(int32_t));
 1612|       |    // Get the csize of the nblock
 1613|      0|    int32_t *block_csizes = (int32_t *)(src + trailer_offset + sizeof(int32_t) + sizeof(int64_t));
 1614|      0|    int32_t block_csize = block_csizes[nblock];
 1615|       |    // Read the lazy block on disk
 1616|      0|    void* fp = NULL;
 1617|      0|    blosc2_io_cb *io_cb = blosc2_get_io_cb(context->schunk->storage->io->id);
 1618|      0|    if (io_cb == NULL) {
  ------------------
  |  Branch (1618:9): [True: 0, False: 0]
  ------------------
 1619|      0|      BLOSC_TRACE_ERROR("Error getting the input/output API");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1620|      0|      return BLOSC2_ERROR_PLUGIN_IO;
 1621|      0|    }
 1622|       |
 1623|      0|    int64_t io_pos = 0;
 1624|      0|    if (frame->sframe) {
  ------------------
  |  Branch (1624:9): [True: 0, False: 0]
  ------------------
 1625|       |      // The chunk is not in the frame
 1626|      0|      char* chunkpath = malloc(strlen(frame->urlpath) + 1 + 8 + strlen(".chunk") + 1);
 1627|      0|      BLOSC_ERROR_NULL(chunkpath, BLOSC2_ERROR_MEMORY_ALLOC);
  ------------------
  |  |  108|      0|    do {                                            \
  |  |  109|      0|        if ((pointer) == NULL) {                    \
  |  |  ------------------
  |  |  |  Branch (109:13): [True: 0, False: 0]
  |  |  ------------------
  |  |  110|      0|            BLOSC_TRACE_ERROR("Pointer is null");   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  111|      0|            return (rc);                            \
  |  |  112|      0|        }                                           \
  |  |  113|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1628|      0|      sprintf(chunkpath, "%s/%08X.chunk", frame->urlpath, nchunk);
 1629|      0|      fp = io_cb->open(chunkpath, "rb", context->schunk->storage->io->params);
 1630|      0|      BLOSC_ERROR_NULL(fp, BLOSC2_ERROR_FILE_OPEN);
  ------------------
  |  |  108|      0|    do {                                            \
  |  |  109|      0|        if ((pointer) == NULL) {                    \
  |  |  ------------------
  |  |  |  Branch (109:13): [True: 0, False: 0]
  |  |  ------------------
  |  |  110|      0|            BLOSC_TRACE_ERROR("Pointer is null");   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  111|      0|            return (rc);                            \
  |  |  112|      0|        }                                           \
  |  |  113|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1631|      0|      free(chunkpath);
 1632|       |      // The offset of the block is src_offset
 1633|      0|      io_pos = src_offset;
 1634|      0|    }
 1635|      0|    else {
 1636|      0|      fp = io_cb->open(urlpath, "rb", context->schunk->storage->io->params);
 1637|      0|      BLOSC_ERROR_NULL(fp, BLOSC2_ERROR_FILE_OPEN);
  ------------------
  |  |  108|      0|    do {                                            \
  |  |  109|      0|        if ((pointer) == NULL) {                    \
  |  |  ------------------
  |  |  |  Branch (109:13): [True: 0, False: 0]
  |  |  ------------------
  |  |  110|      0|            BLOSC_TRACE_ERROR("Pointer is null");   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  111|      0|            return (rc);                            \
  |  |  112|      0|        }                                           \
  |  |  113|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1638|       |      // The offset of the block is src_offset
 1639|      0|      io_pos = frame->file_offset + chunk_offset + src_offset;
 1640|      0|    }
 1641|       |    // We can make use of tmp3 because it will be used after src is not needed anymore
 1642|      0|    int64_t rbytes = io_cb->read((void**)&tmp3, 1, block_csize, io_pos, fp);
 1643|      0|    io_cb->close(fp);
 1644|      0|    if ((int32_t)rbytes != block_csize) {
  ------------------
  |  Branch (1644:9): [True: 0, False: 0]
  ------------------
 1645|      0|      BLOSC_TRACE_ERROR("Cannot read the (lazy) block out of the fileframe.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1646|      0|      return BLOSC2_ERROR_READ_BUFFER;
 1647|      0|    }
 1648|      0|    src = tmp3;
 1649|      0|    src_offset = 0;
 1650|      0|    srcsize = block_csize;
 1651|      0|  }
 1652|       |
 1653|       |  // If the chunk is memcpyed, we just have to copy the block to dest and return
 1654|      5|  if (memcpyed) {
  ------------------
  |  Branch (1654:7): [True: 1, False: 4]
  ------------------
 1655|      1|    int bsize_ = leftoverblock ? chunk_nbytes % context->blocksize : bsize;
  ------------------
  |  Branch (1655:18): [True: 0, False: 1]
  ------------------
 1656|      1|    if (!context->special_type) {
  ------------------
  |  Branch (1656:9): [True: 0, False: 1]
  ------------------
 1657|      0|      if (chunk_nbytes + context->header_overhead != chunk_cbytes) {
  ------------------
  |  Branch (1657:11): [True: 0, False: 0]
  ------------------
 1658|      0|        return BLOSC2_ERROR_WRITE_BUFFER;
 1659|      0|      }
 1660|      0|      if (chunk_cbytes < context->header_overhead + (nblock * context->blocksize) + bsize_) {
  ------------------
  |  Branch (1660:11): [True: 0, False: 0]
  ------------------
 1661|       |        /* Not enough input to copy block */
 1662|      0|        return BLOSC2_ERROR_READ_BUFFER;
 1663|      0|      }
 1664|      0|    }
 1665|      1|    if (!is_lazy) {
  ------------------
  |  Branch (1665:9): [True: 1, False: 0]
  ------------------
 1666|      1|      src += context->header_overhead + nblock * context->blocksize;
 1667|      1|    }
 1668|      1|    _dest = dest + dest_offset;
 1669|      1|    if (context->postfilter != NULL) {
  ------------------
  |  Branch (1669:9): [True: 0, False: 1]
  ------------------
 1670|       |      // We are making use of a postfilter, so use a temp for destination
 1671|      0|      _dest = tmp;
 1672|      0|    }
 1673|      1|    rc = 0;
 1674|      1|    switch (context->special_type) {
 1675|      0|      case BLOSC2_SPECIAL_VALUE:
  ------------------
  |  Branch (1675:7): [True: 0, False: 1]
  ------------------
 1676|       |        // All repeated values
 1677|      0|        rc = set_values(context->typesize, context->src, _dest, bsize_);
 1678|      0|        if (rc < 0) {
  ------------------
  |  Branch (1678:13): [True: 0, False: 0]
  ------------------
 1679|      0|          BLOSC_TRACE_ERROR("set_values failed");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1680|      0|          return BLOSC2_ERROR_DATA;
 1681|      0|        }
 1682|      0|        break;
 1683|      0|      case BLOSC2_SPECIAL_NAN:
  ------------------
  |  Branch (1683:7): [True: 0, False: 1]
  ------------------
 1684|      0|        rc = set_nans(context->typesize, _dest, bsize_);
 1685|      0|        if (rc < 0) {
  ------------------
  |  Branch (1685:13): [True: 0, False: 0]
  ------------------
 1686|      0|          BLOSC_TRACE_ERROR("set_nans failed");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1687|      0|          return BLOSC2_ERROR_DATA;
 1688|      0|        }
 1689|      0|        break;
 1690|      1|      case BLOSC2_SPECIAL_ZERO:
  ------------------
  |  Branch (1690:7): [True: 1, False: 0]
  ------------------
 1691|      1|        memset(_dest, 0, bsize_);
 1692|      1|        break;
 1693|      0|      case BLOSC2_SPECIAL_UNINIT:
  ------------------
  |  Branch (1693:7): [True: 0, False: 1]
  ------------------
 1694|       |        // We do nothing here
 1695|      0|        break;
 1696|      0|      default:
  ------------------
  |  Branch (1696:7): [True: 0, False: 1]
  ------------------
 1697|      0|        memcpy(_dest, src, bsize_);
 1698|      1|    }
 1699|      1|    if (context->postfilter != NULL) {
  ------------------
  |  Branch (1699:9): [True: 0, False: 1]
  ------------------
 1700|       |      // Create new postfilter parameters for this block (must be private for each thread)
 1701|      0|      blosc2_postfilter_params postparams;
 1702|      0|      memcpy(&postparams, context->postparams, sizeof(postparams));
 1703|      0|      postparams.input = tmp;
 1704|      0|      postparams.output = dest + dest_offset;
 1705|      0|      postparams.size = bsize;
 1706|      0|      postparams.typesize = typesize;
 1707|      0|      postparams.offset = nblock * context->blocksize;
 1708|      0|      postparams.nchunk = context->schunk != NULL ? context->schunk->current_nchunk : -1;
  ------------------
  |  Branch (1708:27): [True: 0, False: 0]
  ------------------
 1709|      0|      postparams.nblock = nblock;
 1710|      0|      postparams.tid = thread_context->tid;
 1711|      0|      postparams.ttmp = thread_context->tmp;
 1712|      0|      postparams.ttmp_nbytes = thread_context->tmp_nbytes;
 1713|      0|      postparams.ctx = context;
 1714|       |
 1715|       |      // Execute the postfilter (the processed block will be copied to dest)
 1716|      0|      if (context->postfilter(&postparams) != 0) {
  ------------------
  |  Branch (1716:11): [True: 0, False: 0]
  ------------------
 1717|      0|        BLOSC_TRACE_ERROR("Execution of postfilter function failed");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1718|      0|        return BLOSC2_ERROR_POSTFILTER;
 1719|      0|      }
 1720|      0|    }
 1721|      1|    thread_context->zfp_cell_nitems = 0;
 1722|       |
 1723|      1|    return bsize_;
 1724|      1|  }
 1725|       |
 1726|      4|  if (!is_lazy && (src_offset <= 0 || src_offset >= srcsize)) {
  ------------------
  |  Branch (1726:7): [True: 4, False: 0]
  |  Branch (1726:20): [True: 0, False: 4]
  |  Branch (1726:39): [True: 0, False: 4]
  ------------------
 1727|       |    /* Invalid block src offset encountered */
 1728|      0|    return BLOSC2_ERROR_DATA;
 1729|      0|  }
 1730|       |
 1731|      4|  src += src_offset;
 1732|      4|  srcsize -= src_offset;
 1733|       |
 1734|      4|  int last_filter_index = last_filter(filters, 'd');
 1735|      4|  if (instr_codec) {
  ------------------
  |  Branch (1735:7): [True: 0, False: 4]
  ------------------
 1736|       |    // If instrumented, we don't want to run the filters
 1737|      0|    _dest = dest + dest_offset;
 1738|      0|  }
 1739|      4|  else if (((last_filter_index >= 0) &&
  ------------------
  |  Branch (1739:13): [True: 4, False: 0]
  ------------------
 1740|      4|       (next_filter(filters, BLOSC2_MAX_FILTERS, 'd') != BLOSC_DELTA)) ||
  ------------------
  |  Branch (1740:8): [True: 4, False: 0]
  ------------------
 1741|      4|    context->postfilter != NULL) {
  ------------------
  |  Branch (1741:5): [True: 0, False: 0]
  ------------------
 1742|       |    // We are making use of some filter, so use a temp for destination
 1743|      4|    _dest = tmp;
 1744|      4|  }
 1745|      0|  else {
 1746|       |    // If no filters, or only DELTA in pipeline
 1747|      0|    _dest = dest + dest_offset;
 1748|      0|  }
 1749|       |
 1750|       |  /* The number of compressed data streams for this block */
 1751|      4|  if (!dont_split && !leftoverblock) {
  ------------------
  |  Branch (1751:7): [True: 0, False: 4]
  |  Branch (1751:22): [True: 0, False: 0]
  ------------------
 1752|      0|    nstreams = (int32_t)typesize;
 1753|      0|  }
 1754|      4|  else {
 1755|      4|    nstreams = 1;
 1756|      4|  }
 1757|       |
 1758|      4|  neblock = bsize / nstreams;
 1759|      4|  if (neblock == 0) {
  ------------------
  |  Branch (1759:7): [True: 0, False: 4]
  ------------------
 1760|       |    /* Not enough space to output bytes */
 1761|      0|    BLOSC_ERROR(BLOSC2_ERROR_WRITE_BUFFER);
  ------------------
  |  |  115|      0|    do {                                            \
  |  |  116|      0|        int rc_ = (rc);                             \
  |  |  117|      0|        if (rc_ < BLOSC2_ERROR_SUCCESS) {           \
  |  |  ------------------
  |  |  |  Branch (117:13): [True: 0, False: 0]
  |  |  ------------------
  |  |  118|      0|            char *error_msg = print_error(rc_);     \
  |  |  119|      0|            BLOSC_TRACE_ERROR("%s", error_msg);     \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  120|      0|            return rc_;                             \
  |  |  121|      0|        }                                           \
  |  |  122|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (122:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1762|      0|  }
 1763|      8|  for (int j = 0; j < nstreams; j++) {
  ------------------
  |  Branch (1763:19): [True: 4, False: 4]
  ------------------
 1764|      4|    if (srcsize < (signed)sizeof(int32_t)) {
  ------------------
  |  Branch (1764:9): [True: 0, False: 4]
  ------------------
 1765|       |      /* Not enough input to read compressed size */
 1766|      0|      return BLOSC2_ERROR_READ_BUFFER;
 1767|      0|    }
 1768|      4|    srcsize -= sizeof(int32_t);
 1769|      4|    cbytes = sw32_(src);      /* amount of compressed bytes */
 1770|      4|    if (cbytes > 0) {
  ------------------
  |  Branch (1770:9): [True: 4, False: 0]
  ------------------
 1771|      4|      if (srcsize < cbytes) {
  ------------------
  |  Branch (1771:11): [True: 0, False: 4]
  ------------------
 1772|       |        /* Not enough input to read compressed bytes */
 1773|      0|        return BLOSC2_ERROR_READ_BUFFER;
 1774|      0|      }
 1775|      4|      srcsize -= cbytes;
 1776|      4|    }
 1777|      4|    src += sizeof(int32_t);
 1778|       |    // ctbytes += (signed)sizeof(int32_t);
 1779|       |
 1780|       |    /* Uncompress */
 1781|      4|    if (cbytes == 0) {
  ------------------
  |  Branch (1781:9): [True: 0, False: 4]
  ------------------
 1782|       |      // A run of 0's
 1783|      0|      memset(_dest, 0, (unsigned int)neblock);
 1784|      0|      nbytes = neblock;
 1785|      0|    }
 1786|      4|    else if (cbytes < 0) {
  ------------------
  |  Branch (1786:14): [True: 0, False: 4]
  ------------------
 1787|       |      // A negative number means some encoding depending on the token that comes next
 1788|      0|      uint8_t token;
 1789|       |
 1790|      0|      if (srcsize < (signed)sizeof(uint8_t)) {
  ------------------
  |  Branch (1790:11): [True: 0, False: 0]
  ------------------
 1791|       |        // Not enough input to read token */
 1792|      0|        return BLOSC2_ERROR_READ_BUFFER;
 1793|      0|      }
 1794|      0|      srcsize -= sizeof(uint8_t);
 1795|       |
 1796|      0|      token = src[0];
 1797|      0|      src += 1;
 1798|       |      // ctbytes += 1;
 1799|       |
 1800|      0|      if (token & 0x1) {
  ------------------
  |  Branch (1800:11): [True: 0, False: 0]
  ------------------
 1801|       |        // A run of bytes that are different than 0
 1802|      0|        if (cbytes < -255) {
  ------------------
  |  Branch (1802:13): [True: 0, False: 0]
  ------------------
 1803|       |          // Runs can only encode a byte
 1804|      0|          return BLOSC2_ERROR_RUN_LENGTH;
 1805|      0|        }
 1806|      0|        uint8_t value = -cbytes;
 1807|      0|        memset(_dest, value, (unsigned int)neblock);
 1808|      0|      } else {
 1809|      0|        BLOSC_TRACE_ERROR("Invalid or unsupported compressed stream token value - %d", token);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1810|      0|        return BLOSC2_ERROR_RUN_LENGTH;
 1811|      0|      }
 1812|      0|      nbytes = neblock;
 1813|      0|      cbytes = 0;  // everything is encoded in the cbytes token
 1814|      0|    }
 1815|      4|    else if (cbytes == neblock) {
  ------------------
  |  Branch (1815:14): [True: 0, False: 4]
  ------------------
 1816|      0|      memcpy(_dest, src, (unsigned int)neblock);
 1817|      0|      nbytes = (int32_t)neblock;
 1818|      0|    }
 1819|      4|    else {
 1820|      4|      if (compformat == BLOSC_BLOSCLZ_FORMAT) {
  ------------------
  |  Branch (1820:11): [True: 0, False: 4]
  ------------------
 1821|      0|        nbytes = blosclz_decompress(src, cbytes, _dest, (int)neblock);
 1822|      0|      }
 1823|      4|      else if (compformat == BLOSC_LZ4_FORMAT) {
  ------------------
  |  Branch (1823:16): [True: 4, False: 0]
  ------------------
 1824|      4|        nbytes = lz4_wrap_decompress((char*)src, (size_t)cbytes,
 1825|      4|                                     (char*)_dest, (size_t)neblock);
 1826|      4|      }
 1827|      0|  #if defined(HAVE_ZLIB)
 1828|      0|      else if (compformat == BLOSC_ZLIB_FORMAT) {
  ------------------
  |  Branch (1828:16): [True: 0, False: 0]
  ------------------
 1829|      0|        nbytes = zlib_wrap_decompress((char*)src, (size_t)cbytes,
 1830|      0|                                      (char*)_dest, (size_t)neblock);
 1831|      0|      }
 1832|      0|  #endif /*  HAVE_ZLIB */
 1833|      0|  #if defined(HAVE_ZSTD)
 1834|      0|      else if (compformat == BLOSC_ZSTD_FORMAT) {
  ------------------
  |  Branch (1834:16): [True: 0, False: 0]
  ------------------
 1835|      0|        nbytes = zstd_wrap_decompress(thread_context,
 1836|      0|                                      (char*)src, (size_t)cbytes,
 1837|      0|                                      (char*)_dest, (size_t)neblock);
 1838|      0|      }
 1839|      0|  #endif /*  HAVE_ZSTD */
 1840|      0|      else if (compformat == BLOSC_UDCODEC_FORMAT) {
  ------------------
  |  Branch (1840:16): [True: 0, False: 0]
  ------------------
 1841|      0|        bool getcell = false;
 1842|       |
 1843|      0|#if defined(HAVE_PLUGINS)
 1844|      0|        if ((context->compcode == BLOSC_CODEC_ZFP_FIXED_RATE) &&
  ------------------
  |  Branch (1844:13): [True: 0, False: 0]
  ------------------
 1845|      0|            (thread_context->zfp_cell_nitems > 0)) {
  ------------------
  |  Branch (1845:13): [True: 0, False: 0]
  ------------------
 1846|      0|          nbytes = zfp_getcell(thread_context, src, cbytes, _dest, neblock);
 1847|      0|          if (nbytes < 0) {
  ------------------
  |  Branch (1847:15): [True: 0, False: 0]
  ------------------
 1848|      0|            return BLOSC2_ERROR_DATA;
 1849|      0|          }
 1850|      0|          if (nbytes == thread_context->zfp_cell_nitems * typesize) {
  ------------------
  |  Branch (1850:15): [True: 0, False: 0]
  ------------------
 1851|      0|            getcell = true;
 1852|      0|          }
 1853|      0|        }
 1854|      0|#endif /* HAVE_PLUGINS */
 1855|      0|        if (!getcell) {
  ------------------
  |  Branch (1855:13): [True: 0, False: 0]
  ------------------
 1856|      0|          thread_context->zfp_cell_nitems = 0;
 1857|      0|          for (int i = 0; i < g_ncodecs; ++i) {
  ------------------
  |  Branch (1857:27): [True: 0, False: 0]
  ------------------
 1858|      0|            if (g_codecs[i].compcode == context->compcode) {
  ------------------
  |  Branch (1858:17): [True: 0, False: 0]
  ------------------
 1859|      0|              if (g_codecs[i].decoder == NULL) {
  ------------------
  |  Branch (1859:19): [True: 0, False: 0]
  ------------------
 1860|       |                // Dynamically load codec plugin
 1861|      0|                if (fill_codec(&g_codecs[i]) < 0) {
  ------------------
  |  Branch (1861:21): [True: 0, False: 0]
  ------------------
 1862|      0|                  BLOSC_TRACE_ERROR("Could not load codec %d.", g_codecs[i].compcode);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1863|      0|                  return BLOSC2_ERROR_CODEC_SUPPORT;
 1864|      0|                }
 1865|      0|              }
 1866|      0|              blosc2_dparams dparams;
 1867|      0|              blosc2_ctx_get_dparams(context, &dparams);
 1868|      0|              nbytes = g_codecs[i].decoder(src,
 1869|      0|                                           cbytes,
 1870|      0|                                           _dest,
 1871|      0|                                           neblock,
 1872|      0|                                           context->compcode_meta,
 1873|      0|                                           &dparams,
 1874|      0|                                           context->src);
 1875|      0|              goto urcodecsuccess;
 1876|      0|            }
 1877|      0|          }
 1878|      0|          BLOSC_TRACE_ERROR("User-defined compressor codec %d not found during decompression", context->compcode);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1879|      0|          return BLOSC2_ERROR_CODEC_SUPPORT;
 1880|      0|        }
 1881|      0|      urcodecsuccess:
 1882|      0|        ;
 1883|      0|      }
 1884|      0|      else {
 1885|      0|        compname = clibcode_to_clibname(compformat);
 1886|      0|        BLOSC_TRACE_ERROR(
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1887|      0|                "Blosc has not been compiled with decompression "
 1888|      0|                "support for '%s' format.  "
 1889|      0|                "Please recompile for adding this support.", compname);
 1890|      0|        return BLOSC2_ERROR_CODEC_SUPPORT;
 1891|      0|      }
 1892|       |
 1893|       |      /* Check that decompressed bytes number is correct */
 1894|      4|      if ((nbytes != neblock) && (thread_context->zfp_cell_nitems == 0)) {
  ------------------
  |  Branch (1894:11): [True: 0, False: 4]
  |  Branch (1894:34): [True: 0, False: 0]
  ------------------
 1895|      0|        return BLOSC2_ERROR_DATA;
 1896|      0|      }
 1897|       |
 1898|      4|    }
 1899|      4|    src += cbytes;
 1900|       |    // ctbytes += cbytes;
 1901|      4|    _dest += nbytes;
 1902|      4|    ntbytes += nbytes;
 1903|      4|  } /* Closes j < nstreams */
 1904|       |
 1905|      4|  if (!instr_codec) {
  ------------------
  |  Branch (1905:7): [True: 4, False: 0]
  ------------------
 1906|      4|    if (last_filter_index >= 0 || context->postfilter != NULL) {
  ------------------
  |  Branch (1906:9): [True: 4, False: 0]
  |  Branch (1906:35): [True: 0, False: 0]
  ------------------
 1907|       |      /* Apply regular filter pipeline */
 1908|      4|      int errcode = pipeline_backward(thread_context, bsize, dest, dest_offset, tmp, tmp2, tmp3,
 1909|      4|                                      last_filter_index, nblock);
 1910|      4|      if (errcode < 0)
  ------------------
  |  Branch (1910:11): [True: 0, False: 4]
  ------------------
 1911|      0|        return errcode;
 1912|      4|    }
 1913|      4|  }
 1914|       |
 1915|       |  /* Return the number of uncompressed bytes */
 1916|      4|  return (int)ntbytes;
 1917|      4|}
blosc2.c:lz4_wrap_decompress:
  434|      4|                               char* output, size_t maxout) {
  435|      4|  int nbytes;
  436|       |#ifdef HAVE_IPP
  437|       |  int outlen = (int)maxout;
  438|       |  int inlen = (int)compressed_length;
  439|       |  IppStatus status;
  440|       |  status = ippsDecodeLZ4_8u((const Ipp8u*)input, inlen, (Ipp8u*)output, &outlen);
  441|       |  //status = ippsDecodeLZ4Dict_8u((const Ipp8u*)input, &inlen, (Ipp8u*)output, 0, &outlen, NULL, 1 << 16);
  442|       |  nbytes = (status == ippStsNoErr) ? outlen : -outlen;
  443|       |#else
  444|      4|  nbytes = LZ4_decompress_safe(input, output, (int)compressed_length, (int)maxout);
  445|      4|#endif
  446|      4|  if (nbytes != (int)maxout) {
  ------------------
  |  Branch (446:7): [True: 0, False: 4]
  ------------------
  447|      0|    return 0;
  448|      0|  }
  449|      4|  return (int)maxout;
  450|      4|}
blosc2.c:blosc2_initialize_context_from_header:
  760|      8|static int blosc2_initialize_context_from_header(blosc2_context* context, blosc_header* header) {
  761|      8|  context->header_flags = header->flags;
  762|      8|  context->typesize = header->typesize;
  763|      8|  context->sourcesize = header->nbytes;
  764|      8|  context->blocksize = header->blocksize;
  765|      8|  context->blosc2_flags = header->blosc2_flags;
  766|      8|  context->compcode = header->flags >> 5;
  767|      8|  if (context->compcode == BLOSC_UDCODEC_FORMAT) {
  ------------------
  |  Branch (767:7): [True: 0, False: 8]
  ------------------
  768|      0|    context->compcode = header->udcompcode;
  769|      0|  }
  770|      8|  blosc2_calculate_blocks(context);
  771|       |
  772|      8|  bool is_lazy = false;
  773|      8|  if ((context->header_flags & BLOSC_DOSHUFFLE) &&
  ------------------
  |  Branch (773:7): [True: 8, False: 0]
  ------------------
  774|      8|      (context->header_flags & BLOSC_DOBITSHUFFLE)) {
  ------------------
  |  Branch (774:7): [True: 8, False: 0]
  ------------------
  775|       |    /* Extended header */
  776|      8|    context->header_overhead = BLOSC_EXTENDED_HEADER_LENGTH;
  777|       |
  778|      8|    memcpy(context->filters, header->filters, BLOSC2_MAX_FILTERS);
  779|      8|    memcpy(context->filters_meta, header->filters_meta, BLOSC2_MAX_FILTERS);
  780|      8|    context->compcode_meta = header->compcode_meta;
  781|       |
  782|      8|    context->filter_flags = filters_to_flags(header->filters);
  783|      8|    context->special_type = (header->blosc2_flags >> 4) & BLOSC2_SPECIAL_MASK;
  784|       |
  785|      8|    is_lazy = (context->blosc2_flags & 0x08u);
  786|      8|  }
  787|      0|  else {
  788|      0|    context->header_overhead = BLOSC_MIN_HEADER_LENGTH;
  789|      0|    context->filter_flags = get_filter_flags(context->header_flags, context->typesize);
  790|      0|    flags_to_filters(context->header_flags, context->filters);
  791|      0|  }
  792|       |
  793|       |  // Some checks for malformed headers
  794|      8|  if (!is_lazy && header->cbytes > context->srcsize) {
  ------------------
  |  Branch (794:7): [True: 8, False: 0]
  |  Branch (794:19): [True: 0, False: 8]
  ------------------
  795|      0|    return BLOSC2_ERROR_INVALID_HEADER;
  796|      0|  }
  797|       |
  798|      8|  return 0;
  799|      8|}
blosc2.c:create_thread_context:
 2059|      6|create_thread_context(blosc2_context* context, int32_t tid) {
 2060|      6|  struct thread_context* thread_context;
 2061|      6|  thread_context = (struct thread_context*)my_malloc(sizeof(struct thread_context));
 2062|      6|  BLOSC_ERROR_NULL(thread_context, NULL);
  ------------------
  |  |  108|      6|    do {                                            \
  |  |  109|      6|        if ((pointer) == NULL) {                    \
  |  |  ------------------
  |  |  |  Branch (109:13): [True: 0, False: 6]
  |  |  ------------------
  |  |  110|      0|            BLOSC_TRACE_ERROR("Pointer is null");   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  111|      0|            return (rc);                            \
  |  |  112|      0|        }                                           \
  |  |  113|      6|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 2063|      6|  int rc = init_thread_context(thread_context, context, tid);
 2064|      6|  if (rc < 0) {
  ------------------
  |  Branch (2064:7): [True: 0, False: 6]
  ------------------
 2065|      0|    return NULL;
 2066|      0|  }
 2067|      6|  return thread_context;
 2068|      6|}
blosc2.c:init_thread_context:
 2018|      6|{
 2019|      6|  int32_t ebsize;
 2020|       |
 2021|      6|  thread_context->parent_context = context;
 2022|      6|  thread_context->tid = tid;
 2023|       |
 2024|      6|  ebsize = context->blocksize + context->typesize * (signed)sizeof(int32_t);
 2025|      6|  thread_context->tmp_nbytes = (size_t)4 * ebsize;
 2026|      6|  thread_context->tmp = my_malloc(thread_context->tmp_nbytes);
 2027|      6|  BLOSC_ERROR_NULL(thread_context->tmp, BLOSC2_ERROR_MEMORY_ALLOC);
  ------------------
  |  |  108|      6|    do {                                            \
  |  |  109|      6|        if ((pointer) == NULL) {                    \
  |  |  ------------------
  |  |  |  Branch (109:13): [True: 0, False: 6]
  |  |  ------------------
  |  |  110|      0|            BLOSC_TRACE_ERROR("Pointer is null");   \
  |  |  ------------------
  |  |  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  111|      0|            return (rc);                            \
  |  |  112|      0|        }                                           \
  |  |  113|      6|    } while (0)
  |  |  ------------------
  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 2028|      6|  thread_context->tmp2 = thread_context->tmp + ebsize;
 2029|      6|  thread_context->tmp3 = thread_context->tmp2 + ebsize;
 2030|      6|  thread_context->tmp4 = thread_context->tmp3 + ebsize;
 2031|      6|  thread_context->tmp_blocksize = context->blocksize;
 2032|      6|  thread_context->zfp_cell_nitems = 0;
 2033|      6|  thread_context->zfp_cell_start = 0;
 2034|      6|  #if defined(HAVE_ZSTD)
 2035|      6|  thread_context->zstd_cctx = NULL;
 2036|      6|  thread_context->zstd_dctx = NULL;
 2037|      6|  #endif
 2038|       |
 2039|       |  /* Create the hash table for LZ4 in case we are using IPP */
 2040|       |#ifdef HAVE_IPP
 2041|       |  IppStatus status;
 2042|       |  int inlen = thread_context->tmp_blocksize > 0 ? thread_context->tmp_blocksize : 1 << 16;
 2043|       |  int hash_size = 0;
 2044|       |  status = ippsEncodeLZ4HashTableGetSize_8u(&hash_size);
 2045|       |  if (status != ippStsNoErr) {
 2046|       |      BLOSC_TRACE_ERROR("Error in ippsEncodeLZ4HashTableGetSize_8u.");
 2047|       |  }
 2048|       |  Ipp8u *hash_table = ippsMalloc_8u(hash_size);
 2049|       |  status = ippsEncodeLZ4HashTableInit_8u(hash_table, inlen);
 2050|       |  if (status != ippStsNoErr) {
 2051|       |    BLOSC_TRACE_ERROR("Error in ippsEncodeLZ4HashTableInit_8u.");
 2052|       |  }
 2053|       |  thread_context->lz4_hash_table = hash_table;
 2054|       |#endif
 2055|      6|  return 0;
 2056|      6|}

frame_free:
   50|      1|int frame_free(blosc2_frame_s* frame) {
   51|       |
   52|      1|  if (frame->cframe != NULL && !frame->avoid_cframe_free) {
  ------------------
  |  Branch (52:7): [True: 1, False: 0]
  |  Branch (52:32): [True: 0, False: 1]
  ------------------
   53|      0|    free(frame->cframe);
   54|      0|  }
   55|       |
   56|      1|  if (frame->coffsets != NULL && frame->coffsets_needs_free) {
  ------------------
  |  Branch (56:7): [True: 0, False: 1]
  |  Branch (56:34): [True: 0, False: 0]
  ------------------
   57|      0|    free(frame->coffsets);
   58|      0|  }
   59|       |
   60|      1|  if (frame->urlpath != NULL) {
  ------------------
  |  Branch (60:7): [True: 0, False: 1]
  ------------------
   61|      0|    free(frame->urlpath);
   62|      0|  }
   63|       |
   64|      1|  free(frame);
   65|       |
   66|      1|  return 0;
   67|      1|}
get_header_info:
  360|      7|                    uint8_t *splitmode, const blosc2_io *io) {
  361|      7|  uint8_t* framep = frame->cframe;
  362|      7|  uint8_t* header_ptr;
  363|      7|  uint8_t header[FRAME_HEADER_MINLEN];
  364|       |
  365|      7|  blosc2_io_cb *io_cb = blosc2_get_io_cb(io->id);
  366|      7|  if (io_cb == NULL) {
  ------------------
  |  Branch (366:7): [True: 0, False: 7]
  ------------------
  367|      0|    BLOSC_TRACE_ERROR("Error getting the input/output API");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  368|      0|    return BLOSC2_ERROR_PLUGIN_IO;
  369|      0|  }
  370|       |
  371|      7|  if (frame->len <= 0) {
  ------------------
  |  Branch (371:7): [True: 0, False: 7]
  ------------------
  372|      0|    return BLOSC2_ERROR_READ_BUFFER;
  373|      0|  }
  374|       |
  375|      7|  if (frame->cframe == NULL) {
  ------------------
  |  Branch (375:7): [True: 0, False: 7]
  ------------------
  376|      0|    int64_t rbytes = 0;
  377|      0|    void* fp = NULL;
  378|      0|    int64_t io_pos = 0;
  379|      0|    if (frame->sframe) {
  ------------------
  |  Branch (379:9): [True: 0, False: 0]
  ------------------
  380|      0|      fp = sframe_open_index(frame->urlpath, "rb", io);
  381|      0|      if (fp == NULL) {
  ------------------
  |  Branch (381:11): [True: 0, False: 0]
  ------------------
  382|      0|        BLOSC_TRACE_ERROR("Error opening file in: %s", frame->urlpath);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  383|      0|        return BLOSC2_ERROR_FILE_OPEN;
  384|      0|      }
  385|      0|    }
  386|      0|    else {
  387|      0|      fp = io_cb->open(frame->urlpath, "rb", io->params);
  388|      0|      if (fp == NULL) {
  ------------------
  |  Branch (388:11): [True: 0, False: 0]
  ------------------
  389|      0|        BLOSC_TRACE_ERROR("Error opening file in: %s", frame->urlpath);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  390|      0|        return BLOSC2_ERROR_FILE_OPEN;
  391|      0|      }
  392|      0|      io_pos = frame->file_offset;
  393|      0|    }
  394|      0|    if (io_cb->is_allocation_necessary)
  ------------------
  |  Branch (394:9): [True: 0, False: 0]
  ------------------
  395|      0|      header_ptr = header;
  396|      0|    rbytes = io_cb->read((void**)&header_ptr, 1, FRAME_HEADER_MINLEN, io_pos, fp);
  ------------------
  |  |   43|      0|#define FRAME_HEADER_MINLEN (FRAME_FILTER_PIPELINE + 1 + 16)  // 87 <- minimum length
  |  |  ------------------
  |  |  |  |   40|      0|#define FRAME_FILTER_PIPELINE (FRAME_HAS_VLMETALAYERS + 1 + 1) // 70
  |  |  |  |  ------------------
  |  |  |  |  |  |   39|      0|#define FRAME_HAS_VLMETALAYERS (FRAME_NTHREADS_D + 2)  // 68
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|      0|#define FRAME_NTHREADS_D (FRAME_NTHREADS_C + 2 + 1)  // 66
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|      0|#define FRAME_NTHREADS_C (FRAME_CHUNKSIZE + 4 + 1)  // 63
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   36|      0|#define FRAME_CHUNKSIZE (FRAME_BLOCKSIZE + 4 + 1)  // 58
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   35|      0|#define FRAME_BLOCKSIZE (FRAME_TYPESIZE + 4 + 1)  // 53
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   34|      0|#define FRAME_TYPESIZE (FRAME_CBYTES + 8 + 1) // 48
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   33|      0|#define FRAME_CBYTES (FRAME_NBYTES + 8 + 1)  // 39
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   32|      0|#define FRAME_NBYTES (FRAME_FLAGS + 4 + 1)  // 30
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   28|      0|#define FRAME_FLAGS (FRAME_LEN + 8 + 1)  // 25
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   27|      0|#define FRAME_LEN (FRAME_HEADER_LEN + 4 + 1)  // 16
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   26|      0|#define FRAME_HEADER_LEN (FRAME_HEADER_MAGIC + 8 + 1)  // 11
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   25|      0|#define FRAME_HEADER_MAGIC 2
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  397|      0|    io_cb->close(fp);
  398|      0|    if (rbytes != FRAME_HEADER_MINLEN) {
  ------------------
  |  |   43|      0|#define FRAME_HEADER_MINLEN (FRAME_FILTER_PIPELINE + 1 + 16)  // 87 <- minimum length
  |  |  ------------------
  |  |  |  |   40|      0|#define FRAME_FILTER_PIPELINE (FRAME_HAS_VLMETALAYERS + 1 + 1) // 70
  |  |  |  |  ------------------
  |  |  |  |  |  |   39|      0|#define FRAME_HAS_VLMETALAYERS (FRAME_NTHREADS_D + 2)  // 68
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|      0|#define FRAME_NTHREADS_D (FRAME_NTHREADS_C + 2 + 1)  // 66
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|      0|#define FRAME_NTHREADS_C (FRAME_CHUNKSIZE + 4 + 1)  // 63
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   36|      0|#define FRAME_CHUNKSIZE (FRAME_BLOCKSIZE + 4 + 1)  // 58
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   35|      0|#define FRAME_BLOCKSIZE (FRAME_TYPESIZE + 4 + 1)  // 53
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   34|      0|#define FRAME_TYPESIZE (FRAME_CBYTES + 8 + 1) // 48
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   33|      0|#define FRAME_CBYTES (FRAME_NBYTES + 8 + 1)  // 39
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   32|      0|#define FRAME_NBYTES (FRAME_FLAGS + 4 + 1)  // 30
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   28|      0|#define FRAME_FLAGS (FRAME_LEN + 8 + 1)  // 25
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   27|      0|#define FRAME_LEN (FRAME_HEADER_LEN + 4 + 1)  // 16
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   26|      0|#define FRAME_HEADER_LEN (FRAME_HEADER_MAGIC + 8 + 1)  // 11
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   25|      0|#define FRAME_HEADER_MAGIC 2
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (398:9): [True: 0, False: 0]
  ------------------
  399|      0|      return BLOSC2_ERROR_FILE_READ;
  400|      0|    }
  401|      0|    framep = header_ptr;
  402|      0|  }
  403|       |
  404|       |  // Consistency check for frame type
  405|      7|  uint8_t frame_type = framep[FRAME_TYPE];
  ------------------
  |  |   29|      7|#define FRAME_TYPE (FRAME_FLAGS + 1)  // 26
  |  |  ------------------
  |  |  |  |   28|      7|#define FRAME_FLAGS (FRAME_LEN + 8 + 1)  // 25
  |  |  |  |  ------------------
  |  |  |  |  |  |   27|      7|#define FRAME_LEN (FRAME_HEADER_LEN + 4 + 1)  // 16
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   26|      7|#define FRAME_HEADER_LEN (FRAME_HEADER_MAGIC + 8 + 1)  // 11
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   25|      7|#define FRAME_HEADER_MAGIC 2
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  406|      7|  if (frame->sframe) {
  ------------------
  |  Branch (406:7): [True: 0, False: 7]
  ------------------
  407|      0|    if (frame_type != FRAME_DIRECTORY_TYPE) {
  ------------------
  |  |   21|      0|#define FRAME_DIRECTORY_TYPE 1
  ------------------
  |  Branch (407:9): [True: 0, False: 0]
  ------------------
  408|      0|      return BLOSC2_ERROR_FRAME_TYPE;
  409|      0|    }
  410|      7|  } else {
  411|      7|    if (frame_type != FRAME_CONTIGUOUS_TYPE) {
  ------------------
  |  |   20|      7|#define FRAME_CONTIGUOUS_TYPE 0
  ------------------
  |  Branch (411:9): [True: 0, False: 7]
  ------------------
  412|      0|      return BLOSC2_ERROR_FRAME_TYPE;
  413|      0|    }
  414|      7|  }
  415|       |
  416|       |  // Fetch some internal lengths
  417|      7|  from_big(header_len, framep + FRAME_HEADER_LEN, sizeof(*header_len));
  ------------------
  |  |   31|      7|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
  418|      7|  if (*header_len < FRAME_HEADER_MINLEN) {
  ------------------
  |  |   43|      7|#define FRAME_HEADER_MINLEN (FRAME_FILTER_PIPELINE + 1 + 16)  // 87 <- minimum length
  |  |  ------------------
  |  |  |  |   40|      7|#define FRAME_FILTER_PIPELINE (FRAME_HAS_VLMETALAYERS + 1 + 1) // 70
  |  |  |  |  ------------------
  |  |  |  |  |  |   39|      7|#define FRAME_HAS_VLMETALAYERS (FRAME_NTHREADS_D + 2)  // 68
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|      7|#define FRAME_NTHREADS_D (FRAME_NTHREADS_C + 2 + 1)  // 66
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|      7|#define FRAME_NTHREADS_C (FRAME_CHUNKSIZE + 4 + 1)  // 63
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   36|      7|#define FRAME_CHUNKSIZE (FRAME_BLOCKSIZE + 4 + 1)  // 58
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   35|      7|#define FRAME_BLOCKSIZE (FRAME_TYPESIZE + 4 + 1)  // 53
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   34|      7|#define FRAME_TYPESIZE (FRAME_CBYTES + 8 + 1) // 48
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   33|      7|#define FRAME_CBYTES (FRAME_NBYTES + 8 + 1)  // 39
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   32|      7|#define FRAME_NBYTES (FRAME_FLAGS + 4 + 1)  // 30
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   28|      7|#define FRAME_FLAGS (FRAME_LEN + 8 + 1)  // 25
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   27|      7|#define FRAME_LEN (FRAME_HEADER_LEN + 4 + 1)  // 16
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   26|      7|#define FRAME_HEADER_LEN (FRAME_HEADER_MAGIC + 8 + 1)  // 11
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   25|      7|#define FRAME_HEADER_MAGIC 2
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (418:7): [True: 0, False: 7]
  ------------------
  419|      0|    BLOSC_TRACE_ERROR("Header length is zero or smaller than min allowed.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  420|      0|    return BLOSC2_ERROR_INVALID_HEADER;
  421|      0|  }
  422|      7|  from_big(frame_len, framep + FRAME_LEN, sizeof(*frame_len));
  ------------------
  |  |   31|      7|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
  423|      7|  if (*header_len > *frame_len) {
  ------------------
  |  Branch (423:7): [True: 0, False: 7]
  ------------------
  424|      0|    BLOSC_TRACE_ERROR("Header length exceeds length of the frame.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  425|      0|    return BLOSC2_ERROR_INVALID_HEADER;
  426|      0|  }
  427|      7|  from_big(nbytes, framep + FRAME_NBYTES, sizeof(*nbytes));
  ------------------
  |  |   31|      7|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
  428|      7|  from_big(cbytes, framep + FRAME_CBYTES, sizeof(*cbytes));
  ------------------
  |  |   31|      7|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
  429|      7|  from_big(blocksize, framep + FRAME_BLOCKSIZE, sizeof(*blocksize));
  ------------------
  |  |   31|      7|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
  430|      7|  if (chunksize != NULL) {
  ------------------
  |  Branch (430:7): [True: 7, False: 0]
  ------------------
  431|      7|    from_big(chunksize, framep + FRAME_CHUNKSIZE, sizeof(*chunksize));
  ------------------
  |  |   31|      7|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
  432|      7|  }
  433|      7|  if (typesize != NULL) {
  ------------------
  |  Branch (433:7): [True: 5, False: 2]
  ------------------
  434|      5|    from_big(typesize, framep + FRAME_TYPESIZE, sizeof(*typesize));
  ------------------
  |  |   31|      5|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
  435|      5|    if (*typesize <= 0) {
  ------------------
  |  Branch (435:9): [True: 0, False: 5]
  ------------------
  436|      0|      BLOSC_TRACE_ERROR("`typesize` cannot be zero or negative.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  437|      0|      return BLOSC2_ERROR_INVALID_HEADER;
  438|      0|    }
  439|      5|  }
  440|       |
  441|       |  // Codecs
  442|      7|  uint8_t frame_codecs = framep[FRAME_CODECS];
  ------------------
  |  |   30|      7|#define FRAME_CODECS (FRAME_FLAGS + 2)  // 27
  |  |  ------------------
  |  |  |  |   28|      7|#define FRAME_FLAGS (FRAME_LEN + 8 + 1)  // 25
  |  |  |  |  ------------------
  |  |  |  |  |  |   27|      7|#define FRAME_LEN (FRAME_HEADER_LEN + 4 + 1)  // 16
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   26|      7|#define FRAME_HEADER_LEN (FRAME_HEADER_MAGIC + 8 + 1)  // 11
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   25|      7|#define FRAME_HEADER_MAGIC 2
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  443|      7|  if (clevel != NULL) {
  ------------------
  |  Branch (443:7): [True: 1, False: 6]
  ------------------
  444|      1|    *clevel = frame_codecs >> 4u;
  445|      1|  }
  446|      7|  if (compcode != NULL) {
  ------------------
  |  Branch (446:7): [True: 1, False: 6]
  ------------------
  447|      1|    *compcode = frame_codecs & 0xFu;
  448|      1|    if (*compcode == BLOSC_UDCODEC_FORMAT) {
  ------------------
  |  Branch (448:9): [True: 0, False: 1]
  ------------------
  449|      0|      from_big(compcode, framep + FRAME_UDCODEC, sizeof(*compcode));
  ------------------
  |  |   31|      0|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
  450|      0|    }
  451|      1|  }
  452|       |
  453|       |  // Other flags
  454|      7|  uint8_t other_flags = framep[FRAME_OTHER_FLAGS];
  ------------------
  |  |   31|      7|#define FRAME_OTHER_FLAGS (FRAME_FLAGS + 3)  // 28
  |  |  ------------------
  |  |  |  |   28|      7|#define FRAME_FLAGS (FRAME_LEN + 8 + 1)  // 25
  |  |  |  |  ------------------
  |  |  |  |  |  |   27|      7|#define FRAME_LEN (FRAME_HEADER_LEN + 4 + 1)  // 16
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   26|      7|#define FRAME_HEADER_LEN (FRAME_HEADER_MAGIC + 8 + 1)  // 11
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   25|      7|#define FRAME_HEADER_MAGIC 2
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  455|      7|  if (splitmode != NULL) {
  ------------------
  |  Branch (455:7): [True: 1, False: 6]
  ------------------
  456|      1|    *splitmode = other_flags & 0x4u;
  457|      1|    from_big(splitmode, framep + FRAME_OTHER_FLAGS, sizeof(*splitmode));
  ------------------
  |  |   31|      1|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
  458|      1|    *splitmode += 1;
  459|      1|  }
  460|       |
  461|      7|  if (compcode_meta != NULL) {
  ------------------
  |  Branch (461:7): [True: 1, False: 6]
  ------------------
  462|      1|    from_big(compcode_meta, framep + FRAME_CODEC_META, sizeof(*compcode_meta));
  ------------------
  |  |   31|      1|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
  463|      1|  }
  464|       |
  465|       |  // Filters
  466|      7|  if (filters != NULL && filters_meta != NULL) {
  ------------------
  |  Branch (466:7): [True: 1, False: 6]
  |  Branch (466:26): [True: 1, False: 0]
  ------------------
  467|      1|    uint8_t nfilters = framep[FRAME_FILTER_PIPELINE];
  ------------------
  |  |   40|      1|#define FRAME_FILTER_PIPELINE (FRAME_HAS_VLMETALAYERS + 1 + 1) // 70
  |  |  ------------------
  |  |  |  |   39|      1|#define FRAME_HAS_VLMETALAYERS (FRAME_NTHREADS_D + 2)  // 68
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|      1|#define FRAME_NTHREADS_D (FRAME_NTHREADS_C + 2 + 1)  // 66
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   37|      1|#define FRAME_NTHREADS_C (FRAME_CHUNKSIZE + 4 + 1)  // 63
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   36|      1|#define FRAME_CHUNKSIZE (FRAME_BLOCKSIZE + 4 + 1)  // 58
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   35|      1|#define FRAME_BLOCKSIZE (FRAME_TYPESIZE + 4 + 1)  // 53
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   34|      1|#define FRAME_TYPESIZE (FRAME_CBYTES + 8 + 1) // 48
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   33|      1|#define FRAME_CBYTES (FRAME_NBYTES + 8 + 1)  // 39
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   32|      1|#define FRAME_NBYTES (FRAME_FLAGS + 4 + 1)  // 30
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   28|      1|#define FRAME_FLAGS (FRAME_LEN + 8 + 1)  // 25
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   27|      1|#define FRAME_LEN (FRAME_HEADER_LEN + 4 + 1)  // 16
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   26|      1|#define FRAME_HEADER_LEN (FRAME_HEADER_MAGIC + 8 + 1)  // 11
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   25|      1|#define FRAME_HEADER_MAGIC 2
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  468|      1|    if (nfilters > BLOSC2_MAX_FILTERS) {
  ------------------
  |  Branch (468:9): [True: 0, False: 1]
  ------------------
  469|      0|      BLOSC_TRACE_ERROR("The number of filters in frame header are too large for Blosc2.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  470|      0|      return BLOSC2_ERROR_INVALID_HEADER;
  471|      0|    }
  472|      1|    uint8_t *filters_ = framep + FRAME_FILTER_PIPELINE + 1;
  ------------------
  |  |   40|      1|#define FRAME_FILTER_PIPELINE (FRAME_HAS_VLMETALAYERS + 1 + 1) // 70
  |  |  ------------------
  |  |  |  |   39|      1|#define FRAME_HAS_VLMETALAYERS (FRAME_NTHREADS_D + 2)  // 68
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|      1|#define FRAME_NTHREADS_D (FRAME_NTHREADS_C + 2 + 1)  // 66
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   37|      1|#define FRAME_NTHREADS_C (FRAME_CHUNKSIZE + 4 + 1)  // 63
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   36|      1|#define FRAME_CHUNKSIZE (FRAME_BLOCKSIZE + 4 + 1)  // 58
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   35|      1|#define FRAME_BLOCKSIZE (FRAME_TYPESIZE + 4 + 1)  // 53
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   34|      1|#define FRAME_TYPESIZE (FRAME_CBYTES + 8 + 1) // 48
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   33|      1|#define FRAME_CBYTES (FRAME_NBYTES + 8 + 1)  // 39
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   32|      1|#define FRAME_NBYTES (FRAME_FLAGS + 4 + 1)  // 30
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   28|      1|#define FRAME_FLAGS (FRAME_LEN + 8 + 1)  // 25
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   27|      1|#define FRAME_LEN (FRAME_HEADER_LEN + 4 + 1)  // 16
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   26|      1|#define FRAME_HEADER_LEN (FRAME_HEADER_MAGIC + 8 + 1)  // 11
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   25|      1|#define FRAME_HEADER_MAGIC 2
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  473|      1|    uint8_t *filters_meta_ = framep + FRAME_FILTER_PIPELINE + 1 + FRAME_FILTER_PIPELINE_MAX;
  ------------------
  |  |   40|      1|#define FRAME_FILTER_PIPELINE (FRAME_HAS_VLMETALAYERS + 1 + 1) // 70
  |  |  ------------------
  |  |  |  |   39|      1|#define FRAME_HAS_VLMETALAYERS (FRAME_NTHREADS_D + 2)  // 68
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|      1|#define FRAME_NTHREADS_D (FRAME_NTHREADS_C + 2 + 1)  // 66
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   37|      1|#define FRAME_NTHREADS_C (FRAME_CHUNKSIZE + 4 + 1)  // 63
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   36|      1|#define FRAME_CHUNKSIZE (FRAME_BLOCKSIZE + 4 + 1)  // 58
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   35|      1|#define FRAME_BLOCKSIZE (FRAME_TYPESIZE + 4 + 1)  // 53
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   34|      1|#define FRAME_TYPESIZE (FRAME_CBYTES + 8 + 1) // 48
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   33|      1|#define FRAME_CBYTES (FRAME_NBYTES + 8 + 1)  // 39
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   32|      1|#define FRAME_NBYTES (FRAME_FLAGS + 4 + 1)  // 30
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   28|      1|#define FRAME_FLAGS (FRAME_LEN + 8 + 1)  // 25
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   27|      1|#define FRAME_LEN (FRAME_HEADER_LEN + 4 + 1)  // 16
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   26|      1|#define FRAME_HEADER_LEN (FRAME_HEADER_MAGIC + 8 + 1)  // 11
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   25|      1|#define FRAME_HEADER_MAGIC 2
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
                  uint8_t *filters_meta_ = framep + FRAME_FILTER_PIPELINE + 1 + FRAME_FILTER_PIPELINE_MAX;
  ------------------
  |  |   47|      1|#define FRAME_FILTER_PIPELINE_MAX (8)  // the maximum number of filters that can be stored in header
  ------------------
  474|      7|    for (int i = 0; i < nfilters; i++) {
  ------------------
  |  Branch (474:21): [True: 6, False: 1]
  ------------------
  475|      6|      filters[i] = filters_[i];
  476|      6|      filters_meta[i] = filters_meta_[i];
  477|      6|    }
  478|      1|  }
  479|       |
  480|      7|  if (*nbytes > 0 && *chunksize > 0) {
  ------------------
  |  Branch (480:7): [True: 7, False: 0]
  |  Branch (480:22): [True: 7, False: 0]
  ------------------
  481|       |    // We can compute the number of chunks only when the frame has actual data
  482|      7|    *nchunks = *nbytes / *chunksize;
  483|      7|    if (*nbytes % *chunksize > 0) {
  ------------------
  |  Branch (483:9): [True: 0, False: 7]
  ------------------
  484|      0|      if (*nchunks == INT32_MAX) {
  ------------------
  |  Branch (484:11): [True: 0, False: 0]
  ------------------
  485|      0|        BLOSC_TRACE_ERROR("Number of chunks exceeds maximum allowed.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  486|      0|        return BLOSC2_ERROR_INVALID_HEADER;
  487|      0|      }
  488|      0|      *nchunks += 1;
  489|      0|    }
  490|       |
  491|       |    // Sanity check for compressed sizes
  492|      7|    if ((*cbytes < 0) || ((int64_t)*nchunks * *chunksize < *nbytes)) {
  ------------------
  |  Branch (492:9): [True: 0, False: 7]
  |  Branch (492:26): [True: 0, False: 7]
  ------------------
  493|      0|      BLOSC_TRACE_ERROR("Invalid compressed size in frame header.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  494|      0|      return BLOSC2_ERROR_INVALID_HEADER;
  495|      0|    }
  496|      7|  } else {
  497|      0|    *nchunks = 0;
  498|      0|  }
  499|       |
  500|      7|  return 0;
  501|      7|}
get_trailer_offset:
  504|      1|int64_t get_trailer_offset(blosc2_frame_s *frame, int32_t header_len, bool has_coffsets) {
  505|      1|  if (!has_coffsets) {
  ------------------
  |  Branch (505:7): [True: 0, False: 1]
  ------------------
  506|       |    // No data chunks yet
  507|      0|    return header_len;
  508|      0|  }
  509|      1|  return frame->len - frame->trailer_len;
  510|      1|}
frame_from_cframe:
  881|      7|blosc2_frame_s* frame_from_cframe(uint8_t *cframe, int64_t len, bool copy) {
  882|       |  // Get the length of the frame
  883|      7|  const uint8_t* header = cframe;
  884|      7|  int64_t frame_len;
  885|      7|  if (len < FRAME_HEADER_MINLEN) {
  ------------------
  |  |   43|      7|#define FRAME_HEADER_MINLEN (FRAME_FILTER_PIPELINE + 1 + 16)  // 87 <- minimum length
  |  |  ------------------
  |  |  |  |   40|      7|#define FRAME_FILTER_PIPELINE (FRAME_HAS_VLMETALAYERS + 1 + 1) // 70
  |  |  |  |  ------------------
  |  |  |  |  |  |   39|      7|#define FRAME_HAS_VLMETALAYERS (FRAME_NTHREADS_D + 2)  // 68
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|      7|#define FRAME_NTHREADS_D (FRAME_NTHREADS_C + 2 + 1)  // 66
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|      7|#define FRAME_NTHREADS_C (FRAME_CHUNKSIZE + 4 + 1)  // 63
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   36|      7|#define FRAME_CHUNKSIZE (FRAME_BLOCKSIZE + 4 + 1)  // 58
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   35|      7|#define FRAME_BLOCKSIZE (FRAME_TYPESIZE + 4 + 1)  // 53
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   34|      7|#define FRAME_TYPESIZE (FRAME_CBYTES + 8 + 1) // 48
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   33|      7|#define FRAME_CBYTES (FRAME_NBYTES + 8 + 1)  // 39
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   32|      7|#define FRAME_NBYTES (FRAME_FLAGS + 4 + 1)  // 30
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   28|      7|#define FRAME_FLAGS (FRAME_LEN + 8 + 1)  // 25
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   27|      7|#define FRAME_LEN (FRAME_HEADER_LEN + 4 + 1)  // 16
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   26|      7|#define FRAME_HEADER_LEN (FRAME_HEADER_MAGIC + 8 + 1)  // 11
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   25|      7|#define FRAME_HEADER_MAGIC 2
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (885:7): [True: 0, False: 7]
  ------------------
  886|      0|    return NULL;
  887|      0|  }
  888|       |
  889|      7|  from_big(&frame_len, header + FRAME_LEN, sizeof(frame_len));
  ------------------
  |  |   31|      7|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
  890|      7|  if (frame_len != len) {   // sanity check
  ------------------
  |  Branch (890:7): [True: 6, False: 1]
  ------------------
  891|      6|    return NULL;
  892|      6|  }
  893|       |
  894|      1|  blosc2_frame_s* frame = calloc(1, sizeof(blosc2_frame_s));
  895|      1|  frame->len = frame_len;
  896|      1|  frame->file_offset = 0;
  897|       |
  898|       |  // Now, the trailer length
  899|      1|  const uint8_t* trailer = cframe + frame_len - FRAME_TRAILER_MINLEN;
  ------------------
  |  |   52|      1|#define FRAME_TRAILER_MINLEN (25)  // minimum length for the trailer (msgpack overhead)
  ------------------
  900|      1|  int trailer_offset = FRAME_TRAILER_MINLEN - FRAME_TRAILER_LEN_OFFSET;
  ------------------
  |  |   52|      1|#define FRAME_TRAILER_MINLEN (25)  // minimum length for the trailer (msgpack overhead)
  ------------------
                int trailer_offset = FRAME_TRAILER_MINLEN - FRAME_TRAILER_LEN_OFFSET;
  ------------------
  |  |   53|      1|#define FRAME_TRAILER_LEN_OFFSET (22)  // offset to trailer length (counting from the end)
  ------------------
  901|      1|  if (trailer[trailer_offset - 1] != 0xce) {
  ------------------
  |  Branch (901:7): [True: 0, False: 1]
  ------------------
  902|      0|    free(frame);
  903|      0|    return NULL;
  904|      0|  }
  905|      1|  uint32_t trailer_len;
  906|      1|  from_big(&trailer_len, trailer + trailer_offset, sizeof(trailer_len));
  ------------------
  |  |   31|      1|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
  907|      1|  frame->trailer_len = trailer_len;
  908|       |
  909|      1|  if (copy) {
  ------------------
  |  Branch (909:7): [True: 0, False: 1]
  ------------------
  910|      0|    frame->cframe = malloc((size_t)len);
  911|      0|    memcpy(frame->cframe, cframe, (size_t)len);
  912|      0|  }
  913|      1|  else {
  914|      1|    frame->cframe = cframe;
  915|      1|    frame->avoid_cframe_free = true;
  916|      1|  }
  917|       |
  918|      1|  return frame;
  919|      1|}
get_coffsets:
 1074|      4|                      int64_t nchunks, int32_t *off_cbytes) {
 1075|      4|  int32_t chunk_cbytes;
 1076|      4|  int rc;
 1077|       |
 1078|      4|  if (frame->coffsets != NULL) {
  ------------------
  |  Branch (1078:7): [True: 0, False: 4]
  ------------------
 1079|      0|    if (off_cbytes != NULL) {
  ------------------
  |  Branch (1079:9): [True: 0, False: 0]
  ------------------
 1080|      0|      rc = blosc2_cbuffer_sizes(frame->coffsets, NULL, &chunk_cbytes, NULL);
 1081|      0|      if (rc < 0) {
  ------------------
  |  Branch (1081:11): [True: 0, False: 0]
  ------------------
 1082|      0|        return NULL;
 1083|      0|      }
 1084|      0|      *off_cbytes = (int32_t)chunk_cbytes;
 1085|      0|    }
 1086|      0|    return frame->coffsets;
 1087|      0|  }
 1088|      4|  if (frame->cframe != NULL) {
  ------------------
  |  Branch (1088:7): [True: 4, False: 0]
  ------------------
 1089|      4|    int64_t off_pos = header_len;
 1090|      4|    if (cbytes < INT64_MAX - header_len) {
  ------------------
  |  Branch (1090:9): [True: 4, False: 0]
  ------------------
 1091|      4|      off_pos += cbytes;
 1092|      4|    }
 1093|       |    // Check that there is enough room to read Blosc header
 1094|      4|    if (off_pos < 0 || off_pos > INT64_MAX - BLOSC_EXTENDED_HEADER_LENGTH ||
  ------------------
  |  Branch (1094:9): [True: 0, False: 4]
  |  Branch (1094:24): [True: 0, False: 4]
  ------------------
 1095|      4|        off_pos + BLOSC_EXTENDED_HEADER_LENGTH > frame->len) {
  ------------------
  |  Branch (1095:9): [True: 0, False: 4]
  ------------------
 1096|      0|      BLOSC_TRACE_ERROR("Cannot read the offsets outside of frame boundary.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1097|      0|      return NULL;
 1098|      0|    }
 1099|       |    // For in-memory frames, the coffset is just one pointer away
 1100|      4|    uint8_t* off_start = frame->cframe + off_pos;
 1101|      4|    if (off_cbytes != NULL) {
  ------------------
  |  Branch (1101:9): [True: 4, False: 0]
  ------------------
 1102|      4|      int32_t chunk_nbytes;
 1103|      4|      int32_t chunk_blocksize;
 1104|      4|      rc = blosc2_cbuffer_sizes(off_start, &chunk_nbytes, &chunk_cbytes, &chunk_blocksize);
 1105|      4|      if (rc < 0) {
  ------------------
  |  Branch (1105:11): [True: 0, False: 4]
  ------------------
 1106|      0|        return NULL;
 1107|      0|      }
 1108|      4|      *off_cbytes = (int32_t)chunk_cbytes;
 1109|      4|      if (*off_cbytes < 0 || off_pos + *off_cbytes > frame->len) {
  ------------------
  |  Branch (1109:11): [True: 0, False: 4]
  |  Branch (1109:30): [True: 0, False: 4]
  ------------------
 1110|      0|        BLOSC_TRACE_ERROR("Cannot read the cbytes outside of frame boundary.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1111|      0|        return NULL;
 1112|      0|      }
 1113|      4|      if ((uint64_t)chunk_nbytes != nchunks * sizeof(int64_t)) {
  ------------------
  |  Branch (1113:11): [True: 0, False: 4]
  ------------------
 1114|      0|        BLOSC_TRACE_ERROR("The number of chunks in offset idx "
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1115|      0|                          "does not match the ones in the header frame.");
 1116|      0|        return NULL;
 1117|      0|      }
 1118|       |
 1119|      4|    }
 1120|      4|    return off_start;
 1121|      4|  }
 1122|       |
 1123|      0|  int64_t trailer_offset = get_trailer_offset(frame, header_len, true);
 1124|       |
 1125|      0|  if (trailer_offset < BLOSC_EXTENDED_HEADER_LENGTH || trailer_offset + FRAME_TRAILER_MINLEN > frame->len) {
  ------------------
  |  |   52|      0|#define FRAME_TRAILER_MINLEN (25)  // minimum length for the trailer (msgpack overhead)
  ------------------
  |  Branch (1125:7): [True: 0, False: 0]
  |  Branch (1125:56): [True: 0, False: 0]
  ------------------
 1126|      0|    BLOSC_TRACE_ERROR("Cannot read the trailer out of the frame.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1127|      0|    return NULL;
 1128|      0|  }
 1129|       |
 1130|      0|  int32_t coffsets_cbytes;
 1131|      0|  if (frame->sframe) {
  ------------------
  |  Branch (1131:7): [True: 0, False: 0]
  ------------------
 1132|      0|    coffsets_cbytes = (int32_t)(trailer_offset - (header_len + 0));
 1133|      0|  }
 1134|      0|  else {
 1135|      0|    coffsets_cbytes = (int32_t)(trailer_offset - (header_len + cbytes));
 1136|      0|  }
 1137|       |
 1138|      0|  if (off_cbytes != NULL) {
  ------------------
  |  Branch (1138:7): [True: 0, False: 0]
  ------------------
 1139|      0|    *off_cbytes = coffsets_cbytes;
 1140|      0|  }
 1141|       |
 1142|      0|  blosc2_io_cb *io_cb = blosc2_get_io_cb(frame->schunk->storage->io->id);
 1143|      0|  if (io_cb == NULL) {
  ------------------
  |  Branch (1143:7): [True: 0, False: 0]
  ------------------
 1144|      0|    BLOSC_TRACE_ERROR("Error getting the input/output API");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1145|      0|    return NULL;
 1146|      0|  }
 1147|       |
 1148|      0|  void* fp = NULL;
 1149|      0|  uint8_t* coffsets;
 1150|      0|  if (io_cb->is_allocation_necessary) {
  ------------------
  |  Branch (1150:7): [True: 0, False: 0]
  ------------------
 1151|      0|    coffsets = malloc((size_t)coffsets_cbytes);
 1152|      0|    frame->coffsets_needs_free = true;
 1153|      0|  }
 1154|      0|  else {
 1155|      0|    frame->coffsets_needs_free = false;
 1156|      0|  }
 1157|       |  
 1158|      0|  int64_t io_pos = 0;
 1159|      0|  if (frame->sframe) {
  ------------------
  |  Branch (1159:7): [True: 0, False: 0]
  ------------------
 1160|      0|    fp = sframe_open_index(frame->urlpath, "rb",
 1161|      0|                           frame->schunk->storage->io);
 1162|      0|    if (fp == NULL) {
  ------------------
  |  Branch (1162:9): [True: 0, False: 0]
  ------------------
 1163|      0|      BLOSC_TRACE_ERROR("Error opening file in: %s", frame->urlpath);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1164|      0|      return NULL;
 1165|      0|    }
 1166|      0|    io_pos = header_len + 0;
 1167|      0|  }
 1168|      0|  else {
 1169|      0|    fp = io_cb->open(frame->urlpath, "rb", frame->schunk->storage->io->params);
 1170|      0|    if (fp == NULL) {
  ------------------
  |  Branch (1170:9): [True: 0, False: 0]
  ------------------
 1171|      0|      BLOSC_TRACE_ERROR("Error opening file in: %s", frame->urlpath);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1172|      0|      return NULL;
 1173|      0|    }
 1174|      0|    io_pos = frame->file_offset + header_len + cbytes;
 1175|      0|  }
 1176|      0|  int64_t rbytes = io_cb->read((void**)&coffsets, 1, coffsets_cbytes, io_pos, fp);
 1177|      0|  io_cb->close(fp);
 1178|      0|  if (rbytes != coffsets_cbytes) {
  ------------------
  |  Branch (1178:7): [True: 0, False: 0]
  ------------------
 1179|      0|    BLOSC_TRACE_ERROR("Cannot read the offsets out of the frame.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1180|      0|    if (frame->coffsets_needs_free)
  ------------------
  |  Branch (1180:9): [True: 0, False: 0]
  ------------------
 1181|      0|      free(coffsets);
 1182|      0|    return NULL;
 1183|      0|  }
 1184|      0|  frame->coffsets = coffsets;
 1185|      0|  return coffsets;
 1186|      0|}
frame_get_metalayers:
 1451|      1|int frame_get_metalayers(blosc2_frame_s* frame, blosc2_schunk* schunk) {
 1452|      1|  int32_t header_len;
 1453|      1|  int64_t frame_len;
 1454|      1|  int64_t nbytes;
 1455|      1|  int64_t cbytes;
 1456|      1|  int32_t blocksize;
 1457|      1|  int32_t chunksize;
 1458|      1|  int64_t nchunks;
 1459|      1|  int ret = get_header_info(frame, &header_len, &frame_len, &nbytes, &cbytes,
 1460|      1|                            &blocksize, &chunksize, &nchunks,
 1461|      1|                            NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 1462|      1|                            schunk->storage->io);
 1463|      1|  if (ret < 0) {
  ------------------
  |  Branch (1463:7): [True: 0, False: 1]
  ------------------
 1464|      0|    BLOSC_TRACE_ERROR("Unable to get the header info from frame.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1465|      0|    return ret;
 1466|      0|  }
 1467|       |
 1468|       |  // Get the header
 1469|      1|  uint8_t* header = NULL;
 1470|      1|  bool needs_free = false;
 1471|      1|  if (frame->cframe != NULL) {
  ------------------
  |  Branch (1471:7): [True: 1, False: 0]
  ------------------
 1472|      1|    header = frame->cframe;
 1473|      1|  } else {
 1474|      0|    int64_t rbytes = 0;
 1475|      0|    blosc2_io_cb *io_cb = blosc2_get_io_cb(frame->schunk->storage->io->id);
 1476|      0|    if (io_cb == NULL) {
  ------------------
  |  Branch (1476:9): [True: 0, False: 0]
  ------------------
 1477|      0|      BLOSC_TRACE_ERROR("Error getting the input/output API");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1478|      0|      return BLOSC2_ERROR_PLUGIN_IO;
 1479|      0|    }
 1480|       |
 1481|      0|    if (io_cb->is_allocation_necessary) {
  ------------------
  |  Branch (1481:9): [True: 0, False: 0]
  ------------------
 1482|      0|      header = malloc(header_len);
 1483|      0|      needs_free = true;
 1484|      0|    }
 1485|      0|    else {
 1486|      0|      needs_free = false;
 1487|      0|    }
 1488|       |
 1489|      0|    void* fp = NULL;
 1490|      0|    int64_t io_pos = 0;
 1491|      0|    if (frame->sframe) {
  ------------------
  |  Branch (1491:9): [True: 0, False: 0]
  ------------------
 1492|      0|      fp = sframe_open_index(frame->urlpath, "rb",
 1493|      0|                             frame->schunk->storage->io);
 1494|      0|      if (fp == NULL) {
  ------------------
  |  Branch (1494:11): [True: 0, False: 0]
  ------------------
 1495|      0|        BLOSC_TRACE_ERROR("Error opening file in: %s", frame->urlpath);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1496|      0|        return BLOSC2_ERROR_FILE_OPEN;
 1497|      0|      }
 1498|      0|    }
 1499|      0|    else {
 1500|      0|      fp = io_cb->open(frame->urlpath, "rb", frame->schunk->storage->io->params);
 1501|      0|      if (fp == NULL) {
  ------------------
  |  Branch (1501:11): [True: 0, False: 0]
  ------------------
 1502|      0|        BLOSC_TRACE_ERROR("Error opening file in: %s", frame->urlpath);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1503|      0|        return BLOSC2_ERROR_FILE_OPEN;
 1504|      0|      }
 1505|      0|      io_pos = frame->file_offset;
 1506|      0|    }
 1507|      0|    if (fp != NULL) {
  ------------------
  |  Branch (1507:9): [True: 0, False: 0]
  ------------------
 1508|      0|      rbytes = io_cb->read((void**)&header, 1, header_len, io_pos, fp);
 1509|      0|      io_cb->close(fp);
 1510|      0|    }
 1511|      0|    if (rbytes != header_len) {
  ------------------
  |  Branch (1511:9): [True: 0, False: 0]
  ------------------
 1512|      0|      BLOSC_TRACE_ERROR("Cannot access the header out of the frame.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1513|      0|      if (needs_free)
  ------------------
  |  Branch (1513:11): [True: 0, False: 0]
  ------------------
 1514|      0|        free(header);
 1515|      0|      return BLOSC2_ERROR_FILE_READ;
 1516|      0|    }
 1517|      0|  }
 1518|       |
 1519|      1|  ret = get_meta_from_header(frame, schunk, header, header_len);
 1520|       |
 1521|      1|  if (frame->cframe == NULL && needs_free) {
  ------------------
  |  Branch (1521:7): [True: 0, False: 1]
  |  Branch (1521:32): [True: 0, False: 0]
  ------------------
 1522|      0|    free(header);
 1523|      0|  }
 1524|       |
 1525|      1|  return ret;
 1526|      1|}
frame_get_vlmetalayers:
 1640|      1|int frame_get_vlmetalayers(blosc2_frame_s* frame, blosc2_schunk* schunk) {
 1641|      1|  int32_t header_len;
 1642|      1|  int64_t frame_len;
 1643|      1|  int64_t nbytes;
 1644|      1|  int64_t cbytes;
 1645|      1|  int32_t blocksize;
 1646|      1|  int32_t chunksize;
 1647|      1|  int64_t nchunks;
 1648|      1|  int ret = get_header_info(frame, &header_len, &frame_len, &nbytes, &cbytes,
 1649|      1|                            &blocksize, &chunksize, &nchunks,
 1650|      1|                            NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 1651|      1|                            schunk->storage->io);
 1652|      1|  if (ret < 0) {
  ------------------
  |  Branch (1652:7): [True: 0, False: 1]
  ------------------
 1653|      0|    BLOSC_TRACE_ERROR("Unable to get the trailer info from frame.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1654|      0|    return ret;
 1655|      0|  }
 1656|       |
 1657|      1|  int64_t trailer_offset = get_trailer_offset(frame, header_len, nbytes > 0);
 1658|      1|  int32_t trailer_len = (int32_t) frame->trailer_len;
 1659|       |
 1660|      1|  if (trailer_offset < BLOSC_EXTENDED_HEADER_LENGTH || trailer_offset + trailer_len > frame->len) {
  ------------------
  |  Branch (1660:7): [True: 0, False: 1]
  |  Branch (1660:56): [True: 0, False: 1]
  ------------------
 1661|      0|    BLOSC_TRACE_ERROR("Cannot access the trailer out of the frame.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1662|      0|    return BLOSC2_ERROR_READ_BUFFER;
 1663|      0|  }
 1664|       |
 1665|       |  // Get the trailer
 1666|      1|  uint8_t* trailer = NULL;
 1667|      1|  bool needs_free = false;
 1668|      1|  if (frame->cframe != NULL) {
  ------------------
  |  Branch (1668:7): [True: 1, False: 0]
  ------------------
 1669|      1|    trailer = frame->cframe + trailer_offset;
 1670|      1|  } else {
 1671|      0|    int64_t rbytes = 0;
 1672|       |
 1673|      0|    blosc2_io_cb *io_cb = blosc2_get_io_cb(frame->schunk->storage->io->id);
 1674|      0|    if (io_cb == NULL) {
  ------------------
  |  Branch (1674:9): [True: 0, False: 0]
  ------------------
 1675|      0|      BLOSC_TRACE_ERROR("Error getting the input/output API");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1676|      0|      return BLOSC2_ERROR_PLUGIN_IO;
 1677|      0|    }
 1678|       |
 1679|      0|    if (io_cb->is_allocation_necessary) {
  ------------------
  |  Branch (1679:9): [True: 0, False: 0]
  ------------------
 1680|      0|      trailer = malloc(trailer_len);
 1681|      0|      needs_free = true;
 1682|      0|    }
 1683|      0|    else {
 1684|      0|      needs_free = false;
 1685|      0|    }
 1686|       |
 1687|      0|    void* fp = NULL;
 1688|      0|    int64_t io_pos = 0;
 1689|      0|    if (frame->sframe) {
  ------------------
  |  Branch (1689:9): [True: 0, False: 0]
  ------------------
 1690|      0|      char* eframe_name = malloc(strlen(frame->urlpath) + strlen("/chunks.b2frame") + 1);
 1691|      0|      sprintf(eframe_name, "%s/chunks.b2frame", frame->urlpath);
 1692|      0|      fp = io_cb->open(eframe_name, "rb", frame->schunk->storage->io->params);
 1693|      0|      if (fp == NULL) {
  ------------------
  |  Branch (1693:11): [True: 0, False: 0]
  ------------------
 1694|      0|        BLOSC_TRACE_ERROR("Error opening file in: %s", eframe_name);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1695|      0|        free(eframe_name);
 1696|      0|        return BLOSC2_ERROR_FILE_OPEN;
 1697|      0|      }
 1698|      0|      free(eframe_name);
 1699|      0|      io_pos = trailer_offset;
 1700|      0|    }
 1701|      0|    else {
 1702|      0|      fp = io_cb->open(frame->urlpath, "rb", frame->schunk->storage->io->params);
 1703|      0|      if (fp == NULL) {
  ------------------
  |  Branch (1703:11): [True: 0, False: 0]
  ------------------
 1704|      0|        BLOSC_TRACE_ERROR("Error opening file in: %s", frame->urlpath);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1705|      0|        return BLOSC2_ERROR_FILE_OPEN;
 1706|      0|      }
 1707|      0|      io_pos = frame->file_offset + trailer_offset;
 1708|      0|    }
 1709|      0|    if (fp != NULL) {
  ------------------
  |  Branch (1709:9): [True: 0, False: 0]
  ------------------
 1710|      0|      rbytes = io_cb->read((void**)&trailer, 1, trailer_len, io_pos, fp);
 1711|      0|      io_cb->close(fp);
 1712|      0|    }
 1713|      0|    if (rbytes != trailer_len) {
  ------------------
  |  Branch (1713:9): [True: 0, False: 0]
  ------------------
 1714|      0|      BLOSC_TRACE_ERROR("Cannot access the trailer out of the fileframe.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1715|      0|      if (needs_free)
  ------------------
  |  Branch (1715:11): [True: 0, False: 0]
  ------------------
 1716|      0|        free(trailer);
 1717|      0|      return BLOSC2_ERROR_FILE_READ;
 1718|      0|    }
 1719|      0|  }
 1720|       |
 1721|      1|  ret = get_vlmeta_from_trailer(frame, schunk, trailer, trailer_len);
 1722|       |
 1723|      1|  if (frame->cframe == NULL && needs_free) {
  ------------------
  |  Branch (1723:7): [True: 0, False: 1]
  |  Branch (1723:32): [True: 0, False: 0]
  ------------------
 1724|      0|    free(trailer);
 1725|      0|  }
 1726|       |
 1727|      1|  return ret;
 1728|      1|}
get_new_storage:
 1734|      1|                                const blosc2_io* iodefaults) {
 1735|       |
 1736|      1|  blosc2_storage* new_storage = (blosc2_storage*)calloc(1, sizeof(blosc2_storage));
 1737|      1|  memcpy(new_storage, storage, sizeof(blosc2_storage));
 1738|      1|  if (storage->urlpath != NULL) {
  ------------------
  |  Branch (1738:7): [True: 0, False: 1]
  ------------------
 1739|      0|    char* urlpath = normalize_urlpath(storage->urlpath);
 1740|      0|    new_storage->urlpath = malloc(strlen(urlpath) + 1);
 1741|      0|    strcpy(new_storage->urlpath, urlpath);
 1742|      0|  }
 1743|       |
 1744|       |  // cparams
 1745|      1|  blosc2_cparams* cparams = malloc(sizeof(blosc2_cparams));
 1746|      1|  if (storage->cparams != NULL) {
  ------------------
  |  Branch (1746:7): [True: 0, False: 1]
  ------------------
 1747|      0|    memcpy(cparams, storage->cparams, sizeof(blosc2_cparams));
 1748|      1|  } else {
 1749|      1|    memcpy(cparams, cdefaults, sizeof(blosc2_cparams));
 1750|      1|  }
 1751|      1|  new_storage->cparams = cparams;
 1752|       |
 1753|       |  // dparams
 1754|      1|  blosc2_dparams* dparams = malloc(sizeof(blosc2_dparams));
 1755|      1|  if (storage->dparams != NULL) {
  ------------------
  |  Branch (1755:7): [True: 0, False: 1]
  ------------------
 1756|      0|    memcpy(dparams, storage->dparams, sizeof(blosc2_dparams));
 1757|      0|  }
 1758|      1|  else {
 1759|      1|    memcpy(dparams, ddefaults, sizeof(blosc2_dparams));
 1760|      1|  }
 1761|      1|  new_storage->dparams = dparams;
 1762|       |
 1763|       |  // iodefaults
 1764|      1|  blosc2_io* udio = malloc(sizeof(blosc2_io));
 1765|      1|  if (storage->io != NULL) {
  ------------------
  |  Branch (1765:7): [True: 0, False: 1]
  ------------------
 1766|      0|    memcpy(udio, storage->io, sizeof(blosc2_io));
 1767|      0|  }
 1768|      1|  else {
 1769|      1|    memcpy(udio, iodefaults, sizeof(blosc2_io));
 1770|      1|  }
 1771|      1|  new_storage->io = udio;
 1772|       |
 1773|      1|  return new_storage;
 1774|      1|}
frame_to_schunk:
 1778|      1|blosc2_schunk* frame_to_schunk(blosc2_frame_s* frame, bool copy, const blosc2_io *udio) {
 1779|      1|  int32_t header_len;
 1780|      1|  int64_t frame_len;
 1781|      1|  int rc;
 1782|      1|  blosc2_schunk* schunk = calloc(1, sizeof(blosc2_schunk));
 1783|      1|  schunk->frame = (blosc2_frame*)frame;
 1784|      1|  frame->schunk = schunk;
 1785|       |
 1786|      1|  rc = get_header_info(frame, &header_len, &frame_len, &schunk->nbytes,
 1787|      1|                       &schunk->cbytes, &schunk->blocksize,
 1788|      1|                       &schunk->chunksize, &schunk->nchunks, &schunk->typesize,
 1789|      1|                       &schunk->compcode, &schunk->compcode_meta, &schunk->clevel, schunk->filters,
 1790|      1|                       schunk->filters_meta, &schunk->splitmode, udio);
 1791|      1|  if (rc < 0) {
  ------------------
  |  Branch (1791:7): [True: 0, False: 1]
  ------------------
 1792|      0|    BLOSC_TRACE_ERROR("Unable to get meta info from frame.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1793|      0|    blosc2_schunk_free(schunk);
 1794|      0|    return NULL;
 1795|      0|  }
 1796|      1|  int64_t nchunks = schunk->nchunks;
 1797|      1|  int64_t nbytes = schunk->nbytes;
 1798|      1|  (void) nbytes;
 1799|      1|  int64_t cbytes = schunk->cbytes;
 1800|       |
 1801|       |  // Compression and decompression contexts
 1802|      1|  blosc2_cparams *cparams;
 1803|      1|  blosc2_schunk_get_cparams(schunk, &cparams);
 1804|      1|  schunk->cctx = blosc2_create_cctx(*cparams);
 1805|      1|  if (schunk->cctx == NULL) {
  ------------------
  |  Branch (1805:7): [True: 0, False: 1]
  ------------------
 1806|      0|    BLOSC_TRACE_ERROR("Error while creating the compression context");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1807|      0|    return NULL;
 1808|      0|  }
 1809|      1|  blosc2_dparams *dparams;
 1810|      1|  blosc2_schunk_get_dparams(schunk, &dparams);
 1811|      1|  schunk->dctx = blosc2_create_dctx(*dparams);
 1812|      1|  if (schunk->dctx == NULL) {
  ------------------
  |  Branch (1812:7): [True: 0, False: 1]
  ------------------
 1813|      0|    BLOSC_TRACE_ERROR("Error while creating the decompression context");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1814|      0|    return NULL;
 1815|      0|  }
 1816|      1|  blosc2_storage storage = {.contiguous = copy ? false : true};
  ------------------
  |  Branch (1816:43): [True: 0, False: 1]
  ------------------
 1817|      1|  schunk->storage = get_new_storage(&storage, cparams, dparams, udio);
 1818|      1|  free(cparams);
 1819|      1|  free(dparams);
 1820|      1|  if (!copy) {
  ------------------
  |  Branch (1820:7): [True: 1, False: 0]
  ------------------
 1821|      1|    goto out;
 1822|      1|  }
 1823|       |
 1824|       |  // We are not attached to a frame anymore
 1825|      0|  schunk->frame = NULL;
 1826|       |
 1827|      0|  if (nchunks == 0) {
  ------------------
  |  Branch (1827:7): [True: 0, False: 0]
  ------------------
 1828|      0|    frame->schunk = NULL;
 1829|      0|    goto out;
 1830|      0|  }
 1831|       |
 1832|       |  // Get the compressed offsets
 1833|      0|  int32_t coffsets_cbytes = 0;
 1834|      0|  uint8_t* coffsets = get_coffsets(frame, header_len, cbytes, nchunks, &coffsets_cbytes);
 1835|      0|  if (coffsets == NULL) {
  ------------------
  |  Branch (1835:7): [True: 0, False: 0]
  ------------------
 1836|      0|    blosc2_schunk_free(schunk);
 1837|      0|    BLOSC_TRACE_ERROR("Cannot get the offsets for the frame.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1838|      0|    return NULL;
 1839|      0|  }
 1840|       |
 1841|       |  // Decompress offsets
 1842|      0|  blosc2_dparams off_dparams = BLOSC2_DPARAMS_DEFAULTS;
 1843|      0|  blosc2_context *dctx = blosc2_create_dctx(off_dparams);
 1844|      0|  if (dctx == NULL) {
  ------------------
  |  Branch (1844:7): [True: 0, False: 0]
  ------------------
 1845|      0|    BLOSC_TRACE_ERROR("Error while creating the decompression context");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1846|      0|    return NULL;
 1847|      0|  }
 1848|      0|  int64_t* offsets = (int64_t *) malloc((size_t)nchunks * sizeof(int64_t));
 1849|      0|  int32_t off_nbytes = blosc2_decompress_ctx(dctx, coffsets, coffsets_cbytes,
 1850|      0|                                             offsets, (int32_t)(nchunks * sizeof(int64_t)));
 1851|      0|  blosc2_free_ctx(dctx);
 1852|      0|  if (off_nbytes < 0) {
  ------------------
  |  Branch (1852:7): [True: 0, False: 0]
  ------------------
 1853|      0|    free(offsets);
 1854|      0|    blosc2_schunk_free(schunk);
 1855|      0|    BLOSC_TRACE_ERROR("Cannot decompress the offsets chunk.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1856|      0|    return NULL;
 1857|      0|  }
 1858|       |
 1859|       |  // We want the contiguous schunk, so create the actual data chunks (and, while doing this,
 1860|       |  // get a guess at the blocksize used in this frame)
 1861|      0|  int64_t acc_nbytes = 0;
 1862|      0|  int64_t acc_cbytes = 0;
 1863|      0|  int32_t blocksize = 0;
 1864|      0|  int32_t chunk_nbytes;
 1865|      0|  int32_t chunk_cbytes;
 1866|      0|  int32_t chunk_blocksize;
 1867|      0|  size_t prev_alloc = BLOSC_EXTENDED_HEADER_LENGTH;
 1868|      0|  uint8_t* data_chunk = NULL;
 1869|      0|  bool needs_free = false;
 1870|      0|  const blosc2_io_cb *io_cb = blosc2_get_io_cb(udio->id);
 1871|      0|  if (io_cb == NULL) {
  ------------------
  |  Branch (1871:7): [True: 0, False: 0]
  ------------------
 1872|      0|    blosc2_schunk_free(schunk);
 1873|      0|    BLOSC_TRACE_ERROR("Error getting the input/output API");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1874|      0|    return NULL;
 1875|      0|  }
 1876|       |
 1877|      0|  void* fp = NULL;
 1878|      0|  if (frame->cframe == NULL) {
  ------------------
  |  Branch (1878:7): [True: 0, False: 0]
  ------------------
 1879|      0|    if (io_cb->is_allocation_necessary) {
  ------------------
  |  Branch (1879:9): [True: 0, False: 0]
  ------------------
 1880|      0|      data_chunk = malloc((size_t)prev_alloc);
 1881|      0|      needs_free = true;
 1882|      0|    }
 1883|      0|    else {
 1884|      0|      needs_free = false;
 1885|      0|    }
 1886|       |    
 1887|      0|    if (!frame->sframe) {
  ------------------
  |  Branch (1887:9): [True: 0, False: 0]
  ------------------
 1888|       |      // If not the chunks won't be in the frame
 1889|      0|      fp = io_cb->open(frame->urlpath, "rb", udio->params);
 1890|      0|      if (fp == NULL) {
  ------------------
  |  Branch (1890:11): [True: 0, False: 0]
  ------------------
 1891|      0|        BLOSC_TRACE_ERROR("Error opening file in: %s", frame->urlpath);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1892|      0|        rc = BLOSC2_ERROR_FILE_OPEN;
 1893|      0|        goto end;
 1894|      0|      }
 1895|      0|    }
 1896|      0|  }
 1897|      0|  schunk->data = malloc(nchunks * sizeof(void*));
 1898|      0|  for (int i = 0; i < nchunks; i++) {
  ------------------
  |  Branch (1898:19): [True: 0, False: 0]
  ------------------
 1899|      0|    if (frame->cframe != NULL) {
  ------------------
  |  Branch (1899:9): [True: 0, False: 0]
  ------------------
 1900|      0|      if (needs_free) {
  ------------------
  |  Branch (1900:11): [True: 0, False: 0]
  ------------------
 1901|      0|        free(data_chunk);
 1902|      0|      }
 1903|      0|      if (offsets[i] < 0) {
  ------------------
  |  Branch (1903:11): [True: 0, False: 0]
  ------------------
 1904|      0|        int64_t rbytes = frame_get_chunk(frame, i, &data_chunk, &needs_free);
 1905|      0|        if (rbytes < 0) {
  ------------------
  |  Branch (1905:13): [True: 0, False: 0]
  ------------------
 1906|      0|          break;
 1907|      0|        }
 1908|      0|      }
 1909|      0|      else {
 1910|      0|       data_chunk = frame->cframe + header_len + offsets[i];
 1911|      0|      }
 1912|      0|      rc = blosc2_cbuffer_sizes(data_chunk, NULL, &chunk_cbytes, NULL);
 1913|      0|      if (rc < 0) {
  ------------------
  |  Branch (1913:11): [True: 0, False: 0]
  ------------------
 1914|      0|        break;
 1915|      0|      }
 1916|      0|    }
 1917|      0|    else {
 1918|      0|      int64_t rbytes;
 1919|      0|      if (frame->sframe) {
  ------------------
  |  Branch (1919:11): [True: 0, False: 0]
  ------------------
 1920|      0|        if (needs_free) {
  ------------------
  |  Branch (1920:13): [True: 0, False: 0]
  ------------------
 1921|      0|          free(data_chunk);
 1922|      0|        }
 1923|      0|        rbytes = frame_get_chunk(frame, i, &data_chunk, &needs_free);
 1924|      0|        if (rbytes < 0) {
  ------------------
  |  Branch (1924:13): [True: 0, False: 0]
  ------------------
 1925|      0|          break;
 1926|      0|        }
 1927|      0|      }
 1928|      0|      else {
 1929|      0|        int64_t io_pos = frame->file_offset + header_len + offsets[i];
 1930|      0|        rbytes = io_cb->read((void**)&data_chunk, 1, BLOSC_EXTENDED_HEADER_LENGTH, io_pos, fp);
 1931|      0|      }
 1932|      0|      if (rbytes != BLOSC_EXTENDED_HEADER_LENGTH) {
  ------------------
  |  Branch (1932:11): [True: 0, False: 0]
  ------------------
 1933|      0|        rc = BLOSC2_ERROR_READ_BUFFER;
 1934|      0|        break;
 1935|      0|      }
 1936|      0|      rc = blosc2_cbuffer_sizes(data_chunk, NULL, &chunk_cbytes, NULL);
 1937|      0|      if (rc < 0) {
  ------------------
  |  Branch (1937:11): [True: 0, False: 0]
  ------------------
 1938|      0|        break;
 1939|      0|      }
 1940|      0|      if (chunk_cbytes > (int32_t)prev_alloc) {
  ------------------
  |  Branch (1940:11): [True: 0, False: 0]
  ------------------
 1941|      0|        if (io_cb->is_allocation_necessary)
  ------------------
  |  Branch (1941:13): [True: 0, False: 0]
  ------------------
 1942|      0|          data_chunk = realloc(data_chunk, chunk_cbytes);
 1943|      0|        if (data_chunk == NULL) {
  ------------------
  |  Branch (1943:13): [True: 0, False: 0]
  ------------------
 1944|      0|          BLOSC_TRACE_ERROR("Cannot realloc space for the data_chunk.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1945|      0|          rc = BLOSC2_ERROR_MEMORY_ALLOC;
 1946|      0|          break;
 1947|      0|        }
 1948|      0|        prev_alloc = chunk_cbytes;
 1949|      0|      }
 1950|      0|      if (!frame->sframe) {
  ------------------
  |  Branch (1950:11): [True: 0, False: 0]
  ------------------
 1951|      0|        int64_t io_pos = frame->file_offset + header_len + offsets[i];
 1952|      0|        rbytes = io_cb->read((void**)&data_chunk, 1, chunk_cbytes, io_pos, fp);
 1953|      0|        if (rbytes != chunk_cbytes) {
  ------------------
  |  Branch (1953:13): [True: 0, False: 0]
  ------------------
 1954|      0|          rc = BLOSC2_ERROR_READ_BUFFER;
 1955|      0|          break;
 1956|      0|        }
 1957|      0|      }
 1958|      0|    }
 1959|      0|    uint8_t* new_chunk = malloc(chunk_cbytes);
 1960|      0|    memcpy(new_chunk, data_chunk, chunk_cbytes);
 1961|      0|    schunk->data[i] = new_chunk;
 1962|      0|    rc = blosc2_cbuffer_sizes(data_chunk, &chunk_nbytes, NULL, &chunk_blocksize);
 1963|      0|    if (rc < 0) {
  ------------------
  |  Branch (1963:9): [True: 0, False: 0]
  ------------------
 1964|      0|      break;
 1965|      0|    }
 1966|      0|    acc_nbytes += chunk_nbytes;
 1967|      0|    acc_cbytes += chunk_cbytes;
 1968|      0|    if (i == 0) {
  ------------------
  |  Branch (1968:9): [True: 0, False: 0]
  ------------------
 1969|      0|      blocksize = chunk_blocksize;
 1970|      0|    }
 1971|      0|    else if (blocksize != chunk_blocksize) {
  ------------------
  |  Branch (1971:14): [True: 0, False: 0]
  ------------------
 1972|       |      // Blocksize varies
 1973|      0|      blocksize = 0;
 1974|      0|    }
 1975|      0|  }
 1976|       |
 1977|       |  // We are not attached to a schunk anymore
 1978|      0|  frame->schunk = NULL;
 1979|       |
 1980|      0|  end:
 1981|      0|  if (needs_free) {
  ------------------
  |  Branch (1981:7): [True: 0, False: 0]
  ------------------
 1982|      0|    free(data_chunk);
 1983|      0|  }
 1984|      0|  if (frame->cframe == NULL) {
  ------------------
  |  Branch (1984:7): [True: 0, False: 0]
  ------------------
 1985|      0|    if (!frame->sframe) {
  ------------------
  |  Branch (1985:9): [True: 0, False: 0]
  ------------------
 1986|      0|      io_cb->close(fp);
 1987|      0|    }
 1988|      0|  }
 1989|      0|  free(offsets);
 1990|       |
 1991|       |  // cframes and sframes have different ways to store chunks with special values:
 1992|       |  // 1) cframes represent special chunks as negative offsets
 1993|       |  // 2) sframes does not have the concept of offsets, but rather of data pointers (.data)
 1994|       |  //    so they always have a pointer to a special chunk
 1995|       |  // This is why cframes and sframes have different cbytes and hence, we cannot enforce acc_bytes == schunk->cbytes
 1996|       |  // In the future, maybe we could provide special meanings for .data[i] > 0x7FFFFFFF, but not there yet
 1997|       |  // if (rc < 0 || acc_nbytes != nbytes || acc_cbytes != cbytes) {
 1998|      0|  if (rc < 0 || acc_nbytes != nbytes) {
  ------------------
  |  Branch (1998:7): [True: 0, False: 0]
  |  Branch (1998:17): [True: 0, False: 0]
  ------------------
 1999|      0|    blosc2_schunk_free(schunk);
 2000|      0|    return NULL;
 2001|      0|  }
 2002|       |  // Update counters
 2003|      0|  schunk->cbytes = acc_cbytes;
 2004|      0|  schunk->blocksize = blocksize;
 2005|       |
 2006|      1|  out:
 2007|      1|  rc = frame_get_metalayers(frame, schunk);
 2008|      1|  if (rc < 0) {
  ------------------
  |  Branch (2008:7): [True: 0, False: 1]
  ------------------
 2009|      0|    blosc2_schunk_free(schunk);
 2010|      0|    BLOSC_TRACE_ERROR("Cannot access the metalayers.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2011|      0|    return NULL;
 2012|      0|  }
 2013|       |
 2014|      1|  rc = frame_get_vlmetalayers(frame, schunk);
 2015|      1|  if (rc < 0) {
  ------------------
  |  Branch (2015:7): [True: 0, False: 1]
  ------------------
 2016|      0|    blosc2_schunk_free(schunk);
 2017|      0|    BLOSC_TRACE_ERROR("Cannot access the vlmetalayers.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2018|      0|    return NULL;
 2019|      0|  }
 2020|       |
 2021|      1|  return schunk;
 2022|      1|}
get_coffset:
 2044|      4|                int64_t nchunk, int64_t nchunks, int64_t *offset) {
 2045|      4|  int32_t off_cbytes;
 2046|       |  // Get the offset to nchunk
 2047|      4|  uint8_t *coffsets = get_coffsets(frame, header_len, cbytes, nchunks, &off_cbytes);
 2048|      4|  if (coffsets == NULL) {
  ------------------
  |  Branch (2048:7): [True: 0, False: 4]
  ------------------
 2049|      0|    BLOSC_TRACE_ERROR("Cannot get the offset for chunk %" PRId64 " for the frame.", nchunk);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2050|      0|    return BLOSC2_ERROR_DATA;
 2051|      0|  }
 2052|       |
 2053|       |  // Get the 64-bit offset
 2054|      4|  int rc = blosc2_getitem(coffsets, off_cbytes, (int32_t)nchunk, 1, offset, (int32_t)sizeof(int64_t));
 2055|      4|  if (rc < 0) {
  ------------------
  |  Branch (2055:7): [True: 0, False: 4]
  ------------------
 2056|      0|    BLOSC_TRACE_ERROR("Problems retrieving a chunk offset.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2057|      4|  } else if (!frame->sframe && *offset > frame->len) {
  ------------------
  |  Branch (2057:14): [True: 4, False: 0]
  |  Branch (2057:32): [True: 0, False: 4]
  ------------------
 2058|      0|    BLOSC_TRACE_ERROR("Cannot read chunk %" PRId64 " outside of frame boundary.", nchunk);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2059|      0|    rc = BLOSC2_ERROR_READ_BUFFER;
 2060|      0|  }
 2061|       |
 2062|      0|  return rc;
 2063|      4|}
frame_special_chunk:
 2068|      1|                        uint8_t** chunk, int32_t cbytes, bool *needs_free) {
 2069|      1|  int rc = 0;
 2070|      1|  *chunk = malloc(cbytes);
 2071|      1|  *needs_free = true;
 2072|       |
 2073|       |  // Detect the kind of special value
 2074|      1|  uint64_t zeros_mask = (uint64_t) BLOSC2_SPECIAL_ZERO << (8 * 7);  // chunk of zeros
 2075|      1|  uint64_t nans_mask = (uint64_t) BLOSC2_SPECIAL_NAN << (8 * 7);  // chunk of NaNs
 2076|      1|  uint64_t uninit_mask = (uint64_t) BLOSC2_SPECIAL_UNINIT << (8 * 7);  // chunk of uninit values
 2077|       |
 2078|      1|  blosc2_cparams cparams = BLOSC2_CPARAMS_DEFAULTS;
 2079|      1|  cparams.typesize = typesize;
 2080|      1|  cparams.blocksize = blocksize;
 2081|      1|  if (special_value & zeros_mask) {
  ------------------
  |  Branch (2081:7): [True: 1, False: 0]
  ------------------
 2082|      1|    rc = blosc2_chunk_zeros(cparams, nbytes, *chunk, cbytes);
 2083|      1|    if (rc < 0) {
  ------------------
  |  Branch (2083:9): [True: 0, False: 1]
  ------------------
 2084|      0|      BLOSC_TRACE_ERROR("Error creating a zero chunk");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2085|      0|    }
 2086|      1|  }
 2087|      0|  else if (special_value & uninit_mask) {
  ------------------
  |  Branch (2087:12): [True: 0, False: 0]
  ------------------
 2088|      0|    rc = blosc2_chunk_uninit(cparams, nbytes, *chunk, cbytes);
 2089|      0|    if (rc < 0) {
  ------------------
  |  Branch (2089:9): [True: 0, False: 0]
  ------------------
 2090|      0|      BLOSC_TRACE_ERROR("Error creating a non initialized chunk");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2091|      0|    }
 2092|      0|  }
 2093|      0|  else if (special_value & nans_mask) {
  ------------------
  |  Branch (2093:12): [True: 0, False: 0]
  ------------------
 2094|      0|    rc = blosc2_chunk_nans(cparams, nbytes, *chunk, cbytes);
 2095|      0|    if (rc < 0) {
  ------------------
  |  Branch (2095:9): [True: 0, False: 0]
  ------------------
 2096|      0|      BLOSC_TRACE_ERROR("Error creating a nan chunk");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2097|      0|    }
 2098|      0|  }
 2099|      0|  else {
 2100|      0|    BLOSC_TRACE_ERROR("Special value not recognized: %" PRId64 "", special_value);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2101|      0|    rc = BLOSC2_ERROR_DATA;
 2102|      0|  }
 2103|       |
 2104|      1|  if (rc < 0) {
  ------------------
  |  Branch (2104:7): [True: 0, False: 1]
  ------------------
 2105|      0|    free(*chunk);
 2106|      0|    *needs_free = false;
 2107|      0|    *chunk = NULL;
 2108|      0|  }
 2109|       |
 2110|      1|  return rc;
 2111|      1|}
frame_get_lazychunk:
 2251|      4|int frame_get_lazychunk(blosc2_frame_s *frame, int64_t nchunk, uint8_t **chunk, bool *needs_free) {
 2252|      4|  int32_t header_len;
 2253|      4|  int64_t frame_len;
 2254|      4|  int64_t nbytes;
 2255|      4|  int64_t cbytes;
 2256|      4|  int32_t blocksize;
 2257|      4|  int32_t chunksize;
 2258|      4|  int64_t nchunks;
 2259|      4|  int32_t typesize;
 2260|      4|  int32_t lazychunk_cbytes;
 2261|      4|  int64_t offset;
 2262|      4|  void* fp = NULL;
 2263|       |
 2264|      4|  *chunk = NULL;
 2265|      4|  *needs_free = false;
 2266|      4|  int rc = get_header_info(frame, &header_len, &frame_len, &nbytes, &cbytes,
 2267|      4|                           &blocksize, &chunksize, &nchunks,
 2268|      4|                           &typesize, NULL, NULL, NULL, NULL, NULL, NULL,
 2269|      4|                           frame->schunk->storage->io);
 2270|      4|  if (rc < 0) {
  ------------------
  |  Branch (2270:7): [True: 0, False: 4]
  ------------------
 2271|      0|    BLOSC_TRACE_ERROR("Unable to get meta info from frame.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2272|      0|    return rc;
 2273|      0|  }
 2274|       |
 2275|      4|  if (nchunk >= nchunks) {
  ------------------
  |  Branch (2275:7): [True: 0, False: 4]
  ------------------
 2276|      0|    BLOSC_TRACE_ERROR("nchunk ('%" PRId64 "') exceeds the number of chunks "
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2277|      0|                      "('%" PRId64 "') in frame.", nchunk, nchunks);
 2278|      0|    return BLOSC2_ERROR_INVALID_PARAM;
 2279|      0|  }
 2280|       |
 2281|       |  // Get the offset to nchunk
 2282|      4|  rc = get_coffset(frame, header_len, cbytes, nchunk, nchunks, &offset);
 2283|      4|  if (rc < 0) {
  ------------------
  |  Branch (2283:7): [True: 0, False: 4]
  ------------------
 2284|      0|    BLOSC_TRACE_ERROR("Unable to get offset to chunk %" PRId64 ".", nchunk);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2285|      0|    return rc;
 2286|      0|  }
 2287|       |
 2288|      4|  if (offset < 0) {
  ------------------
  |  Branch (2288:7): [True: 1, False: 3]
  ------------------
 2289|       |    // Special value
 2290|      1|    lazychunk_cbytes = BLOSC_EXTENDED_HEADER_LENGTH;
 2291|      1|    int32_t chunksize_ = chunksize;
 2292|      1|    if ((nchunk == nchunks - 1) && (nbytes % chunksize)) {
  ------------------
  |  Branch (2292:9): [True: 0, False: 1]
  |  Branch (2292:36): [True: 0, False: 0]
  ------------------
 2293|       |      // Last chunk is incomplete.  Compute its actual size.
 2294|      0|      chunksize_ = (int32_t) (nbytes % chunksize);
 2295|      0|    }
 2296|      1|    rc = frame_special_chunk(offset, chunksize_, typesize, blocksize, chunk,
 2297|      1|                             (int32_t)lazychunk_cbytes, needs_free);
 2298|      1|    goto end;
 2299|      1|  }
 2300|       |
 2301|      3|  blosc2_io_cb *io_cb = blosc2_get_io_cb(frame->schunk->storage->io->id);
 2302|      3|  if (io_cb == NULL) {
  ------------------
  |  Branch (2302:7): [True: 0, False: 3]
  ------------------
 2303|      0|    BLOSC_TRACE_ERROR("Error getting the input/output API");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2304|      0|    rc = BLOSC2_ERROR_PLUGIN_IO;
 2305|      0|    goto end;
 2306|      0|  }
 2307|       |
 2308|      3|  if (frame->cframe == NULL) {
  ------------------
  |  Branch (2308:7): [True: 0, False: 3]
  ------------------
 2309|       |    // TODO: make this portable across different endianness
 2310|       |    // Get info for building a lazy chunk
 2311|      0|    int32_t chunk_nbytes;
 2312|      0|    int32_t chunk_cbytes;
 2313|      0|    int32_t chunk_blocksize;
 2314|      0|    uint8_t* header_ptr;
 2315|      0|    uint8_t header[BLOSC_EXTENDED_HEADER_LENGTH];
 2316|      0|    int64_t io_pos = 0;
 2317|      0|    if (frame->sframe) {
  ------------------
  |  Branch (2317:9): [True: 0, False: 0]
  ------------------
 2318|       |      // The chunk is not in the frame
 2319|      0|      fp = sframe_open_chunk(frame->urlpath, offset, "rb",
 2320|      0|                             frame->schunk->storage->io);
 2321|      0|      if (fp == NULL) {
  ------------------
  |  Branch (2321:11): [True: 0, False: 0]
  ------------------
 2322|      0|        BLOSC_TRACE_ERROR("Error opening file in: %s", frame->urlpath);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2323|      0|        return BLOSC2_ERROR_FILE_OPEN;
 2324|      0|      }
 2325|      0|    }
 2326|      0|    else {
 2327|      0|      fp = io_cb->open(frame->urlpath, "rb", frame->schunk->storage->io->params);
 2328|      0|      if (fp == NULL) {
  ------------------
  |  Branch (2328:11): [True: 0, False: 0]
  ------------------
 2329|      0|        BLOSC_TRACE_ERROR("Error opening file in: %s", frame->urlpath);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2330|      0|        return BLOSC2_ERROR_FILE_OPEN;
 2331|      0|      }
 2332|      0|      io_pos = frame->file_offset + header_len + offset;
 2333|      0|    }
 2334|      0|    if (io_cb->is_allocation_necessary)
  ------------------
  |  Branch (2334:9): [True: 0, False: 0]
  ------------------
 2335|      0|      header_ptr = header;
 2336|      0|    int64_t rbytes = io_cb->read((void**)&header_ptr, 1, BLOSC_EXTENDED_HEADER_LENGTH, io_pos, fp);
 2337|      0|    if (rbytes != BLOSC_EXTENDED_HEADER_LENGTH) {
  ------------------
  |  Branch (2337:9): [True: 0, False: 0]
  ------------------
 2338|      0|      BLOSC_TRACE_ERROR("Cannot read the header for chunk in the frame.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2339|      0|      rc = BLOSC2_ERROR_FILE_READ;
 2340|      0|      goto end;
 2341|      0|    }
 2342|      0|    rc = blosc2_cbuffer_sizes(header_ptr, &chunk_nbytes, &chunk_cbytes, &chunk_blocksize);
 2343|      0|    if (rc < 0) {
  ------------------
  |  Branch (2343:9): [True: 0, False: 0]
  ------------------
 2344|      0|      goto end;
 2345|      0|    }
 2346|      0|    size_t nblocks = chunk_nbytes / chunk_blocksize;
 2347|      0|    size_t leftover_block = chunk_nbytes % chunk_blocksize;
 2348|      0|    nblocks = leftover_block ? nblocks + 1 : nblocks;
  ------------------
  |  Branch (2348:15): [True: 0, False: 0]
  ------------------
 2349|       |    // Allocate space for the lazy chunk
 2350|      0|    int32_t trailer_len;
 2351|      0|    int32_t special_type = (header_ptr[BLOSC2_CHUNK_BLOSC2_FLAGS] >> 4) & BLOSC2_SPECIAL_MASK;
 2352|      0|    int memcpyed = header_ptr[BLOSC2_CHUNK_FLAGS] & (uint8_t) BLOSC_MEMCPYED;
 2353|       |
 2354|      0|    int32_t trailer_offset = BLOSC_EXTENDED_HEADER_LENGTH;
 2355|      0|    size_t streams_offset = BLOSC_EXTENDED_HEADER_LENGTH;
 2356|      0|    if (special_type == 0) {
  ------------------
  |  Branch (2356:9): [True: 0, False: 0]
  ------------------
 2357|       |      // Regular values have offsets for blocks
 2358|      0|      trailer_offset += (int32_t) (nblocks * sizeof(int32_t));
 2359|      0|      if (memcpyed) {
  ------------------
  |  Branch (2359:11): [True: 0, False: 0]
  ------------------
 2360|      0|        streams_offset += 0;
 2361|      0|      } else {
 2362|      0|        streams_offset += nblocks * sizeof(int32_t);
 2363|      0|      }
 2364|      0|      trailer_len = (int32_t) (sizeof(int32_t) + sizeof(int64_t) + nblocks * sizeof(int32_t));
 2365|      0|      lazychunk_cbytes = trailer_offset + trailer_len;
 2366|      0|    }
 2367|      0|    else if (special_type == BLOSC2_SPECIAL_VALUE) {
  ------------------
  |  Branch (2367:14): [True: 0, False: 0]
  ------------------
 2368|      0|      trailer_offset += typesize;
 2369|      0|      streams_offset += typesize;
 2370|      0|      trailer_len = 0;
 2371|      0|      lazychunk_cbytes = trailer_offset + trailer_len;
 2372|      0|    }
 2373|      0|    else {
 2374|      0|      rc = BLOSC2_ERROR_INVALID_HEADER;
 2375|      0|      goto end;
 2376|      0|    }
 2377|       |
 2378|       |    // Read just the full header and bstarts section too (lazy partial length)
 2379|      0|    if (frame->sframe) {
  ------------------
  |  Branch (2379:9): [True: 0, False: 0]
  ------------------
 2380|      0|      io_pos = 0;
 2381|      0|    }
 2382|      0|    else {
 2383|      0|      io_pos = frame->file_offset + header_len + offset;
 2384|      0|    }
 2385|       |
 2386|       |    // The case here is a bit special because more memory is allocated than read from the file
 2387|       |    // and the chunk is modified after reading. Due to the modification, we cannot directly use
 2388|       |    // the memory provided by the io
 2389|      0|    *chunk = malloc(lazychunk_cbytes);
 2390|      0|    *needs_free = true;
 2391|       |
 2392|      0|    if (io_cb->is_allocation_necessary) {
  ------------------
  |  Branch (2392:9): [True: 0, False: 0]
  ------------------
 2393|      0|      rbytes = io_cb->read((void**)chunk, 1, (int64_t)streams_offset, io_pos, fp);
 2394|      0|    }
 2395|      0|    else {
 2396|      0|      uint8_t* chunk_ptr;
 2397|      0|      rbytes = io_cb->read((void**)&chunk_ptr, 1, (int64_t)streams_offset, io_pos, fp);
 2398|      0|      memcpy(*chunk, chunk_ptr, streams_offset);
 2399|      0|    }
 2400|       |    
 2401|      0|    if (rbytes != (int64_t)streams_offset) {
  ------------------
  |  Branch (2401:9): [True: 0, False: 0]
  ------------------
 2402|      0|      BLOSC_TRACE_ERROR("Cannot read the (lazy) chunk out of the frame.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2403|      0|      rc = BLOSC2_ERROR_FILE_READ;
 2404|      0|      goto end;
 2405|      0|    }
 2406|      0|    if (special_type == BLOSC2_SPECIAL_VALUE) {
  ------------------
  |  Branch (2406:9): [True: 0, False: 0]
  ------------------
 2407|       |      // Value runlen is not returning a lazy chunk.  We are done.
 2408|      0|      goto end;
 2409|      0|    }
 2410|       |
 2411|       |    // Mark chunk as lazy
 2412|      0|    uint8_t* blosc2_flags = *chunk + BLOSC2_CHUNK_BLOSC2_FLAGS;
 2413|      0|    *blosc2_flags |= 0x08U;
 2414|       |
 2415|       |    // Add the trailer (currently, nchunk + offset + block_csizes)
 2416|      0|    if (frame->sframe) {
  ------------------
  |  Branch (2416:9): [True: 0, False: 0]
  ------------------
 2417|      0|      *(int32_t*)(*chunk + trailer_offset) = (int32_t)offset;   // offset is nchunk for sframes
 2418|      0|      *(int64_t*)(*chunk + trailer_offset + sizeof(int32_t)) = offset;
 2419|      0|    }
 2420|      0|    else {
 2421|      0|      *(int32_t*)(*chunk + trailer_offset) = (int32_t)nchunk;
 2422|      0|      *(int64_t*)(*chunk + trailer_offset + sizeof(int32_t)) = header_len + offset;
 2423|      0|    }
 2424|       |
 2425|      0|    int32_t* block_csizes = malloc(nblocks * sizeof(int32_t));
 2426|       |
 2427|      0|    if (memcpyed) {
  ------------------
  |  Branch (2427:9): [True: 0, False: 0]
  ------------------
 2428|       |      // When memcpyed the blocksizes are trivial to compute
 2429|      0|      for (int i = 0; i < (int)nblocks - 1; i++) {
  ------------------
  |  Branch (2429:23): [True: 0, False: 0]
  ------------------
 2430|      0|        block_csizes[i] = (int)chunk_blocksize;
 2431|      0|      }
 2432|       |      // The last block could be incomplete, mainly due to the fact that the block size is not divisible
 2433|       |      // by the typesize
 2434|      0|      block_csizes[nblocks - 1] = (int32_t)leftover_block ? (int32_t)leftover_block : chunk_blocksize;
  ------------------
  |  Branch (2434:35): [True: 0, False: 0]
  ------------------
 2435|      0|    }
 2436|      0|    else {
 2437|       |      // In regular, compressed chunks, we need to sort the bstarts (they can be out
 2438|       |      // of order because of multi-threading), and get a reverse index too.
 2439|      0|      memcpy(block_csizes, *chunk + BLOSC_EXTENDED_HEADER_LENGTH, nblocks * sizeof(int32_t));
 2440|       |      // Helper structure to keep track of original indexes
 2441|      0|      struct csize_idx *csize_idx = malloc(nblocks * sizeof(struct csize_idx));
 2442|      0|      for (int n = 0; n < (int)nblocks; n++) {
  ------------------
  |  Branch (2442:23): [True: 0, False: 0]
  ------------------
 2443|      0|        csize_idx[n].val = block_csizes[n];
 2444|      0|        csize_idx[n].idx = n;
 2445|      0|      }
 2446|      0|      qsort(csize_idx, nblocks, sizeof(struct csize_idx), &sort_offset);
 2447|       |      // Compute the actual csizes
 2448|      0|      int idx;
 2449|      0|      for (int n = 0; n < (int)nblocks - 1; n++) {
  ------------------
  |  Branch (2449:23): [True: 0, False: 0]
  ------------------
 2450|      0|        idx = csize_idx[n].idx;
 2451|      0|        block_csizes[idx] = csize_idx[n + 1].val - csize_idx[n].val;
 2452|      0|      }
 2453|      0|      idx = csize_idx[nblocks - 1].idx;
 2454|      0|      block_csizes[idx] = (int)chunk_cbytes - csize_idx[nblocks - 1].val;
 2455|      0|      free(csize_idx);
 2456|      0|    }
 2457|       |    // Copy the csizes at the end of the trailer
 2458|      0|    void *trailer_csizes = *chunk + lazychunk_cbytes - nblocks * sizeof(int32_t);
 2459|      0|    memcpy(trailer_csizes, block_csizes, nblocks * sizeof(int32_t));
 2460|      0|    free(block_csizes);
 2461|      3|  } else {
 2462|       |    // The chunk is in memory and just one pointer away
 2463|      3|    int64_t chunk_header_offset = header_len + offset;
 2464|      3|    int64_t chunk_cbytes_offset = chunk_header_offset + BLOSC_MIN_HEADER_LENGTH;
 2465|       |
 2466|      3|    *chunk = frame->cframe + chunk_header_offset;
 2467|       |
 2468|      3|    if (chunk_cbytes_offset > frame->len) {
  ------------------
  |  Branch (2468:9): [True: 0, False: 3]
  ------------------
 2469|      0|      BLOSC_TRACE_ERROR("Cannot read the header for chunk in the (contiguous) frame.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2470|      0|      rc = BLOSC2_ERROR_READ_BUFFER;
 2471|      3|    } else {
 2472|      3|      rc = blosc2_cbuffer_sizes(*chunk, NULL, &lazychunk_cbytes, NULL);
 2473|      3|      if (rc && chunk_cbytes_offset + lazychunk_cbytes > frame_len) {
  ------------------
  |  Branch (2473:11): [True: 0, False: 3]
  |  Branch (2473:17): [True: 0, False: 0]
  ------------------
 2474|      0|        BLOSC_TRACE_ERROR("Compressed bytes exceed beyond frame length.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2475|      0|        rc = BLOSC2_ERROR_READ_BUFFER;
 2476|      0|      }
 2477|      3|    }
 2478|      3|  }
 2479|       |
 2480|      4|  end:
 2481|      4|  if (fp != NULL) {
  ------------------
  |  Branch (2481:7): [True: 0, False: 4]
  ------------------
 2482|      0|    io_cb->close(fp);
 2483|      0|  }
 2484|      4|  if (rc < 0) {
  ------------------
  |  Branch (2484:7): [True: 0, False: 4]
  ------------------
 2485|      0|    if (*needs_free) {
  ------------------
  |  Branch (2485:9): [True: 0, False: 0]
  ------------------
 2486|      0|      free(*chunk);
 2487|      0|      *chunk = NULL;
 2488|      0|      *needs_free = false;
 2489|      0|    }
 2490|      0|    return rc;
 2491|      0|  }
 2492|       |
 2493|      4|  return (int)lazychunk_cbytes;
 2494|      4|}
frame_decompress_chunk:
 3716|      4|int frame_decompress_chunk(blosc2_context *dctx, blosc2_frame_s* frame, int64_t nchunk, void *dest, int32_t nbytes) {
 3717|      4|  uint8_t* src;
 3718|      4|  bool needs_free;
 3719|      4|  int32_t chunk_nbytes;
 3720|      4|  int32_t chunk_cbytes;
 3721|      4|  int rc;
 3722|       |
 3723|       |  // Use a lazychunk here in order to do a potential parallel read.
 3724|      4|  rc = frame_get_lazychunk(frame, nchunk, &src, &needs_free);
 3725|      4|  if (rc < 0) {
  ------------------
  |  Branch (3725:7): [True: 0, False: 4]
  ------------------
 3726|      0|    BLOSC_TRACE_ERROR("Cannot get the chunk in position %" PRId64 ".", nchunk);
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3727|      0|    goto end;
 3728|      0|  }
 3729|      4|  chunk_cbytes = rc;
 3730|      4|  if (chunk_cbytes < (signed)sizeof(int32_t)) {
  ------------------
  |  Branch (3730:7): [True: 0, False: 4]
  ------------------
 3731|       |    /* Not enough input to read `nbytes` */
 3732|      0|    rc = BLOSC2_ERROR_READ_BUFFER;
 3733|      0|  }
 3734|       |
 3735|      4|  rc = blosc2_cbuffer_sizes(src, &chunk_nbytes, &chunk_cbytes, NULL);
 3736|      4|  if (rc < 0) {
  ------------------
  |  Branch (3736:7): [True: 0, False: 4]
  ------------------
 3737|      0|    goto end;
 3738|      0|  }
 3739|       |
 3740|       |  /* Create a buffer for destination */
 3741|      4|  if (chunk_nbytes > nbytes) {
  ------------------
  |  Branch (3741:7): [True: 0, False: 4]
  ------------------
 3742|      0|    BLOSC_TRACE_ERROR("Not enough space for decompressing in dest.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3743|      0|    rc = BLOSC2_ERROR_WRITE_BUFFER;
 3744|      0|    goto end;
 3745|      0|  }
 3746|       |  /* And decompress it */
 3747|      4|  dctx->header_overhead = BLOSC_EXTENDED_HEADER_LENGTH;
 3748|      4|  int chunksize = rc = blosc2_decompress_ctx(dctx, src, chunk_cbytes, dest, nbytes);
 3749|      4|  if (chunksize < 0 || chunksize != chunk_nbytes) {
  ------------------
  |  Branch (3749:7): [True: 1, False: 3]
  |  Branch (3749:24): [True: 0, False: 3]
  ------------------
 3750|      1|    BLOSC_TRACE_ERROR("Error in decompressing chunk.");
  ------------------
  |  |   97|      1|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      1|    do {                                            \
  |  |  |  |  102|      1|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      1|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 1, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      1|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3751|      1|    if (chunksize >= 0)
  ------------------
  |  Branch (3751:9): [True: 0, False: 1]
  ------------------
 3752|      0|      rc = BLOSC2_ERROR_FAILURE;
 3753|      1|  }
 3754|      4|  end:
 3755|      4|  if (needs_free) {
  ------------------
  |  Branch (3755:7): [True: 1, False: 3]
  ------------------
 3756|      1|    free(src);
 3757|      1|  }
 3758|      4|  return rc;
 3759|      4|}
frame.c:get_meta_from_header:
 1342|      1|                                int32_t header_len) {
 1343|      1|  BLOSC_UNUSED_PARAM(frame);
  ------------------
  |  |   28|      1|#define BLOSC_UNUSED_PARAM(x) ((void)(x))
  ------------------
 1344|      1|  int64_t header_pos = FRAME_IDX_SIZE;
  ------------------
  |  |   45|      1|#define FRAME_IDX_SIZE (FRAME_METALAYERS + 1 + 1)  // 89
  |  |  ------------------
  |  |  |  |   44|      1|#define FRAME_METALAYERS (FRAME_HEADER_MINLEN)  // 87
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|      1|#define FRAME_HEADER_MINLEN (FRAME_FILTER_PIPELINE + 1 + 16)  // 87 <- minimum length
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   40|      1|#define FRAME_FILTER_PIPELINE (FRAME_HAS_VLMETALAYERS + 1 + 1) // 70
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   39|      1|#define FRAME_HAS_VLMETALAYERS (FRAME_NTHREADS_D + 2)  // 68
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      1|#define FRAME_NTHREADS_D (FRAME_NTHREADS_C + 2 + 1)  // 66
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      1|#define FRAME_NTHREADS_C (FRAME_CHUNKSIZE + 4 + 1)  // 63
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   36|      1|#define FRAME_CHUNKSIZE (FRAME_BLOCKSIZE + 4 + 1)  // 58
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   35|      1|#define FRAME_BLOCKSIZE (FRAME_TYPESIZE + 4 + 1)  // 53
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   34|      1|#define FRAME_TYPESIZE (FRAME_CBYTES + 8 + 1) // 48
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   33|      1|#define FRAME_CBYTES (FRAME_NBYTES + 8 + 1)  // 39
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   32|      1|#define FRAME_NBYTES (FRAME_FLAGS + 4 + 1)  // 30
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   28|      1|#define FRAME_FLAGS (FRAME_LEN + 8 + 1)  // 25
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   27|      1|#define FRAME_LEN (FRAME_HEADER_LEN + 4 + 1)  // 16
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   26|      1|#define FRAME_HEADER_LEN (FRAME_HEADER_MAGIC + 8 + 1)  // 11
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   25|      1|#define FRAME_HEADER_MAGIC 2
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1345|       |
 1346|       |  // Get the size for the index of metalayers
 1347|      1|  uint16_t idx_size;
 1348|      1|  header_pos += sizeof(idx_size);
 1349|      1|  if (header_len < header_pos) {
  ------------------
  |  Branch (1349:7): [True: 0, False: 1]
  ------------------
 1350|      0|    return BLOSC2_ERROR_READ_BUFFER;
 1351|      0|  }
 1352|      1|  from_big(&idx_size, header + FRAME_IDX_SIZE, sizeof(idx_size));
  ------------------
  |  |   31|      1|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
 1353|       |
 1354|       |  // Get the actual index of metalayers
 1355|      1|  uint8_t* metalayers_idx = header + FRAME_IDX_SIZE + 2;
  ------------------
  |  |   45|      1|#define FRAME_IDX_SIZE (FRAME_METALAYERS + 1 + 1)  // 89
  |  |  ------------------
  |  |  |  |   44|      1|#define FRAME_METALAYERS (FRAME_HEADER_MINLEN)  // 87
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|      1|#define FRAME_HEADER_MINLEN (FRAME_FILTER_PIPELINE + 1 + 16)  // 87 <- minimum length
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   40|      1|#define FRAME_FILTER_PIPELINE (FRAME_HAS_VLMETALAYERS + 1 + 1) // 70
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   39|      1|#define FRAME_HAS_VLMETALAYERS (FRAME_NTHREADS_D + 2)  // 68
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      1|#define FRAME_NTHREADS_D (FRAME_NTHREADS_C + 2 + 1)  // 66
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      1|#define FRAME_NTHREADS_C (FRAME_CHUNKSIZE + 4 + 1)  // 63
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   36|      1|#define FRAME_CHUNKSIZE (FRAME_BLOCKSIZE + 4 + 1)  // 58
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   35|      1|#define FRAME_BLOCKSIZE (FRAME_TYPESIZE + 4 + 1)  // 53
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   34|      1|#define FRAME_TYPESIZE (FRAME_CBYTES + 8 + 1) // 48
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   33|      1|#define FRAME_CBYTES (FRAME_NBYTES + 8 + 1)  // 39
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   32|      1|#define FRAME_NBYTES (FRAME_FLAGS + 4 + 1)  // 30
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   28|      1|#define FRAME_FLAGS (FRAME_LEN + 8 + 1)  // 25
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   27|      1|#define FRAME_LEN (FRAME_HEADER_LEN + 4 + 1)  // 16
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   26|      1|#define FRAME_HEADER_LEN (FRAME_HEADER_MAGIC + 8 + 1)  // 11
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   25|      1|#define FRAME_HEADER_MAGIC 2
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1356|      1|  header_pos += 1;
 1357|      1|  if (header_len < header_pos) {
  ------------------
  |  Branch (1357:7): [True: 0, False: 1]
  ------------------
 1358|      0|    return BLOSC2_ERROR_READ_BUFFER;
 1359|      0|  }
 1360|      1|  if (metalayers_idx[0] != 0xde) {   // sanity check
  ------------------
  |  Branch (1360:7): [True: 0, False: 1]
  ------------------
 1361|      0|    return BLOSC2_ERROR_DATA;
 1362|      0|  }
 1363|      1|  uint8_t* idxp = metalayers_idx + 1;
 1364|      1|  uint16_t nmetalayers;
 1365|      1|  header_pos += sizeof(nmetalayers);
 1366|      1|  if (header_len < header_pos) {
  ------------------
  |  Branch (1366:7): [True: 0, False: 1]
  ------------------
 1367|      0|    return BLOSC2_ERROR_READ_BUFFER;
 1368|      0|  }
 1369|      1|  from_big(&nmetalayers, idxp, sizeof(uint16_t));
  ------------------
  |  |   31|      1|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
 1370|      1|  idxp += 2;
 1371|      1|  if (nmetalayers > BLOSC2_MAX_METALAYERS) {
  ------------------
  |  | 1640|      1|#define BLOSC2_MAX_METALAYERS 16
  ------------------
  |  Branch (1371:7): [True: 0, False: 1]
  ------------------
 1372|      0|    return BLOSC2_ERROR_DATA;
 1373|      0|  }
 1374|      1|  schunk->nmetalayers = nmetalayers;
 1375|       |
 1376|       |  // Populate the metalayers and its serialized values
 1377|      1|  for (int nmetalayer = 0; nmetalayer < nmetalayers; nmetalayer++) {
  ------------------
  |  Branch (1377:28): [True: 0, False: 1]
  ------------------
 1378|      0|    header_pos += 1;
 1379|      0|    if (header_len < header_pos) {
  ------------------
  |  Branch (1379:9): [True: 0, False: 0]
  ------------------
 1380|      0|      return BLOSC2_ERROR_READ_BUFFER;
 1381|      0|    }
 1382|      0|    if ((*idxp & 0xe0u) != 0xa0u) {   // sanity check
  ------------------
  |  Branch (1382:9): [True: 0, False: 0]
  ------------------
 1383|      0|      return BLOSC2_ERROR_DATA;
 1384|      0|    }
 1385|      0|    blosc2_metalayer* metalayer = calloc(1, sizeof(blosc2_metalayer));
 1386|      0|    schunk->metalayers[nmetalayer] = metalayer;
 1387|       |
 1388|       |    // Populate the metalayer string
 1389|      0|    uint8_t nslen = *idxp & (uint8_t)0x1F;
 1390|      0|    idxp += 1;
 1391|      0|    header_pos += nslen;
 1392|      0|    if (header_len < header_pos) {
  ------------------
  |  Branch (1392:9): [True: 0, False: 0]
  ------------------
 1393|      0|      return BLOSC2_ERROR_READ_BUFFER;
 1394|      0|    }
 1395|      0|    char* ns = malloc((size_t)nslen + 1);
 1396|      0|    memcpy(ns, idxp, nslen);
 1397|      0|    ns[nslen] = '\0';
 1398|      0|    idxp += nslen;
 1399|      0|    metalayer->name = ns;
 1400|       |
 1401|       |    // Populate the serialized value for this metalayer
 1402|       |    // Get the offset
 1403|      0|    header_pos += 1;
 1404|      0|    if (header_len < header_pos) {
  ------------------
  |  Branch (1404:9): [True: 0, False: 0]
  ------------------
 1405|      0|      return BLOSC2_ERROR_READ_BUFFER;
 1406|      0|    }
 1407|      0|    if ((*idxp & 0xffu) != 0xd2u) {   // sanity check
  ------------------
  |  Branch (1407:9): [True: 0, False: 0]
  ------------------
 1408|      0|      return BLOSC2_ERROR_DATA;
 1409|      0|    }
 1410|      0|    idxp += 1;
 1411|      0|    int32_t offset;
 1412|      0|    header_pos += sizeof(offset);
 1413|      0|    if (header_len < header_pos) {
  ------------------
  |  Branch (1413:9): [True: 0, False: 0]
  ------------------
 1414|      0|      return BLOSC2_ERROR_READ_BUFFER;
 1415|      0|    }
 1416|      0|    from_big(&offset, idxp, sizeof(offset));
  ------------------
  |  |   31|      0|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
 1417|      0|    idxp += 4;
 1418|      0|    if (offset < 0 || offset >= header_len) {
  ------------------
  |  Branch (1418:9): [True: 0, False: 0]
  |  Branch (1418:23): [True: 0, False: 0]
  ------------------
 1419|       |      // Offset is less than zero or exceeds header length
 1420|      0|      return BLOSC2_ERROR_DATA;
 1421|      0|    }
 1422|       |    // Go to offset and see if we have the correct marker
 1423|      0|    uint8_t* content_marker = header + offset;
 1424|      0|    if (header_len < offset + 1 + 4) {
  ------------------
  |  Branch (1424:9): [True: 0, False: 0]
  ------------------
 1425|      0|      return BLOSC2_ERROR_READ_BUFFER;
 1426|      0|    }
 1427|      0|    if (*content_marker != 0xc6) {
  ------------------
  |  Branch (1427:9): [True: 0, False: 0]
  ------------------
 1428|      0|      return BLOSC2_ERROR_DATA;
 1429|      0|    }
 1430|       |
 1431|       |    // Read the size of the content
 1432|      0|    int32_t content_len;
 1433|      0|    from_big(&content_len, content_marker + 1, sizeof(content_len));
  ------------------
  |  |   31|      0|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
 1434|      0|    if (content_len < 0) {
  ------------------
  |  Branch (1434:9): [True: 0, False: 0]
  ------------------
 1435|      0|      return BLOSC2_ERROR_DATA;
 1436|      0|    }
 1437|      0|    metalayer->content_len = content_len;
 1438|       |
 1439|       |    // Finally, read the content
 1440|      0|    if (header_len < offset + 1 + 4 + content_len) {
  ------------------
  |  Branch (1440:9): [True: 0, False: 0]
  ------------------
 1441|      0|      return BLOSC2_ERROR_READ_BUFFER;
 1442|      0|    }
 1443|      0|    char* content = malloc((size_t)content_len);
 1444|      0|    memcpy(content, content_marker + 1 + 4, (size_t)content_len);
 1445|      0|    metalayer->content = (uint8_t*)content;
 1446|      0|  }
 1447|       |
 1448|      1|  return 1;
 1449|      1|}
frame.c:get_vlmeta_from_trailer:
 1529|      1|                                   int32_t trailer_len) {
 1530|       |
 1531|      1|  BLOSC_UNUSED_PARAM(frame);
  ------------------
  |  |   28|      1|#define BLOSC_UNUSED_PARAM(x) ((void)(x))
  ------------------
 1532|      1|  int64_t trailer_pos = FRAME_TRAILER_VLMETALAYERS + 2;
  ------------------
  |  |   54|      1|#define FRAME_TRAILER_VLMETALAYERS (2)
  ------------------
 1533|      1|  uint8_t* idxp = trailer + trailer_pos;
 1534|       |
 1535|       |  // Get the size for the index of metalayers
 1536|      1|  trailer_pos += 2;
 1537|      1|  if (trailer_len < trailer_pos) {
  ------------------
  |  Branch (1537:7): [True: 0, False: 1]
  ------------------
 1538|      0|    return BLOSC2_ERROR_READ_BUFFER;
 1539|      0|  }
 1540|      1|  uint16_t idx_size;
 1541|      1|  from_big(&idx_size, idxp, sizeof(idx_size));
  ------------------
  |  |   31|      1|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
 1542|      1|  idxp += 2;
 1543|       |
 1544|      1|  trailer_pos += 1;
 1545|       |  // Get the actual index of metalayers
 1546|      1|  if (trailer_len < trailer_pos) {
  ------------------
  |  Branch (1546:7): [True: 0, False: 1]
  ------------------
 1547|      0|    return BLOSC2_ERROR_READ_BUFFER;
 1548|      0|  }
 1549|      1|  if (idxp[0] != 0xde) {   // sanity check
  ------------------
  |  Branch (1549:7): [True: 0, False: 1]
  ------------------
 1550|      0|    return BLOSC2_ERROR_DATA;
 1551|      0|  }
 1552|      1|  idxp += 1;
 1553|       |
 1554|      1|  int16_t nmetalayers;
 1555|      1|  trailer_pos += sizeof(nmetalayers);
 1556|      1|  if (trailer_len < trailer_pos) {
  ------------------
  |  Branch (1556:7): [True: 0, False: 1]
  ------------------
 1557|      0|    return BLOSC2_ERROR_READ_BUFFER;
 1558|      0|  }
 1559|      1|  from_big(&nmetalayers, idxp, sizeof(uint16_t));
  ------------------
  |  |   31|      1|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
 1560|      1|  idxp += 2;
 1561|      1|  if (nmetalayers > BLOSC2_MAX_VLMETALAYERS) {
  ------------------
  |  | 1646|      1|#define BLOSC2_MAX_VLMETALAYERS (8 * 1024)
  ------------------
  |  Branch (1561:7): [True: 0, False: 1]
  ------------------
 1562|      0|    return BLOSC2_ERROR_DATA;
 1563|      0|  }
 1564|      1|  schunk->nvlmetalayers = nmetalayers;
 1565|       |
 1566|       |  // Populate the metalayers and its serialized values
 1567|      2|  for (int nmetalayer = 0; nmetalayer < nmetalayers; nmetalayer++) {
  ------------------
  |  Branch (1567:28): [True: 1, False: 1]
  ------------------
 1568|      1|    trailer_pos += 1;
 1569|      1|    if (trailer_len < trailer_pos) {
  ------------------
  |  Branch (1569:9): [True: 0, False: 1]
  ------------------
 1570|      0|      return BLOSC2_ERROR_READ_BUFFER;
 1571|      0|    }
 1572|      1|    if ((*idxp & 0xe0u) != 0xa0u) {   // sanity check
  ------------------
  |  Branch (1572:9): [True: 0, False: 1]
  ------------------
 1573|      0|      return BLOSC2_ERROR_DATA;
 1574|      0|    }
 1575|      1|    blosc2_metalayer* metalayer = calloc(1, sizeof(blosc2_metalayer));
 1576|      1|    schunk->vlmetalayers[nmetalayer] = metalayer;
 1577|       |
 1578|       |    // Populate the metalayer string
 1579|      1|    uint8_t nslen = *idxp & (uint8_t)0x1F;
 1580|      1|    idxp += 1;
 1581|      1|    trailer_pos += nslen;
 1582|      1|    if (trailer_len < trailer_pos) {
  ------------------
  |  Branch (1582:9): [True: 0, False: 1]
  ------------------
 1583|      0|      return BLOSC2_ERROR_READ_BUFFER;
 1584|      0|    }
 1585|      1|    char* ns = malloc((size_t)nslen + 1);
 1586|      1|    memcpy(ns, idxp, nslen);
 1587|      1|    ns[nslen] = '\0';
 1588|      1|    idxp += nslen;
 1589|      1|    metalayer->name = ns;
 1590|       |
 1591|       |    // Populate the serialized value for this metalayer
 1592|       |    // Get the offset
 1593|      1|    trailer_pos += 1;
 1594|      1|    if (trailer_len < trailer_pos) {
  ------------------
  |  Branch (1594:9): [True: 0, False: 1]
  ------------------
 1595|      0|      return BLOSC2_ERROR_READ_BUFFER;
 1596|      0|    }
 1597|      1|    if ((*idxp & 0xffu) != 0xd2u) {   // sanity check
  ------------------
  |  Branch (1597:9): [True: 0, False: 1]
  ------------------
 1598|      0|      return BLOSC2_ERROR_DATA;
 1599|      0|    }
 1600|      1|    idxp += 1;
 1601|      1|    int32_t offset;
 1602|      1|    trailer_pos += sizeof(offset);
 1603|      1|    if (trailer_len < trailer_pos) {
  ------------------
  |  Branch (1603:9): [True: 0, False: 1]
  ------------------
 1604|      0|      return BLOSC2_ERROR_READ_BUFFER;
 1605|      0|    }
 1606|      1|    from_big(&offset, idxp, sizeof(offset));
  ------------------
  |  |   31|      1|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
 1607|      1|    idxp += 4;
 1608|      1|    if (offset < 0 || offset >= trailer_len) {
  ------------------
  |  Branch (1608:9): [True: 0, False: 1]
  |  Branch (1608:23): [True: 0, False: 1]
  ------------------
 1609|       |      // Offset is less than zero or exceeds trailer length
 1610|      0|      return BLOSC2_ERROR_DATA;
 1611|      0|    }
 1612|       |    // Go to offset and see if we have the correct marker
 1613|      1|    uint8_t* content_marker = trailer + offset;
 1614|      1|    if (trailer_len < offset + 1 + 4) {
  ------------------
  |  Branch (1614:9): [True: 0, False: 1]
  ------------------
 1615|      0|      return BLOSC2_ERROR_READ_BUFFER;
 1616|      0|    }
 1617|      1|    if (*content_marker != 0xc6) {
  ------------------
  |  Branch (1617:9): [True: 0, False: 1]
  ------------------
 1618|      0|      return BLOSC2_ERROR_DATA;
 1619|      0|    }
 1620|       |
 1621|       |    // Read the size of the content
 1622|      1|    int32_t content_len;
 1623|      1|    from_big(&content_len, content_marker + 1, sizeof(content_len));
  ------------------
  |  |   31|      1|#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
  ------------------
 1624|      1|    if (content_len < 0) {
  ------------------
  |  Branch (1624:9): [True: 0, False: 1]
  ------------------
 1625|      0|      return BLOSC2_ERROR_DATA;
 1626|      0|    }
 1627|      1|    metalayer->content_len = content_len;
 1628|       |
 1629|       |    // Finally, read the content
 1630|      1|    if (trailer_len < offset + 1 + 4 + content_len) {
  ------------------
  |  Branch (1630:9): [True: 0, False: 1]
  ------------------
 1631|      0|      return BLOSC2_ERROR_READ_BUFFER;
 1632|      0|    }
 1633|      1|    char* content = malloc((size_t)content_len);
 1634|      1|    memcpy(content, content_marker + 1 + 4, (size_t)content_len);
 1635|      1|    metalayer->content = (uint8_t*)content;
 1636|      1|  }
 1637|      1|  return 1;
 1638|      1|}

blosc2_schunk_get_cparams:
   39|      1|int blosc2_schunk_get_cparams(blosc2_schunk *schunk, blosc2_cparams **cparams) {
   40|      1|  *cparams = calloc(1, sizeof(blosc2_cparams));
   41|      1|  (*cparams)->schunk = schunk;
   42|      7|  for (int i = 0; i < BLOSC2_MAX_FILTERS; i++) {
  ------------------
  |  Branch (42:19): [True: 6, False: 1]
  ------------------
   43|      6|    (*cparams)->filters[i] = schunk->filters[i];
   44|      6|    (*cparams)->filters_meta[i] = schunk->filters_meta[i];
   45|      6|  }
   46|      1|  (*cparams)->compcode = schunk->compcode;
   47|      1|  (*cparams)->compcode_meta = schunk->compcode_meta;
   48|      1|  (*cparams)->clevel = schunk->clevel;
   49|      1|  (*cparams)->typesize = schunk->typesize;
   50|      1|  (*cparams)->blocksize = schunk->blocksize;
   51|      1|  (*cparams)->splitmode = schunk->splitmode;
   52|      1|  if (schunk->cctx == NULL) {
  ------------------
  |  Branch (52:7): [True: 1, False: 0]
  ------------------
   53|      1|    (*cparams)->nthreads = blosc2_get_nthreads();
   54|      1|  }
   55|      0|  else {
   56|      0|    (*cparams)->nthreads = (int16_t)schunk->cctx->nthreads;
   57|      0|  }
   58|      1|  return 0;
   59|      1|}
blosc2_schunk_get_dparams:
   63|      1|int blosc2_schunk_get_dparams(blosc2_schunk *schunk, blosc2_dparams **dparams) {
   64|      1|  *dparams = calloc(1, sizeof(blosc2_dparams));
   65|      1|  (*dparams)->schunk = schunk;
   66|      1|  if (schunk->dctx == NULL) {
  ------------------
  |  Branch (66:7): [True: 1, False: 0]
  ------------------
   67|      1|    (*dparams)->nthreads = blosc2_get_nthreads();
   68|      1|  }
   69|      0|  else {
   70|      0|    (*dparams)->nthreads = schunk->dctx->nthreads;
   71|      0|  }
   72|      1|  return 0;
   73|      1|}
blosc2_schunk_free:
  486|      1|int blosc2_schunk_free(blosc2_schunk *schunk) {
  487|      1|  if (schunk->data != NULL) {
  ------------------
  |  Branch (487:7): [True: 0, False: 1]
  ------------------
  488|      0|    for (int i = 0; i < schunk->nchunks; i++) {
  ------------------
  |  Branch (488:21): [True: 0, False: 0]
  ------------------
  489|      0|      free(schunk->data[i]);
  490|      0|    }
  491|      0|    free(schunk->data);
  492|      0|  }
  493|      1|  if (schunk->cctx != NULL)
  ------------------
  |  Branch (493:7): [True: 1, False: 0]
  ------------------
  494|      1|    blosc2_free_ctx(schunk->cctx);
  495|      1|  if (schunk->dctx != NULL)
  ------------------
  |  Branch (495:7): [True: 1, False: 0]
  ------------------
  496|      1|    blosc2_free_ctx(schunk->dctx);
  497|      1|  if (schunk->blockshape != NULL)
  ------------------
  |  Branch (497:7): [True: 0, False: 1]
  ------------------
  498|      0|    free(schunk->blockshape);
  499|       |
  500|      1|  if (schunk->nmetalayers > 0) {
  ------------------
  |  Branch (500:7): [True: 0, False: 1]
  ------------------
  501|      0|    for (int i = 0; i < schunk->nmetalayers; i++) {
  ------------------
  |  Branch (501:21): [True: 0, False: 0]
  ------------------
  502|      0|      if (schunk->metalayers[i] != NULL) {
  ------------------
  |  Branch (502:11): [True: 0, False: 0]
  ------------------
  503|      0|        if (schunk->metalayers[i]->name != NULL)
  ------------------
  |  Branch (503:13): [True: 0, False: 0]
  ------------------
  504|      0|          free(schunk->metalayers[i]->name);
  505|      0|        if (schunk->metalayers[i]->content != NULL)
  ------------------
  |  Branch (505:13): [True: 0, False: 0]
  ------------------
  506|      0|          free(schunk->metalayers[i]->content);
  507|      0|        free(schunk->metalayers[i]);
  508|      0|      }
  509|      0|    }
  510|      0|    schunk->nmetalayers = 0;
  511|      0|  }
  512|       |
  513|      1|  if (schunk->storage != NULL) {
  ------------------
  |  Branch (513:7): [True: 1, False: 0]
  ------------------
  514|      1|    blosc2_io_cb *io_cb = blosc2_get_io_cb(schunk->storage->io->id);
  515|      1|    if (io_cb != NULL) {
  ------------------
  |  Branch (515:9): [True: 1, False: 0]
  ------------------
  516|      1|      int rc = io_cb->destroy(schunk->storage->io->params);
  517|      1|      if (rc < 0) {
  ------------------
  |  Branch (517:11): [True: 0, False: 1]
  ------------------
  518|      0|        BLOSC_TRACE_ERROR("Could not free the I/O resources.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  519|      0|      }
  520|      1|    }
  521|       |
  522|      1|    if (schunk->storage->urlpath != NULL) {
  ------------------
  |  Branch (522:9): [True: 0, False: 1]
  ------------------
  523|      0|      free(schunk->storage->urlpath);
  524|      0|    }
  525|      1|    free(schunk->storage->cparams);
  526|      1|    free(schunk->storage->dparams);
  527|      1|    free(schunk->storage->io);
  528|      1|    free(schunk->storage);
  529|      1|  }
  530|       |
  531|      1|  if (schunk->frame != NULL) {
  ------------------
  |  Branch (531:7): [True: 1, False: 0]
  ------------------
  532|      1|    frame_free((blosc2_frame_s *) schunk->frame);
  533|      1|  }
  534|       |
  535|      1|  if (schunk->nvlmetalayers > 0) {
  ------------------
  |  Branch (535:7): [True: 1, False: 0]
  ------------------
  536|      2|    for (int i = 0; i < schunk->nvlmetalayers; ++i) {
  ------------------
  |  Branch (536:21): [True: 1, False: 1]
  ------------------
  537|      1|      if (schunk->vlmetalayers[i] != NULL) {
  ------------------
  |  Branch (537:11): [True: 1, False: 0]
  ------------------
  538|      1|        if (schunk->vlmetalayers[i]->name != NULL)
  ------------------
  |  Branch (538:13): [True: 1, False: 0]
  ------------------
  539|      1|          free(schunk->vlmetalayers[i]->name);
  540|      1|        if (schunk->vlmetalayers[i]->content != NULL)
  ------------------
  |  Branch (540:13): [True: 1, False: 0]
  ------------------
  541|      1|          free(schunk->vlmetalayers[i]->content);
  542|      1|        free(schunk->vlmetalayers[i]);
  543|      1|      }
  544|      1|    }
  545|      1|  }
  546|       |
  547|      1|  free(schunk);
  548|       |
  549|      1|  return 0;
  550|      1|}
blosc2_schunk_from_buffer:
  554|      7|blosc2_schunk* blosc2_schunk_from_buffer(uint8_t *cframe, int64_t len, bool copy) {
  555|      7|  blosc2_frame_s* frame = frame_from_cframe(cframe, len, false);
  556|      7|  if (frame == NULL) {
  ------------------
  |  Branch (556:7): [True: 6, False: 1]
  ------------------
  557|      6|    return NULL;
  558|      6|  }
  559|       |  // Check that the buffer actually comes from a cframe
  560|      1|  char *magic_number = (char *)cframe;
  561|      1|  magic_number += FRAME_HEADER_MAGIC;
  ------------------
  |  |   25|      1|#define FRAME_HEADER_MAGIC 2
  ------------------
  562|      1|  if (strcmp(magic_number, "b2frame\0") != 0) {
  ------------------
  |  Branch (562:7): [True: 0, False: 1]
  ------------------
  563|      0|    frame_free(frame);
  564|      0|    return NULL;
  565|      0|  }
  566|      1|  blosc2_schunk* schunk = frame_to_schunk(frame, copy, &BLOSC2_IO_DEFAULTS);
  567|      1|  if (schunk && copy) {
  ------------------
  |  Branch (567:7): [True: 1, False: 0]
  |  Branch (567:17): [True: 0, False: 1]
  ------------------
  568|       |    // Super-chunk has its own copy of frame
  569|      0|    frame_free(frame);
  570|      0|  }
  571|      1|  return schunk;
  572|      1|}
blosc2_schunk_decompress_chunk:
 1062|      4|                                   void *dest, int32_t nbytes) {
 1063|      4|  int32_t chunk_nbytes;
 1064|      4|  int32_t chunk_cbytes;
 1065|      4|  int chunksize;
 1066|      4|  int rc;
 1067|      4|  blosc2_frame_s* frame = (blosc2_frame_s*)schunk->frame;
 1068|       |
 1069|      4|  schunk->current_nchunk = nchunk;
 1070|      4|  if (frame == NULL) {
  ------------------
  |  Branch (1070:7): [True: 0, False: 4]
  ------------------
 1071|      0|    if (nchunk >= schunk->nchunks) {
  ------------------
  |  Branch (1071:9): [True: 0, False: 0]
  ------------------
 1072|      0|      BLOSC_TRACE_ERROR("nchunk ('%" PRId64 "') exceeds the number of chunks "
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1073|      0|                        "('%" PRId64 "') in super-chunk.", nchunk, schunk->nchunks);
 1074|      0|      return BLOSC2_ERROR_INVALID_PARAM;
 1075|      0|    }
 1076|      0|    uint8_t* src = schunk->data[nchunk];
 1077|      0|    if (src == 0) {
  ------------------
  |  Branch (1077:9): [True: 0, False: 0]
  ------------------
 1078|      0|      return 0;
 1079|      0|    }
 1080|       |
 1081|      0|    rc = blosc2_cbuffer_sizes(src, &chunk_nbytes, &chunk_cbytes, NULL);
 1082|      0|    if (rc < 0) {
  ------------------
  |  Branch (1082:9): [True: 0, False: 0]
  ------------------
 1083|      0|      return rc;
 1084|      0|    }
 1085|       |
 1086|      0|    if (nbytes < chunk_nbytes) {
  ------------------
  |  Branch (1086:9): [True: 0, False: 0]
  ------------------
 1087|      0|      BLOSC_TRACE_ERROR("Buffer size is too small for the decompressed buffer "
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1088|      0|                        "('%d' bytes, but '%d' are needed).", nbytes, chunk_nbytes);
 1089|      0|      return BLOSC2_ERROR_INVALID_PARAM;
 1090|      0|    }
 1091|       |
 1092|      0|    chunksize = blosc2_decompress_ctx(schunk->dctx, src, chunk_cbytes, dest, nbytes);
 1093|      0|    if (chunksize < 0 || chunksize != chunk_nbytes) {
  ------------------
  |  Branch (1093:9): [True: 0, False: 0]
  |  Branch (1093:26): [True: 0, False: 0]
  ------------------
 1094|      0|      BLOSC_TRACE_ERROR("Error in decompressing chunk.");
  ------------------
  |  |   97|      0|#define BLOSC_TRACE_ERROR(msg, ...) BLOSC_TRACE(error, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1095|      0|      if (chunksize < 0)
  ------------------
  |  Branch (1095:11): [True: 0, False: 0]
  ------------------
 1096|      0|        return chunksize;
 1097|      0|      return BLOSC2_ERROR_FAILURE;
 1098|      0|    }
 1099|      4|  } else {
 1100|      4|    chunksize = frame_decompress_chunk(schunk->dctx, frame, nchunk, dest, nbytes);
 1101|      4|    if (chunksize < 0) {
  ------------------
  |  Branch (1101:9): [True: 1, False: 3]
  ------------------
 1102|      1|      return chunksize;
 1103|      1|    }
 1104|      4|  }
 1105|      3|  return chunksize;
 1106|      4|}

unshuffle_avx2:
  693|      4|               const uint8_t *_src, uint8_t *_dest) {
  694|      4|  const int32_t vectorized_chunk_size = bytesoftype * (int32_t)sizeof(__m256i);
  695|       |
  696|       |  /* If the block size is too small to be vectorized,
  697|       |     use the generic implementation. */
  698|      4|  if (blocksize < vectorized_chunk_size) {
  ------------------
  |  Branch (698:7): [True: 0, False: 4]
  ------------------
  699|      0|    unshuffle_generic(bytesoftype, blocksize, _src, _dest);
  700|      0|    return;
  701|      0|  }
  702|       |
  703|       |  /* If the blocksize is not a multiple of both the typesize and
  704|       |     the vector size, round the blocksize down to the next value
  705|       |     which is a multiple of both. The vectorized unshuffle can be
  706|       |     used for that portion of the data, and the naive implementation
  707|       |     can be used for the remaining portion. */
  708|      4|  const int32_t vectorizable_bytes = blocksize - (blocksize % vectorized_chunk_size);
  709|       |
  710|      4|  const int32_t vectorizable_elements = vectorizable_bytes / bytesoftype;
  711|      4|  const int32_t total_elements = blocksize / bytesoftype;
  712|       |
  713|       |  /* Optimized unshuffle implementations */
  714|      4|  switch (bytesoftype) {
  715|      0|    case 2:
  ------------------
  |  Branch (715:5): [True: 0, False: 4]
  ------------------
  716|      0|      unshuffle2_avx2(_dest, _src, vectorizable_elements, total_elements);
  717|      0|      break;
  718|      4|    case 4:
  ------------------
  |  Branch (718:5): [True: 4, False: 0]
  ------------------
  719|      4|      unshuffle4_avx2(_dest, _src, vectorizable_elements, total_elements);
  720|      4|      break;
  721|      0|    case 8:
  ------------------
  |  Branch (721:5): [True: 0, False: 4]
  ------------------
  722|      0|      unshuffle8_avx2(_dest, _src, vectorizable_elements, total_elements);
  723|      0|      break;
  724|      0|    case 16:
  ------------------
  |  Branch (724:5): [True: 0, False: 4]
  ------------------
  725|      0|      unshuffle16_avx2(_dest, _src, vectorizable_elements, total_elements);
  726|      0|      break;
  727|      0|    default:
  ------------------
  |  Branch (727:5): [True: 0, False: 4]
  ------------------
  728|       |      /* For types larger than 16 bytes, use the AVX2 tiled unshuffle. */
  729|      0|      if (bytesoftype > (int32_t)sizeof(__m128i)) {
  ------------------
  |  Branch (729:11): [True: 0, False: 0]
  ------------------
  730|      0|        unshuffle16_tiled_avx2(_dest, _src, vectorizable_elements, total_elements, bytesoftype);
  731|      0|      }
  732|      0|      else {
  733|       |        /* Non-optimized unshuffle */
  734|      0|        unshuffle_generic(bytesoftype, blocksize, _src, _dest);
  735|       |        /* The non-optimized function covers the whole buffer,
  736|       |           so we're done processing here. */
  737|      0|        return;
  738|      0|      }
  739|      4|  }
  740|       |
  741|       |  /* If the buffer had any bytes at the end which couldn't be handled
  742|       |     by the vectorized implementations, use the non-optimized version
  743|       |     to finish them up. */
  744|      4|  if (vectorizable_bytes < blocksize) {
  ------------------
  |  Branch (744:7): [True: 2, False: 2]
  ------------------
  745|      2|    unshuffle_generic_inline(bytesoftype, vectorizable_bytes, blocksize, _src, _dest);
  746|      2|  }
  747|      4|}
shuffle-avx2.c:unshuffle4_avx2:
  357|      4|                const int32_t vectorizable_elements, const int32_t total_elements) {
  358|      4|  static const int32_t bytesoftype = 4;
  359|      4|  int32_t i;
  360|      4|  int j;
  361|      4|  __m256i ymm0[4], ymm1[4];
  362|       |
  363|  3.12k|  for (i = 0; i < vectorizable_elements; i += sizeof(__m256i)) {
  ------------------
  |  Branch (363:15): [True: 3.12k, False: 4]
  ------------------
  364|       |    /* Load 32 elements (128 bytes) into 4 YMM registers. */
  365|  3.12k|    const uint8_t* const src_for_ith_element = src + i;
  366|  15.6k|    for (j = 0; j < 4; j++) {
  ------------------
  |  Branch (366:17): [True: 12.4k, False: 3.12k]
  ------------------
  367|  12.4k|      ymm0[j] = _mm256_loadu_si256((__m256i*)(src_for_ith_element + (j * total_elements)));
  368|  12.4k|    }
  369|       |    /* Shuffle bytes */
  370|  9.37k|    for (j = 0; j < 2; j++) {
  ------------------
  |  Branch (370:17): [True: 6.24k, False: 3.12k]
  ------------------
  371|       |      /* Compute the low 64 bytes */
  372|  6.24k|      ymm1[j] = _mm256_unpacklo_epi8(ymm0[j * 2], ymm0[j * 2 + 1]);
  373|       |      /* Compute the hi 64 bytes */
  374|  6.24k|      ymm1[2 + j] = _mm256_unpackhi_epi8(ymm0[j * 2], ymm0[j * 2 + 1]);
  375|  6.24k|    }
  376|       |    /* Shuffle 2-byte words */
  377|  9.37k|    for (j = 0; j < 2; j++) {
  ------------------
  |  Branch (377:17): [True: 6.24k, False: 3.12k]
  ------------------
  378|       |      /* Compute the low 64 bytes */
  379|  6.24k|      ymm0[j] = _mm256_unpacklo_epi16(ymm1[j * 2], ymm1[j * 2 + 1]);
  380|       |      /* Compute the hi 64 bytes */
  381|  6.24k|      ymm0[2 + j] = _mm256_unpackhi_epi16(ymm1[j * 2], ymm1[j * 2 + 1]);
  382|  6.24k|    }
  383|  3.12k|    ymm1[0] = _mm256_permute2x128_si256(ymm0[0], ymm0[2], 0x20);
  384|  3.12k|    ymm1[1] = _mm256_permute2x128_si256(ymm0[1], ymm0[3], 0x20);
  385|  3.12k|    ymm1[2] = _mm256_permute2x128_si256(ymm0[0], ymm0[2], 0x31);
  386|  3.12k|    ymm1[3] = _mm256_permute2x128_si256(ymm0[1], ymm0[3], 0x31);
  387|       |
  388|       |    /* Store the result vectors in proper order */
  389|  15.6k|    for (j = 0; j < 4; j++) {
  ------------------
  |  Branch (389:17): [True: 12.4k, False: 3.12k]
  ------------------
  390|  12.4k|      _mm256_storeu_si256((__m256i*)(dest + (i * bytesoftype) + (j * sizeof(__m256i))), ymm1[j]);
  391|  12.4k|    }
  392|  3.12k|  }
  393|      4|}

shuffle-avx2.c:unshuffle_generic_inline:
   64|      2|                                     const uint8_t *_src, uint8_t *_dest) {
   65|      2|  int32_t i, j;
   66|       |
   67|       |  /* Calculate the number of elements in the block. */
   68|      2|  const int32_t neblock_quot = blocksize / type_size;
   69|      2|  const int32_t neblock_rem = blocksize % type_size;
   70|      2|  const int32_t vectorizable_elements = vectorizable_blocksize / type_size;
   71|       |
   72|       |  /* Non-optimized unshuffle */
   73|     34|  for (i = vectorizable_elements; i < (int32_t)neblock_quot; i++) {
  ------------------
  |  Branch (73:35): [True: 32, False: 2]
  ------------------
   74|    160|    for (j = 0; j < type_size; j++) {
  ------------------
  |  Branch (74:17): [True: 128, False: 32]
  ------------------
   75|    128|      _dest[i * type_size + j] = _src[j * neblock_quot + i];
   76|    128|    }
   77|     32|  }
   78|       |
   79|       |  /* Copy any leftover bytes in the block without unshuffling them. */
   80|      2|  memcpy(_dest + (blocksize - neblock_rem), _src + (blocksize - neblock_rem), neblock_rem);
   81|      2|}

unshuffle:
  435|      4|          const uint8_t* _src, const uint8_t* _dest) {
  436|       |  /* Initialize the shuffle implementation if necessary. */
  437|      4|  init_shuffle_implementation();
  438|       |
  439|       |  /* The implementation is initialized.
  440|       |     Dispatch to it's unshuffle routine. */
  441|      4|  (host_implementation.unshuffle)(bytesoftype, blocksize, _src, _dest);
  442|      4|}
shuffle.c:init_shuffle_implementation:
  396|      4|void init_shuffle_implementation(void) {
  397|       |  /* Initialization could (in rare cases) take place concurrently on
  398|       |     multiple threads, but it shouldn't matter because the
  399|       |     initialization should return the same result on each thread (so
  400|       |     the implementation will be the same). Since that's the case we
  401|       |     can avoid complicated synchronization here and get a small
  402|       |     performance benefit because we don't need to perform a volatile
  403|       |     load on the initialization variable each time this function is
  404|       |     called. */
  405|      4|#if defined(__GNUC__) || defined(__clang__)
  406|      4|  if (__builtin_expect(!implementation_initialized, 0)) {
  ------------------
  |  Branch (406:7): [True: 1, False: 3]
  ------------------
  407|       |#else
  408|       |    if (!implementation_initialized) {
  409|       |#endif
  410|       |    /* Initialize the implementation. */
  411|      1|    host_implementation = get_shuffle_implementation();
  412|       |
  413|       |    /* Set the flag indicating the implementation has been initialized. */
  414|      1|    implementation_initialized = 1;
  415|      1|  }
  416|      4|}
shuffle.c:get_shuffle_implementation:
  297|      1|static shuffle_implementation_t get_shuffle_implementation(void) {
  298|      1|  blosc_cpu_features cpu_features = blosc_get_cpu_features();
  299|      1|#if defined(SHUFFLE_AVX512_ENABLED)
  300|      1|  if (cpu_features & BLOSC_HAVE_AVX512 && is_shuffle_avx2 && is_bshuf_AVX512) {
  ------------------
  |  Branch (300:7): [True: 0, False: 1]
  |  Branch (300:43): [True: 0, False: 0]
  |  Branch (300:62): [True: 0, False: 0]
  ------------------
  301|      0|    shuffle_implementation_t impl_avx512;
  302|      0|    impl_avx512.name = "avx512";
  303|      0|    impl_avx512.shuffle = (shuffle_func)shuffle_avx2;
  304|      0|    impl_avx512.unshuffle = (unshuffle_func)unshuffle_avx2;
  305|      0|    impl_avx512.bitshuffle = (bitshuffle_func) bshuf_trans_bit_elem_AVX512;
  306|      0|    impl_avx512.bitunshuffle = (bitunshuffle_func)bshuf_untrans_bit_elem_AVX512;
  307|      0|    return impl_avx512;
  308|      0|  }
  309|      1|#endif  /* defined(SHUFFLE_AVX512_ENABLED) */
  310|       |
  311|      1|#if defined(SHUFFLE_AVX2_ENABLED)
  312|      1|  if (cpu_features & BLOSC_HAVE_AVX2 && is_shuffle_avx2 && is_bshuf_AVX) {
  ------------------
  |  Branch (312:7): [True: 1, False: 0]
  |  Branch (312:41): [True: 1, False: 0]
  |  Branch (312:60): [True: 1, False: 0]
  ------------------
  313|      1|    shuffle_implementation_t impl_avx2;
  314|      1|    impl_avx2.name = "avx2";
  315|      1|    impl_avx2.shuffle = (shuffle_func)shuffle_avx2;
  316|      1|    impl_avx2.unshuffle = (unshuffle_func)unshuffle_avx2;
  317|      1|    impl_avx2.bitshuffle = (bitshuffle_func) bshuf_trans_bit_elem_AVX;
  318|      1|    impl_avx2.bitunshuffle = (bitunshuffle_func)bshuf_untrans_bit_elem_AVX;
  319|      1|    return impl_avx2;
  320|      1|  }
  321|      0|#endif  /* defined(SHUFFLE_AVX2_ENABLED) */
  322|       |
  323|      0|#if defined(SHUFFLE_SSE2_ENABLED)
  324|      0|  if (cpu_features & BLOSC_HAVE_SSE2 && is_shuffle_sse2 && is_bshuf_SSE) {
  ------------------
  |  Branch (324:7): [True: 0, False: 0]
  |  Branch (324:41): [True: 0, False: 0]
  |  Branch (324:60): [True: 0, False: 0]
  ------------------
  325|      0|    shuffle_implementation_t impl_sse2;
  326|      0|    impl_sse2.name = "sse2";
  327|      0|    impl_sse2.shuffle = (shuffle_func)shuffle_sse2;
  328|      0|    impl_sse2.unshuffle = (unshuffle_func)unshuffle_sse2;
  329|      0|    impl_sse2.bitshuffle = (bitshuffle_func)bshuf_trans_bit_elem_SSE;
  330|      0|    impl_sse2.bitunshuffle = (bitunshuffle_func) bshuf_untrans_bit_elem_SSE;
  331|      0|    return impl_sse2;
  332|      0|  }
  333|      0|#endif  /* defined(SHUFFLE_SSE2_ENABLED) */
  334|       |
  335|       |#if defined(SHUFFLE_NEON_ENABLED)
  336|       |  if (cpu_features & BLOSC_HAVE_NEON && is_shuffle_neon) { // && is_bshuf_NEON if using NEON bitshuffle
  337|       |    shuffle_implementation_t impl_neon;
  338|       |    impl_neon.name = "neon";
  339|       |    impl_neon.shuffle = (shuffle_func)shuffle_neon;
  340|       |    impl_neon.unshuffle = (unshuffle_func)unshuffle_neon;
  341|       |    //impl_neon.shuffle = (shuffle_func)shuffle_generic;
  342|       |    //impl_neon.unshuffle = (unshuffle_func)unshuffle_generic;
  343|       |    //impl_neon.bitshuffle = (bitshuffle_func)bshuf_trans_bit_elem_NEON;
  344|       |    //impl_neon.bitunshuffle = (bitunshuffle_func)bshuf_untrans_bit_elem_NEON;
  345|       |    // The current bitshuffle optimized for NEON is not any faster
  346|       |    // (in fact, it is pretty much slower) than the scalar implementation.
  347|       |    // So, let's use the scalar one, which is pretty fast, at least on a M1 CPU.
  348|       |    impl_neon.bitshuffle = (bitshuffle_func)bshuf_trans_bit_elem_scal;
  349|       |    impl_neon.bitunshuffle = (bitunshuffle_func)bshuf_untrans_bit_elem_scal;
  350|       |    return impl_neon;
  351|       |  }
  352|       |#endif  /* defined(SHUFFLE_NEON_ENABLED) */
  353|       |
  354|       |#if defined(SHUFFLE_ALTIVEC_ENABLED)
  355|       |  if (cpu_features & BLOSC_HAVE_ALTIVEC && is_shuffle_altivec && is_bshuf_altivec) {
  356|       |    shuffle_implementation_t impl_altivec;
  357|       |    impl_altivec.name = "altivec";
  358|       |    impl_altivec.shuffle = (shuffle_func)shuffle_altivec;
  359|       |    impl_altivec.unshuffle = (unshuffle_func)unshuffle_altivec;
  360|       |    impl_altivec.bitshuffle = (bitshuffle_func)bshuf_trans_bit_elem_altivec;
  361|       |    impl_altivec.bitunshuffle = (bitunshuffle_func)bshuf_untrans_bit_elem_altivec;
  362|       |    return impl_altivec;
  363|       |  }
  364|       |#endif  /* defined(SHUFFLE_ALTIVEC_ENABLED) */
  365|       |
  366|       |  /* Processor doesn't support any of the hardware-accelerated implementations,
  367|       |     so use the generic implementation. */
  368|      0|  shuffle_implementation_t impl_generic;
  369|      0|  impl_generic.name = "generic";
  370|      0|  impl_generic.shuffle = (shuffle_func)shuffle_generic;
  371|      0|  impl_generic.unshuffle = (unshuffle_func)unshuffle_generic;
  372|      0|  impl_generic.bitshuffle = (bitshuffle_func)bshuf_trans_bit_elem_scal;
  373|      0|  impl_generic.bitunshuffle = (bitunshuffle_func)bshuf_untrans_bit_elem_scal;
  374|      0|  return impl_generic;
  375|      0|}
shuffle.c:blosc_get_cpu_features:
   98|      1|static blosc_cpu_features blosc_get_cpu_features(void) {
   99|      1|  blosc_cpu_features cpu_features = BLOSC_HAVE_NOTHING;
  100|      1|  if (__builtin_cpu_supports("sse2")) {
  ------------------
  |  Branch (100:7): [True: 1, False: 0]
  ------------------
  101|      1|    cpu_features |= BLOSC_HAVE_SSE2;
  102|      1|  }
  103|      1|  if (__builtin_cpu_supports("avx2")) {
  ------------------
  |  Branch (103:7): [True: 1, False: 0]
  ------------------
  104|      1|    cpu_features |= BLOSC_HAVE_AVX2;
  105|      1|  }
  106|      1|  if (__builtin_cpu_supports("avx512f") && __builtin_cpu_supports("avx512bw")) {
  ------------------
  |  Branch (106:7): [True: 0, False: 1]
  |  Branch (106:44): [True: 0, False: 0]
  ------------------
  107|      0|    cpu_features |= BLOSC_HAVE_AVX512;
  108|      0|  }
  109|      1|  return cpu_features;
  110|      1|}

blosc_stune_next_blocksize:
   46|      1|int blosc_stune_next_blocksize(blosc2_context *context) {
   47|      1|  int32_t clevel = context->clevel;
   48|      1|  int32_t typesize = context->typesize;
   49|      1|  int32_t nbytes = context->sourcesize;
   50|      1|  int32_t user_blocksize = context->blocksize;
   51|      1|  int32_t blocksize = nbytes;
   52|       |
   53|       |  // Protection against very small buffers
   54|      1|  if (nbytes < typesize) {
  ------------------
  |  Branch (54:7): [True: 0, False: 1]
  ------------------
   55|      0|    context->blocksize = 1;
   56|      0|    return BLOSC2_ERROR_SUCCESS;
   57|      0|  }
   58|       |
   59|      1|  if (user_blocksize) {
  ------------------
  |  Branch (59:7): [True: 0, False: 1]
  ------------------
   60|      0|    blocksize = user_blocksize;
   61|      0|    goto last;
   62|      0|  }
   63|       |
   64|      1|  if (nbytes >= L1) {
  ------------------
  |  |   19|      1|#define L1 (32 * 1024)
  ------------------
  |  Branch (64:7): [True: 1, False: 0]
  ------------------
   65|      1|    blocksize = L1;
  ------------------
  |  |   19|      1|#define L1 (32 * 1024)
  ------------------
   66|       |
   67|       |    /* For HCR codecs, increase the block sizes by a factor of 2 because they
   68|       |        are meant for compressing large blocks (i.e. they show a big overhead
   69|       |        when compressing small ones). */
   70|      1|    if (is_HCR(context)) {
  ------------------
  |  Branch (70:9): [True: 0, False: 1]
  ------------------
   71|      0|      blocksize *= 2;
   72|      0|    }
   73|       |
   74|       |    // Choose a different blocksize depending on the compression level
   75|      1|    switch (clevel) {
   76|      0|      case 0:
  ------------------
  |  Branch (76:7): [True: 0, False: 1]
  ------------------
   77|       |        // Case of plain copy
   78|      0|        blocksize /= 4;
   79|      0|        break;
   80|      0|      case 1:
  ------------------
  |  Branch (80:7): [True: 0, False: 1]
  ------------------
   81|      0|        blocksize /= 2;
   82|      0|        break;
   83|      0|      case 2:
  ------------------
  |  Branch (83:7): [True: 0, False: 1]
  ------------------
   84|      0|        blocksize *= 1;
   85|      0|        break;
   86|      0|      case 3:
  ------------------
  |  Branch (86:7): [True: 0, False: 1]
  ------------------
   87|      0|        blocksize *= 2;
   88|      0|        break;
   89|      0|      case 4:
  ------------------
  |  Branch (89:7): [True: 0, False: 1]
  ------------------
   90|      1|      case 5:
  ------------------
  |  Branch (90:7): [True: 1, False: 0]
  ------------------
   91|      1|        blocksize *= 4;
   92|      1|        break;
   93|      0|      case 6:
  ------------------
  |  Branch (93:7): [True: 0, False: 1]
  ------------------
   94|      0|      case 7:
  ------------------
  |  Branch (94:7): [True: 0, False: 1]
  ------------------
   95|      0|      case 8:
  ------------------
  |  Branch (95:7): [True: 0, False: 1]
  ------------------
   96|      0|        blocksize *= 8;
   97|      0|        break;
   98|      0|      case 9:
  ------------------
  |  Branch (98:7): [True: 0, False: 1]
  ------------------
   99|       |        // Do not exceed 256 KB for non HCR codecs
  100|      0|        blocksize *= 8;
  101|      0|        if (is_HCR(context)) {
  ------------------
  |  Branch (101:13): [True: 0, False: 0]
  ------------------
  102|      0|          blocksize *= 2;
  103|      0|        }
  104|      0|        break;
  105|      0|      default:
  ------------------
  |  Branch (105:7): [True: 0, False: 1]
  ------------------
  106|      0|        break;
  107|      1|    }
  108|      1|  }
  109|       |
  110|       |  /* Now the blocksize for splittable codecs */
  111|      1|  int splitmode = split_block(context, typesize, blocksize);
  112|      1|  if (clevel > 0 && splitmode) {
  ------------------
  |  Branch (112:7): [True: 1, False: 0]
  |  Branch (112:21): [True: 1, False: 0]
  ------------------
  113|       |    // For performance reasons, do not exceed 256 KB (it must fit in L2 cache)
  114|      1|    switch (clevel) {
  115|      0|      case 1:
  ------------------
  |  Branch (115:7): [True: 0, False: 1]
  ------------------
  116|      0|      case 2:
  ------------------
  |  Branch (116:7): [True: 0, False: 1]
  ------------------
  117|      0|      case 3:
  ------------------
  |  Branch (117:7): [True: 0, False: 1]
  ------------------
  118|      0|        blocksize = 32 * 1024;
  119|      0|        break;
  120|      0|      case 4:
  ------------------
  |  Branch (120:7): [True: 0, False: 1]
  ------------------
  121|      1|      case 5:
  ------------------
  |  Branch (121:7): [True: 1, False: 0]
  ------------------
  122|      1|      case 6:
  ------------------
  |  Branch (122:7): [True: 0, False: 1]
  ------------------
  123|      1|        blocksize = 64 * 1024;
  124|      1|        break;
  125|      0|      case 7:
  ------------------
  |  Branch (125:7): [True: 0, False: 1]
  ------------------
  126|      0|        blocksize = 128 * 1024;
  127|      0|        break;
  128|      0|      case 8:
  ------------------
  |  Branch (128:7): [True: 0, False: 1]
  ------------------
  129|      0|        blocksize = 256 * 1024;
  130|      0|        break;
  131|      0|      case 9:
  ------------------
  |  Branch (131:7): [True: 0, False: 1]
  ------------------
  132|      0|      default:
  ------------------
  |  Branch (132:7): [True: 0, False: 1]
  ------------------
  133|      0|        blocksize = 512 * 1024;
  134|      0|        break;
  135|      1|    }
  136|       |    // Multiply by typesize to get proper split sizes
  137|      1|    blocksize *= typesize;
  138|       |    // But do not exceed 4 MB per thread (having this capacity in L3 is normal in modern CPUs)
  139|      1|    if (blocksize > 4 * 1024 * 1024) {
  ------------------
  |  Branch (139:9): [True: 0, False: 1]
  ------------------
  140|      0|      blocksize = 4 * 1024 * 1024;
  141|      0|    }
  142|      1|    if (blocksize < 32 * 1024) {
  ------------------
  |  Branch (142:9): [True: 0, False: 1]
  ------------------
  143|       |      /* Do not use a too small blocksize (< 32 KB) when typesize is small */
  144|      0|      blocksize = 32 * 1024;
  145|      0|    }
  146|      1|  }
  147|       |
  148|      1|  last:
  149|       |  /* Check that blocksize is not too large */
  150|      1|  if (blocksize > nbytes) {
  ------------------
  |  Branch (150:7): [True: 1, False: 0]
  ------------------
  151|      1|    blocksize = nbytes;
  152|      1|  }
  153|       |
  154|       |  // blocksize *must absolutely* be a multiple of the typesize
  155|      1|  if (blocksize > typesize) {
  ------------------
  |  Branch (155:7): [True: 1, False: 0]
  ------------------
  156|      1|    blocksize = blocksize / typesize * typesize;
  157|      1|  }
  158|       |
  159|      1|  context->blocksize = blocksize;
  160|      1|  BLOSC_INFO("compcode: %d, clevel: %d, blocksize: %d, splitmode: %d, typesize: %d",
  ------------------
  |  |  125|      1|    do {                                            \
  |  |  126|      1|        const char *__e = getenv("BLOSC_INFO");     \
  |  |  127|      1|        if (!__e) { break; }                        \
  |  |  ------------------
  |  |  |  Branch (127:13): [True: 1, False: 0]
  |  |  ------------------
  |  |  128|      1|        fprintf(stderr, "[INFO] - " msg "\n", ##__VA_ARGS__); \
  |  |  129|      0|    } while(0)
  |  |  ------------------
  |  |  |  Branch (129:13): [Folded - Ignored]
  |  |  ------------------
  ------------------
  161|      1|             context->compcode, context->clevel, blocksize, splitmode, typesize);
  162|       |
  163|      0|  return BLOSC2_ERROR_SUCCESS;
  164|      1|}
split_block:
  185|      1|int split_block(blosc2_context *context, int32_t typesize, int32_t blocksize) {
  186|      1|  switch (context->splitmode) {
  187|      0|    case BLOSC_ALWAYS_SPLIT:
  ------------------
  |  Branch (187:5): [True: 0, False: 1]
  ------------------
  188|      0|      return 1;
  189|      0|    case BLOSC_NEVER_SPLIT:
  ------------------
  |  Branch (189:5): [True: 0, False: 1]
  ------------------
  190|      0|      return 0;
  191|      1|    case BLOSC_FORWARD_COMPAT_SPLIT:
  ------------------
  |  Branch (191:5): [True: 1, False: 0]
  ------------------
  192|      1|    case BLOSC_AUTO_SPLIT:
  ------------------
  |  Branch (192:5): [True: 0, False: 1]
  ------------------
  193|       |      // These cases will be handled later
  194|      1|      break;
  195|      0|    default:
  ------------------
  |  Branch (195:5): [True: 0, False: 1]
  ------------------
  196|      0|      BLOSC_TRACE_WARNING("Unrecognized split mode.  Default to BLOSC_FORWARD_COMPAT_SPLIT");
  ------------------
  |  |   98|      0|#define BLOSC_TRACE_WARNING(msg, ...) BLOSC_TRACE(warning, msg, ##__VA_ARGS__)
  |  |  ------------------
  |  |  |  |  101|      0|    do {                                            \
  |  |  |  |  102|      0|        const char *__e = getenv("BLOSC_TRACE");    \
  |  |  |  |  103|      0|        if (!__e) { break; }                        \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        fprintf(stderr, "[%s] - " msg " (%s:%d)\n", #cat, ##__VA_ARGS__, __FILE__, __LINE__); \
  |  |  |  |  105|      0|    } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (105:13): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  197|      1|  }
  198|       |
  199|      1|  int compcode = context->compcode;
  200|      1|  return (
  201|       |          // Fast codecs like blosclz, lz4 seems to prefer to split
  202|      1|          ((compcode == BLOSC_BLOSCLZ) || (compcode == BLOSC_LZ4)
  ------------------
  |  Branch (202:12): [True: 1, False: 0]
  |  Branch (202:43): [True: 0, False: 0]
  ------------------
  203|       |            // and low levels of zstd too
  204|      1|            || ((compcode == BLOSC_ZSTD) && (context->clevel <= 5))
  ------------------
  |  Branch (204:17): [True: 0, False: 0]
  |  Branch (204:45): [True: 0, False: 0]
  ------------------
  205|      1|            ) &&
  206|       |          // ...but split seems to harm cratio too much when not using shuffle
  207|      1|          (context->filter_flags & BLOSC_DOSHUFFLE) &&
  ------------------
  |  Branch (207:11): [True: 1, False: 0]
  ------------------
  208|      1|          (typesize <= MAX_STREAMS) &&
  ------------------
  |  |   24|      1|#define MAX_STREAMS 16 /* Cannot be larger than 128 */
  ------------------
  |  Branch (208:11): [True: 1, False: 0]
  ------------------
  209|      1|          (blocksize / typesize) >= BLOSC_MIN_BUFFERSIZE);
  ------------------
  |  Branch (209:11): [True: 1, False: 0]
  ------------------
  210|      1|}
stune.c:is_HCR:
   20|      1|static bool is_HCR(blosc2_context * context) {
   21|      1|  switch (context->compcode) {
   22|      1|    case BLOSC_BLOSCLZ :
  ------------------
  |  Branch (22:5): [True: 1, False: 0]
  ------------------
   23|      1|      return false;
   24|      0|    case BLOSC_LZ4 :
  ------------------
  |  Branch (24:5): [True: 0, False: 1]
  ------------------
   25|       |      // return (context->filter_flags & BLOSC_DOBITSHUFFLE) ? true : false;
   26|       |      // Do not treat LZ4 differently than BloscLZ here
   27|      0|      return false;
   28|      0|    case BLOSC_LZ4HC :
  ------------------
  |  Branch (28:5): [True: 0, False: 1]
  ------------------
   29|      0|    case BLOSC_ZLIB :
  ------------------
  |  Branch (29:5): [True: 0, False: 1]
  ------------------
   30|      0|    case BLOSC_ZSTD :
  ------------------
  |  Branch (30:5): [True: 0, False: 1]
  ------------------
   31|      0|      return true;
   32|      0|    default :
  ------------------
  |  Branch (32:5): [True: 0, False: 1]
  ------------------
   33|      0|      return false;
   34|      1|  }
   35|      1|}

LZ4_decompress_safe:
 2452|      4|{
 2453|      4|    return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize,
 2454|      4|                                  decode_full_block, noDict,
 2455|      4|                                  (BYTE*)dest, NULL, 0);
 2456|      4|}
lz4.c:LZ4_wildCopy8:
  466|      4|{
  467|      4|    BYTE* d = (BYTE*)dstPtr;
  468|      4|    const BYTE* s = (const BYTE*)srcPtr;
  469|      4|    BYTE* const e = (BYTE*)dstEnd;
  470|       |
  471|  22.7k|    do { LZ4_memcpy(d,s,8); d+=8; s+=8; } while (d<e);
  ------------------
  |  |  349|  22.7k|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
  |  Branch (471:50): [True: 22.7k, False: 4]
  ------------------
  472|      4|}
lz4.c:LZ4_isLittleEndian:
  364|    600|{
  365|    600|    const union { U32 u; BYTE c[4]; } one = { 1 };   /* don't use static : performance detrimental */
  366|    600|    return one.c[0];
  367|    600|}
lz4.c:LZ4_read16:
  393|    600|static U16 LZ4_read16(const void* ptr) { return ((const LZ4_unalign16*)ptr)->u16; }
lz4.c:LZ4_write32:
  398|      4|static void LZ4_write32(void* memPtr, U32 value) { ((LZ4_unalign32*)memPtr)->u32 = value; }
lz4.c:LZ4_decompress_generic:
 2035|      4|{
 2036|      4|    if ((src == NULL) || (outputSize < 0)) { return -1; }
  ------------------
  |  Branch (2036:9): [True: 0, False: 4]
  |  Branch (2036:26): [True: 0, False: 4]
  ------------------
 2037|       |
 2038|      4|    {   const BYTE* ip = (const BYTE*) src;
 2039|      4|        const BYTE* const iend = ip + srcSize;
 2040|       |
 2041|      4|        BYTE* op = (BYTE*) dst;
 2042|      4|        BYTE* const oend = op + outputSize;
 2043|      4|        BYTE* cpy;
 2044|       |
 2045|      4|        const BYTE* const dictEnd = (dictStart == NULL) ? NULL : dictStart + dictSize;
  ------------------
  |  Branch (2045:37): [True: 4, False: 0]
  ------------------
 2046|       |
 2047|      4|        const int checkOffset = (dictSize < (int)(64 KB));
  ------------------
  |  |  251|      4|#define KB *(1 <<10)
  ------------------
 2048|       |
 2049|       |
 2050|       |        /* Set up the "end" pointers for the shortcut. */
 2051|      4|        const BYTE* const shortiend = iend - 14 /*maxLL*/ - 2 /*offset*/;
 2052|      4|        const BYTE* const shortoend = oend - 14 /*maxLL*/ - 18 /*maxML*/;
 2053|       |
 2054|      4|        const BYTE* match;
 2055|      4|        size_t offset;
 2056|      4|        unsigned token;
 2057|      4|        size_t length;
 2058|       |
 2059|       |
 2060|      4|        DEBUGLOG(5, "LZ4_decompress_generic (srcSize:%i, dstSize:%i)", srcSize, outputSize);
  ------------------
  |  |  289|      4|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2061|       |
 2062|       |        /* Special cases */
 2063|      4|        assert(lowPrefix <= op);
  ------------------
  |  |  273|      4|#    define assert(condition) ((void)0)
  ------------------
 2064|      4|        if (unlikely(outputSize==0)) {
  ------------------
  |  |  180|      4|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|      4|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 4]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2065|       |            /* Empty output buffer */
 2066|      0|            if (partialDecoding) return 0;
  ------------------
  |  Branch (2066:17): [True: 0, False: 0]
  ------------------
 2067|      0|            return ((srcSize==1) && (*ip==0)) ? 0 : -1;
  ------------------
  |  Branch (2067:21): [True: 0, False: 0]
  |  Branch (2067:37): [True: 0, False: 0]
  ------------------
 2068|      0|        }
 2069|      4|        if (unlikely(srcSize==0)) { return -1; }
  ------------------
  |  |  180|      4|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|      4|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 4]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2070|       |
 2071|       |    /* LZ4_FAST_DEC_LOOP:
 2072|       |     * designed for modern OoO performance cpus,
 2073|       |     * where copying reliably 32-bytes is preferable to an unpredictable branch.
 2074|       |     * note : fast loop may show a regression for some client arm chips. */
 2075|      4|#if LZ4_FAST_DEC_LOOP
 2076|      4|        if ((oend - op) < FASTLOOP_SAFE_DISTANCE) {
  ------------------
  |  |  248|      4|#define FASTLOOP_SAFE_DISTANCE 64
  ------------------
  |  Branch (2076:13): [True: 0, False: 4]
  ------------------
 2077|      0|            DEBUGLOG(6, "move to safe decode loop");
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2078|      0|            goto safe_decode;
 2079|      0|        }
 2080|       |
 2081|       |        /* Fast loop : decode sequences as long as output < oend-FASTLOOP_SAFE_DISTANCE */
 2082|      4|        DEBUGLOG(6, "using fast decode loop");
  ------------------
  |  |  289|      4|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2083|    600|        while (1) {
  ------------------
  |  Branch (2083:16): [Folded - Ignored]
  ------------------
 2084|       |            /* Main fastloop assertion: We can always wildcopy FASTLOOP_SAFE_DISTANCE */
 2085|    600|            assert(oend - op >= FASTLOOP_SAFE_DISTANCE);
  ------------------
  |  |  273|    600|#    define assert(condition) ((void)0)
  ------------------
 2086|    600|            assert(ip < iend);
  ------------------
  |  |  273|    600|#    define assert(condition) ((void)0)
  ------------------
 2087|    600|            token = *ip++;
 2088|    600|            length = token >> ML_BITS;  /* literal length */
  ------------------
  |  |  260|    600|#define ML_BITS  4
  ------------------
 2089|    600|            DEBUGLOG(7, "blockPos%6u: litLength token = %u", (unsigned)(op-(BYTE*)dst), (unsigned)length);
  ------------------
  |  |  289|    600|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2090|       |
 2091|       |            /* decode literal length */
 2092|    600|            if (length == RUN_MASK) {
  ------------------
  |  |  263|    600|#define RUN_MASK ((1U<<RUN_BITS)-1)
  |  |  ------------------
  |  |  |  |  262|    600|#define RUN_BITS (8-ML_BITS)
  |  |  |  |  ------------------
  |  |  |  |  |  |  260|    600|#define ML_BITS  4
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (2092:17): [True: 4, False: 596]
  ------------------
 2093|      4|                size_t const addl = read_variable_length(&ip, iend-RUN_MASK, 1);
  ------------------
  |  |  263|      4|#define RUN_MASK ((1U<<RUN_BITS)-1)
  |  |  ------------------
  |  |  |  |  262|      4|#define RUN_BITS (8-ML_BITS)
  |  |  |  |  ------------------
  |  |  |  |  |  |  260|      4|#define ML_BITS  4
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2094|      4|                if (addl == rvl_error) {
  ------------------
  |  Branch (2094:21): [True: 0, False: 4]
  ------------------
 2095|      0|                    DEBUGLOG(6, "error reading long literal length");
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2096|      0|                    goto _output_error;
 2097|      0|                }
 2098|      4|                length += addl;
 2099|      4|                if (unlikely((uptrval)(op)+length<(uptrval)(op))) { goto _output_error; } /* overflow detection */
  ------------------
  |  |  180|      4|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|      4|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 4]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2100|      4|                if (unlikely((uptrval)(ip)+length<(uptrval)(ip))) { goto _output_error; } /* overflow detection */
  ------------------
  |  |  180|      4|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|      4|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 4]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2101|       |
 2102|       |                /* copy literals */
 2103|      4|                LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH);
  ------------------
  |  |  277|      4|#define LZ4_STATIC_ASSERT(c)   { enum { LZ4_static_assert = 1/(int)(!!(c)) }; }   /* use after variable declarations */
  ------------------
 2104|      4|                if ((op+length>oend-32) || (ip+length>iend-32)) { goto safe_literal_copy; }
  ------------------
  |  Branch (2104:21): [True: 0, False: 4]
  |  Branch (2104:44): [True: 0, False: 4]
  ------------------
 2105|      4|                LZ4_wildCopy32(op, ip, op+length);
 2106|      4|                ip += length; op += length;
 2107|    596|            } else if (ip <= iend-(16 + 1/*max lit + offset + nextToken*/)) {
  ------------------
  |  Branch (2107:24): [True: 596, False: 0]
  ------------------
 2108|       |                /* We don't need to check oend, since we check it once for each loop below */
 2109|    596|                DEBUGLOG(7, "copy %u bytes in a 16-bytes stripe", (unsigned)length);
  ------------------
  |  |  289|    596|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2110|       |                /* Literals can only be <= 14, but hope compilers optimize better when copy by a register size */
 2111|    596|                LZ4_memcpy(op, ip, 16);
  ------------------
  |  |  349|    596|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2112|    596|                ip += length; op += length;
 2113|    596|            } else {
 2114|      0|                goto safe_literal_copy;
 2115|      0|            }
 2116|       |
 2117|       |            /* get offset */
 2118|    600|            offset = LZ4_readLE16(ip); ip+=2;
 2119|    600|            DEBUGLOG(6, "blockPos%6u: offset = %u", (unsigned)(op-(BYTE*)dst), (unsigned)offset);
  ------------------
  |  |  289|    600|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2120|    600|            match = op - offset;
 2121|    600|            assert(match <= op);  /* overflow check */
  ------------------
  |  |  273|    600|#    define assert(condition) ((void)0)
  ------------------
 2122|       |
 2123|       |            /* get matchlength */
 2124|    600|            length = token & ML_MASK;
  ------------------
  |  |  261|    600|#define ML_MASK  ((1U<<ML_BITS)-1)
  |  |  ------------------
  |  |  |  |  260|    600|#define ML_BITS  4
  |  |  ------------------
  ------------------
 2125|    600|            DEBUGLOG(7, "  match length token = %u (len==%u)", (unsigned)length, (unsigned)length+MINMATCH);
  ------------------
  |  |  289|    600|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2126|       |
 2127|    600|            if (length == ML_MASK) {
  ------------------
  |  |  261|    600|#define ML_MASK  ((1U<<ML_BITS)-1)
  |  |  ------------------
  |  |  |  |  260|    600|#define ML_BITS  4
  |  |  ------------------
  ------------------
  |  Branch (2127:17): [True: 600, False: 0]
  ------------------
 2128|    600|                size_t const addl = read_variable_length(&ip, iend - LASTLITERALS + 1, 0);
  ------------------
  |  |  245|    600|#define LASTLITERALS   5   /* see ../doc/lz4_Block_format.md#parsing-restrictions */
  ------------------
 2129|    600|                if (addl == rvl_error) {
  ------------------
  |  Branch (2129:21): [True: 0, False: 600]
  ------------------
 2130|      0|                    DEBUGLOG(5, "error reading long match length");
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2131|      0|                    goto _output_error;
 2132|      0|                }
 2133|    600|                length += addl;
 2134|    600|                length += MINMATCH;
  ------------------
  |  |  242|    600|#define MINMATCH 4
  ------------------
 2135|    600|                DEBUGLOG(7, "  long match length == %u", (unsigned)length);
  ------------------
  |  |  289|    600|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2136|    600|                if (unlikely((uptrval)(op)+length<(uptrval)op)) { goto _output_error; } /* overflow detection */
  ------------------
  |  |  180|    600|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|    600|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 600]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2137|    600|                if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) {
  ------------------
  |  |  248|    600|#define FASTLOOP_SAFE_DISTANCE 64
  ------------------
  |  Branch (2137:21): [True: 4, False: 596]
  ------------------
 2138|      4|                    goto safe_match_copy;
 2139|      4|                }
 2140|    600|            } else {
 2141|      0|                length += MINMATCH;
  ------------------
  |  |  242|      0|#define MINMATCH 4
  ------------------
 2142|      0|                if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) {
  ------------------
  |  |  248|      0|#define FASTLOOP_SAFE_DISTANCE 64
  ------------------
  |  Branch (2142:21): [True: 0, False: 0]
  ------------------
 2143|      0|                    DEBUGLOG(7, "moving to safe_match_copy (ml==%u)", (unsigned)length);
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2144|      0|                    goto safe_match_copy;
 2145|      0|                }
 2146|       |
 2147|       |                /* Fastpath check: skip LZ4_wildCopy32 when true */
 2148|      0|                if ((dict == withPrefix64k) || (match >= lowPrefix)) {
  ------------------
  |  Branch (2148:21): [True: 0, False: 0]
  |  Branch (2148:48): [True: 0, False: 0]
  ------------------
 2149|      0|                    if (offset >= 8) {
  ------------------
  |  Branch (2149:25): [True: 0, False: 0]
  ------------------
 2150|      0|                        assert(match >= lowPrefix);
  ------------------
  |  |  273|      0|#    define assert(condition) ((void)0)
  ------------------
 2151|      0|                        assert(match <= op);
  ------------------
  |  |  273|      0|#    define assert(condition) ((void)0)
  ------------------
 2152|      0|                        assert(op + 18 <= oend);
  ------------------
  |  |  273|      0|#    define assert(condition) ((void)0)
  ------------------
 2153|       |
 2154|      0|                        LZ4_memcpy(op, match, 8);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2155|      0|                        LZ4_memcpy(op+8, match+8, 8);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2156|      0|                        LZ4_memcpy(op+16, match+16, 2);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2157|      0|                        op += length;
 2158|      0|                        continue;
 2159|      0|            }   }   }
 2160|       |
 2161|    596|            if ( checkOffset && (unlikely(match + dictSize < lowPrefix)) ) {
  ------------------
  |  |  180|    596|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|    596|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  ------------------
  ------------------
  |  Branch (2161:18): [True: 596, False: 0]
  |  Branch (2161:33): [True: 0, False: 596]
  ------------------
 2162|      0|                DEBUGLOG(5, "Error : pos=%zi, offset=%zi => outside buffers", op-lowPrefix, op-match);
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2163|      0|                goto _output_error;
 2164|      0|            }
 2165|       |            /* match starting within external dictionary */
 2166|    596|            if ((dict==usingExtDict) && (match < lowPrefix)) {
  ------------------
  |  Branch (2166:17): [True: 0, False: 596]
  |  Branch (2166:41): [True: 0, False: 0]
  ------------------
 2167|      0|                assert(dictEnd != NULL);
  ------------------
  |  |  273|      0|#    define assert(condition) ((void)0)
  ------------------
 2168|      0|                if (unlikely(op+length > oend-LASTLITERALS)) {
  ------------------
  |  |  180|      0|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|      0|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2169|      0|                    if (partialDecoding) {
  ------------------
  |  Branch (2169:25): [True: 0, False: 0]
  ------------------
 2170|      0|                        DEBUGLOG(7, "partialDecoding: dictionary match, close to dstEnd");
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2171|      0|                        length = MIN(length, (size_t)(oend-op));
  ------------------
  |  | 1845|      0|#define MIN(a,b)    ( (a) < (b) ? (a) : (b) )
  |  |  ------------------
  |  |  |  Branch (1845:23): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2172|      0|                    } else {
 2173|      0|                        DEBUGLOG(6, "end-of-block condition violated")
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2174|      0|                        goto _output_error;
 2175|      0|                }   }
 2176|       |
 2177|      0|                if (length <= (size_t)(lowPrefix-match)) {
  ------------------
  |  Branch (2177:21): [True: 0, False: 0]
  ------------------
 2178|       |                    /* match fits entirely within external dictionary : just copy */
 2179|      0|                    LZ4_memmove(op, dictEnd - (lowPrefix-match), length);
  ------------------
  |  |  357|      0|#    define LZ4_memmove __builtin_memmove
  ------------------
 2180|      0|                    op += length;
 2181|      0|                } else {
 2182|       |                    /* match stretches into both external dictionary and current block */
 2183|      0|                    size_t const copySize = (size_t)(lowPrefix - match);
 2184|      0|                    size_t const restSize = length - copySize;
 2185|      0|                    LZ4_memcpy(op, dictEnd - copySize, copySize);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2186|      0|                    op += copySize;
 2187|      0|                    if (restSize > (size_t)(op - lowPrefix)) {  /* overlap copy */
  ------------------
  |  Branch (2187:25): [True: 0, False: 0]
  ------------------
 2188|      0|                        BYTE* const endOfMatch = op + restSize;
 2189|      0|                        const BYTE* copyFrom = lowPrefix;
 2190|      0|                        while (op < endOfMatch) { *op++ = *copyFrom++; }
  ------------------
  |  Branch (2190:32): [True: 0, False: 0]
  ------------------
 2191|      0|                    } else {
 2192|      0|                        LZ4_memcpy(op, lowPrefix, restSize);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2193|      0|                        op += restSize;
 2194|      0|                }   }
 2195|      0|                continue;
 2196|      0|            }
 2197|       |
 2198|       |            /* copy match within block */
 2199|    596|            cpy = op + length;
 2200|       |
 2201|    596|            assert((op <= oend) && (oend-op >= 32));
  ------------------
  |  |  273|    596|#    define assert(condition) ((void)0)
  ------------------
 2202|    596|            if (unlikely(offset<16)) {
  ------------------
  |  |  180|    596|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|    596|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 588, False: 8]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2203|    588|                LZ4_memcpy_using_offset(op, match, cpy, offset);
 2204|    588|            } else {
 2205|      8|                LZ4_wildCopy32(op, match, cpy);
 2206|      8|            }
 2207|       |
 2208|    596|            op = cpy;   /* wildcopy correction */
 2209|    596|        }
 2210|      0|    safe_decode:
 2211|      0|#endif
 2212|       |
 2213|       |        /* Main Loop : decode remaining sequences where output < FASTLOOP_SAFE_DISTANCE */
 2214|      0|        DEBUGLOG(6, "using safe decode loop");
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2215|      4|        while (1) {
  ------------------
  |  Branch (2215:16): [Folded - Ignored]
  ------------------
 2216|      4|            assert(ip < iend);
  ------------------
  |  |  273|      4|#    define assert(condition) ((void)0)
  ------------------
 2217|      4|            token = *ip++;
 2218|      4|            length = token >> ML_BITS;  /* literal length */
  ------------------
  |  |  260|      4|#define ML_BITS  4
  ------------------
 2219|      4|            DEBUGLOG(7, "blockPos%6u: litLength token = %u", (unsigned)(op-(BYTE*)dst), (unsigned)length);
  ------------------
  |  |  289|      4|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2220|       |
 2221|       |            /* A two-stage shortcut for the most common case:
 2222|       |             * 1) If the literal length is 0..14, and there is enough space,
 2223|       |             * enter the shortcut and copy 16 bytes on behalf of the literals
 2224|       |             * (in the fast mode, only 8 bytes can be safely copied this way).
 2225|       |             * 2) Further if the match length is 4..18, copy 18 bytes in a similar
 2226|       |             * manner; but we ensure that there's enough space in the output for
 2227|       |             * those 18 bytes earlier, upon entering the shortcut (in other words,
 2228|       |             * there is a combined check for both stages).
 2229|       |             */
 2230|      4|            if ( (length != RUN_MASK)
  ------------------
  |  |  263|      4|#define RUN_MASK ((1U<<RUN_BITS)-1)
  |  |  ------------------
  |  |  |  |  262|      4|#define RUN_BITS (8-ML_BITS)
  |  |  |  |  ------------------
  |  |  |  |  |  |  260|      4|#define ML_BITS  4
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (2230:18): [True: 4, False: 0]
  ------------------
 2231|       |                /* strictly "less than" on input, to re-enter the loop with at least one byte */
 2232|      4|              && likely((ip < shortiend) & (op <= shortoend)) ) {
  ------------------
  |  |  177|      4|#define likely(expr)     expect((expr) != 0, 1)
  |  |  ------------------
  |  |  |  |  171|      4|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 4]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2233|       |                /* Copy the literals */
 2234|      0|                LZ4_memcpy(op, ip, 16);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2235|      0|                op += length; ip += length;
 2236|       |
 2237|       |                /* The second stage: prepare for match copying, decode full info.
 2238|       |                 * If it doesn't work out, the info won't be wasted. */
 2239|      0|                length = token & ML_MASK; /* match length */
  ------------------
  |  |  261|      0|#define ML_MASK  ((1U<<ML_BITS)-1)
  |  |  ------------------
  |  |  |  |  260|      0|#define ML_BITS  4
  |  |  ------------------
  ------------------
 2240|      0|                DEBUGLOG(7, "blockPos%6u: matchLength token = %u (len=%u)", (unsigned)(op-(BYTE*)dst), (unsigned)length, (unsigned)length + 4);
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2241|      0|                offset = LZ4_readLE16(ip); ip += 2;
 2242|      0|                match = op - offset;
 2243|      0|                assert(match <= op); /* check overflow */
  ------------------
  |  |  273|      0|#    define assert(condition) ((void)0)
  ------------------
 2244|       |
 2245|       |                /* Do not deal with overlapping matches. */
 2246|      0|                if ( (length != ML_MASK)
  ------------------
  |  |  261|      0|#define ML_MASK  ((1U<<ML_BITS)-1)
  |  |  ------------------
  |  |  |  |  260|      0|#define ML_BITS  4
  |  |  ------------------
  ------------------
  |  Branch (2246:22): [True: 0, False: 0]
  ------------------
 2247|      0|                  && (offset >= 8)
  ------------------
  |  Branch (2247:22): [True: 0, False: 0]
  ------------------
 2248|      0|                  && (dict==withPrefix64k || match >= lowPrefix) ) {
  ------------------
  |  Branch (2248:23): [True: 0, False: 0]
  |  Branch (2248:46): [True: 0, False: 0]
  ------------------
 2249|       |                    /* Copy the match. */
 2250|      0|                    LZ4_memcpy(op + 0, match + 0, 8);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2251|      0|                    LZ4_memcpy(op + 8, match + 8, 8);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2252|      0|                    LZ4_memcpy(op +16, match +16, 2);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2253|      0|                    op += length + MINMATCH;
  ------------------
  |  |  242|      0|#define MINMATCH 4
  ------------------
 2254|       |                    /* Both stages worked, load the next token. */
 2255|      0|                    continue;
 2256|      0|                }
 2257|       |
 2258|       |                /* The second stage didn't work out, but the info is ready.
 2259|       |                 * Propel it right to the point of match copying. */
 2260|      0|                goto _copy_match;
 2261|      0|            }
 2262|       |
 2263|       |            /* decode literal length */
 2264|      4|            if (length == RUN_MASK) {
  ------------------
  |  |  263|      4|#define RUN_MASK ((1U<<RUN_BITS)-1)
  |  |  ------------------
  |  |  |  |  262|      4|#define RUN_BITS (8-ML_BITS)
  |  |  |  |  ------------------
  |  |  |  |  |  |  260|      4|#define ML_BITS  4
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (2264:17): [True: 0, False: 4]
  ------------------
 2265|      0|                size_t const addl = read_variable_length(&ip, iend-RUN_MASK, 1);
  ------------------
  |  |  263|      0|#define RUN_MASK ((1U<<RUN_BITS)-1)
  |  |  ------------------
  |  |  |  |  262|      0|#define RUN_BITS (8-ML_BITS)
  |  |  |  |  ------------------
  |  |  |  |  |  |  260|      0|#define ML_BITS  4
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2266|      0|                if (addl == rvl_error) { goto _output_error; }
  ------------------
  |  Branch (2266:21): [True: 0, False: 0]
  ------------------
 2267|      0|                length += addl;
 2268|      0|                if (unlikely((uptrval)(op)+length<(uptrval)(op))) { goto _output_error; } /* overflow detection */
  ------------------
  |  |  180|      0|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|      0|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2269|      0|                if (unlikely((uptrval)(ip)+length<(uptrval)(ip))) { goto _output_error; } /* overflow detection */
  ------------------
  |  |  180|      0|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|      0|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2270|      0|            }
 2271|       |
 2272|      4|#if LZ4_FAST_DEC_LOOP
 2273|      4|        safe_literal_copy:
 2274|      4|#endif
 2275|       |            /* copy literals */
 2276|      4|            cpy = op+length;
 2277|       |
 2278|      4|            LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH);
  ------------------
  |  |  277|      4|#define LZ4_STATIC_ASSERT(c)   { enum { LZ4_static_assert = 1/(int)(!!(c)) }; }   /* use after variable declarations */
  ------------------
 2279|      4|            if ((cpy>oend-MFLIMIT) || (ip+length>iend-(2+1+LASTLITERALS))) {
  ------------------
  |  |  246|      4|#define MFLIMIT       12   /* see ../doc/lz4_Block_format.md#parsing-restrictions */
  ------------------
                          if ((cpy>oend-MFLIMIT) || (ip+length>iend-(2+1+LASTLITERALS))) {
  ------------------
  |  |  245|      0|#define LASTLITERALS   5   /* see ../doc/lz4_Block_format.md#parsing-restrictions */
  ------------------
  |  Branch (2279:17): [True: 4, False: 0]
  |  Branch (2279:39): [True: 0, False: 0]
  ------------------
 2280|       |                /* We've either hit the input parsing restriction or the output parsing restriction.
 2281|       |                 * In the normal scenario, decoding a full block, it must be the last sequence,
 2282|       |                 * otherwise it's an error (invalid input or dimensions).
 2283|       |                 * In partialDecoding scenario, it's necessary to ensure there is no buffer overflow.
 2284|       |                 */
 2285|      4|                if (partialDecoding) {
  ------------------
  |  Branch (2285:21): [True: 0, False: 4]
  ------------------
 2286|       |                    /* Since we are partial decoding we may be in this block because of the output parsing
 2287|       |                     * restriction, which is not valid since the output buffer is allowed to be undersized.
 2288|       |                     */
 2289|      0|                    DEBUGLOG(7, "partialDecoding: copying literals, close to input or output end")
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2290|      0|                    DEBUGLOG(7, "partialDecoding: literal length = %u", (unsigned)length);
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2291|      0|                    DEBUGLOG(7, "partialDecoding: remaining space in dstBuffer : %i", (int)(oend - op));
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2292|      0|                    DEBUGLOG(7, "partialDecoding: remaining space in srcBuffer : %i", (int)(iend - ip));
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2293|       |                    /* Finishing in the middle of a literals segment,
 2294|       |                     * due to lack of input.
 2295|       |                     */
 2296|      0|                    if (ip+length > iend) {
  ------------------
  |  Branch (2296:25): [True: 0, False: 0]
  ------------------
 2297|      0|                        length = (size_t)(iend-ip);
 2298|      0|                        cpy = op + length;
 2299|      0|                    }
 2300|       |                    /* Finishing in the middle of a literals segment,
 2301|       |                     * due to lack of output space.
 2302|       |                     */
 2303|      0|                    if (cpy > oend) {
  ------------------
  |  Branch (2303:25): [True: 0, False: 0]
  ------------------
 2304|      0|                        cpy = oend;
 2305|      0|                        assert(op<=oend);
  ------------------
  |  |  273|      0|#    define assert(condition) ((void)0)
  ------------------
 2306|      0|                        length = (size_t)(oend-op);
 2307|      0|                    }
 2308|      4|                } else {
 2309|       |                     /* We must be on the last sequence (or invalid) because of the parsing limitations
 2310|       |                      * so check that we exactly consume the input and don't overrun the output buffer.
 2311|       |                      */
 2312|      4|                    if ((ip+length != iend) || (cpy > oend)) {
  ------------------
  |  Branch (2312:25): [True: 0, False: 4]
  |  Branch (2312:48): [True: 0, False: 4]
  ------------------
 2313|      0|                        DEBUGLOG(5, "should have been last run of literals")
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2314|      0|                        DEBUGLOG(5, "ip(%p) + length(%i) = %p != iend (%p)", ip, (int)length, ip+length, iend);
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2315|      0|                        DEBUGLOG(5, "or cpy(%p) > (oend-MFLIMIT)(%p)", cpy, oend-MFLIMIT);
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2316|      0|                        DEBUGLOG(5, "after writing %u bytes / %i bytes available", (unsigned)(op-(BYTE*)dst), outputSize);
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2317|      0|                        goto _output_error;
 2318|      0|                    }
 2319|      4|                }
 2320|      4|                LZ4_memmove(op, ip, length);  /* supports overlapping memory regions, for in-place decompression scenarios */
  ------------------
  |  |  357|      4|#    define LZ4_memmove __builtin_memmove
  ------------------
 2321|      4|                ip += length;
 2322|      4|                op += length;
 2323|       |                /* Necessarily EOF when !partialDecoding.
 2324|       |                 * When partialDecoding, it is EOF if we've either
 2325|       |                 * filled the output buffer or
 2326|       |                 * can't proceed with reading an offset for following match.
 2327|       |                 */
 2328|      4|                if (!partialDecoding || (cpy == oend) || (ip >= (iend-2))) {
  ------------------
  |  Branch (2328:21): [True: 4, False: 0]
  |  Branch (2328:41): [True: 0, False: 0]
  |  Branch (2328:58): [True: 0, False: 0]
  ------------------
 2329|      4|                    break;
 2330|      4|                }
 2331|      4|            } else {
 2332|      0|                LZ4_wildCopy8(op, ip, cpy);   /* can overwrite up to 8 bytes beyond cpy */
 2333|      0|                ip += length; op = cpy;
 2334|      0|            }
 2335|       |
 2336|       |            /* get offset */
 2337|      0|            offset = LZ4_readLE16(ip); ip+=2;
 2338|      0|            match = op - offset;
 2339|       |
 2340|       |            /* get matchlength */
 2341|      0|            length = token & ML_MASK;
  ------------------
  |  |  261|      0|#define ML_MASK  ((1U<<ML_BITS)-1)
  |  |  ------------------
  |  |  |  |  260|      0|#define ML_BITS  4
  |  |  ------------------
  ------------------
 2342|      0|            DEBUGLOG(7, "blockPos%6u: matchLength token = %u", (unsigned)(op-(BYTE*)dst), (unsigned)length);
  ------------------
  |  |  289|      0|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2343|       |
 2344|      0|    _copy_match:
 2345|      0|            if (length == ML_MASK) {
  ------------------
  |  |  261|      0|#define ML_MASK  ((1U<<ML_BITS)-1)
  |  |  ------------------
  |  |  |  |  260|      0|#define ML_BITS  4
  |  |  ------------------
  ------------------
  |  Branch (2345:17): [True: 0, False: 0]
  ------------------
 2346|      0|                size_t const addl = read_variable_length(&ip, iend - LASTLITERALS + 1, 0);
  ------------------
  |  |  245|      0|#define LASTLITERALS   5   /* see ../doc/lz4_Block_format.md#parsing-restrictions */
  ------------------
 2347|      0|                if (addl == rvl_error) { goto _output_error; }
  ------------------
  |  Branch (2347:21): [True: 0, False: 0]
  ------------------
 2348|      0|                length += addl;
 2349|      0|                if (unlikely((uptrval)(op)+length<(uptrval)op)) goto _output_error;   /* overflow detection */
  ------------------
  |  |  180|      0|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|      0|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2350|      0|            }
 2351|      0|            length += MINMATCH;
  ------------------
  |  |  242|      0|#define MINMATCH 4
  ------------------
 2352|       |
 2353|      0|#if LZ4_FAST_DEC_LOOP
 2354|      4|        safe_match_copy:
 2355|      4|#endif
 2356|      4|            if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) goto _output_error;   /* Error : offset outside buffers */
  ------------------
  |  |  180|      4|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|      4|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  ------------------
  ------------------
  |  Branch (2356:17): [True: 4, False: 0]
  |  Branch (2356:34): [True: 0, False: 4]
  ------------------
 2357|       |            /* match starting within external dictionary */
 2358|      4|            if ((dict==usingExtDict) && (match < lowPrefix)) {
  ------------------
  |  Branch (2358:17): [True: 0, False: 4]
  |  Branch (2358:41): [True: 0, False: 0]
  ------------------
 2359|      0|                assert(dictEnd != NULL);
  ------------------
  |  |  273|      0|#    define assert(condition) ((void)0)
  ------------------
 2360|      0|                if (unlikely(op+length > oend-LASTLITERALS)) {
  ------------------
  |  |  180|      0|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|      0|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2361|      0|                    if (partialDecoding) length = MIN(length, (size_t)(oend-op));
  ------------------
  |  | 1845|      0|#define MIN(a,b)    ( (a) < (b) ? (a) : (b) )
  |  |  ------------------
  |  |  |  Branch (1845:23): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (2361:25): [True: 0, False: 0]
  ------------------
 2362|      0|                    else goto _output_error;   /* doesn't respect parsing restriction */
 2363|      0|                }
 2364|       |
 2365|      0|                if (length <= (size_t)(lowPrefix-match)) {
  ------------------
  |  Branch (2365:21): [True: 0, False: 0]
  ------------------
 2366|       |                    /* match fits entirely within external dictionary : just copy */
 2367|      0|                    LZ4_memmove(op, dictEnd - (lowPrefix-match), length);
  ------------------
  |  |  357|      0|#    define LZ4_memmove __builtin_memmove
  ------------------
 2368|      0|                    op += length;
 2369|      0|                } else {
 2370|       |                    /* match stretches into both external dictionary and current block */
 2371|      0|                    size_t const copySize = (size_t)(lowPrefix - match);
 2372|      0|                    size_t const restSize = length - copySize;
 2373|      0|                    LZ4_memcpy(op, dictEnd - copySize, copySize);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2374|      0|                    op += copySize;
 2375|      0|                    if (restSize > (size_t)(op - lowPrefix)) {  /* overlap copy */
  ------------------
  |  Branch (2375:25): [True: 0, False: 0]
  ------------------
 2376|      0|                        BYTE* const endOfMatch = op + restSize;
 2377|      0|                        const BYTE* copyFrom = lowPrefix;
 2378|      0|                        while (op < endOfMatch) *op++ = *copyFrom++;
  ------------------
  |  Branch (2378:32): [True: 0, False: 0]
  ------------------
 2379|      0|                    } else {
 2380|      0|                        LZ4_memcpy(op, lowPrefix, restSize);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2381|      0|                        op += restSize;
 2382|      0|                }   }
 2383|      0|                continue;
 2384|      0|            }
 2385|      4|            assert(match >= lowPrefix);
  ------------------
  |  |  273|      4|#    define assert(condition) ((void)0)
  ------------------
 2386|       |
 2387|       |            /* copy match within block */
 2388|      4|            cpy = op + length;
 2389|       |
 2390|       |            /* partialDecoding : may end anywhere within the block */
 2391|      4|            assert(op<=oend);
  ------------------
  |  |  273|      4|#    define assert(condition) ((void)0)
  ------------------
 2392|      4|            if (partialDecoding && (cpy > oend-MATCH_SAFEGUARD_DISTANCE)) {
  ------------------
  |  |  247|      0|#define MATCH_SAFEGUARD_DISTANCE  ((2*WILDCOPYLENGTH) - MINMATCH)   /* ensure it's possible to write 2 x wildcopyLength without overflowing output buffer */
  |  |  ------------------
  |  |  |  |  244|      0|#define WILDCOPYLENGTH 8
  |  |  ------------------
  |  |               #define MATCH_SAFEGUARD_DISTANCE  ((2*WILDCOPYLENGTH) - MINMATCH)   /* ensure it's possible to write 2 x wildcopyLength without overflowing output buffer */
  |  |  ------------------
  |  |  |  |  242|      0|#define MINMATCH 4
  |  |  ------------------
  ------------------
  |  Branch (2392:17): [True: 0, False: 4]
  |  Branch (2392:36): [True: 0, False: 0]
  ------------------
 2393|      0|                size_t const mlen = MIN(length, (size_t)(oend-op));
  ------------------
  |  | 1845|      0|#define MIN(a,b)    ( (a) < (b) ? (a) : (b) )
  |  |  ------------------
  |  |  |  Branch (1845:23): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2394|      0|                const BYTE* const matchEnd = match + mlen;
 2395|      0|                BYTE* const copyEnd = op + mlen;
 2396|      0|                if (matchEnd > op) {   /* overlap copy */
  ------------------
  |  Branch (2396:21): [True: 0, False: 0]
  ------------------
 2397|      0|                    while (op < copyEnd) { *op++ = *match++; }
  ------------------
  |  Branch (2397:28): [True: 0, False: 0]
  ------------------
 2398|      0|                } else {
 2399|      0|                    LZ4_memcpy(op, match, mlen);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2400|      0|                }
 2401|      0|                op = copyEnd;
 2402|      0|                if (op == oend) { break; }
  ------------------
  |  Branch (2402:21): [True: 0, False: 0]
  ------------------
 2403|      0|                continue;
 2404|      0|            }
 2405|       |
 2406|      4|            if (unlikely(offset<8)) {
  ------------------
  |  |  180|      4|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|      4|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 4, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2407|      4|                LZ4_write32(op, 0);   /* silence msan warning when offset==0 */
 2408|      4|                op[0] = match[0];
 2409|      4|                op[1] = match[1];
 2410|      4|                op[2] = match[2];
 2411|      4|                op[3] = match[3];
 2412|      4|                match += inc32table[offset];
 2413|      4|                LZ4_memcpy(op+4, match, 4);
  ------------------
  |  |  349|      4|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2414|      4|                match -= dec64table[offset];
 2415|      4|            } else {
 2416|      0|                LZ4_memcpy(op, match, 8);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2417|      0|                match += 8;
 2418|      0|            }
 2419|      4|            op += 8;
 2420|       |
 2421|      4|            if (unlikely(cpy > oend-MATCH_SAFEGUARD_DISTANCE)) {
  ------------------
  |  |  180|      4|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|      4|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 4, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2422|      4|                BYTE* const oCopyLimit = oend - (WILDCOPYLENGTH-1);
  ------------------
  |  |  244|      4|#define WILDCOPYLENGTH 8
  ------------------
 2423|      4|                if (cpy > oend-LASTLITERALS) { goto _output_error; } /* Error : last LASTLITERALS bytes must be literals (uncompressed) */
  ------------------
  |  |  245|      4|#define LASTLITERALS   5   /* see ../doc/lz4_Block_format.md#parsing-restrictions */
  ------------------
  |  Branch (2423:21): [True: 0, False: 4]
  ------------------
 2424|      4|                if (op < oCopyLimit) {
  ------------------
  |  Branch (2424:21): [True: 4, False: 0]
  ------------------
 2425|      4|                    LZ4_wildCopy8(op, match, oCopyLimit);
 2426|      4|                    match += oCopyLimit - op;
 2427|      4|                    op = oCopyLimit;
 2428|      4|                }
 2429|     12|                while (op < cpy) { *op++ = *match++; }
  ------------------
  |  Branch (2429:24): [True: 8, False: 4]
  ------------------
 2430|      4|            } else {
 2431|      0|                LZ4_memcpy(op, match, 8);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
 2432|      0|                if (length > 16) { LZ4_wildCopy8(op+8, match+8, cpy); }
  ------------------
  |  Branch (2432:21): [True: 0, False: 0]
  ------------------
 2433|      0|            }
 2434|      4|            op = cpy;   /* wildcopy correction */
 2435|      4|        }
 2436|       |
 2437|       |        /* end of decoding */
 2438|      4|        DEBUGLOG(5, "decoded %i bytes", (int) (((char*)op)-dst));
  ------------------
  |  |  289|      4|#  define DEBUGLOG(l, ...) {}    /* disabled */
  ------------------
 2439|      4|        return (int) (((char*)op)-dst);     /* Nb of output bytes decoded */
 2440|       |
 2441|       |        /* Overflow error detected */
 2442|      0|    _output_error:
 2443|      0|        return (int) (-(((const char*)ip)-src))-1;
 2444|      0|    }
 2445|      0|}
lz4.c:read_variable_length:
 1981|    604|{
 1982|    604|    Rvl_t s, length = 0;
 1983|    604|    assert(ip != NULL);
  ------------------
  |  |  273|    604|#    define assert(condition) ((void)0)
  ------------------
 1984|    604|    assert(*ip !=  NULL);
  ------------------
  |  |  273|    604|#    define assert(condition) ((void)0)
  ------------------
 1985|    604|    assert(ilimit != NULL);
  ------------------
  |  |  273|    604|#    define assert(condition) ((void)0)
  ------------------
 1986|    604|    if (initial_check && unlikely((*ip) >= ilimit)) {    /* read limit reached */
  ------------------
  |  |  180|      4|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|      4|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 4]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1986:9): [True: 4, False: 600]
  ------------------
 1987|      0|        return rvl_error;
 1988|      0|    }
 1989|    604|    s = **ip;
 1990|    604|    (*ip)++;
 1991|    604|    length += s;
 1992|    604|    if (unlikely((*ip) > ilimit)) {    /* read limit reached */
  ------------------
  |  |  180|    604|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|    604|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 604]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1993|      0|        return rvl_error;
 1994|      0|    }
 1995|       |    /* accumulator overflow detection (32-bit mode only) */
 1996|    604|    if ((sizeof(length) < 8) && unlikely(length > ((Rvl_t)(-1)/2)) ) {
  ------------------
  |  |  180|      0|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|      0|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1996:9): [Folded - Ignored]
  ------------------
 1997|      0|        return rvl_error;
 1998|      0|    }
 1999|    604|    if (likely(s != 255)) return length;
  ------------------
  |  |  177|    604|#define likely(expr)     expect((expr) != 0, 1)
  |  |  ------------------
  |  |  |  |  171|    604|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 595, False: 9]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2000|  1.16k|    do {
 2001|  1.16k|        s = **ip;
 2002|  1.16k|        (*ip)++;
 2003|  1.16k|        length += s;
 2004|  1.16k|        if (unlikely((*ip) > ilimit)) {    /* read limit reached */
  ------------------
  |  |  180|  1.16k|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|  1.16k|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 1.16k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2005|      0|            return rvl_error;
 2006|      0|        }
 2007|       |        /* accumulator overflow detection (32-bit mode only) */
 2008|  1.16k|        if ((sizeof(length) < 8) && unlikely(length > ((Rvl_t)(-1)/2)) ) {
  ------------------
  |  |  180|      0|#define unlikely(expr)   expect((expr) != 0, 0)
  |  |  ------------------
  |  |  |  |  171|      0|#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (171:33): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (2008:13): [Folded - Ignored]
  ------------------
 2009|      0|            return rvl_error;
 2010|      0|        }
 2011|  1.16k|    } while (s == 255);
  ------------------
  |  Branch (2011:14): [True: 1.15k, False: 9]
  ------------------
 2012|       |
 2013|      9|    return length;
 2014|      9|}
lz4.c:LZ4_wildCopy32:
  523|     12|{
  524|     12|    BYTE* d = (BYTE*)dstPtr;
  525|     12|    const BYTE* s = (const BYTE*)srcPtr;
  526|     12|    BYTE* const e = (BYTE*)dstEnd;
  527|       |
  528|  3.14k|    do { LZ4_memcpy(d,s,16); LZ4_memcpy(d+16,s+16,16); d+=32; s+=32; } while (d<e);
  ------------------
  |  |  349|  3.14k|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
                  do { LZ4_memcpy(d,s,16); LZ4_memcpy(d+16,s+16,16); d+=32; s+=32; } while (d<e);
  ------------------
  |  |  349|  3.14k|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
  |  Branch (528:79): [True: 3.13k, False: 12]
  ------------------
  529|     12|}
lz4.c:LZ4_readLE16:
  431|    600|{
  432|    600|    if (LZ4_isLittleEndian()) {
  ------------------
  |  Branch (432:9): [True: 600, False: 0]
  ------------------
  433|    600|        return LZ4_read16(memPtr);
  434|    600|    } else {
  435|      0|        const BYTE* p = (const BYTE*)memPtr;
  436|      0|        return (U16)((U16)p[0] | (p[1]<<8));
  437|      0|    }
  438|    600|}
lz4.c:LZ4_memcpy_using_offset:
  536|    588|{
  537|    588|    BYTE v[8];
  538|       |
  539|    588|    assert(dstEnd >= dstPtr + MINMATCH);
  ------------------
  |  |  273|    588|#    define assert(condition) ((void)0)
  ------------------
  540|       |
  541|    588|    switch(offset) {
  542|    587|    case 1:
  ------------------
  |  Branch (542:5): [True: 587, False: 1]
  ------------------
  543|    587|        MEM_INIT(v, *srcPtr, 8);
  ------------------
  |  |  236|    587|#define MEM_INIT(p,v,s)   LZ4_memset((p),(v),(s))
  |  |  ------------------
  |  |  |  |  234|    587|#  define LZ4_memset(p,v,s) memset((p),(v),(s))
  |  |  ------------------
  ------------------
  544|    587|        break;
  545|      1|    case 2:
  ------------------
  |  Branch (545:5): [True: 1, False: 587]
  ------------------
  546|      1|        LZ4_memcpy(v, srcPtr, 2);
  ------------------
  |  |  349|      1|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
  547|      1|        LZ4_memcpy(&v[2], srcPtr, 2);
  ------------------
  |  |  349|      1|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
  548|       |#if defined(_MSC_VER) && (_MSC_VER <= 1937) /* MSVC 2022 ver 17.7 or earlier */
  549|       |#  pragma warning(push)
  550|       |#  pragma warning(disable : 6385) /* warning C6385: Reading invalid data from 'v'. */
  551|       |#endif
  552|      1|        LZ4_memcpy(&v[4], v, 4);
  ------------------
  |  |  349|      1|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
  553|       |#if defined(_MSC_VER) && (_MSC_VER <= 1937) /* MSVC 2022 ver 17.7 or earlier */
  554|       |#  pragma warning(pop)
  555|       |#endif
  556|      1|        break;
  557|      0|    case 4:
  ------------------
  |  Branch (557:5): [True: 0, False: 588]
  ------------------
  558|      0|        LZ4_memcpy(v, srcPtr, 4);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
  559|      0|        LZ4_memcpy(&v[4], srcPtr, 4);
  ------------------
  |  |  349|      0|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
  560|      0|        break;
  561|      0|    default:
  ------------------
  |  Branch (561:5): [True: 0, False: 588]
  ------------------
  562|      0|        LZ4_memcpy_using_offset_base(dstPtr, srcPtr, dstEnd, offset);
  563|      0|        return;
  564|    588|    }
  565|       |
  566|    588|    LZ4_memcpy(dstPtr, v, 8);
  ------------------
  |  |  349|    588|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
  567|    588|    dstPtr += 8;
  568|  14.6k|    while (dstPtr < dstEnd) {
  ------------------
  |  Branch (568:12): [True: 14.0k, False: 588]
  ------------------
  569|  14.0k|        LZ4_memcpy(dstPtr, v, 8);
  ------------------
  |  |  349|  14.0k|#    define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
  ------------------
  570|  14.0k|        dstPtr += 8;
  571|  14.0k|    }
  572|    588|}

register_codecs:
   13|      7|void register_codecs(void) {
   14|       |
   15|      7|  blosc2_codec ndlz;
   16|      7|  ndlz.compcode = BLOSC_CODEC_NDLZ;
   17|      7|  ndlz.version = 1;
   18|      7|  ndlz.complib = BLOSC_CODEC_NDLZ;
   19|      7|  ndlz.encoder = &ndlz_compress;
   20|      7|  ndlz.decoder = &ndlz_decompress;
   21|      7|  ndlz.compname = "ndlz";
   22|      7|  register_codec_private(&ndlz);
   23|       |
   24|      7|  blosc2_codec zfp_acc;
   25|      7|  zfp_acc.compcode = BLOSC_CODEC_ZFP_FIXED_ACCURACY;
   26|      7|  zfp_acc.version = 1;
   27|      7|  zfp_acc.complib = BLOSC_CODEC_ZFP_FIXED_ACCURACY;
   28|      7|  zfp_acc.encoder = &zfp_acc_compress;
   29|      7|  zfp_acc.decoder = &zfp_acc_decompress;
   30|      7|  zfp_acc.compname = "zfp_acc";
   31|      7|  register_codec_private(&zfp_acc);
   32|       |
   33|      7|  blosc2_codec zfp_prec;
   34|      7|  zfp_prec.compcode = BLOSC_CODEC_ZFP_FIXED_PRECISION;
   35|      7|  zfp_prec.version = 1;
   36|      7|  zfp_prec.complib = BLOSC_CODEC_ZFP_FIXED_PRECISION;
   37|      7|  zfp_prec.encoder = &zfp_prec_compress;
   38|      7|  zfp_prec.decoder = &zfp_prec_decompress;
   39|      7|  zfp_prec.compname = "zfp_prec";
   40|      7|  register_codec_private(&zfp_prec);
   41|       |
   42|      7|  blosc2_codec zfp_rate;
   43|      7|  zfp_rate.compcode = BLOSC_CODEC_ZFP_FIXED_RATE;
   44|      7|  zfp_rate.version = 1;
   45|      7|  zfp_rate.complib = BLOSC_CODEC_ZFP_FIXED_RATE;
   46|      7|  zfp_rate.encoder = &zfp_rate_compress;
   47|      7|  zfp_rate.decoder = &zfp_rate_decompress;
   48|      7|  zfp_rate.compname = "zfp_rate";
   49|      7|  register_codec_private(&zfp_rate);
   50|       |
   51|      7|  blosc2_codec openhtj2k;
   52|      7|  openhtj2k.compcode = BLOSC_CODEC_OPENHTJ2K;
   53|      7|  openhtj2k.version = 1;
   54|      7|  openhtj2k.complib = BLOSC_CODEC_OPENHTJ2K;
   55|      7|  openhtj2k.encoder = NULL;
   56|      7|  openhtj2k.decoder = NULL;
   57|      7|  openhtj2k.compname = "openhtj2k";
   58|      7|  register_codec_private(&openhtj2k);
   59|       |
   60|      7|  blosc2_codec grok;
   61|      7|  grok.compcode = BLOSC_CODEC_GROK;
   62|      7|  grok.version = 1;
   63|      7|  grok.complib = BLOSC_CODEC_GROK;
   64|      7|  grok.encoder = NULL;
   65|      7|  grok.decoder = NULL;
   66|      7|  grok.compname = "grok";
   67|      7|  register_codec_private(&grok);
   68|      7|}

register_filters:
   15|      7|void register_filters(void) {
   16|       |
   17|      7|  blosc2_filter ndcell;
   18|      7|  ndcell.id = BLOSC_FILTER_NDCELL;
   19|      7|  ndcell.name = "ndcell";
   20|      7|  ndcell.version = 1;
   21|      7|  ndcell.forward = &ndcell_forward;
   22|      7|  ndcell.backward = &ndcell_backward;
   23|      7|  register_filter_private(&ndcell);
   24|       |
   25|      7|  blosc2_filter ndmean;
   26|      7|  ndmean.id = BLOSC_FILTER_NDMEAN;
   27|      7|  ndmean.name = "ndmean";
   28|      7|  ndmean.version = 1;
   29|      7|  ndmean.forward = &ndmean_forward;
   30|      7|  ndmean.backward = &ndmean_backward;
   31|      7|  register_filter_private(&ndmean);
   32|       |
   33|       |  // Buggy version. See #524
   34|      7|  blosc2_filter bytedelta_buggy;
   35|      7|  bytedelta_buggy.id = BLOSC_FILTER_BYTEDELTA_BUGGY;
   36|      7|  bytedelta_buggy.name = "bytedelta_buggy";
   37|      7|  bytedelta_buggy.version = 1;
   38|      7|  bytedelta_buggy.forward = &bytedelta_forward_buggy;
   39|      7|  bytedelta_buggy.backward = &bytedelta_backward_buggy;
   40|      7|  register_filter_private(&bytedelta_buggy);
   41|       |
   42|       |  // Fixed version. See #524
   43|      7|  blosc2_filter bytedelta;
   44|      7|  bytedelta.id = BLOSC_FILTER_BYTEDELTA;
   45|      7|  bytedelta.name = "bytedelta";
   46|      7|  bytedelta.version = 1;
   47|      7|  bytedelta.forward = &bytedelta_forward;
   48|      7|  bytedelta.backward = &bytedelta_backward;
   49|      7|  register_filter_private(&bytedelta);
   50|       |
   51|      7|  blosc2_filter int_trunc;
   52|      7|  int_trunc.id = BLOSC_FILTER_INT_TRUNC;
   53|      7|  int_trunc.name = "int_trunc";
   54|      7|  int_trunc.version = 1;
   55|      7|  int_trunc.forward = &int_trunc_forward;
   56|      7|  int_trunc.backward = &int_trunc_backward;
   57|      7|  register_filter_private(&int_trunc);
   58|       |
   59|      7|}

register_tuners:
   13|      7|void register_tuners(void) {
   14|       |
   15|      7|  blosc2_tuner btune;
   16|      7|  btune.id = BLOSC_BTUNE;
   17|      7|  btune.name = "btune";
   18|      7|  btune.init = NULL;
   19|      7|  btune.next_cparams = NULL;
   20|      7|  btune.next_blocksize = NULL;
   21|      7|  btune.update = NULL;
   22|      7|  btune.free = NULL;
   23|       |
   24|      7|  register_tuner_private(&btune);
   25|      7|}

LLVMFuzzerTestOneInput:
   11|      7|int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   12|      7|  int32_t i = 0, dsize = 0;
   13|      7|  int32_t nchunk = 0;
   14|       |
   15|      7|  blosc2_init();
   16|      7|  blosc2_set_nthreads(1);
   17|       |
   18|       |  /* Create a super-chunk backed by an in-memory frame */
   19|      7|  blosc2_schunk* schunk = blosc2_schunk_from_buffer((uint8_t *) data, (int64_t)size, false);
   20|      7|  if (schunk == NULL) {
  ------------------
  |  Branch (20:7): [True: 6, False: 1]
  ------------------
   21|      6|    blosc2_destroy();
   22|      6|    return 0;
   23|      6|  }
   24|       |  /* Don't allow address sanitizer to allocate more than INT32_MAX */
   25|      1|  if (schunk->nbytes >= INT32_MAX) {
  ------------------
  |  Branch (25:7): [True: 0, False: 1]
  ------------------
   26|      0|    blosc2_schunk_free(schunk);
   27|      0|    blosc2_destroy();
   28|      0|    return 0;
   29|      0|  }
   30|       |  /* Decompress data */
   31|      1|  uint8_t *uncompressed_data = (uint8_t *)malloc((size_t)schunk->nbytes+1);
   32|      1|  if (uncompressed_data != NULL) {
  ------------------
  |  Branch (32:7): [True: 1, False: 0]
  ------------------
   33|      4|    for (i = 0, nchunk = 0; nchunk < schunk->nchunks-1; nchunk++) {
  ------------------
  |  Branch (33:29): [True: 4, False: 0]
  ------------------
   34|      4|      dsize = blosc2_schunk_decompress_chunk(schunk, nchunk, uncompressed_data + i, schunk->chunksize);
   35|      4|      if (dsize < 0) {
  ------------------
  |  Branch (35:11): [True: 1, False: 3]
  ------------------
   36|      1|        printf("Decompression error.  Error code: %d\n", dsize);
   37|      1|        break;
   38|      1|      }
   39|      3|      i += dsize;
   40|      3|    }
   41|       |
   42|      1|    free(uncompressed_data);
   43|      1|  }
   44|       |
   45|      1|  blosc2_schunk_free(schunk);
   46|      1|  blosc2_destroy();
   47|      1|  return 0;
   48|      1|}

