--- Makefile
+++ Makefile
@@ -9,8 +9,8 @@
 zlibcppflags=-I$(zlibdir)
 pylibprefix=/
 CFLAGS = -fPIC -O2 -Wall -g
-CPPFLAGS = -fPIC -DDELTARPM_64BIT -DBSDIFF_NO_SUF -DRPMDUMPHEADER=\"$(rpmdumpheader)\" $(zlibcppflags)
-LDLIBS = -lbz2 $(zlibldflags) -llzma
+CPPFLAGS = -fPIC -DDELTARPM_64BIT -DBSDIFF_NO_SUF -DRPMDUMPHEADER=\"$(rpmdumpheader)\" $(zlibcppflags) -Ilzmaalpha-utils/src/liblzma/api
+LDLIBS = -lbz2 $(zlibldflags) -llzma lzmaalpha-utils/liblzmaalpha.a
 LDFLAGS =
 PYTHONS = python python3
 
@@ -40,7 +40,7 @@
 			PYCFLAGS=`$$PY-config --cflags`; \
 			if [ ! -f "python$$PYVER/$@" ]; then \
 				mkdir -p python$$PYVER ;\
-				$(CC) $(CFLAGS) $$PYCFLAGS $(zlibcppflags) -fPIC -c -o python$$PYVER/deltarpmmodule.o deltarpmmodule.c ;\
+				$(CC) $(CFLAGS) $$PYCFLAGS $(zlibcppflags) -Ilzmaalpha-utils/src/liblzma/api -fPIC -c -o python$$PYVER/deltarpmmodule.o deltarpmmodule.c ;\
 				$(CC) $(LDFLAGS) -o python$$PYVER/$@ python$$PYVER/deltarpmmodule.o $^ -shared -Wl,-soname,_deltarpmmodule.so $(LDLIBS); \
 			fi; \
 		fi; \
--- cfile.c
+++ cfile.c
@@ -13,6 +13,7 @@
 
 #include <zlib.h>
 #include <bzlib.h>
+#include <lzmaalpha.h>
 #include <lzma.h>
 
 #include "cfile.h"
