// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Utility for manipulating firmware screen block (BMPBLOCK) in GBB.
//

#include <assert.h>
#include <errno.h>
#include <getopt.h>
#include <lzma.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <yaml.h>

#include "bmpblk_utility.h"
#include "image_types.h"
#include "vboot_api.h"

extern "C" {
#include "eficompress.h"
}


static void error(const char *format, ...) {
  va_list ap;
  va_start(ap, format);
  fprintf(stderr, "ERROR: ");
  vfprintf(stderr, format, ap);
  va_end(ap);
  exit(1);
}

///////////////////////////////////////////////////////////////////////
// BmpBlock Utility implementation

namespace vboot_reference {

  BmpBlockUtil::BmpBlockUtil(bool debug) {
    major_version_ = BMPBLOCK_MAJOR_VERSION;
    minor_version_ = BMPBLOCK_MINOR_VERSION;
    config_.config_filename.clear();
    memset(&config_.header, '\0', BMPBLOCK_SIGNATURE_SIZE);
    config_.images_map.clear();
    config_.screens_map.clear();
    config_.localizations.clear();
    bmpblock_.clear();
    set_compression_ = false;
    compression_ = COMPRESS_NONE;
    debug_ = debug;
    render_hwid_ = true;
    support_font_ = true;
    got_font_ = false;
    got_rtol_font_ = false;
  }

  BmpBlockUtil::~BmpBlockUtil() {
  }

  void BmpBlockUtil::force_compression(uint32_t compression) {
    compression_ = compression;
    set_compression_ = true;
  }

  void BmpBlockUtil::load_from_config(const char *filename) {
    load_yaml_config(filename);
    fill_bmpblock_header();
    load_all_image_files();
  }

  void BmpBlockUtil::load_yaml_config(const char *filename) {
    yaml_parser_t parser;

    config_.config_filename = filename;
    config_.images_map.clear();
    config_.screens_map.clear();
    config_.localizations.clear();
    config_.locale_names.clear();

    FILE *fp = fopen(filename, "rb");
    if (!fp) {
      perror(filename);
      exit(errno);
    }

    yaml_parser_initialize(&parser);
    yaml_parser_set_input_file(&parser, fp);
    parse_config(&parser);
    yaml_parser_delete(&parser);
    fclose(fp);


    // TODO: Check the yaml file for self-consistency. Warn on any problems.
    // All images should be used somewhere in the screens.
    // All images referenced in the screens should be defined.
    // All screens should be used somewhere in the localizations.
    // All screens referenced in the localizations should be defined.
    // The number of localizations should match the number of locale_index

    if (debug_) {
      printf("%ld image_names\n", config_.image_names.size());
      for (unsigned int i = 0; i < config_.image_names.size(); ++i) {
        printf(" %d: \"%s\"\n", i, config_.image_names[i].c_str());
      }
      printf("%ld images_map\n", config_.images_map.size());
      for (StrImageConfigMap::iterator it = config_.images_map.begin();
           it != config_.images_map.end();
           ++it) {
        printf("  \"%s\": filename=\"%s\" offset=0x%x tag=%d fmt=%d\n",
               it->first.c_str(),
               it->second.filename.c_str(),
               it->second.offset,
               it->second.data.tag,
               it->second.data.format);
      }
      printf("%ld screens_map\n", config_.screens_map.size());
      for (StrScreenConfigMap::iterator it = config_.screens_map.begin();
           it != config_.screens_map.end();
           ++it) {
        printf("  \"%s\":\n", it->first.c_str());
        for (int k=0; k<MAX_IMAGE_IN_LAYOUT; k++) {
          printf("    %d: \"%s\" (%d,%d) ofs=0x%x\n",
                 k,
                 it->second.image_names[k].c_str(),
                 it->second.data.images[k].x,
                 it->second.data.images[k].y,
                 it->second.data.images[k].image_info_offset);
        }
      }
    }
  }

  void BmpBlockUtil::expect_event(yaml_parser_t *parser,
                                  const yaml_event_type_e type) {
    yaml_event_t event;
    yaml_parser_parse(parser, &event);
    if (event.type != type) {
      error("Syntax error.\n");
    }
    yaml_event_delete(&event);
  }

