1d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson// Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 2d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson// Use of this source code is governed by a BSD-style license that can be 3d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson// found in the LICENSE file. 4d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson// 5d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson// Utility for manipulating firmware screen block (BMPBLOCK) in GBB. 6d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson// 7d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 8d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson#include <assert.h> 9d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson#include <errno.h> 10d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson#include <getopt.h> 11ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam#include <lzma.h> 12d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson#include <stdarg.h> 130c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson#include <stdint.h> 14d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson#include <stdio.h> 15d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson#include <stdlib.h> 16d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson#include <string.h> 17d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson#include <yaml.h> 18d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 190c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson#include "bmpblk_utility.h" 200c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson#include "image_types.h" 210c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson#include "vboot_api.h" 220c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson 2361362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardsonextern "C" { 2461362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson#include "eficompress.h" 2561362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson} 2661362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson 2761362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson 28d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardsonstatic void error(const char *format, ...) { 29d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson va_list ap; 30d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson va_start(ap, format); 31d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson fprintf(stderr, "ERROR: "); 32d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson vfprintf(stderr, format, ap); 33d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson va_end(ap); 34d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson exit(1); 35d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson} 36d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 37d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson/////////////////////////////////////////////////////////////////////// 38d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson// BmpBlock Utility implementation 39d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 40d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardsonnamespace vboot_reference { 41d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 4254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson BmpBlockUtil::BmpBlockUtil(bool debug) { 4354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson major_version_ = BMPBLOCK_MAJOR_VERSION; 4454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson minor_version_ = BMPBLOCK_MINOR_VERSION; 4554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.config_filename.clear(); 4654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson memset(&config_.header, '\0', BMPBLOCK_SIGNATURE_SIZE); 4754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.images_map.clear(); 4854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.screens_map.clear(); 4954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.localizations.clear(); 5054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson bmpblock_.clear(); 5154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson set_compression_ = false; 5254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson compression_ = COMPRESS_NONE; 5354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson debug_ = debug; 540a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson render_hwid_ = true; 550a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson support_font_ = true; 560a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson got_font_ = false; 570a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson got_rtol_font_ = false; 5854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 59d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 6054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson BmpBlockUtil::~BmpBlockUtil() { 6154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 62d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 6354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::force_compression(uint32_t compression) { 6454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson compression_ = compression; 6554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson set_compression_ = true; 6654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 6761362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson 6854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::load_from_config(const char *filename) { 6954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson load_yaml_config(filename); 7054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson fill_bmpblock_header(); 7154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson load_all_image_files(); 7254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 73d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 7454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::load_yaml_config(const char *filename) { 7554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_parser_t parser; 76d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 7754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.config_filename = filename; 7854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.images_map.clear(); 7954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.screens_map.clear(); 8054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.localizations.clear(); 818ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson config_.locale_names.clear(); 82d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 8354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson FILE *fp = fopen(filename, "rb"); 8454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (!fp) { 8554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson perror(filename); 8654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson exit(errno); 8754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 88d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 8954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_parser_initialize(&parser); 9054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_parser_set_input_file(&parser, fp); 9154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson parse_config(&parser); 9254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_parser_delete(&parser); 9354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson fclose(fp); 94d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 95d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 962e0226309d1407e0968a6b699e99126c98407319Bill Richardson // TODO: Check the yaml file for self-consistency. Warn on any problems. 9754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson // All images should be used somewhere in the screens. 9854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson // All images referenced in the screens should be defined. 9954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson // All screens should be used somewhere in the localizations. 10054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson // All screens referenced in the localizations should be defined. 1018ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson // The number of localizations should match the number of locale_index 102d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 10354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (debug_) { 10454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson printf("%ld image_names\n", config_.image_names.size()); 10554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (unsigned int i = 0; i < config_.image_names.size(); ++i) { 10654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson printf(" %d: \"%s\"\n", i, config_.image_names[i].c_str()); 10754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 10854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson printf("%ld images_map\n", config_.images_map.size()); 10954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (StrImageConfigMap::iterator it = config_.images_map.begin(); 11054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it != config_.images_map.end(); 11154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson ++it) { 1120a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson printf(" \"%s\": filename=\"%s\" offset=0x%x tag=%d fmt=%d\n", 11354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->first.c_str(), 11454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.filename.c_str(), 11554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.offset, 1160a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson it->second.data.tag, 1170a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson it->second.data.format); 11854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 11954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson printf("%ld screens_map\n", config_.screens_map.size()); 12054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (StrScreenConfigMap::iterator it = config_.screens_map.begin(); 12154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it != config_.screens_map.end(); 12254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson ++it) { 12354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson printf(" \"%s\":\n", it->first.c_str()); 12454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (int k=0; k<MAX_IMAGE_IN_LAYOUT; k++) { 12554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson printf(" %d: \"%s\" (%d,%d) ofs=0x%x\n", 12654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson k, 12754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.image_names[k].c_str(), 12854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.data.images[k].x, 12954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.data.images[k].y, 13054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.data.images[k].image_info_offset); 13154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 13254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 13354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 13454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 135d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 13654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::expect_event(yaml_parser_t *parser, 13754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson const yaml_event_type_e type) { 13854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_t event; 139d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson yaml_parser_parse(parser, &event); 14054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (event.type != type) { 14154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson error("Syntax error.\n"); 14254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 14354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_delete(&event); 14454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 14554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson 14654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::parse_config(yaml_parser_t *parser) { 14754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson expect_event(parser, YAML_STREAM_START_EVENT); 14854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson expect_event(parser, YAML_DOCUMENT_START_EVENT); 14954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson parse_first_layer(parser); 15054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson expect_event(parser, YAML_DOCUMENT_END_EVENT); 15154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson expect_event(parser, YAML_STREAM_END_EVENT); 15254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 15354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson 15454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::parse_first_layer(yaml_parser_t *parser) { 15554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_t event; 15654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson string keyword; 15754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson expect_event(parser, YAML_MAPPING_START_EVENT); 15854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (;;) { 15954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_parser_parse(parser, &event); 16054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson switch (event.type) { 161d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson case YAML_SCALAR_EVENT: 162d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson keyword = (char*)event.data.scalar.value; 163d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson if (keyword == "bmpblock") { 164d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson parse_bmpblock(parser); 165a7209ee2de570a1404e6df247df4a68c72d16245Bill Richardson } else if (keyword == "compression") { 166a7209ee2de570a1404e6df247df4a68c72d16245Bill Richardson parse_compression(parser); 167d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } else if (keyword == "images") { 168d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson parse_images(parser); 169d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } else if (keyword == "screens") { 170d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson parse_screens(parser); 171d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } else if (keyword == "localizations") { 172d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson parse_localizations(parser); 1738ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson } else if (keyword == "locale_index") { 1748ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson parse_locale_index(parser); 175d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 176d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson break; 177d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson case YAML_MAPPING_END_EVENT: 178d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson yaml_event_delete(&event); 179d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson return; 180d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson default: 181d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson error("Syntax error in parsing config file.\n"); 18254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 18354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_delete(&event); 184d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 185d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 186d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 18754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::parse_bmpblock(yaml_parser_t *parser) { 18854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_t event; 18954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_parser_parse(parser, &event); 19054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (event.type != YAML_SCALAR_EVENT) { 19154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson error("Syntax error in parsing bmpblock.\n"); 19254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 19354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson string gotversion = (char*)event.data.scalar.value; 1943985f94fae52aa1df853f7d47388c67c3022e069Dave Parker if (gotversion != "2.0") { 19554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson error("Unsupported version specified in config file (%s)\n", 19654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson gotversion.c_str()); 19754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 19854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_delete(&event); 199fc05bb854f2d38b714cec3924e3ade2d4fb84561Bill Richardson } 200d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 20154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::parse_compression(yaml_parser_t *parser) { 20254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_t event; 20354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_parser_parse(parser, &event); 20454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (event.type != YAML_SCALAR_EVENT) { 20554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson error("Syntax error in parsing bmpblock.\n"); 20654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 20754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson char *comp_str = (char *)event.data.scalar.value; 20854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson char *e = 0; 20954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson uint32_t comp = (uint32_t)strtoul(comp_str, &e, 0); 21054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (!*comp_str || (e && *e) || comp >= MAX_COMPRESS) { 21154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson error("Invalid compression specified in config file (%d)\n", comp); 21254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 21354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (!set_compression_) { 21454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson compression_ = comp; 21554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 21654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_delete(&event); 217a7209ee2de570a1404e6df247df4a68c72d16245Bill Richardson } 218a7209ee2de570a1404e6df247df4a68c72d16245Bill Richardson 21954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::parse_images(yaml_parser_t *parser) { 22054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_t event; 22154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson string image_name, image_filename; 22254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson expect_event(parser, YAML_MAPPING_START_EVENT); 22354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (;;) { 22454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_parser_parse(parser, &event); 22554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson switch (event.type) { 226d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson case YAML_SCALAR_EVENT: 227d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson image_name = (char*)event.data.scalar.value; 228d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson yaml_event_delete(&event); 229d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson yaml_parser_parse(parser, &event); 230d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson if (event.type != YAML_SCALAR_EVENT) { 231d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson error("Syntax error in parsing images.\n"); 232d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 233d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson image_filename = (char*)event.data.scalar.value; 234f82f941b803b0c28240913eb57b34ab4c6c6b96aBill Richardson config_.image_names.push_back(image_name); 235d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson config_.images_map[image_name] = ImageConfig(); 236d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson config_.images_map[image_name].filename = image_filename; 2370a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson if (image_name == RENDER_HWID) { 2380a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson got_font_ = true; 2390a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson } 2400a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson if (image_name == RENDER_HWID_RTOL) { 2410a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson got_rtol_font_ = true; 2420a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson } 243d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson break; 244d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson case YAML_MAPPING_END_EVENT: 245d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson yaml_event_delete(&event); 246d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson return; 247d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson default: 248d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson error("Syntax error in parsing images.\n"); 24954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 25054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_delete(&event); 251d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 252d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 253d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 25454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::parse_layout(yaml_parser_t *parser, ScreenConfig &screen) { 25554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_t event; 25654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson int depth = 0, index1 = 0, index2 = 0; 25754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson expect_event(parser, YAML_SEQUENCE_START_EVENT); 25854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (;;) { 25954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_parser_parse(parser, &event); 26054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson switch (event.type) { 261d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson case YAML_SEQUENCE_START_EVENT: 262d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson depth++; 263d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson break; 264d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson case YAML_SCALAR_EVENT: 265d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson switch (index2) { 26654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson case 0: 26754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson screen.data.images[index1].x = atoi((char*)event.data.scalar.value); 26854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson break; 26954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson case 1: 27054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson screen.data.images[index1].y = atoi((char*)event.data.scalar.value); 27154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson break; 27254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson case 2: 27354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson screen.image_names[index1] = (char*)event.data.scalar.value; 27454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson // Detect the special case where we're rendering the HWID string 2750a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson // instead of displaying a bitmap. The image name may not 2760a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson // exist in the list of images (v1.1), but we will still need an 27754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson // ImageInfo struct to remember where to draw the text. 2780a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson // Note that v1.2 requires that the image name DOES exist, because 2790a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson // the corresponding file is used to hold the font glpyhs. 28054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (render_hwid_) { 28154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (screen.image_names[index1] == RENDER_HWID) { 28254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.images_map[RENDER_HWID].data.tag = TAG_HWID; 2830a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson if (support_font_ && !got_font_) 2840a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson error("Font required in 'image:' section for %s\n", 2850a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson RENDER_HWID); 28654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } else if (screen.image_names[index1] == RENDER_HWID_RTOL) { 28754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.images_map[RENDER_HWID_RTOL].data.tag = TAG_HWID_RTOL; 2880a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson if (support_font_ && !got_rtol_font_) 2890a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson error("Font required in 'image:' section for %s\n", 2900a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson RENDER_HWID_RTOL); 29154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 29254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 29354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson break; 29454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson default: 29554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson error("Syntax error in parsing layout\n"); 296d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 297d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson index2++; 298d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson break; 299d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson case YAML_SEQUENCE_END_EVENT: 300d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson if (depth == 1) { 301d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson index1++; 302d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson index2 = 0; 303d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } else if (depth == 0) { 304d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson yaml_event_delete(&event); 305d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson return; 306d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 307d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson depth--; 308d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson break; 309d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson default: 310d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson error("Syntax error in paring layout.\n"); 31154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 31254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_delete(&event); 313d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 314d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 315d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 31654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::parse_screens(yaml_parser_t *parser) { 31754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_t event; 31854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson string screen_name; 31954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson expect_event(parser, YAML_MAPPING_START_EVENT); 32054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (;;) { 32154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_parser_parse(parser, &event); 32254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson switch (event.type) { 323d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson case YAML_SCALAR_EVENT: 324d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson screen_name = (char*)event.data.scalar.value; 325d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson config_.screens_map[screen_name] = ScreenConfig(); 326d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson parse_layout(parser, config_.screens_map[screen_name]); 327d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson break; 328d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson case YAML_MAPPING_END_EVENT: 329d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson yaml_event_delete(&event); 330d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson return; 331d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson default: 332d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson error("Syntax error in parsing screens.\n"); 33354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 33454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_delete(&event); 335d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 336d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 337d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 33854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::parse_localizations(yaml_parser_t *parser) { 33954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_t event; 34054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson int depth = 0, index = 0; 34154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson expect_event(parser, YAML_SEQUENCE_START_EVENT); 34254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (;;) { 34354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_parser_parse(parser, &event); 34454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson switch (event.type) { 345d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson case YAML_SEQUENCE_START_EVENT: 346d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson config_.localizations.push_back(vector<string>()); 347d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson depth++; 348d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson break; 349d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson case YAML_SCALAR_EVENT: 350d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson config_.localizations[index].push_back((char*)event.data.scalar.value); 351d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson break; 352d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson case YAML_SEQUENCE_END_EVENT: 353d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson if (depth == 1) { 354d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson index++; 355d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } else if (depth == 0) { 356d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson yaml_event_delete(&event); 357d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson return; 358d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 359d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson depth--; 360d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson break; 361d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson default: 362d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson error("Syntax error in parsing localizations.\n"); 36354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 36454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson yaml_event_delete(&event); 365d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 366d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 367d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 3688ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson void BmpBlockUtil::parse_locale_index(yaml_parser_t *parser) { 3698ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson yaml_event_t event; 3708ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson expect_event(parser, YAML_SEQUENCE_START_EVENT); 3718ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson for (;;) { 3728ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson yaml_parser_parse(parser, &event); 3738ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson switch (event.type) { 3748ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson case YAML_SCALAR_EVENT: 3758ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson config_.locale_names.append((char*)event.data.scalar.value); 3768ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson config_.locale_names.append(1, (char)'\0'); // '\0' to delimit 3778ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson break; 3788ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson case YAML_SEQUENCE_END_EVENT: 3798ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson yaml_event_delete(&event); 3808ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson config_.locale_names.append(1, (char)'\0'); // double '\0' to terminate 3818ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson return; 3828ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson default: 3838ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson error("Syntax error in parsing localizations.\n"); 3848ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson } 3858ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson } 3868ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson } 3878ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson 38854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::load_all_image_files() { 38954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (unsigned int i = 0; i < config_.image_names.size(); i++) { 39054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson StrImageConfigMap::iterator it = 39154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.images_map.find(config_.image_names[i]); 39254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (debug_) { 39354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson printf("loading image \"%s\" from \"%s\"\n", 39454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.image_names[i].c_str(), 39554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.filename.c_str()); 39654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 39754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson const string &content = read_image_file(it->second.filename.c_str()); 39854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.raw_content = content; 39954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.data.original_size = content.size(); 4000a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson it->second.data.format = 4010a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson identify_image_type(content.c_str(), 4020a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson (uint32_t)content.size(), &it->second.data); 4030a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson if (FORMAT_INVALID == it->second.data.format) { 40454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson error("Unsupported image format in %s\n", it->second.filename.c_str()); 40554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 40654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson switch(compression_) { 40754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson case COMPRESS_NONE: 40854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.data.compression = compression_; 40954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.compressed_content = content; 41054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.data.compressed_size = content.size(); 41154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson break; 41254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson case COMPRESS_EFIv1: 41361362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson { 41461362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson // The content will always compress smaller (so sez the docs). 41561362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson uint32_t tmpsize = content.size(); 41661362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson uint8_t *tmpbuf = (uint8_t *)malloc(tmpsize); 41761362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson // The size of the compressed content is also returned. 41861362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson if (EFI_SUCCESS != EfiCompress((uint8_t *)content.c_str(), tmpsize, 41961362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson tmpbuf, &tmpsize)) { 42061362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson error("Unable to compress!\n"); 42161362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson } 42261362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson it->second.data.compression = compression_; 42361362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson it->second.compressed_content.assign((const char *)tmpbuf, tmpsize); 42461362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson it->second.data.compressed_size = tmpsize; 42561362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson free(tmpbuf); 42661362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson } 42761362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson break; 42854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson case COMPRESS_LZMA1: 429ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam { 430ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam // Calculate the worst case of buffer size. 431ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam uint32_t tmpsize = lzma_stream_buffer_bound(content.size()); 432ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam uint8_t *tmpbuf = (uint8_t *)malloc(tmpsize); 433ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam lzma_stream stream = LZMA_STREAM_INIT; 434ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam lzma_options_lzma options; 435ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam lzma_ret result; 436ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam 437ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam lzma_lzma_preset(&options, 9); 438ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam result = lzma_alone_encoder(&stream, &options); 439ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam if (result != LZMA_OK) { 440ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam error("Unable to initialize easy encoder (error: %d)!\n", result); 441ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam } 442ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam 443ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam stream.next_in = (uint8_t *)content.data(); 444ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam stream.avail_in = content.size(); 445ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam stream.next_out = tmpbuf; 446ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam stream.avail_out = tmpsize; 447ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam result = lzma_code(&stream, LZMA_FINISH); 448ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam if (result != LZMA_STREAM_END) { 449ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam error("Unable to encode data (error: %d)!\n", result); 450ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam } 451ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam 452ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam it->second.data.compression = compression_; 453ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam it->second.compressed_content.assign((const char *)tmpbuf, 454ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam tmpsize - stream.avail_out); 455ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam it->second.data.compressed_size = tmpsize - stream.avail_out; 456ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam lzma_end(&stream); 457ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam free(tmpbuf); 458ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam } 459ee2bc91d4393796721dc8a48d3510e3352f2b893Tom Wai-Hong Tam break; 46054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson default: 46154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson error("Unsupported compression method attempted.\n"); 46254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 46361362d65fcdd6f6aff90fc5be51237b39cfeb9aeBill Richardson } 464d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 465d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 46654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson const string BmpBlockUtil::read_image_file(const char *filename) { 46754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson string content; 46854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson vector<char> buffer; 469d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 47054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson FILE *fp = fopen(filename, "rb"); 47154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (!fp) { 472d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson perror(filename); 47354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson exit(errno); 474d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 475d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 47654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (fseek(fp, 0, SEEK_END) == 0) { 47754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson buffer.resize(ftell(fp)); 47854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson rewind(fp); 47954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 480fc05bb854f2d38b714cec3924e3ade2d4fb84561Bill Richardson 48154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (!buffer.empty()) { 48254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if(fread(&buffer[0], buffer.size(), 1, fp) != 1) { 48354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson perror(filename); 48454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson buffer.clear(); 48554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } else { 48654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson content.assign(buffer.begin(), buffer.end()); 48754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 48854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 489fc05bb854f2d38b714cec3924e3ade2d4fb84561Bill Richardson 49054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson fclose(fp); 49154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson return content; 49254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 493d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 49454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::fill_bmpblock_header() { 49554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson memset(&config_.header, '\0', sizeof(config_.header)); 49654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson memcpy(&config_.header.signature, BMPBLOCK_SIGNATURE, 49754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson BMPBLOCK_SIGNATURE_SIZE); 49854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.header.major_version = major_version_; 49954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.header.minor_version = minor_version_; 50054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.header.number_of_localizations = config_.localizations.size(); 50154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.header.number_of_screenlayouts = config_.localizations[0].size(); 5026df3e33912baf2633ed27fce6fe166d87e2f04a8Bill Richardson // NOTE: this is part of the yaml consistency check 50354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (unsigned int i = 1; i < config_.localizations.size(); ++i) { 50454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson assert(config_.header.number_of_screenlayouts == 50554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.localizations[i].size()); 506d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 50754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.header.number_of_imageinfos = config_.images_map.size(); 5088ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson config_.header.locale_string_offset = 0; // Filled by pack_bmpblock() 509d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 51054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson 51154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::pack_bmpblock() { 51254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson bmpblock_.clear(); 51354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson 51454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson /* Compute the ImageInfo offsets from start of BMPBLOCK. */ 51554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson uint32_t current_offset = sizeof(BmpBlockHeader) + 51654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson sizeof(ScreenLayout) * (config_.header.number_of_localizations * 51754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.header.number_of_screenlayouts); 51854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (StrImageConfigMap::iterator it = config_.images_map.begin(); 51954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it != config_.images_map.end(); 52054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson ++it) { 52154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.offset = current_offset; 52254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (debug_) 5230a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson printf(" \"%s\": filename=\"%s\" offset=0x%x tag=%d fmt=%d\n", 52454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->first.c_str(), 52554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.filename.c_str(), 52654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.offset, 5270a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson it->second.data.tag, 5280a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson it->second.data.format); 52954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson current_offset += sizeof(ImageInfo) + 53054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.data.compressed_size; 53154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson /* Make it 4-byte aligned. */ 53254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if ((current_offset & 3) > 0) { 53354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson current_offset = (current_offset & ~3) + 4; 534d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 535d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 5368ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson /* And leave room for the locale_index string */ 5378ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson if (config_.locale_names.size()) { 5388ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson config_.header.locale_string_offset = current_offset; 5398ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson current_offset += config_.locale_names.size(); 5408ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson } 5418ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson 54254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson bmpblock_.resize(current_offset); 543d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 54454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson /* Fill BmpBlockHeader struct. */ 54554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson string::iterator current_filled = bmpblock_.begin(); 54654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson std::copy(reinterpret_cast<char*>(&config_.header), 54754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson reinterpret_cast<char*>(&config_.header + 1), 548d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson current_filled); 54954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson current_filled += sizeof(config_.header); 55054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson current_offset = sizeof(config_.header); 55154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson 55254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson /* Fill all ScreenLayout structs. */ 55354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (unsigned int i = 0; i < config_.localizations.size(); ++i) { 55454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (unsigned int j = 0; j < config_.localizations[i].size(); ++j) { 55554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson ScreenConfig &screen = config_.screens_map[config_.localizations[i][j]]; 55654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (unsigned int k = 0; 55754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson k < MAX_IMAGE_IN_LAYOUT && !screen.image_names[k].empty(); 55854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson ++k) { 55954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (config_.images_map.find(screen.image_names[k]) == 56054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.images_map.end()) { 56154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson error("Invalid image name \"%s\"\n", screen.image_names[k].c_str()); 56254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 56354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (debug_) 56454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson printf("i=%d j=%d k=%d=\"%s\" (%d,%d) ofs=%x\n", i,j,k, 56554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson screen.image_names[k].c_str(), 56654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson screen.data.images[k].x, screen.data.images[k].y, 56754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.images_map[screen.image_names[k]].offset 56854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson ); 56954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson screen.data.images[k].image_info_offset = 57054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_.images_map[screen.image_names[k]].offset; 57154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 57254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson std::copy(reinterpret_cast<char*>(&screen.data), 57354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson reinterpret_cast<char*>(&screen.data + 1), 57454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson current_filled); 57554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson current_filled += sizeof(screen.data); 57654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (debug_) 57754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson printf("S: current offset is 0x%08x\n", current_offset); 57854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson current_offset += sizeof(screen.data); 57954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 58054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 58154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson 58254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson /* Fill all ImageInfo structs and image contents. */ 58354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson for (StrImageConfigMap::iterator it = config_.images_map.begin(); 58454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it != config_.images_map.end(); 58554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson ++it) { 58654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson current_filled = bmpblock_.begin() + it->second.offset; 58754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson current_offset = it->second.offset; 58854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (debug_) 58954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson printf("I0: current offset is 0x%08x\n", current_offset); 59054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson std::copy(reinterpret_cast<char*>(&it->second.data), 59154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson reinterpret_cast<char*>(&it->second.data + 1), 59254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson current_filled); 59354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson current_filled += sizeof(it->second.data); 59454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson current_offset += sizeof(it->second.data); 59554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (debug_) 59654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson printf("I1: current offset is 0x%08x (len %ld)\n", 59754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson current_offset, it->second.compressed_content.length()); 59854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson std::copy(it->second.compressed_content.begin(), 59954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson it->second.compressed_content.end(), 60054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson current_filled); 60154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 6028ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson 6038ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson /* Fill in locale_names. */ 6048ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson if (config_.header.locale_string_offset) { 6058ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson current_offset = config_.header.locale_string_offset; 6068ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson current_filled = bmpblock_.begin() + current_offset; 6078ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson if (debug_) 6088ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson printf("locale_names: offset 0x%08x (len %ld)\n", 6098ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson current_offset, config_.locale_names.size()); 6108ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson std::copy(config_.locale_names.begin(), 6118ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson config_.locale_names.end(), 6128ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson current_filled); 6138ba3d790e16c6e0759686b1bd8b25db778c3fc9fBill Richardson } 614d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 615d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 61654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson void BmpBlockUtil::write_to_bmpblock(const char *filename) { 61754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson assert(!bmpblock_.empty()); 618d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 61954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson FILE *fp = fopen(filename, "wb"); 62054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (!fp) { 62154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson perror(filename); 62254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson exit(errno); 62354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 624d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 62554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson int r = fwrite(bmpblock_.c_str(), bmpblock_.size(), 1, fp); 62654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson fclose(fp); 62754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (r != 1) { 62854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson perror(filename); 62954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson exit(errno); 63054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 631d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 632d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 633d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson} // namespace vboot_reference 634d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 63517f8d341099120da78a6ca71165834eefb0960edRandall Spangler#ifndef FOR_LIBRARY 636d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 63754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson ////////////////////////////////////////////////////////////////////////////// 63854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson // Command line utilities. 639794d4d44db984759466b5b6779833e2d5281e527Bill Richardson 64054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson extern "C" { 641794d4d44db984759466b5b6779833e2d5281e527Bill Richardson#include "bmpblk_util.h" 64254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 643d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 64454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson using vboot_reference::BmpBlockUtil; 64554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson 64654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson // utility function: provide usage of this utility and exit. 64754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson static void usagehelp_exit(const char *prog_name) { 64854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson printf( 64954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson "\n" 65054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson "To create a new BMPBLOCK file using config from YAML file:\n" 65154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson "\n" 65254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson " %s [-z NUM] -c YAML BMPBLOCK\n" 65354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson "\n" 65454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson " -z NUM = compression algorithm to use\n" 65554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson " 0 = none\n" 65654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson " 1 = EFIv1\n" 65754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson " 2 = LZMA1\n" 65854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson "\n", prog_name); 65954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson printf( 66054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson "To display the contents of a BMPBLOCK:\n" 66154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson "\n" 66254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson " %s [-y] BMPBLOCK\n" 66354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson "\n" 66454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson " -y = display as yaml\n" 66554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson "\n", prog_name); 66654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson printf( 66754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson "To unpack a BMPBLOCK file:\n" 66854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson "\n" 66954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson " %s -x [-d DIR] [-f] BMPBLOCK\n" 67054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson "\n" 67154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson " -d DIR = directory to use (default '.')\n" 67254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson " -f = force overwriting existing files\n" 67354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson "\n", prog_name); 67454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson exit(1); 67554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 676d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 67754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson /////////////////////////////////////////////////////////////////////// 67854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson // main 67954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson 68054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson int main(int argc, char *argv[]) { 68154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson 68254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson const char *prog_name = strrchr(argv[0], '/'); 68354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (prog_name) 68454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson prog_name++; 68554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson else 68654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson prog_name = argv[0]; 68754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson 68854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson int overwrite = 0, extract_mode = 0; 68954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson int compression = 0; 69054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson int set_compression = 0; 69154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson const char *config_fn = 0, *bmpblock_fn = 0, *extract_dir = "."; 69254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson int show_as_yaml = 0; 69354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson bool debug = false; 69454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson 69554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson int opt; 69654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson opterr = 0; // quiet 69754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson int errorcnt = 0; 69854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson char *e = 0; 69954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson while ((opt = getopt(argc, argv, ":c:xz:fd:yD")) != -1) { 70054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson switch (opt) { 70154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson case 'c': 70254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson config_fn = optarg; 70354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson break; 70454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson case 'x': 70554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson extract_mode = 1; 70654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson break; 70754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson case 'y': 70854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson show_as_yaml = 1; 70954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson break; 71054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson case 'z': 71154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson compression = (int)strtoul(optarg, &e, 0); 71254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (!*optarg || (e && *e)) { 71354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson fprintf(stderr, "%s: invalid argument to -%c: \"%s\"\n", 71454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson prog_name, opt, optarg); 71554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson errorcnt++; 71654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 71754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (compression >= MAX_COMPRESS) { 71854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson fprintf(stderr, "%s: compression type must be less than %d\n", 71954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson prog_name, MAX_COMPRESS); 72054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson errorcnt++; 72154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 72254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson set_compression = 1; 72354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson break; 72454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson case 'f': 72554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson overwrite = 1; 72654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson break; 72754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson case 'd': 72854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson extract_dir= optarg; 72954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson break; 73054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson case 'D': 73154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson debug = true; 73254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson break; 73354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson case ':': 73454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson fprintf(stderr, "%s: missing argument to -%c\n", 73554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson prog_name, optopt); 736794d4d44db984759466b5b6779833e2d5281e527Bill Richardson errorcnt++; 73754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson break; 73854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson default: 73954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson fprintf(stderr, "%s: unrecognized switch: -%c\n", 74054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson prog_name, optopt); 741794d4d44db984759466b5b6779833e2d5281e527Bill Richardson errorcnt++; 74254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson break; 743794d4d44db984759466b5b6779833e2d5281e527Bill Richardson } 74454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 74554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson argc -= optind; 74654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson argv += optind; 74754e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson 74854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (argc >= 1) { 74954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson bmpblock_fn = argv[0]; 75054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } else { 75154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson fprintf(stderr, "%s: missing BMPBLOCK name\n", prog_name); 752794d4d44db984759466b5b6779833e2d5281e527Bill Richardson errorcnt++; 753d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson } 754d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 75554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (errorcnt) 75654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson usagehelp_exit(prog_name); 757794d4d44db984759466b5b6779833e2d5281e527Bill Richardson 75854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson BmpBlockUtil util(debug); 759794d4d44db984759466b5b6779833e2d5281e527Bill Richardson 76054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (config_fn) { 76154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson if (set_compression) 76254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson util.force_compression(compression); 76354e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson util.load_from_config(config_fn); 76454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson util.pack_bmpblock(); 76554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson util.write_to_bmpblock(bmpblock_fn); 76654e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 767d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 76854e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson else if (extract_mode) { 76954e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson return dump_bmpblock(bmpblock_fn, 1, extract_dir, overwrite); 77054e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } else { 77154e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson return dump_bmpblock(bmpblock_fn, show_as_yaml, 0, 0); 77254e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 773d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 77454e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson return 0; 77554e95825b30d4f730cbd70c109fb6622dda6fbb8Bill Richardson } 776d55085da49da8b7981494ea53ad23a6038fbb5c9Bill Richardson 77717f8d341099120da78a6ca71165834eefb0960edRandall Spangler#endif // FOR_LIBRARY 778