Build EFI compression utilities on host

Build eficompress and efidecompress utilities on host.

R=rpangler@chromium.org
BUG=chromium-os:13037
TEST=none

Review URL: http://codereview.chromium.org/6880176
(cherry picked from commit 573d4f6d80730ac56d23b2c5c8620a9fd843e816)

Change-Id: I0fb9eb037d2720b98c98d9229be0bbc60cfdd267
Reviewed-on: http://gerrit.chromium.org/gerrit/1050
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Tested-by: Bill Richardson <wfrichar@chromium.org>
diff --git a/utility/Makefile b/utility/Makefile
index fbbd065..a60ef21 100644
--- a/utility/Makefile
+++ b/utility/Makefile
@@ -40,7 +40,7 @@
 		pack_firmware_image
 
 ifeq ($(MINIMAL),)
-TARGET_NAMES += bmpblk_utility
+TARGET_NAMES += bmpblk_utility eficompress efidecompress
 endif
 
 TARGET_BINS = $(addprefix ${BUILD_ROOT}/,$(TARGET_NAMES))
@@ -69,9 +69,15 @@
 ${BUILD_ROOT}/eficompress.o: eficompress.c
 	$(CC) $(CFLAGS) -c $< -o $@
 
+${BUILD_ROOT}/eficompress: eficompress.c
+	$(CC) $(CFLAGS) -DSTANDALONE $< -o $@
+
 ${BUILD_ROOT}/efidecompress.o: efidecompress.c
 	$(CC) $(CFLAGS) -c $< -o $@
 
+${BUILD_ROOT}/efidecompress: efidecompress.c
+	$(CC) $(CFLAGS) -DSTANDALONE $< -o $@
+
 ${BUILD_ROOT}/bmpblk_utility: ${BUILD_ROOT}/bmpblk_utility.o \
 				${BUILD_ROOT}/bmpblk_util.o \
 				${BUILD_ROOT}/eficompress.o \
diff --git a/utility/eficompress.c b/utility/eficompress.c
index b0cf4fb..b598700 100644
--- a/utility/eficompress.c
+++ b/utility/eficompress.c
@@ -1607,3 +1607,126 @@
   //
   return k;
 }
+
+
+#ifdef STANDALONE
+int main(int argc, char *argv[])
+{
+  char *progname;
+  int retval = 1;
+
+  progname = strrchr(argv[0], '/');
+  if (progname)
+    progname++;
+  else
+    progname = argv[0];
+
+  if (argc != 3)
+  {
+    fprintf(stderr, "\nUsage:  %s INFILE OUTFILE\n\n", progname);
+    exit(1);
+  }
+
+  char *infile = argv[1];
+  char *outfile = argv[2];
+
+  struct stat istat;
+  if (0 != stat(infile, &istat)) {
+    fprintf(stderr, "%s: can't stat %s: %s\n",
+            progname,
+            infile,
+            strerror(errno));
+    exit(1);
+  }
+  uint32_t isize = (uint32_t)istat.st_size;
+
+  printf("%s is %d bytes\n", infile, isize);
+
+  FILE *ifp = fopen(infile, "rb");
+  if (!ifp)
+  {
+    fprintf(stderr, "%s: can't read %s: %s\n",
+            progname,
+            infile,
+            strerror(errno));
+    exit(1);
+  }
+  printf("opened %s\n", infile);
+
+  // read input file into buffer
+  uint8_t *ibuf = malloc(isize);
+  if (!ibuf) {
+    fprintf(stderr, "%s: can't malloc %d bytes: %s\n",
+            progname,
+            isize,
+            strerror(errno));
+    goto done1;
+  }
+  if (1 != fread(ibuf, isize, 1, ifp)) {
+    fprintf(stderr, "%s: can't read %d bytes: %s\n",
+            progname,
+            isize,
+            strerror(errno));
+    goto done2;
+  }
+
+  // assume compression will actually work
+  uint32_t osize = isize;
+  uint8_t *obuf = malloc(osize);
+  if (!obuf) {
+    fprintf(stderr, "%s: can't allocate %d bytes: %s\n",
+            progname,
+            osize,
+            strerror(errno));
+    goto done2;
+  }
+
+  // try it and see
+  EFI_STATUS r = EfiCompress(ibuf, isize, obuf, &osize);
+  if (r != EFI_SUCCESS) {
+    fprintf(stderr, "%s: compression failed with code %d\n",
+            progname,
+            r);
+    goto done3;
+  }
+
+  printf("Compressed %d bytes to %d bytes\n", isize, osize);
+
+  // Write it out
+  FILE *ofp = fopen(outfile, "wb");
+  if (!ofp)
+  {
+    fprintf(stderr, "%s: can't open %s for writing: %s\n",
+            progname,
+            outfile,
+            strerror(errno));
+    goto done3;
+  }
+  printf("opened %s\n", outfile);
+
+  if (1 != fwrite(obuf, osize, 1, ofp)) {
+    fprintf(stderr, "%s: can't write %d bytes: %s\n",
+            progname,
+            osize,
+            strerror(errno));
+    goto done4;
+  }
+
+  printf("wrote %d bytes to %s\n", osize, outfile);
+  retval = 0;
+
+done4:
+  fclose(ofp);
+
+done3:
+  free(obuf);
+
+done2:
+  free(ibuf);
+
+done1:
+  fclose(ifp);
+
+  return retval;
+}
+#endif // STANDALONE
diff --git a/utility/efidecompress.c b/utility/efidecompress.c
index 8ec4a08..5e7e14d 100644
--- a/utility/efidecompress.c
+++ b/utility/efidecompress.c
@@ -1006,3 +1006,157 @@
           2
           );
 }
