Revert for fixing the chromium os build.

Revert "This change define the data structure of bmp block and implements the create more of bmpblk_utility. It reads a YAML config file, parse the informations, and creates bmpblock file as output."

This reverts commit 95b0ae01ea.

BUG=none
TEST=emerge-x86 vboot_reference
TBR=waihong@chromium.org

Change-Id: If1692ca12ddb61b7814ca7dddccee5a395c8bed1
This commit is contained in:
Satoru Takabayashi
2011-01-27 20:05:04 +09:00
parent 95b0ae01ea
commit 25364052f2
5 changed files with 0 additions and 892 deletions

View File

@@ -1,122 +0,0 @@
/* 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.
*
* Data structure definitions for firmware screen block (BMPBLOCK).
*
* The BmpBlock structure looks like:
* +----------------------------------------+
* | BmpBlock Header |
* +----------------------------------------+
* | ScrenLayout[0] | \
* +----------------------------------------+ |
* | ScrenLayout[1] | |
* +----------------------------------------+ Localization[0]
* | ... | |
* +----------------------------------------+ |
* | ScrenLayout[number_of_screenlayouts-1] | /
* +----------------------------------------+
* | ScrenLayout[0] | \
* +----------------------------------------+ Localization[1]
* | ... | /
* +----------------------------------------+ ...
* | ScrenLayout[0] | \
* +----------------------------------------+ Localization[
* | ... | / number_of_localizations-1]
* +----------------------------------------+
* | ImageInfo[0] |
* +----------------------------------------+
* | Image Content |
* +----------------------------------------+
* | ImageInfo[2] | ImageInfo is 4-byte aligned.
* +----------------------------------------+
* | Image Content |
* +----------------------------------------+
* | ... |
* +----------------------------------------+
* | ImageInfo[number_fo_images-1] |
* +----------------------------------------+
* | Image Content |
* +----------------------------------------+
*
*/
#ifndef VBOOT_REFERENCE_BMPBLK_HEADER_H_
#define VBOOT_REFERENCE_BMPBLK_HEADER_H_
#include "sysincludes.h"
__pragma(pack(push, 1)) /* Support packing for MSVC. */
#define BMPBLOCK_SIGNATURE "$BMP"
#define BMPBLOCK_SIGNATURE_SIZE (4)
#define BMPBLOCK_MAJOR_VER (0x01)
#define BMPBLOCK_MINOR_VER (0x00)
#define MAX_IMAGE_IN_LAYOUT (8)
/* BMPBLOCK header, describing how many screen layouts and image infos */
typedef struct BmpBlockHeader {
uint8_t signature[BMPBLOCK_SIGNATURE_SIZE]; /* BMPBLOCK_SIGNATURE $BMP */
uint16_t major_version; /* See BMPBLOCK_MAJOR_VER */
uint16_t minor_version; /* See BMPBLOCK_MINOR_VER */
uint32_t number_of_localizations; /* Number of localizations */
uint32_t number_of_screenlayouts; /* Number of screen layouts in each
* localization */
uint32_t number_of_imageinfos; /* Number of image infos */
uint32_t reserved[3];
} __attribute__((packed)) BmpBlockHeader;
/* Screen layout, describing how to stack multiple images on screen */
typedef struct ScreenLayout {
struct {
uint32_t x; /* X-offset of the image to be rendered */
uint32_t y; /* Y-offset of the image to be rendered */
uint32_t image_info_offset; /* Offset of image info from start of
* BMPBLOCK. 0 means end of it. */
} images[MAX_IMAGE_IN_LAYOUT]; /* Images contained in the screen. Will be
* rendered from 0 to (number_of_images-1). */
} __attribute__((packed)) ScreenLayout;
/* Constants for screen index */
typedef enum ScreenIndex {
SCREEN_DEVELOPER_MODE = 0,
SCREEN_RECOVERY_MODE,
SCREEN_RECOVERY_NO_OS,
SCREEN_RECOVERY_MISSING_OS,
MAX_SCREEN_INDEX,
} ScreenIndex;
/* Image info, describing the information of the image block */
typedef struct ImageInfo {
uint32_t tag; /* Tag it as a special image, like HWID */
uint32_t width; /* Width of the image */
uint32_t height; /* Height of the image */
uint32_t format; /* File format of the image */
uint32_t compression; /* Compression method to the image file */
uint32_t original_size; /* Size of the original uncompressed image */
uint32_t compressed_size; /* Size of the compressed image */
uint32_t reserved;
/* NOTE: actual image content follows immediately */
} __attribute__((packed)) ImageInfo;
/* Constants for ImageInfo.tag */
typedef enum ImageTag {
TAG_NONE = 0,
TAG_HWID,
} ImageTag;
/* Constants for ImageInfo.format */
typedef enum ImageFormat {
FORMAT_INVALID = 0,
FORMAT_BMP,
} ImageFormat;
/* Constants for ImageInfo.compression */
typedef enum Compression {
COMPRESS_NONE = 0,
COMPRESS_LZMA,
} Compression;
#endif /* VBOOT_REFERENCE_BMPBLK_HEADER_H_ */

