// 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 "bmpblk_utility.h"

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

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


/* BMP header, used to validate image requirements
 * See http://en.wikipedia.org/wiki/BMP_file_format
 */
typedef struct {
  uint8_t         CharB;                // must be 'B'
  uint8_t         CharM;                // must be 'M'
  uint32_t        Size;
  uint16_t        Reserved[2];
  uint32_t        ImageOffset;
  uint32_t        HeaderSize;
  uint32_t        PixelWidth;
  uint32_t        PixelHeight;
  uint16_t        Planes;               // Must be 1 for x86
  uint16_t        BitPerPixel;          // 1, 4, 8, or 24 for x86
  uint32_t        CompressionType;      // 0 (none) for x86, 1 (RLE) for arm
  uint32_t        ImageSize;
  uint32_t        XPixelsPerMeter;
  uint32_t        YPixelsPerMeter;
  uint32_t        NumberOfColors;
  uint32_t        ImportantColors;
} __attribute__((packed)) BMP_IMAGE_HEADER;


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;
  }

  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);


    // HEY: Check the yaml file for self-consistency now. 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\n",
               it->first.c_str(),
               it->second.filename.c_str(),
               it->second.offset,
               it->second.data.tag);
      }
      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);
        }
      }
      // TODO(wfrichar): print debugging info about locale_names
    }
  }

  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 == "1.1") {
      render_hwid_ = true;
    } else if (gotversion == "1.0") {
      minor_version_ = 0;
      render_hwid_ = false;
    } else {
      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;
        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 shouldn't
          // exist in the list of images, but we will still need an
          // ImageInfo struct to remember where to draw the text.
          // Note that if the image name DOES exist, we still will won't
          // display it (yet). Future versions may use that image to hold the
          // font glpyhs, which is why we pass it around now.
          if (render_hwid_) {
            if (screen.image_names[index1] == RENDER_HWID) {
              config_.images_map[RENDER_HWID].data.tag = TAG_HWID;
            } else if (screen.image_names[index1] == RENDER_HWID_RTOL) {
              config_.images_map[RENDER_HWID_RTOL].data.tag = TAG_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 = get_image_format(content);
      switch (it->second.data.format) {
      case FORMAT_BMP:
        it->second.data.width = get_bmp_image_width(it->second.raw_content);
        it->second.data.height = get_bmp_image_height(it->second.raw_content);
        break;
      default:
        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;
  }

  ImageFormat BmpBlockUtil::get_image_format(const string content) {
    if (content.size() < sizeof(BMP_IMAGE_HEADER))
      return FORMAT_INVALID;
    const BMP_IMAGE_HEADER *hdr = (const BMP_IMAGE_HEADER *)content.c_str();

    if (hdr->CharB != 'B' || hdr->CharM != 'M' ||
        hdr->Planes != 1 ||
        (hdr->CompressionType != 0 && hdr->CompressionType != 1) ||
        (hdr->BitPerPixel != 1 && hdr->BitPerPixel != 4 &&
         hdr->BitPerPixel != 8 && hdr->BitPerPixel != 24))
      return FORMAT_INVALID;

    return FORMAT_BMP;
  }

  uint32_t BmpBlockUtil::get_bmp_image_width(const string content) {
    const BMP_IMAGE_HEADER *hdr = (const BMP_IMAGE_HEADER *)content.c_str();
    return hdr->PixelWidth;
  }

  uint32_t BmpBlockUtil::get_bmp_image_height(const string content) {
    const BMP_IMAGE_HEADER *hdr = (const BMP_IMAGE_HEADER *)content.c_str();
    return hdr->PixelHeight;
  }

  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\n",
               it->first.c_str(),
               it->second.filename.c_str(),
               it->second.offset,
               it->second.data.tag);
      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

#ifdef WITH_UTIL_MAIN

  //////////////////////////////////////////////////////////////////////////////
  // 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  // WITH_UTIL_MAIN