  void BmpBlockUtil::parse_config(yaml_parser_t *parser) {
    expect_event(parser, YAML_STREAM_START_EVENT);
    expect_event(parser, YAML_DOCUMENT_START_EVENT);
    parse_first_layer(parser);
    expect_event(parser, YAML_DOCUMENT_END_EVENT);
    expect_event(parser, YAML_STREAM_END_EVENT);
  }

  void BmpBlockUtil::parse_first_layer(yaml_parser_t *parser) {
    yaml_event_t event;
    string keyword;
    expect_event(parser, YAML_MAPPING_START_EVENT);
    for (;;) {
      yaml_parser_parse(parser, &event);
      switch (event.type) {
      case YAML_SCALAR_EVENT:
        keyword = (char*)event.data.scalar.value;
        if (keyword == "bmpblock") {
          parse_bmpblock(parser);
        } else if (keyword == "compression") {
          parse_compression(parser);
        } else if (keyword == "images") {
          parse_images(parser);
        } else if (keyword == "screens") {
          parse_screens(parser);
        } else if (keyword == "localizations") {
          parse_localizations(parser);
        } else if (keyword == "locale_index") {
          parse_locale_index(parser);
        }
        break;
      case YAML_MAPPING_END_EVENT:
        yaml_event_delete(&event);
        return;
      default:
        error("Syntax error in parsing config file.\n");
      }
      yaml_event_delete(&event);
    }
  }

  void BmpBlockUtil::parse_bmpblock(yaml_parser_t *parser) {
    yaml_event_t event;
    yaml_parser_parse(parser, &event);
    if (event.type != YAML_SCALAR_EVENT) {
      error("Syntax error in parsing bmpblock.\n");
    }
    string gotversion = (char*)event.data.scalar.value;
    if (gotversion != "2.0") {
      error("Unsupported version specified in config file (%s)\n",
            gotversion.c_str());
    }
    yaml_event_delete(&event);
  }

  void BmpBlockUtil::parse_compression(yaml_parser_t *parser) {
    yaml_event_t event;
    yaml_parser_parse(parser, &event);
    if (event.type != YAML_SCALAR_EVENT) {
      error("Syntax error in parsing bmpblock.\n");
    }
    char *comp_str = (char *)event.data.scalar.value;
    char *e = 0;
    uint32_t comp = (uint32_t)strtoul(comp_str, &e, 0);
    if (!*comp_str || (e && *e) || comp >= MAX_COMPRESS) {
      error("Invalid compression specified in config file (%d)\n", comp);
    }
    if (!set_compression_) {
      compression_ = comp;
    }
    yaml_event_delete(&event);
  }

  void BmpBlockUtil::parse_images(yaml_parser_t *parser) {
    yaml_event_t event;
    string image_name, image_filename;
    expect_event(parser, YAML_MAPPING_START_EVENT);
    for (;;) {
      yaml_parser_parse(parser, &event);
      switch (event.type) {
      case YAML_SCALAR_EVENT:
        image_name = (char*)event.data.scalar.value;
        yaml_event_delete(&event);
        yaml_parser_parse(parser, &event);
        if (event.type != YAML_SCALAR_EVENT) {
          error("Syntax error in parsing images.\n");
        }
        image_filename = (char*)event.data.scalar.value;
        config_.image_names.push_back(image_name);
        config_.images_map[image_name] = ImageConfig();
        config_.images_map[image_name].filename = image_filename;
        if (image_name == RENDER_HWID) {
          got_font_ = true;
        }
        if (image_name == RENDER_HWID_RTOL) {
          got_rtol_font_ = true;
        }
        break;
      case YAML_MAPPING_END_EVENT:
        yaml_event_delete(&event);
        return;
      default:
        error("Syntax error in parsing images.\n");
      }
      yaml_event_delete(&event);
    }
  }