View File

@@ -1,100 +0,0 @@
# This describes four screens, with three localizations.
bmpblock: 1.0
# These are the individual images which are layered to produce a screen layout.
images:
devmode: Developer.bmp
recovery: Recovery.bmp
rec_insert: RecoveryMissingOS.bmp
rec_yuck: RecoveryNoOS.bmp
url: url.bmp
dev_text_en: dev_text_en.bmp
rec_text_en: rec_text_en.bmp
ins_text_en: ins_text_en.bmp
yuck_text_en: yuck_text_en.bmp
dev_text_fr: dev_text_fr.bmp
rec_text_fr: rec_text_fr.bmp
ins_text_fr: ins_text_fr.bmp
yuck_text_fr: yuck_text_fr.bmp
dev_text_de: dev_text_de.bmp
rec_text_de: rec_text_de.bmp
ins_text_de: ins_text_de.bmp
yuck_text_de: yuck_text_de.bmp
# These are all of the distinct layouts that we know how to display.
screens:
dev_en:
- [0, 0, devmode]
- [100, 500, url]
- [100, 620, dev_text_en]
dev_fr:
- [0, 0, devmode]
- [100, 500, url]
- [100, 620, dev_text_fr]
dev_de:
- [0, 0, devmode]
- [100, 500, url]
- [100, 620, dev_text_de]
rec_en:
- [0, 0, recovery]
- [100, 500, url]
- [100, 620, rec_text_en]
rec_fr:
- [0, 0, recovery]
- [100, 500, url]
- [100, 620, rec_text_fr]
rec_de:
- [0, 0, recovery]
- [100, 500, url]
- [100, 620, rec_text_de]
ins_en:
- [0, 0, rec_insert]
- [100, 500, url]
- [100, 620, ins_text_en]
ins_fr:
- [0, 0, rec_insert]
- [100, 500, url]
- [100, 620, ins_text_fr]
ins_de:
- [0, 0, rec_insert]
- [100, 500, url]
- [100, 620, ins_text_de]
yuck_en:
- [0, 0, rec_yuck]
- [100, 500, url]
- [100, 620, yuck_text_en]
yuck_fr:
- [0, 0, rec_yuck]
- [100, 500, url]
- [100, 620, yuck_text_fr]
yuck_de:
- [0, 0, rec_yuck]
- [100, 500, url]
- [100, 620, yuck_text_de]
# To customize the images for a particular locale, just reorder this list so
# that the default language appears first.
localizations:
- [ dev_en, rec_en, ins_en, yuck_en ]
- [ dev_fr, rec_fr, ins_fr, yuck_fr ]
- [ dev_de, rec_de, ins_de, yuck_de ]

View File

@@ -20,7 +20,6 @@ DESTDIR ?= /usr/bin
TARGET_NAMES = dumpRSAPublicKey \
dump_kernel_config \
gbb_utility \
bmpblk_utility \
load_kernel_test \
signature_digest_utility \
tlcl_generator \
@@ -51,9 +50,6 @@ ${BUILD_ROOT}/dump_kernel_config: dump_kernel_config.c $(LIBS)
${BUILD_ROOT}/gbb_utility: gbb_utility.cc
$(CXX) -DWITH_UTIL_MAIN $(CFLAGS) $< -o $@
${BUILD_ROOT}/bmpblk_utility: bmpblk_utility.cc
$(CXX) -DWITH_UTIL_MAIN -lyaml $(CFLAGS) $< -o $@
${BUILD_ROOT}/load_kernel_test: load_kernel_test.c $(LIBS)
$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto

View File

