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
diff --git a/utility/bmpblk_util.c b/utility/bmpblk_util.c
index 214beda..f2b0adc 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 @@
   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_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 @@
         }
         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);