@@ -650,12 +651,166 @@
 
 
 /*****************************************************************
- *  lzma io
+ *  lzma (alpha) io
  */
 
 static struct cfile *
 cropen_lz(struct cfile *f)
 {
+  lzmaalpha_stream tmp = LZMAALPHA_STREAM_INIT_VAR;
+  f->strm.lza = tmp;
+  if (lzmaalpha_auto_decoder(&f->strm.lza, 0, 0) != LZMAALPHA_OK)
+    {
+      free(f);
+      return 0;
+    }
+  f->eof = 0;
+  f->strm.lza.avail_in = f->bufN == -1 ? 0 : f->bufN;
+  f->strm.lza.next_in  = (unsigned char *)f->buf;
+  return f;
+}
+
+static int
+crread_lz(struct cfile *f, void *buf, int len)
+{
+  int ret, used;
+  if (f->eof)
+    return 0;
+  f->strm.lza.avail_out = len;
+  f->strm.lza.next_out = buf;
+  for (;;)
+    {
+      if (f->strm.lza.avail_in == 0 && f->bufN)
+	{
+	  if (cfile_readbuf(f, f->buf, sizeof(f->buf)) == -1)
+	    return -1;
+	  f->strm.lza.avail_in = f->bufN;
+	  f->strm.lza.next_in = (unsigned char *)f->buf;
+	}
+      used = f->strm.lza.avail_in;
+      ret = lzmaalpha_code(&f->strm.lza, LZMAALPHA_RUN);
+      if (ret != LZMAALPHA_OK && ret != LZMAALPHA_STREAM_END)
+	return -1;
+      used -= f->strm.lza.avail_in;
+      if (used && f->ctxup)
+	f->ctxup(f->ctx, (unsigned char *)(f->strm.lza.next_in - used), used);
+      f->bytes += used;
+      if (ret == LZMAALPHA_STREAM_END)
+	{
+	  f->eof = 1;
+	  return len - f->strm.lza.avail_out;
+	}
+      if (f->strm.lza.avail_out == 0)
+	return len;
+      if (f->bufN == 0)
+	return -1;
+    }
+}
+
+static int
+crclose_lz(struct cfile *f)
+{
+  int r;
+  lzmaalpha_end(&f->strm.lza);
+  if (f->fd == CFILE_IO_CFILE && f->strm.lza.avail_in)
+    {
+      struct cfile *cf = (struct cfile *)f->fp;
+      if (cf->unread(cf, (void *)f->strm.lza.next_in, f->strm.lza.avail_in) != -1)
+        f->strm.lza.avail_in = 0;
+    }
+  r = (f->len != CFILE_LEN_UNLIMITED ? f->len : 0) + f->strm.lza.avail_in;
+  if (f->unreadbuf != f->buf)
+    free(f->unreadbuf);
+  free(f);
+  return r;
+}
+
+static struct cfile *
+cwopen_lz(struct cfile *f)
+{
+  lzmaalpha_options_alone alone;
+  lzmaalpha_stream tmp = LZMAALPHA_STREAM_INIT_VAR;
+
+  if (!f->level)
+    f->level = 3;
+  lzmaalpha_init_encoder();
+  f->strm.lza = tmp;
+  alone.uncompressed_size = LZMAALPHA_VLI_VALUE_UNKNOWN;
+  memcpy(&alone.lzma, &lzmaalpha_preset_lzma[f->level - 1], sizeof(alone.lzma));
+  if (lzmaalpha_alone_encoder(&f->strm.lza, &alone) != LZMAALPHA_OK)
+    {
+      free(f);
+      return 0;
+    }
+  return f;
+}
+
+static int
+cwclose_lz(struct cfile *f)
+{
+  int bytes, ret, n;
+  f->strm.lza.avail_in = 0;
+  f->strm.lza.next_in = 0;
+  for (;;)
+    {
+      f->strm.lza.avail_out = sizeof(f->buf);
+      f->strm.lza.next_out = (unsigned char *)f->buf;
+      ret = lzmaalpha_code(&f->strm.lza, LZMAALPHA_FINISH);
+      if (ret != LZMAALPHA_OK && ret != LZMAALPHA_STREAM_END)
+        return -1;
+      n = sizeof(f->buf) - f->strm.lza.avail_out;
+      if (n > 0)
+        if (cfile_writebuf(f, f->buf, n) != n)
+          return -1;
+      if (ret == LZMAALPHA_STREAM_END)
+        break;
+    }
+  lzmaalpha_end(&f->strm.lza);
+  if (f->fd == CFILE_IO_ALLOC)
+    cwclose_fixupalloc(f);
+  bytes = f->bytes;
+  free(f);
+  return bytes;
+}
+
+static int
+cwwrite_lz(struct cfile *f, void *buf, int len)
+{
+  int n, ret;
+
+  if (len <= 0)
+    return len < 0 ? -1 : 0;
+  f->strm.lza.avail_in = len;
+  f->strm.lza.next_in = buf;
+  for (;;)
+    {
+      f->strm.lza.avail_out = sizeof(f->buf);
+      f->strm.lza.next_out = (unsigned char *)f->buf;
+      ret = lzmaalpha_code(&f->strm.lza, LZMAALPHA_RUN);
+      if (ret != LZMA_OK)
+	return -1;
+      n = sizeof(f->buf) - f->strm.lza.avail_out;
+      if (n > 0)
+	if (cfile_writebuf(f, f->buf, n) != n)
+	  return -1;
+      if (f->strm.lza.avail_in == 0)
+	return len;
+    }
+}
+
+static int
+crunread_lz(struct cfile *f, void *buf, int len)
+{
+  return cfile_unreadbuf(f, buf, len, 0);
+}
+
+/*****************************************************************
+ *  xz io
+ */
+
+static struct cfile *
+cropen_xz(struct cfile *f)
+{
   lzma_stream tmp = LZMA_STREAM_INIT;
   f->strm.lz = tmp;
   if (lzma_auto_decoder(&f->strm.lz, 1 << 25, 0) != LZMA_OK)
@@ -670,7 +825,7 @@
 }
 
 static int