@@ -1,554 +0,0 @@
// 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 <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <yaml.h>
/* The offsets of width and height fields in a BMP file.
* See http://en.wikipedia.org/wiki/BMP_file_format */
#define BMP_WIDTH_OFFSET 18
#define BMP_HEIGHT_OFFSET 22
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() {
initialize();
}
BmpBlockUtil::~BmpBlockUtil() {
}
void BmpBlockUtil::initialize() {
config_.config_filename.clear();
memset(&config_.header, '\0', BMPBLOCK_SIGNATURE_SIZE);
config_.images_map.clear();
config_.screens_map.clear();
config_.localizations.clear();
bmpblock_.clear();
}
void BmpBlockUtil::load_from_config(const char *filename) {
load_yaml_config(filename);
fill_bmpblock_header();
load_all_image_files();
fill_all_image_infos();
}
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();
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);
}
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 == "images") {
parse_images(parser);
} else if (keyword == "screens") {
parse_screens(parser);
} else if (keyword == "localizations") {
parse_localizations(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");
}
config_.header.major_version = atoi((char*)event.data.scalar.value);
config_.header.minor_version = atoi(
strchr((char*)event.data.scalar.value, '.') + 1);
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_.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;
string screen_name;
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;
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::load_all_image_files() {
for (StrImageConfigMap::iterator it = config_.images_map.begin();
it != config_.images_map.end();
++it) {
const string &content = read_image_file(it->second.filename.c_str());
it->second.raw_content = content;
it->second.data.original_size = content.size();
/* Use no compression as default */
it->second.data.compression = COMPRESS_NONE;
it->second.compressed_content = content;
it->second.data.compressed_size = content.size();
}
}
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[0] == 'B' && content[1] == 'M')
return FORMAT_BMP;
else
return FORMAT_INVALID;
}
uint32_t BmpBlockUtil::get_bmp_image_width(const string content) {
const char *start = content.c_str();
uint32_t width = *(uint32_t*)(start + BMP_WIDTH_OFFSET);
/* Do a rough verification. */
assert(width > 0 && width < 1600);
return width;
}
uint32_t BmpBlockUtil::get_bmp_image_height(const string content) {
const char *start = content.c_str();
uint32_t height = *(uint32_t*)(start + BMP_HEIGHT_OFFSET);
/* Do a rough verification. */
assert(height > 0 && height < 1000);
return height;
}
void BmpBlockUtil::fill_all_image_infos() {
for (StrImageConfigMap::iterator it = config_.images_map.begin();
it != config_.images_map.end();
++it) {
it->second.data.format = (uint32_t)get_image_format(it->second.raw_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.");
}
}
}
void BmpBlockUtil::compress_all_images(const Compression compress) {
switch (compress) {
case COMPRESS_NONE:
for (StrImageConfigMap::iterator it = config_.images_map.begin();
it != config_.images_map.end();
++it) {
it->second.data.compression = compress;
it->second.compressed_content = it->second.raw_content;
it->second.data.compressed_size = it->second.compressed_content.size();
}
break;
case COMPRESS_LZMA:
/* TODO(waihong): Implement the support of LZMA. */
break;
default:
error("Unsupported data compression.");
}
}
void BmpBlockUtil::fill_bmpblock_header() {
memset(&config_.header, '\0', sizeof(config_.header));
memcpy(&config_.header.signature, BMPBLOCK_SIGNATURE,
BMPBLOCK_SIGNATURE_SIZE);
config_.header.number_of_localizations = config_.localizations.size();
config_.header.number_of_screenlayouts = config_.localizations[0].size();
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();
}
void BmpBlockUtil::pack_bmpblock() {
bmpblock_.clear();
/* Compute the ImageInfo offsets from start of BMPBLOCK. */
uint32_t current_offset = sizeof(BmpBlockHeader) +
sizeof(ScreenLayout) * config_.images_map.size();
for (StrImageConfigMap::iterator it = config_.images_map.begin();
it != config_.images_map.end();
++it) {
it->second.offset = current_offset;
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;
}
}
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);
/* 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) {
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);
}
}
/* 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;
std::copy(reinterpret_cast<char*>(&it->second.data),
reinterpret_cast<char*>(&it->second.data + 1),
current_filled);
current_filled += sizeof(it->second.data);
std::copy(it->second.compressed_content.begin(),
it->second.compressed_content.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
using vboot_reference::BmpBlockUtil;
// utility function: provide usage of this utility and exit.
static void usagehelp_exit(const char *prog_name) {
printf(
"Utility to manage firmware screen block (BMPBLOCK)\n"
"Usage: %s -c|-l|-x [options] BMPBLOCK_FILE\n"
"\n"
"Main Operation Mode:\n"
" -c, --create Create a new BMPBLOCK file. Should specify --config.\n"
" -l, --list List the contents of a BMPBLOCK file.\n"
" -x, --extract Extract embedded images and config file from a BMPBLOCK\n"
" file.\n"
"\n"
"Other Options:\n"
" -C, --config=CONFIG_FILE Config file describing screen layouts and\n"
" embedded images. (default: bmpblk.cfg)\n"
"\n"
"Example:\n"
" %s --create --config=screens.cfg bmpblk.bin\n"
, prog_name, prog_name);
exit(1);
}
///////////////////////////////////////////////////////////////////////
// main
int main(int argc, char *argv[]) {
const char *prog_name = argv[0];
BmpBlockUtil util;
struct BmpBlockUtilOptions {
bool create_mode, list_mode, extract_mode;
string config_fn, bmpblock_fn;
} options;
int longindex, opt;
static struct option longopts[] = {
{"create", 0, NULL, 'c'},
{"list", 0, NULL, 'l'},
{"extract", 0, NULL, 'x'},
{"config", 1, NULL, 'C'},
{ NULL, 0, NULL, 0 },
};
while ((opt = getopt_long(argc, argv, "clxC:", longopts, &longindex)) >= 0) {
switch (opt) {
case 'c':
options.create_mode = true;
break;
case 'l':
options.list_mode = true;
break;
case 'x':
options.extract_mode = true;
break;
case 'C':
options.config_fn = optarg;
break;
default:
case '?':
usagehelp_exit(prog_name);
break;
}
}
argc -= optind;
argv += optind;
if (argc == 1) {
options.bmpblock_fn = argv[0];
} else {
usagehelp_exit(prog_name);
}
if (options.create_mode) {
util.load_from_config(options.config_fn.c_str());
util.pack_bmpblock();
util.write_to_bmpblock(options.bmpblock_fn.c_str());
printf("The BMPBLOCK is sucessfully created in: %s.\n",
options.bmpblock_fn.c_str());
}
if (options.list_mode) {
/* TODO(waihong): Implement the list mode. */
error("List mode hasn't been implemented yet.\n");
}
if (options.extract_mode) {
/* TODO(waihong): Implement the extract mode. */
error("Extract mode hasn't been implemented yet.\n");
}
return 0;
}
#endif // WITH_UTIL_MAIN