  void BmpBlockUtil::parse_layout(yaml_parser_t *parser, ScreenConfig &screen) {
    yaml_event_t event;
    int depth = 0, index1 = 0, index2 = 0;
    expect_event(parser, YAML_SEQUENCE_START_EVENT);
    for (;;) {
      yaml_parser_parse(parser, &event);
      switch (event.type) {
      case YAML_SEQUENCE_START_EVENT:
        depth++;
        break;
      case YAML_SCALAR_EVENT:
        switch (index2) {
        case 0:
          screen.data.images[index1].x = atoi((char*)event.data.scalar.value);
          break;
        case 1:
          screen.data.images[index1].y = atoi((char*)event.data.scalar.value);
          break;
        case 2:
          screen.image_names[index1] = (char*)event.data.scalar.value;
          // Detect the special case where we're rendering the HWID string
          // instead of displaying a bitmap.  The image name may not
          // exist in the list of images (v1.1), but we will still need an
          // ImageInfo struct to remember where to draw the text.
          // Note that v1.2 requires that the image name DOES exist, because
          // the corresponding file is used to hold the font glpyhs.
          if (render_hwid_) {
            if (screen.image_names[index1] == RENDER_HWID) {
              config_.images_map[RENDER_HWID].data.tag = TAG_HWID;
              if (support_font_ && !got_font_)
                error("Font required in 'image:' section for %s\n",
                      RENDER_HWID);
            } else if (screen.image_names[index1] == RENDER_HWID_RTOL) {
              config_.images_map[RENDER_HWID_RTOL].data.tag = TAG_HWID_RTOL;
              if (support_font_ && !got_rtol_font_)
                error("Font required in 'image:' section for %s\n",
                      RENDER_HWID_RTOL);
            }
          }
          break;
        default:
          error("Syntax error in parsing layout\n");
        }
        index2++;
        break;
      case YAML_SEQUENCE_END_EVENT:
        if (depth == 1) {
          index1++;
          index2 = 0;
        } else if (depth == 0) {
          yaml_event_delete(&event);
          return;
        }
        depth--;
        break;
      default:
        error("Syntax error in paring layout.\n");
      }
      yaml_event_delete(&event);
    }
  }

  void BmpBlockUtil::parse_screens(yaml_parser_t *parser) {
    yaml_event_t event;
    string screen_name;
    expect_event(parser, YAML_MAPPING_START_EVENT);
    for (;;) {
      yaml_parser_parse(parser, &event);
      switch (event.type) {
      case YAML_SCALAR_EVENT:
        screen_name = (char*)event.data.scalar.value;
        config_.screens_map[screen_name] = ScreenConfig();
        parse_layout(parser, config_.screens_map[screen_name]);
        break;
      case YAML_MAPPING_END_EVENT:
        yaml_event_delete(&event);
        return;
      default:
        error("Syntax error in parsing screens.\n");
      }
      yaml_event_delete(&event);
    }
  }

  void BmpBlockUtil::parse_localizations(yaml_parser_t *parser) {
    yaml_event_t event;
    int depth = 0, index = 0;
    expect_event(parser, YAML_SEQUENCE_START_EVENT);
    for (;;) {
      yaml_parser_parse(parser, &event);
      switch (event.type) {
      case YAML_SEQUENCE_START_EVENT:
        config_.localizations.push_back(vector<string>());
        depth++;
        break;
      case YAML_SCALAR_EVENT:
        config_.localizations[index].push_back((char*)event.data.scalar.value);
        break;
      case YAML_SEQUENCE_END_EVENT:
        if (depth == 1) {
          index++;
        } else if (depth == 0) {
          yaml_event_delete(&event);
          return;
        }
        depth--;
        break;
      default:
        error("Syntax error in parsing localizations.\n");
      }
      yaml_event_delete(&event);
    }
  }

  void BmpBlockUtil::parse_locale_index(yaml_parser_t *parser) {
    yaml_event_t event;
    expect_event(parser, YAML_SEQUENCE_START_EVENT);
    for (;;) {
      yaml_parser_parse(parser, &event);
      switch (event.type) {
      case YAML_SCALAR_EVENT:
        config_.locale_names.append((char*)event.data.scalar.value);
        config_.locale_names.append(1, (char)'\0'); // '\0' to delimit
        break;
      case YAML_SEQUENCE_END_EVENT:
        yaml_event_delete(&event);
        config_.locale_names.append(1, (char)'\0'); // double '\0' to terminate
        return;
      default:
        error("Syntax error in parsing localizations.\n");
      }
    }
  }