-crread_lz(struct cfile *f, void *buf, int len)
+crread_xz(struct cfile *f, void *buf, int len)
 {
   int ret, used;
   if (f->eof)
@@ -707,7 +862,7 @@
 }
 
 static int
-crclose_lz(struct cfile *f)
+crclose_xz(struct cfile *f)
 {
   int r;
   lzma_end(&f->strm.lz);
@@ -725,24 +880,6 @@
 }
 
 static struct cfile *
-cwopen_lz(struct cfile *f)
-{
-  lzma_options_lzma alone;
-  lzma_stream tmp = LZMA_STREAM_INIT;
-
-  if (!f->level)
-    f->level = 2;
-  f->strm.lz = tmp;
-  lzma_lzma_preset(&alone, f->level);
-  if (lzma_alone_encoder(&f->strm.lz, &alone) != LZMA_OK)
-    {
-      free(f);
-      return 0;
-    }
-  return f;
-}
-
-static struct cfile *
 cwopen_xz(struct cfile *f)
 {
   lzma_stream tmp = LZMA_STREAM_INIT;
@@ -760,7 +897,7 @@
 }
 
 static int
-cwclose_lz(struct cfile *f)
+cwclose_xz(struct cfile *f)
 {
   int bytes, ret, n;
   f->strm.lz.avail_in = 0;
@@ -788,7 +925,7 @@
 }
 
 static int
-cwwrite_lz(struct cfile *f, void *buf, int len)
+cwwrite_xz(struct cfile *f, void *buf, int len)
 {
   int n, ret;
 
@@ -813,7 +950,7 @@
 }
 
 static int
-crunread_lz(struct cfile *f, void *buf, int len)
+crunread_xz(struct cfile *f, void *buf, int len)
 {
   return cfile_unreadbuf(f, buf, len, 0);
 }
@@ -1199,11 +1336,11 @@
     case CFILE_COMP_XZ:
       f->strm.lz.allocator = 0;
       f->strm.lz.internal = 0;
-      f->read   = mode == CFILE_OPEN_RD ? crread_lz : 0;
-      f->unread = mode == CFILE_OPEN_RD ? crunread_lz : 0;
-      f->write  = mode == CFILE_OPEN_WR ? cwwrite_lz : 0;
-      f->close  = mode == CFILE_OPEN_RD ? crclose_lz : cwclose_lz;
-      return mode == CFILE_OPEN_RD ? cropen_lz(f) : cwopen_xz(f);
+      f->read   = mode == CFILE_OPEN_RD ? crread_xz : 0;
+      f->unread = mode == CFILE_OPEN_RD ? crunread_xz : 0;
+      f->write  = mode == CFILE_OPEN_WR ? cwwrite_xz : 0;
+      f->close  = mode == CFILE_OPEN_RD ? crclose_xz : cwclose_xz;
+      return mode == CFILE_OPEN_RD ? cropen_xz(f) : cwopen_xz(f);
     default:
       free(f);
       return 0;
--- cfile.h
+++ cfile.h
@@ -8,6 +8,7 @@
 #include <zlib.h>
 #include <bzlib.h>
 #include <lzma.h>
+#include <lzmaalpha.h>
 
 struct cfile {
   int fd;
@@ -28,6 +29,7 @@
   union {
     bz_stream bz;
     z_stream gz;
+    lzmaalpha_stream lza;
     lzma_stream lz;
   } strm;
   int (*read)(struct cfile *f, void *buf, int len);