View File

@@ -1,112 +0,0 @@
// 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.
#ifndef VBOOT_REFERENCE_BMPBLK_UTILITY_H_
#define VBOOT_REFERENCE_BMPBLK_UTILITY_H_
#include "bmpblk_header.h"
#include <yaml.h>
#include <map>
#include <string>
#include <vector>
using std::map;
using std::string;
using std::vector;
namespace vboot_reference {
/* Internal struct for contructing ImageInfo. */
typedef struct ImageConfig {
ImageInfo data;
string filename;
string raw_content;
string compressed_content;
uint32_t offset;
} ImageConfig;
/* Internal struct for contructing ScreenLayout. */
typedef struct ScreenConfig {
ScreenLayout data;
string image_names[MAX_IMAGE_IN_LAYOUT];
} ScreenConfig;
typedef map<string, ImageConfig> StrImageConfigMap;
typedef map<string, ScreenConfig> StrScreenConfigMap;
/* Internal struct for contructing the whole BmpBlock. */
typedef struct BmpBlockConfig {
string config_filename;
BmpBlockHeader header;
StrImageConfigMap images_map;
StrScreenConfigMap screens_map;
vector<vector<string> > localizations;
} BmpBlockConfig;
class BmpBlockUtil {
public:
BmpBlockUtil();
~BmpBlockUtil();
/* Load all the images and related infomations according to a config file. */
void load_from_config(const char *filename);
/* Compress all the images using a given comression method. */
void compress_all_images(const Compression compress);
/* Contruct the bmpblock. */
void pack_bmpblock();
/* Write the bmpblock to a file */
void write_to_bmpblock(const char *filename);
private:
/* Clear all internal data. */
void initialize();
/* Elemental function called from load_from_config.
* Load the config file (yaml format) and parse it. */
void load_yaml_config(const char *filename);
/* Elemental function called from load_from_config.
* Load all image files into the internal variables. */
void load_all_image_files();
/* Elemental function called from load_from_config.
* Contruct all ImageInfo structs. */
void fill_all_image_infos();
/* Elemental function called from load_from_config.
* Contruct the BmpBlockHeader struct. */
void fill_bmpblock_header();
/* Helper functions for parsing a YAML config file. */
void expect_event(yaml_parser_t *parser, const yaml_event_type_e type);
void parse_config(yaml_parser_t *parser);
void parse_first_layer(yaml_parser_t *parser);
void parse_bmpblock(yaml_parser_t *parser);
void parse_images(yaml_parser_t *parser);
void parse_layout(yaml_parser_t *parser, ScreenConfig &screen);
void parse_screens(yaml_parser_t *parser);
void parse_localizations(yaml_parser_t *parser);
/* Useful functions */
const string read_image_file(const char *filename);
ImageFormat get_image_format(const string content);
uint32_t get_bmp_image_width(const string content);
uint32_t get_bmp_image_height(const string content);
/* Internal variable for storing the config of BmpBlock. */
BmpBlockConfig config_;
/* Internal variable for storing the content of BmpBlock. */
string bmpblock_;
};
} // namespace vboot_reference
#endif // VBOOT_REFERENCE_BMPBLK_UTILITY_H_