  void BmpBlockUtil::load_all_image_files() {
    for (unsigned int i = 0; i < config_.image_names.size(); i++) {
      StrImageConfigMap::iterator it =
        config_.images_map.find(config_.image_names[i]);
      if (debug_) {
        printf("loading image \"%s\" from \"%s\"\n",
               config_.image_names[i].c_str(),
               it->second.filename.c_str());
      }
      const string &content = read_image_file(it->second.filename.c_str());
      it->second.raw_content = content;
      it->second.data.original_size = content.size();
      it->second.data.format =
        identify_image_type(content.c_str(),
                            (uint32_t)content.size(), &it->second.data);
      if (FORMAT_INVALID == it->second.data.format) {
        error("Unsupported image format in %s\n", it->second.filename.c_str());
      }
      switch(compression_) {
      case COMPRESS_NONE:
        it->second.data.compression = compression_;
        it->second.compressed_content = content;
        it->second.data.compressed_size = content.size();
        break;
      case COMPRESS_EFIv1:
      {
        // The content will always compress smaller (so sez the docs).
        uint32_t tmpsize = content.size();
        uint8_t *tmpbuf = (uint8_t *)malloc(tmpsize);
        // The size of the compressed content is also returned.
        if (EFI_SUCCESS != EfiCompress((uint8_t *)content.c_str(), tmpsize,
                                       tmpbuf, &tmpsize)) {
          error("Unable to compress!\n");
        }
        it->second.data.compression = compression_;
        it->second.compressed_content.assign((const char *)tmpbuf, tmpsize);
        it->second.data.compressed_size = tmpsize;
        free(tmpbuf);
      }
      break;
      case COMPRESS_LZMA1:
      {
        // Calculate the worst case of buffer size.
        uint32_t tmpsize = lzma_stream_buffer_bound(content.size());
        uint8_t *tmpbuf = (uint8_t *)malloc(tmpsize);
        lzma_stream stream = LZMA_STREAM_INIT;
        lzma_options_lzma options;
        lzma_ret result;

        lzma_lzma_preset(&options, 9);
        result = lzma_alone_encoder(&stream, &options);
        if (result != LZMA_OK) {
          error("Unable to initialize easy encoder (error: %d)!\n", result);
        }

        stream.next_in = (uint8_t *)content.data();
        stream.avail_in = content.size();
        stream.next_out = tmpbuf;
        stream.avail_out = tmpsize;
        result = lzma_code(&stream, LZMA_FINISH);
        if (result != LZMA_STREAM_END) {
          error("Unable to encode data (error: %d)!\n", result);
        }

        it->second.data.compression = compression_;
        it->second.compressed_content.assign((const char *)tmpbuf,
                                             tmpsize - stream.avail_out);
        it->second.data.compressed_size = tmpsize - stream.avail_out;
        lzma_end(&stream);
        free(tmpbuf);
      }
      break;
      default:
        error("Unsupported compression method attempted.\n");
      }
    }
  }

  const string BmpBlockUtil::read_image_file(const char *filename) {
    string content;
    vector<char> buffer;

    FILE *fp = fopen(filename, "rb");
    if (!fp) {
      perror(filename);
      exit(errno);
    }

    if (fseek(fp, 0, SEEK_END) == 0) {
      buffer.resize(ftell(fp));
      rewind(fp);
    }

    if (!buffer.empty()) {
      if(fread(&buffer[0], buffer.size(), 1, fp) != 1) {
        perror(filename);
        buffer.clear();
      } else {
        content.assign(buffer.begin(), buffer.end());
      }
    }

    fclose(fp);
    return content;
  }

  void BmpBlockUtil::fill_bmpblock_header() {
    memset(&config_.header, '\0', sizeof(config_.header));
    memcpy(&config_.header.signature, BMPBLOCK_SIGNATURE,
           BMPBLOCK_SIGNATURE_SIZE);
    config_.header.major_version = major_version_;
    config_.header.minor_version = minor_version_;
    config_.header.number_of_localizations = config_.localizations.size();
    config_.header.number_of_screenlayouts = config_.localizations[0].size();
    // HEY: this is part of the yaml consistency check
    for (unsigned int i = 1; i < config_.localizations.size(); ++i) {
      assert(config_.header.number_of_screenlayouts ==
             config_.localizations[i].size());
    }
    config_.header.number_of_imageinfos = config_.images_map.size();
    config_.header.locale_string_offset = 0; // Filled by pack_bmpblock()
  }

