diff options
author | Tom Wai-Hong Tam <waihong@google.com> | 2011-02-17 12:58:58 +0800 |
---|---|---|
committer | Tom Wai-Hong Tam <waihong@google.com> | 2011-02-17 12:58:58 +0800 |
commit | ee2bc91d4393796721dc8a48d3510e3352f2b893 (patch) | |
tree | 87df9e47236b4949aec9760e7b0b92f33934635a | |
parent | 686dd5cefb172968b8491a941d124fbfeefe230f (diff) | |
download | vboot-ee2bc91d4393796721dc8a48d3510e3352f2b893.tar.gz |
Enable LZMA compression in bmpbklk_utility.
LZMA has better compression ratio and is also supported in u-boot already.
ARM BIOS will use LZMA to compress BMP files.
BUG=chromium-os:11017
TEST=manual
$ make
$ make runbmptests
Change-Id: I6b791e3284b65eb3085b0de548bd241eab2ee598
Review URL: http://codereview.chromium.org/6523019
-rw-r--r-- | firmware/include/bmpblk_header.h | 2 | ||||
-rwxr-xr-x | tests/bitmaps/TestBmpBlock.py | 16 | ||||
-rw-r--r-- | utility/Makefile | 4 | ||||
-rw-r--r-- | utility/bmpblk_util.c | 57 | ||||
-rw-r--r-- | utility/bmpblk_utility.cc | 35 |
5 files changed, 105 insertions, 9 deletions
diff --git a/firmware/include/bmpblk_header.h b/firmware/include/bmpblk_header.h index 0d67a496..0c609dd2 100644 --- a/firmware/include/bmpblk_header.h +++ b/firmware/include/bmpblk_header.h @@ -117,7 +117,7 @@ typedef enum ImageFormat { typedef enum Compression { COMPRESS_NONE = 0, COMPRESS_EFIv1, /* The x86 BIOS only supports this */ - COMPRESS_TBD, /* Only on ARM? */ + COMPRESS_LZMA1, /* The ARM BIOS supports LZMA1 */ MAX_COMPRESS, } Compression; diff --git a/tests/bitmaps/TestBmpBlock.py b/tests/bitmaps/TestBmpBlock.py index ced270ee..be815929 100755 --- a/tests/bitmaps/TestBmpBlock.py +++ b/tests/bitmaps/TestBmpBlock.py @@ -89,19 +89,27 @@ class TestPackUnpack(unittest.TestCase): self.assertEqual(0, rc) os.chdir('..') - def testPackUnpackZ(self): - """Create, unpack, recreate with explicit compression""" - rc, out, err = runprog(prog, '-z', '1', '-c', 'case_simple.yaml', 'FOO') + def doPackUnpackZ(self, comp): + """Create, unpack, recreate with a given compression""" + rc, out, err = runprog(prog, '-z', comp, '-c', 'case_simple.yaml', 'FOO') self.assertEqual(0, rc) rc, out, err = runprog(prog, '-x', '-d', './FOO_DIR', 'FOO') self.assertEqual(0, rc) os.chdir('./FOO_DIR') - rc, out, err = runprog(prog, '-z', '1', '-c', 'config.yaml', 'BAR') + rc, out, err = runprog(prog, '-z', comp, '-c', 'config.yaml', 'BAR') self.assertEqual(0, rc) rc, out, err = runprog('/usr/bin/cmp', '../FOO', 'BAR') self.assertEqual(0, rc) os.chdir('..') + def testPackUnpackZ1(self): + """Create, unpack, recreate with EFIv1 compression""" + self.doPackUnpackZ('1'); + + def testPackUnpackZ2(self): + """Create, unpack, recreate with LZMA compression""" + self.doPackUnpackZ('2'); + def tearDown(self): rc, out, err = runprog('/bin/rm', '-rf', './FOO_DIR', 'FOO') self.assertEqual(0, rc) diff --git a/utility/Makefile b/utility/Makefile index af0187b3..8ea53a62 100644 --- a/utility/Makefile +++ b/utility/Makefile @@ -60,7 +60,7 @@ ${BUILD_ROOT}/gbb_utility: gbb_utility.cc $(CXX) -DWITH_UTIL_MAIN $(CFLAGS) $< -o $@ ${BUILD_ROOT}/bmpblk_utility.o: bmpblk_utility.cc - $(CXX) -DWITH_UTIL_MAIN -lyaml $(CFLAGS) -c $< -o $@ + $(CXX) -DWITH_UTIL_MAIN $(CFLAGS) -c $< -o $@ ${BUILD_ROOT}/bmpblk_util.o: bmpblk_util.c $(CC) $(CFLAGS) -c $< -o $@ @@ -75,7 +75,7 @@ ${BUILD_ROOT}/bmpblk_utility: ${BUILD_ROOT}/bmpblk_utility.o \ ${BUILD_ROOT}/bmpblk_util.o \ ${BUILD_ROOT}/eficompress.o \ ${BUILD_ROOT}/efidecompress.o - $(CXX) -DWITH_UTIL_MAIN -lyaml $(CFLAGS) $^ -o $@ + $(CXX) -llzma -lyaml $(CFLAGS) $^ -o $@ ${BUILD_ROOT}/load_kernel_test: load_kernel_test.c $(LIBS) $(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto diff --git a/utility/bmpblk_util.c b/utility/bmpblk_util.c index 214beda4..f2b0adc8 100644 --- a/utility/bmpblk_util.c +++ b/utility/bmpblk_util.c @@ -5,6 +5,7 @@ #include <errno.h> #include <fcntl.h> #include <limits.h> +#include <lzma.h> #include <stdio.h> #include <string.h> #include <sys/mman.h> @@ -99,7 +100,7 @@ static void *do_efi_decompress(ImageInfo *img) { uint32_t osize; EFI_STATUS r; - ibuf = ((void *)img) + sizeof(ImageInfo); + ibuf = (void*)(img + 1); isize = img->compressed_size; r = EfiGetInfo(ibuf, isize, &osize, &ssize); @@ -139,6 +140,50 @@ static void *do_efi_decompress(ImageInfo *img) { } + +static void *do_lzma_decompress(ImageInfo *img) { + void *ibuf; + void *obuf; + uint32_t isize; + uint32_t osize; + lzma_stream stream = LZMA_STREAM_INIT; + lzma_ret result; + + ibuf = (void*)(img + 1); + isize = img->compressed_size; + osize = img->original_size; + obuf = malloc(osize); + if (!obuf) { + fprintf(stderr, "Can't allocate %d bytes: %s\n", + osize, + strerror(errno)); + return 0; + } + + result = lzma_auto_decoder(&stream, -1, 0); + if (result != LZMA_OK) { + fprintf(stderr, "Unable to initialize auto decoder (error: %d)!\n", + result); + free(obuf); + return 0; + } + + stream.next_in = ibuf; + stream.avail_in = isize; + stream.next_out = obuf; + stream.avail_out = osize; + result = lzma_code(&stream, LZMA_FINISH); + if (result != LZMA_STREAM_END) { + fprintf(stderr, "Unalbe to decode data (error: %d)!\n", result); + free(obuf); + return 0; + } + lzma_end(&stream); + return obuf; +} + + + // Show what's inside. If todir is NULL, just print. Otherwise unpack. int dump_bmpblock(const char *infile, int show_as_yaml, const char *todir, int overwrite) { @@ -266,6 +311,16 @@ int dump_bmpblock(const char *infile, int show_as_yaml, } free_data = 1; break; + case COMPRESS_LZMA1: + data_ptr = do_lzma_decompress(img); + if (!data_ptr) { + fclose(bfp); + fclose(yfp); + discard_file(ptr, length); + return 1; + } + free_data = 1; + break; default: fprintf(stderr, "Unsupported compression method encountered.\n"); fclose(bfp); diff --git a/utility/bmpblk_utility.cc b/utility/bmpblk_utility.cc index 9f912d0b..c9188a8e 100644 --- a/utility/bmpblk_utility.cc +++ b/utility/bmpblk_utility.cc @@ -10,6 +10,7 @@ #include <assert.h> #include <errno.h> #include <getopt.h> +#include <lzma.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -326,6 +327,38 @@ void BmpBlockUtil::load_all_image_files() { 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"); } @@ -535,7 +568,7 @@ static void usagehelp_exit(const char *prog_name) { " -z NUM = compression algorithm to use\n" " 0 = none\n" " 1 = EFIv1\n" - " 2 = TBD\n" + " 2 = LZMA1\n" "\n", prog_name); printf( "To display the contents of a BMPBLOCK:\n" |