+
+
+#ifdef STANDALONE
+int main(int argc, char *argv[])
+{
+  char *progname;
+  int retval = 1;
+
+  progname = strrchr(argv[0], '/');
+  if (progname)
+    progname++;
+  else
+    progname = argv[0];
+
+  if (argc != 3)
+  {
+    fprintf(stderr, "\nUsage:  %s INFILE OUTFILE\n\n", progname);
+    exit(1);
+  }
+
+  char *infile = argv[1];
+  char *outfile = argv[2];
+
+  struct stat istat;
+  if (0 != stat(infile, &istat)) {
+    fprintf(stderr, "%s: can't stat %s: %s\n",
+            progname,
+            infile,
+            strerror(errno));
+    exit(1);
+  }
+  uint32_t isize = (uint32_t)istat.st_size;
+
+  printf("%s is %d bytes\n", infile, isize);
+
+  FILE *ifp = fopen(infile, "rb");
+  if (!ifp)
+  {
+    fprintf(stderr, "%s: can't read %s: %s\n",
+            progname,
+            infile,
+            strerror(errno));
+    exit(1);
+  }
+  printf("opened %s\n", infile);
+
+  // read input file into buffer
+  uint8_t *ibuf = malloc(isize);
+  if (!ibuf) {
+    fprintf(stderr, "%s: can't allocate %d bytes: %s\n",
+            progname,
+            isize,
+            strerror(errno));
+    goto done1;
+  }
+  if (1 != fread(ibuf, isize, 1, ifp)) {
+    fprintf(stderr, "%s: can't read %d bytes: %s\n",
+            progname,
+            isize,
+            strerror(errno));
+    goto done2;
+  }
+
+
+  // Determine required parameters
+  uint32_t ssize=0, osize=0;
+  EFI_STATUS r = GetInfo(ibuf, isize, &osize, &ssize);
+  if (r != EFI_SUCCESS) {
+    fprintf(stderr, "%s: GetInfo failed with code %d\n",
+            progname,
+            r);
+    goto done2;
+  }
+  printf("need %d bytes of scratch to produce %d bytes of data\n",
+         ssize, osize);
+
+  uint8_t *sbuf = malloc(ssize);
+  if (!sbuf) {
+    fprintf(stderr, "%s: can't allocate %d bytes: %s\n",
+            progname,
+            ssize,
+            strerror(errno));
+    goto done2;
+  }
+
+  uint8_t *obuf = malloc(osize);
+  if (!obuf) {
+    fprintf(stderr, "%s: can't allocate %d bytes: %s\n",
+            progname,
+            osize,
+            strerror(errno));
+    goto done3;
+  }
+
+  // Try new version first
+  r = TianoDecompress(ibuf, isize, obuf, osize, sbuf, ssize);
+  if (r != EFI_SUCCESS) {
+    fprintf(stderr, "%s: TianoDecompress failed with code %d\n",
+            progname,
+            r);
+
+    // Try old version
+    r = EfiDecompress(ibuf, isize, obuf, osize, sbuf, ssize);
+    if (r != EFI_SUCCESS) {
+      fprintf(stderr, "%s: TianoDecompress failed with code %d\n",
+              progname,
+              r);
+      goto done4;
+    }
+  }
+
+  printf("Uncompressed %d bytes to %d bytes\n", isize, osize);
+
+  // Write it out
+  FILE *ofp = fopen(outfile, "wb");
+  if (!ofp)
+  {
+    fprintf(stderr, "%s: can't open %s for writing: %s\n",
+            progname,
+            outfile,
+            strerror(errno));
+    goto done4;
+  }
+  printf("opened %s\n", outfile);
+
+  if (1 != fwrite(obuf, osize, 1, ofp)) {
+    fprintf(stderr, "%s: can't write %d bytes: %s\n",
+            progname,
+            osize,
+            strerror(errno));
+    goto done5;
+  }
+
+  printf("wrote %d bytes to %s\n", osize, outfile);
+  retval = 0;
+
+done5:
+  fclose(ofp);
+
+done4:
+  free(obuf);
+
+done3:
+  free(sbuf);
+
+done2:
+  free(ibuf);
+
+done1:
+  fclose(ifp);
+
+  return retval;
+}
+#endif // STANDALONE