  void BmpBlockUtil::pack_bmpblock() {
    bmpblock_.clear();

    /* Compute the ImageInfo offsets from start of BMPBLOCK. */
    uint32_t current_offset = sizeof(BmpBlockHeader) +
      sizeof(ScreenLayout) * (config_.header.number_of_localizations *
                              config_.header.number_of_screenlayouts);
    for (StrImageConfigMap::iterator it = config_.images_map.begin();
         it != config_.images_map.end();
         ++it) {
      it->second.offset = current_offset;
      if (debug_)
        printf("  \"%s\": filename=\"%s\" offset=0x%x tag=%d fmt=%d\n",
               it->first.c_str(),
               it->second.filename.c_str(),
               it->second.offset,
               it->second.data.tag,
               it->second.data.format);
      current_offset += sizeof(ImageInfo) +
        it->second.data.compressed_size;
      /* Make it 4-byte aligned. */
      if ((current_offset & 3) > 0) {
        current_offset = (current_offset & ~3) + 4;
      }
    }
    /* And leave room for the locale_index string */
    if (config_.locale_names.size()) {
      config_.header.locale_string_offset = current_offset;
      current_offset += config_.locale_names.size();
    }

    bmpblock_.resize(current_offset);

    /* Fill BmpBlockHeader struct. */
    string::iterator current_filled = bmpblock_.begin();
    std::copy(reinterpret_cast<char*>(&config_.header),
              reinterpret_cast<char*>(&config_.header + 1),
              current_filled);
    current_filled += sizeof(config_.header);
    current_offset = sizeof(config_.header);

    /* Fill all ScreenLayout structs. */
    for (unsigned int i = 0; i < config_.localizations.size(); ++i) {
      for (unsigned int j = 0; j < config_.localizations[i].size(); ++j) {
        ScreenConfig &screen = config_.screens_map[config_.localizations[i][j]];
        for (unsigned int k = 0;
             k < MAX_IMAGE_IN_LAYOUT && !screen.image_names[k].empty();
             ++k) {
          if (config_.images_map.find(screen.image_names[k]) ==
              config_.images_map.end()) {
            error("Invalid image name \"%s\"\n", screen.image_names[k].c_str());
          }
          if (debug_)
            printf("i=%d j=%d k=%d=\"%s\" (%d,%d) ofs=%x\n", i,j,k,
                   screen.image_names[k].c_str(),
                   screen.data.images[k].x, screen.data.images[k].y,
                   config_.images_map[screen.image_names[k]].offset
              );
          screen.data.images[k].image_info_offset =
            config_.images_map[screen.image_names[k]].offset;
        }
        std::copy(reinterpret_cast<char*>(&screen.data),
                  reinterpret_cast<char*>(&screen.data + 1),
                  current_filled);
        current_filled += sizeof(screen.data);
        if (debug_)
          printf("S: current offset is 0x%08x\n", current_offset);
        current_offset += sizeof(screen.data);
      }
    }

    /* Fill all ImageInfo structs and image contents. */
    for (StrImageConfigMap::iterator it = config_.images_map.begin();
         it != config_.images_map.end();
         ++it) {
      current_filled = bmpblock_.begin() + it->second.offset;
      current_offset = it->second.offset;
      if (debug_)
        printf("I0: current offset is 0x%08x\n", current_offset);
      std::copy(reinterpret_cast<char*>(&it->second.data),
                reinterpret_cast<char*>(&it->second.data + 1),
                current_filled);
      current_filled += sizeof(it->second.data);
      current_offset += sizeof(it->second.data);
      if (debug_)
        printf("I1: current offset is 0x%08x (len %ld)\n",
               current_offset, it->second.compressed_content.length());
      std::copy(it->second.compressed_content.begin(),
                it->second.compressed_content.end(),
                current_filled);
    }

    /* Fill in locale_names. */
    if (config_.header.locale_string_offset) {
      current_offset = config_.header.locale_string_offset;
      current_filled = bmpblock_.begin() + current_offset;
      if (debug_)
        printf("locale_names: offset 0x%08x (len %ld)\n",
               current_offset, config_.locale_names.size());
      std::copy(config_.locale_names.begin(),
                config_.locale_names.end(),
                current_filled);
    }
  }

  void BmpBlockUtil::write_to_bmpblock(const char *filename) {
    assert(!bmpblock_.empty());

    FILE *fp = fopen(filename, "wb");
    if (!fp) {
      perror(filename);
      exit(errno);
    }

    int r = fwrite(bmpblock_.c_str(), bmpblock_.size(), 1, fp);
    fclose(fp);
    if (r != 1) {
      perror(filename);
      exit(errno);
    }
  }

}  // namespace vboot_reference

#ifndef FOR_LIBRARY

  //////////////////////////////////////////////////////////////////////////////
  // Command line utilities.

  extern "C" {
#include "bmpblk_util.h"
  }

  using vboot_reference::BmpBlockUtil;

  // utility function: provide usage of this utility and exit.
  static void usagehelp_exit(const char *prog_name) {
    printf(
      "\n"
      "To create a new BMPBLOCK file using config from YAML file:\n"
      "\n"
      "  %s [-z NUM] -c YAML BMPBLOCK\n"
      "\n"
      "    -z NUM  = compression algorithm to use\n"
      "              0 = none\n"
      "              1 = EFIv1\n"
      "              2 = LZMA1\n"
      "\n", prog_name);
    printf(
      "To display the contents of a BMPBLOCK:\n"
      "\n"
      "  %s [-y] BMPBLOCK\n"
      "\n"
      "    -y  = display as yaml\n"
      "\n", prog_name);
    printf(
      "To unpack a BMPBLOCK file:\n"
      "\n"
      "  %s -x [-d DIR] [-f] BMPBLOCK\n"
      "\n"
      "    -d DIR  = directory to use (default '.')\n"
      "    -f      = force overwriting existing files\n"
      "\n", prog_name);
    exit(1);
  }

  ///////////////////////////////////////////////////////////////////////
  // main

  int main(int argc, char *argv[]) {

    const char *prog_name = strrchr(argv[0], '/');
    if (prog_name)
      prog_name++;
    else
      prog_name = argv[0];

    int overwrite = 0, extract_mode = 0;
    int compression = 0;
    int set_compression = 0;
    const char *config_fn = 0, *bmpblock_fn = 0, *extract_dir = ".";
    int show_as_yaml = 0;
    bool debug = false;

    int opt;
    opterr = 0;                           // quiet
    int errorcnt = 0;
    char *e = 0;
    while ((opt = getopt(argc, argv, ":c:xz:fd:yD")) != -1) {
      switch (opt) {
      case 'c':
        config_fn = optarg;
        break;
      case 'x':
        extract_mode = 1;
        break;
      case 'y':
        show_as_yaml = 1;
        break;
      case 'z':
        compression = (int)strtoul(optarg, &e, 0);
        if (!*optarg || (e && *e)) {
          fprintf(stderr, "%s: invalid argument to -%c: \"%s\"\n",
                  prog_name, opt, optarg);
          errorcnt++;
        }
        if (compression >= MAX_COMPRESS) {
          fprintf(stderr, "%s: compression type must be less than %d\n",
                  prog_name, MAX_COMPRESS);
          errorcnt++;
        }
        set_compression = 1;
        break;
      case 'f':
        overwrite = 1;
        break;
      case 'd':
        extract_dir= optarg;
        break;
      case 'D':
        debug = true;
        break;
      case ':':
        fprintf(stderr, "%s: missing argument to -%c\n",
                prog_name, optopt);
        errorcnt++;
        break;
      default:
        fprintf(stderr, "%s: unrecognized switch: -%c\n",
                prog_name, optopt);
        errorcnt++;
        break;
      }
    }
    argc -= optind;
    argv += optind;

    if (argc >= 1) {
      bmpblock_fn = argv[0];
    } else {
      fprintf(stderr, "%s: missing BMPBLOCK name\n", prog_name);
      errorcnt++;
    }

    if (errorcnt)
      usagehelp_exit(prog_name);

    BmpBlockUtil util(debug);

    if (config_fn) {
      if (set_compression)
        util.force_compression(compression);
      util.load_from_config(config_fn);
      util.pack_bmpblock();
      util.write_to_bmpblock(bmpblock_fn);
    }

    else if (extract_mode) {
      return dump_bmpblock(bmpblock_fn, 1, extract_dir, overwrite);
    } else {
      return dump_bmpblock(bmpblock_fn, show_as_yaml, 0, 0);
    }

    return 0;
  }

#endif // FOR_LIBRARY
