diff --git a/examples/hello/CMakeLists.txt b/examples/hello/CMakeLists.txt
index 43b9e6a4bc0f6d23aef3571dc119cb7a67579a1e..2850407da804fce34afa2c23bdfce603865e4795 100644
--- a/examples/hello/CMakeLists.txt
+++ b/examples/hello/CMakeLists.txt
@@ -19,3 +19,12 @@ endif()
 if(ADIOS2_HAVE_HDF5)
   add_subdirectory(hdf5Writer)
 endif()
+
+if(ADIOS2_HAVE_BZip2)
+  add_subdirectory(bpBZip2Wrapper)
+endif()
+
+if(ADIOS2_HAVE_ZFP)
+  add_subdirectory(bpZfpWrapper)
+endif()
+
diff --git a/examples/hello/bpBZip2Wrapper/CMakeLists.txt b/examples/hello/bpBZip2Wrapper/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3803a998a7103673cdee602633c71a03a049da24
--- /dev/null
+++ b/examples/hello/bpBZip2Wrapper/CMakeLists.txt
@@ -0,0 +1,18 @@
+#------------------------------------------------------------------------------#
+# Distributed under the OSI-approved Apache License, Version 2.0.  See
+# accompanying file Copyright.txt for details.
+#------------------------------------------------------------------------------#
+
+if(ADIOS2_HAVE_MPI)
+  find_package(MPI COMPONENTS C REQUIRED)
+
+  add_executable(hello_bpBZip2Wrapper helloBPBZip2Wrapper.cpp)
+  target_include_directories(hello_bpBZip2Wrapper PRIVATE ${MPI_C_INCLUDE_PATH})
+  target_link_libraries(hello_bpBZip2Wrapper ${MPI_C_LIBRARIES})
+  
+else()
+  add_executable(hello_bpBZip2Wrapper helloBPBZip2Wrapper_nompi.cpp)
+  
+endif()
+
+target_link_libraries(hello_bpBZip2Wrapper adios2)
diff --git a/examples/hello/bpBZip2Wrapper/helloBPBZip2Wrapper.cpp b/examples/hello/bpBZip2Wrapper/helloBPBZip2Wrapper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bb425051ccd39c7bfdbb56f1925f1d014476be42
--- /dev/null
+++ b/examples/hello/bpBZip2Wrapper/helloBPBZip2Wrapper.cpp
@@ -0,0 +1,120 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * helloBPBZip2Wrapper.cpp: Simple self-descriptive example of how to write a
+ * variable to a BP File that lives in several MPI processes and is compressed
+ * with BZip2 http://www.bzip.org/
+ *
+ *  Created on: Jul 26, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+#include <mpi.h>
+
+#include <ios>       //std::ios_base::failure
+#include <iostream>  //std::cout
+#include <numeric>   //std::iota
+#include <stdexcept> //std::invalid_argument std::exception
+#include <vector>
+
+#include <adios2.h>
+
+int main(int argc, char *argv[])
+{
+    MPI_Init(&argc, &argv);
+    int rank, size;
+    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+    MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+    /** Application variable uints from 0 to 1000 */
+    std::vector<unsigned int> myUInts(1000);
+    std::iota(myUInts.begin(), myUInts.end(), 0.f);
+    const std::size_t Nx = myUInts.size();
+    const std::size_t inputBytes = Nx * sizeof(unsigned int);
+
+    try
+    {
+        /** ADIOS class factory of IO class objects, DebugON is recommended */
+        adios2::ADIOS adios(MPI_COMM_WORLD, adios2::DebugON);
+
+        // Get a Transform of type BZip2
+        adios2::Transform &adiosBZip2 = adios.GetTransform("bzip2");
+
+        /*** IO class object: settings and factory of Settings: Variables,
+         * Parameters, Transports, and Execution: Engines */
+        adios2::IO &bpIO = adios.DeclareIO("BPFile_N2N_BZip2");
+
+        /** global array : name, { shape (total) }, { start (local) }, { count
+         * (local) }, all are constant dimensions */
+        adios2::Variable<unsigned int> &bpUInts =
+            bpIO.DefineVariable<unsigned int>("bpUInts", {size * Nx},
+                                              {rank * Nx}, {Nx},
+                                              adios2::ConstantDims);
+
+        // 1st way: adding transform metadata to variable to Engine can decide:
+        // &adiosBZip2 gets mapped to bpUInts.TransformInfo[bzip2ID].Operator
+        const unsigned int bzip2ID =
+            bpUInts.AddTransform(adiosBZip2, {{"BlockSize100K", "9"}});
+
+        // 2nd way: treat Transforms as wrappers to underlying library.
+        // you can redefine parameters
+        const std::size_t estimatedSize =
+            adiosBZip2.BufferMaxSize(Nx * bpUInts.m_ElementSize);
+        std::vector<char> compressedBuffer(estimatedSize);
+        size_t compressedSize = adiosBZip2.Compress(
+            myUInts.data(), bpUInts.m_Count, bpUInts.m_ElementSize,
+            bpUInts.m_Type, compressedBuffer.data(), {{"BlockSize100K", "1"}});
+
+        compressedBuffer.resize(compressedSize);
+
+        std::cout << "Rank " << rank << "\n";
+        std::cout << "Compression summary:\n";
+        std::cout << "Input data size: " << inputBytes << " bytes\n";
+        std::cout << "BZip2 estimated output size: " << estimatedSize
+                  << " bytes\n";
+        std::cout << "BZip2 final output size: " << compressedSize
+                  << " bytes\n\n";
+
+        // Allocate original data size
+        std::vector<unsigned int> decompressedBuffer(Nx);
+        size_t decompressedSize = adiosBZip2.Decompress(
+            compressedBuffer.data(), compressedSize, decompressedBuffer.data(),
+            decompressedBuffer.size() * sizeof(unsigned int));
+
+        std::cout << "Decompression summary:\n";
+        std::cout << "Decompressed size: " << decompressedSize << " bytes\n";
+        std::cout << "Data:\n";
+
+        for (const auto number : decompressedBuffer)
+        {
+            if (number % 25 == 0)
+            {
+                std::cout << "\n";
+            }
+            std::cout << number << " ";
+        }
+        std::cout << "\n";
+    }
+    catch (std::invalid_argument &e)
+    {
+        std::cout << "Invalid argument exception, STOPPING PROGRAM from rank "
+                  << rank << "\n";
+        std::cout << e.what() << "\n";
+    }
+    catch (std::ios_base::failure &e)
+    {
+        std::cout
+            << "IO System base failure exception, STOPPING PROGRAM from rank "
+            << rank << "\n";
+        std::cout << e.what() << "\n";
+    }
+    catch (std::exception &e)
+    {
+        std::cout << "Exception, STOPPING PROGRAM from rank " << rank << "\n";
+        std::cout << e.what() << "\n";
+    }
+
+    MPI_Finalize();
+
+    return 0;
+}
diff --git a/examples/hello/bpBZip2Wrapper/helloBPBZip2Wrapper_nompi.cpp b/examples/hello/bpBZip2Wrapper/helloBPBZip2Wrapper_nompi.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fe7e2b7b027a031f5b63c3d61f94b2788763c6d9
--- /dev/null
+++ b/examples/hello/bpBZip2Wrapper/helloBPBZip2Wrapper_nompi.cpp
@@ -0,0 +1,103 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * helloBPBZip2Writer_nompi.cpp sequential non-mpi version of helloBPBZip2Writer
+ * using BZip2 http://www.bzip.org/
+ *
+ *  Created on: Jul 26, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+
+#include <ios>       //std::ios_base::failure
+#include <iostream>  //std::cout
+#include <numeric>   //std::iota
+#include <stdexcept> //std::invalid_argument std::exception
+#include <vector>
+
+#include <adios2.h>
+
+int main(int argc, char *argv[])
+{
+    /** Application variable uints from 0 to 1000 */
+    std::vector<unsigned int> myUInts(1000);
+    std::iota(myUInts.begin(), myUInts.end(), 0.f);
+    const std::size_t Nx = myUInts.size();
+    const std::size_t inputBytes = Nx * sizeof(unsigned int);
+
+    try
+    {
+        /** ADIOS class factory of IO class objects, DebugON is recommended */
+        adios2::ADIOS adios(adios2::DebugON);
+
+        // Get a Transform of type BZip2
+        adios2::Transform &adiosBZip2 = adios.GetTransform("bzip2");
+
+        /*** IO class object: settings and factory of Settings: Variables,
+         * Parameters, Transports, and Execution: Engines */
+        adios2::IO &bpIO = adios.DeclareIO("BPFile_N2N_BZip2");
+
+        /** global array : name, { shape (total) }, { start (local) }, { count
+         * (local) }, all are constant dimensions */
+        adios2::Variable<unsigned int> &bpUInts =
+            bpIO.DefineVariable<unsigned int>("bpUInts", {}, {}, {Nx},
+                                              adios2::ConstantDims);
+
+        // 1st way: adding transform metadata to variable to Engine can decide:
+        bpUInts.AddTransform(adiosBZip2, {{"BlockSize100K", "10"}});
+
+        // 2nd way: treat Transforms as wrappers to underlying library:
+        const std::size_t estimatedSize =
+            adiosBZip2.BufferMaxSize(Nx * bpUInts.m_ElementSize);
+        std::vector<char> compressedBuffer(estimatedSize);
+        size_t compressedSize = adiosBZip2.Compress(
+            myUInts.data(), bpUInts.m_Count, bpUInts.m_ElementSize,
+            bpUInts.m_Type, compressedBuffer.data(), {{"BlockSize100K", "9"}});
+
+        compressedBuffer.resize(compressedSize);
+
+        std::cout << "Compression summary:\n";
+        std::cout << "Input data size: " << inputBytes << " bytes\n";
+        std::cout << "BZip2 estimated output size: " << estimatedSize
+                  << " bytes\n";
+        std::cout << "BZip2 final output size: " << compressedSize
+                  << " bytes\n\n";
+
+        // Allocate original data size
+        std::vector<unsigned int> decompressedBuffer(Nx);
+        size_t decompressedSize = adiosBZip2.Decompress(
+            compressedBuffer.data(), compressedSize, decompressedBuffer.data(),
+            decompressedBuffer.size() * sizeof(unsigned int));
+
+        std::cout << "Decompression summary:\n";
+        std::cout << "Decompressed size: " << decompressedSize << " bytes\n";
+        std::cout << "Data:\n";
+
+        for (const auto number : decompressedBuffer)
+        {
+            if (number % 25 == 0)
+            {
+                std::cout << "\n";
+            }
+            std::cout << number << " ";
+        }
+        std::cout << "\n";
+    }
+    catch (std::invalid_argument &e)
+    {
+        std::cout << "Invalid argument exception, STOPPING PROGRAM\n";
+        std::cout << e.what() << "\n";
+    }
+    catch (std::ios_base::failure &e)
+    {
+        std::cout << "IO System base failure exception, STOPPING PROGRAM\n";
+        std::cout << e.what() << "\n";
+    }
+    catch (std::exception &e)
+    {
+        std::cout << "Exception, STOPPING PROGRAM\n";
+        std::cout << e.what() << "\n";
+    }
+
+    return 0;
+}
diff --git a/examples/hello/bpZfpWrapper/CMakeLists.txt b/examples/hello/bpZfpWrapper/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c5cb52b74f20dc3bdced1ea0e63a5a5373a33329
--- /dev/null
+++ b/examples/hello/bpZfpWrapper/CMakeLists.txt
@@ -0,0 +1,18 @@
+#------------------------------------------------------------------------------#
+# Distributed under the OSI-approved Apache License, Version 2.0.  See
+# accompanying file Copyright.txt for details.
+#------------------------------------------------------------------------------#
+
+if(ADIOS2_HAVE_MPI)
+  find_package(MPI COMPONENTS C REQUIRED)
+
+  add_executable(hello_bpZfpWrapper helloBPZfpWrapper.cpp)
+  target_include_directories(hello_bpZfpWrapper PRIVATE ${MPI_C_INCLUDE_PATH})
+  target_link_libraries(hello_bpZfpWrapper ${MPI_C_LIBRARIES})
+  
+else()
+  add_executable(hello_bpZfpWrapper helloBPZfpWrapper_nompi.cpp)
+  
+endif()
+
+target_link_libraries(hello_bpZfpWrapper adios2)
diff --git a/examples/hello/bpZfpWrapper/helloBPZfpWrapper.cpp b/examples/hello/bpZfpWrapper/helloBPZfpWrapper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a9227e20c7c266d94f61e64eb71bbac290e48476
--- /dev/null
+++ b/examples/hello/bpZfpWrapper/helloBPZfpWrapper.cpp
@@ -0,0 +1,122 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * helloBPZfpWrapper.cpp: Simple self-descriptive example of how to write a
+ * variable to a BP File that lives in several MPI processes and is compressed
+ * with Zfp https://computation.llnl.gov/projects/floating-point-compression
+ *
+ *  Created on: Jul 26, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+#include <mpi.h>
+
+#include <cstdint>   //std::int32_t
+#include <ios>       //std::ios_base::failure
+#include <iostream>  //std::cout
+#include <numeric>   //std::iota
+#include <stdexcept> //std::invalid_argument std::exception
+#include <vector>
+
+#include <adios2.h>
+
+int main(int argc, char *argv[])
+{
+    MPI_Init(&argc, &argv);
+    int rank, size;
+    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+    MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+    /** Application variable uints from 0 to 100 */
+    std::vector<float> myFloats(100);
+    std::iota(myFloats.begin(), myFloats.end(), 0.f);
+    const std::size_t Nx = myFloats.size();
+    const std::size_t inputBytes = Nx * sizeof(float);
+
+    try
+    {
+        /** ADIOS class factory of IO class objects, DebugON is recommended */
+        adios2::ADIOS adios(MPI_COMM_WORLD, adios2::DebugON);
+
+        // Get a Transform of type BZip2
+        adios2::Transform &adiosZfp = adios.GetTransform("zfp");
+
+        /*** IO class object: settings and factory of Settings: Variables,
+         * Parameters, Transports, and Execution: Engines */
+        adios2::IO &bpIO = adios.DeclareIO("BPFile_N2N_Zfp");
+
+        /** global array : name, { shape (total) }, { start (local) }, { count
+         * (local) }, all are constant dimensions */
+        adios2::Variable<float> &bpFloats = bpIO.DefineVariable<float>(
+            "bpFloats", {size * Nx}, {rank * Nx}, {Nx}, adios2::ConstantDims);
+
+        // 1st way: adding transform metadata to variable to Engine can decide:
+        const unsigned int zfpID =
+            bpFloats.AddTransform(adiosZfp, {{"Rate", "8"}});
+
+        // 2nd way: treat Transforms as wrappers to underlying library:
+        const std::size_t estimatedSize =
+            adiosZfp.BufferMaxSize(myFloats.data(), bpFloats.m_Count,
+                                   bpFloats.m_TransformsInfo[zfpID].Parameters);
+
+        // Compress
+        std::vector<char> compressedBuffer(estimatedSize);
+
+        size_t compressedSize = adiosZfp.Compress(
+            myFloats.data(), bpFloats.m_Count, bpFloats.m_ElementSize,
+            bpFloats.m_Type, compressedBuffer.data(),
+            bpFloats.m_TransformsInfo[zfpID].Parameters);
+
+        compressedBuffer.resize(compressedSize);
+
+        std::cout << "Compression summary:\n";
+        std::cout << "Input data size: " << inputBytes << " bytes\n";
+        std::cout << "Zfp estimated output size: " << estimatedSize
+                  << " bytes\n";
+        std::cout << "Zfp final output size: " << compressedSize
+                  << " bytes\n\n";
+
+        // Allocate original data size
+        std::vector<float> decompressedBuffer(Nx);
+        size_t decompressedSize = adiosZfp.Decompress(
+            compressedBuffer.data(), compressedBuffer.size(),
+            decompressedBuffer.data(), bpFloats.m_Count, bpFloats.m_Type,
+            bpFloats.m_TransformsInfo[zfpID].Parameters);
+
+        std::cout << "Decompression summary:\n";
+        std::cout << "Decompressed size: " << decompressedSize << " bytes\n ";
+        std::cout << "Data:\n";
+
+        for (const auto number : decompressedBuffer)
+        {
+            if (static_cast<int>(number) % 25 == 0 && number != 0)
+            {
+                std::cout << "\n";
+            }
+            std::cout << number << " ";
+        }
+        std::cout << "\n";
+    }
+    catch (std::invalid_argument &e)
+    {
+        std::cout << "Invalid argument exception, STOPPING PROGRAM from rank "
+                  << rank << "\n";
+        std::cout << e.what() << "\n";
+    }
+    catch (std::ios_base::failure &e)
+    {
+        std::cout
+            << "IO System base failure exception, STOPPING PROGRAM from rank "
+            << rank << "\n";
+        std::cout << e.what() << "\n";
+    }
+    catch (std::exception &e)
+    {
+        std::cout << "Exception, STOPPING PROGRAM from rank " << rank << "\n";
+        std::cout << e.what() << "\n";
+    }
+
+    MPI_Finalize();
+
+    return 0;
+}
diff --git a/examples/hello/bpZfpWrapper/helloBPZfpWrapper_nompi.cpp b/examples/hello/bpZfpWrapper/helloBPZfpWrapper_nompi.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e84feee7b8c75401da3ee360ac22b29a291ce70f
--- /dev/null
+++ b/examples/hello/bpZfpWrapper/helloBPZfpWrapper_nompi.cpp
@@ -0,0 +1,114 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * helloBPZfpWriter_nompi.cpp sequential non-mpi version of helloBPZfpWrapper
+ * using  Zfp https://computation.llnl.gov/projects/floating-point-compression
+ *
+ *  Created on: Jul 26, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+
+#include <cstdint>   //std::int32_t
+#include <ios>       //std::ios_base::failure
+#include <iostream>  //std::cout
+#include <numeric>   //std::iota
+#include <stdexcept> //std::invalid_argument std::exception
+#include <vector>
+
+#include <adios2.h>
+
+int main(int argc, char *argv[])
+{
+    /** Application variable uints from 0 to 100 */
+    std::vector<float> myFloats(100);
+    std::iota(myFloats.begin(), myFloats.end(), 0.f);
+    const std::size_t Nx = myFloats.size();
+    const std::size_t inputBytes = Nx * sizeof(float);
+
+    try
+    {
+        /** ADIOS class factory of IO class objects, DebugON is recommended */
+        adios2::ADIOS adios(adios2::DebugON);
+
+        // Get a Transform of type BZip2
+        adios2::Transform &adiosZfp = adios.GetTransform("zfp");
+
+        /*** IO class object: settings and factory of Settings: Variables,
+         * Parameters, Transports, and Execution: Engines */
+        adios2::IO &bpIO = adios.DeclareIO("BPVariable_Zfp");
+
+        /** global array : name, { shape (total) }, { start (local) }, { count
+         * (local) }, all are constant dimensions */
+        adios2::Variable<float> &bpFloats = bpIO.DefineVariable<float>(
+            "bpUInts", {}, {}, {Nx}, adios2::ConstantDims);
+
+        // Adding transform metadata to variable:
+        // Options:
+        // Rate double
+        // Tolerance
+        // Precision
+        const unsigned int zfpID =
+            bpFloats.AddTransform(adiosZfp, {{"Rate", "8"}});
+
+        // Treat Transforms as wrappers to underlying library (zfp):
+        const std::size_t estimatedSize =
+            adiosZfp.BufferMaxSize(myFloats.data(), bpFloats.m_Count,
+                                   bpFloats.m_TransformsInfo[zfpID].Parameters);
+
+        // Compress
+        std::vector<char> compressedBuffer(estimatedSize);
+
+        size_t compressedSize = adiosZfp.Compress(
+            myFloats.data(), bpFloats.m_Count, bpFloats.m_ElementSize,
+            bpFloats.m_Type, compressedBuffer.data(),
+            bpFloats.m_TransformsInfo[zfpID].Parameters);
+
+        compressedBuffer.resize(compressedSize);
+
+        std::cout << "Compression summary:\n";
+        std::cout << "Input data size: " << inputBytes << " bytes\n";
+        std::cout << "Zfp estimated output size: " << estimatedSize
+                  << " bytes\n";
+        std::cout << "Zfp final output size: " << compressedSize
+                  << " bytes\n\n";
+
+        // Decompress, allocate original data size
+        std::vector<float> decompressedBuffer(Nx);
+        size_t decompressedSize = adiosZfp.Decompress(
+            compressedBuffer.data(), compressedBuffer.size(),
+            decompressedBuffer.data(), bpFloats.m_Count, bpFloats.m_Type,
+            bpFloats.m_TransformsInfo[zfpID].Parameters);
+
+        std::cout << "Decompression summary:\n";
+        std::cout << "Decompressed size: " << decompressedSize << " bytes\n ";
+        std::cout << "Data:\n";
+
+        for (const auto number : decompressedBuffer)
+        {
+            if (static_cast<int>(number) % 25 == 0 && number != 0)
+            {
+                std::cout << "\n";
+            }
+            std::cout << number << " ";
+        }
+        std::cout << "\n";
+    }
+    catch (std::invalid_argument &e)
+    {
+        std::cout << "Invalid argument exception, STOPPING PROGRAM\n";
+        std::cout << e.what() << "\n";
+    }
+    catch (std::ios_base::failure &e)
+    {
+        std::cout << "IO System base failure exception, STOPPING PROGRAM\n";
+        std::cout << e.what() << "\n";
+    }
+    catch (std::exception &e)
+    {
+        std::cout << "Exception, STOPPING PROGRAM\n";
+        std::cout << e.what() << "\n";
+    }
+
+    return 0;
+}
diff --git a/source/adios2/ADIOSConfig.h.in b/source/adios2/ADIOSConfig.h.in
index c917b81a8b1a06b2b43b4844cd1715e70ebff69e..2ed35a170040bebcd83e0466c29a9127e9e8fc97 100644
--- a/source/adios2/ADIOSConfig.h.in
+++ b/source/adios2/ADIOSConfig.h.in
@@ -27,10 +27,10 @@
 /* CMake Option: ADIOS_USE_MPI=OFF */
 #cmakedefine ADIOS2_HAVE_MPI
 
-/* CMake Option: ADIOS_USE_ZFP=OFF */
+/* CMake Option: ADIOS_USE_ZFP=ON */
 #cmakedefine ADIOS2_HAVE_ZFP
 
-/* CMake Option: ADIOS_USE_BZip2=OFF */
+/* CMake Option: ADIOS_USE_BZip2=ON */
 #cmakedefine ADIOS2_HAVE_BZIP2
 
 /* CMake Option: ADIOS_USE_ADIOS1=ON */
diff --git a/source/adios2/ADIOSMacros.h b/source/adios2/ADIOSMacros.h
index 8f1471a4a7067ea274f5620ba439320856679df0..f3043732b588cbde469d3b5f9e06adcc85afa03b 100644
--- a/source/adios2/ADIOSMacros.h
+++ b/source/adios2/ADIOSMacros.h
@@ -56,4 +56,10 @@
     MACRO(float)                                                               \
     MACRO(double)
 
+#define ADIOS2_FOREACH_ZFP_TYPE_1ARG(MACRO)                                    \
+    MACRO(int32_t)                                                             \
+    MACRO(int64_t)                                                             \
+    MACRO(float)                                                               \
+    MACRO(double)
+
 #endif /* ADIOS2_ADIOSMACROS_H */
diff --git a/source/adios2/CMakeLists.txt b/source/adios2/CMakeLists.txt
index ce6a31efdf961afe5dce50bbb256c2d5f53ee7de..3bd8861811fcdb0cf4812ccd591e53c957331c4e 100644
--- a/source/adios2/CMakeLists.txt
+++ b/source/adios2/CMakeLists.txt
@@ -10,7 +10,7 @@ add_library(adios2
   core/Selection.cpp
   core/SelectionBoundingBox.cpp
   core/SelectionPoints.cpp
-  core/Transform.cpp
+  core/Transform.cpp core/Transform.tcc
   core/Variable.cpp core/Variable.tcc
   core/VariableBase.cpp
   core/VariableCompound.cpp core/VariableCompound.tcc
@@ -71,15 +71,14 @@ endif()
   
 if(ADIOS2_HAVE_BZip2)
   find_package(BZip2 REQUIRED)
-  target_sources(adios2 PRIVATE transform/compression/BZip2.cpp)
+  target_sources(adios2 PRIVATE transform/compress/CompressBZip2.cpp)
   target_link_libraries(adios2 PRIVATE BZip2::BZip2)
 endif()
 
 if(ADIOS2_HAVE_ZFP)
   find_package(ZFP REQUIRED)
-  message("ADIOS ZFP support not yet implemented")
-#  target_sources(adios2 PRIVATE transform/compression/ZFP.cpp)
-#  target_link_libraries(adios2 PRIVATE zfp::zfp)
+  target_sources(adios2 PRIVATE transform/compress/CompressZfp.cpp)
+  target_link_libraries(adios2 PRIVATE zfp::zfp)
 endif()
 
 if(ADIOS2_HAVE_MPI)
diff --git a/source/adios2/core/ADIOS.cpp b/source/adios2/core/ADIOS.cpp
index af7020254e84fd396c9e4c8be71c984deef9b8f0..d4853c603d064962abc543a8caa94dfc36a01643 100644
--- a/source/adios2/core/ADIOS.cpp
+++ b/source/adios2/core/ADIOS.cpp
@@ -21,6 +21,15 @@
 #include "adios2/ADIOSMPI.h"
 #include "adios2/helper/adiosFunctions.h"
 
+// transforms
+#ifdef ADIOS2_HAVE_BZIP2
+#include "adios2/transform/compress/CompressBZip2.h"
+#endif
+
+#ifdef ADIOS2_HAVE_ZFP
+#include "adios2/transform/compress/CompressZfp.h"
+#endif
+
 namespace adios2
 {
 
@@ -86,11 +95,59 @@ IO &ADIOS::GetIO(const std::string name)
     {
         throw std::invalid_argument(
             "ERROR: Unable to find previously defined IO object with name \"" +
-            name + "\" in call to GetIO.");
+            name + "\", in call to GetIO.");
     }
     return itIO->second;
 }
 
+Transform &ADIOS::GetTransform(const std::string transform)
+{
+    auto itTransform = m_Transforms.find(transform);
+
+    if (itTransform != m_Transforms.end())
+    {
+        return *itTransform->second.get();
+    }
+
+    if (transform == "bzip2" || transform == "BZip2")
+    {
+#ifdef ADIOS2_HAVE_BZIP2
+        auto itPair = m_Transforms.emplace(
+            "bzip2",
+            std::make_shared<adios2::transform::CompressBZip2>(m_DebugMode));
+        return *itPair.first->second;
+#else
+        throw std::invalid_argument(
+            "ERROR: this version of ADIOS2 didn't compile with "
+            "bzip2 library, in call to GetTransport\n");
+#endif
+    }
+    else if (transform == "zfp" || transform == "Zfp")
+    {
+#ifdef ADIOS2_HAVE_ZFP
+        auto itPair = m_Transforms.emplace(
+            "zfp",
+            std::make_shared<adios2::transform::CompressZfp>(m_DebugMode));
+        return *itPair.first->second;
+#else
+        throw std::invalid_argument(
+            "ERROR: this version of ADIOS2 didn't compile with "
+            "zfp library, in call to GetTransport\n");
+#endif
+    }
+    else
+    {
+        if (m_DebugMode)
+        {
+            throw std::invalid_argument(
+                "ERROR: transform " + transform +
+                " not supported by ADIOS2, in call to GetTransport\n");
+        }
+    }
+
+    return *itTransform->second.get();
+}
+
 // PRIVATE FUNCTIONS
 void ADIOS::CheckMPI() const
 {
diff --git a/source/adios2/core/ADIOS.h b/source/adios2/core/ADIOS.h
index 618a33232bf29cc7d931dc36d3b0932166d85818..2a019274b0478c1608a108fe171706ab85919c63 100644
--- a/source/adios2/core/ADIOS.h
+++ b/source/adios2/core/ADIOS.h
@@ -96,6 +96,8 @@ public:
      */
     IO &GetIO(const std::string name);
 
+    Transform &GetTransform(const std::string transform);
+
 private:
     /** XML File to be read containing configuration information */
     const std::string m_ConfigFile;
@@ -104,7 +106,7 @@ private:
     const bool m_DebugMode = false;
 
     /** transforms associated with ADIOS run */
-    std::vector<std::shared_ptr<Transform>> m_Transforms;
+    std::map<std::string, std::shared_ptr<Transform>> m_Transforms;
 
     /**
      * @brief List of IO class objects defined from either ADIOS
diff --git a/source/adios2/core/Transform.cpp b/source/adios2/core/Transform.cpp
index dc4079aed7aa725493c67f6eab8cda3c1f4617de..02973f2460c664fc9f214a9b6692728ed4c91229 100644
--- a/source/adios2/core/Transform.cpp
+++ b/source/adios2/core/Transform.cpp
@@ -9,20 +9,90 @@
  */
 
 #include "Transform.h"
+#include "Transform.tcc"
 
 namespace adios2
 {
 
-Transform::Transform(const std::string method) : m_Method(method) {}
+Transform::Transform(const std::string library, const bool debugMode)
+: m_Library(library), m_DebugMode(debugMode)
+{
+}
+
+size_t Transform::BufferMaxSize(const size_t sizeIn) const
+{
+    if (m_DebugMode)
+    {
+        throw std::invalid_argument(
+            "ERROR: signature (const size_t) not supported "
+            "by derived class implemented with " +
+            m_Library + ", in call to BufferMaxSize\n");
+    }
+    return 0;
+}
+
+size_t Transform::Compress(const void * /*dataIn*/, const Dims & /*dimensions*/,
+                           const size_t /*elementSize*/,
+                           const std::string /*type*/, void * /*bufferOut*/,
+                           const Params & /*params*/) const
+{
+    if (m_DebugMode)
+    {
+        throw std::invalid_argument("ERROR: signature (const void*, const "
+                                    "Dims, const size_t, const std::string, "
+                                    "void*, const Params&) not supported "
+                                    "by derived class implemented with " +
+                                    m_Library + ", in call to Compress\n");
+    }
+    return 0;
+}
 
-void Transform::Compress(const std::vector<char> & /*bufferIn*/,
-                         std::vector<char> & /*bufferOut*/)
+size_t Transform::Decompress(const void *bufferIn, const size_t sizeIn,
+                             void *dataOut, const size_t sizeOut) const
 {
+    if (m_DebugMode)
+    {
+        throw std::invalid_argument(
+            "ERROR: signature (const void*, const size_t, void) not supported "
+            "by derived class implemented with " +
+            m_Library + ", in call to Decompress\n");
+    }
+
+    return 0;
 }
 
-void Transform::Decompress(const std::vector<char> & /*bufferIn*/,
-                           std::vector<char> & /*bufferOut*/)
+size_t Transform::Decompress(const void * /*bufferIn*/, const size_t /*sizeIn*/,
+                             void * /*dataOut*/, const Dims & /*dimensions*/,
+                             const std::string /*type*/,
+                             const Params & /*parameters*/) const
 {
+    if (m_DebugMode)
+    {
+        throw std::invalid_argument("ERROR: signature (const void*, const "
+                                    "size_t, void*, const Dims&, const "
+                                    "std::string ) not supported "
+                                    "by derived class implemented with " +
+                                    m_Library + ", in call to Decompress\n");
+    }
+
+    return 0;
+}
+
+// PROTECTED
+size_t Transform::DoBufferMaxSize(const void *dataIn, const Dims &dimensions,
+                                  const std::string type,
+                                  const Params &parameters) const
+{
+    if (m_DebugMode)
+    {
+        throw std::invalid_argument(
+            "ERROR: signature (const void*, const Dims& "
+            "std::string ) not supported "
+            "by derived class implemented with " +
+            m_Library + ", in call to BufferMaxSize\n");
+    }
+
+    return 0;
 }
 
-} // end namespace adios
+} // end namespace adios2
diff --git a/source/adios2/core/Transform.h b/source/adios2/core/Transform.h
index 32c857293ef9d7ee29ecb02abda652c81d9d261b..19d617432da299dfd62ac0e2f279946c1b8e31ff 100644
--- a/source/adios2/core/Transform.h
+++ b/source/adios2/core/Transform.h
@@ -16,33 +16,96 @@
 #include <vector>
 /// \endcond
 
-#include "adios2/ADIOSConfig.h"
+#include "adios2/ADIOSTypes.h"
 
 namespace adios2
 {
 
-/** Base class that defines data variable transformations */
+/** Base class that defines data variable transformations implemented under
+ * adios2/transform */
 class Transform
 {
 
 public:
-    /** From derived class to identify the transform */
-    const std::string m_Method;
+    /** From derived class */
+    const std::string m_Library;
 
     /**
-     * Initialize parent method
-     * @param method zlib, bzip2, szip
+     * Unique base class constructor
+     * @param method bzip2, zfp
+     * @param debugMode true: extra exceptions checks
      */
-    Transform(const std::string method);
+    Transform(const std::string library, const bool debugMode);
 
     virtual ~Transform() = default;
 
-    virtual void Compress(const std::vector<char> &bufferIn,
-                          std::vector<char> &bufferOut);
+    /**
+     * Returns a conservative buffer size to hold input data for classes
+     * @param sizeIn size of input data to be compressed in bytes
+     * @return recommended allocation for output buffer
+     */
+    virtual size_t BufferMaxSize(const size_t sizeIn) const;
+
+    /**
+     * Used by Zfp
+     * Returns a conservative buffer size to hold input data for classes
+     * @param dataIn
+     * @param dimensions
+     * @return recommended allocation for output buffer in bytes
+     */
+    template <class T>
+    size_t BufferMaxSize(const T *dataIn, const Dims &dimensions,
+                         const Params &params) const;
+
+    /**
+     * BZip2 and Zfp common call
+     * @param dataIn
+     * @param dimensions
+     * @param elementSize
+     * @param type
+     * @param bufferOut
+     * @param parameters
+     * @return size of compressed buffer
+     */
+    virtual size_t Compress(const void *dataIn, const Dims &dimensions,
+                            const size_t elementSize, const std::string type,
+                            void *bufferOut,
+                            const Params &parameters = Params()) const;
 
-    virtual void Decompress(const std::vector<char> &bufferIn,
-                            std::vector<char> &bufferOut);
+    virtual size_t Decompress(const void *bufferIn, const size_t sizeIn,
+                              void *dataOut, const size_t sizeOut) const;
+
+    /**
+     * Zfp signature
+     * @param bufferIn
+     * @param sizeIn
+     * @param dataOut
+     * @param dimensions
+     * @param type
+     * @return
+     */
+    virtual size_t Decompress(const void *bufferIn, const size_t sizeIn,
+                              void *dataOut, const Dims &dimensions,
+                              const std::string type,
+                              const Params &parameters) const;
+
+protected:
+    /** true: extra exception checks, false: skip exception checks */
+    const bool m_DebugMode = false;
+
+    /**
+     * Used by CompressZfp
+     * Returns a conservative buffer size to hold input data for classes
+     * @param dataIn
+     * @param dimensions
+     * @param type
+     * @return conservative buffer size for allocation
+     */
+    virtual size_t DoBufferMaxSize(const void *dataIn, const Dims &dimensions,
+                                   const std::string type,
+                                   const Params &parameters) const;
 };
 
-} // end namespace adios
+} // end namespace adios2
+
 #endif /* ADIOS2_CORE_TRANSFORM_H_ */
diff --git a/source/adios2/core/Transform.tcc b/source/adios2/core/Transform.tcc
new file mode 100644
index 0000000000000000000000000000000000000000..3fac195fda0603970a939ab6f817c9c553c5079f
--- /dev/null
+++ b/source/adios2/core/Transform.tcc
@@ -0,0 +1,35 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * Transform.tcc : specialization of template functions
+ *
+ *  Created on: Jul 25, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+
+#ifndef ADIOS2_CORE_TRANSFORM_TCC_
+#define ADIOS2_CORE_TRANSFORM_TCC_
+
+#include "Transform.h"
+
+#include "adios2/ADIOSMacros.h"
+#include "adios2/helper/adiosFunctions.h"
+
+namespace adios2
+{
+
+#define declare_type(T)                                                        \
+    template <>                                                                \
+    size_t Transform::BufferMaxSize<T>(                                        \
+        const T *dataIn, const Dims &dimensions, const Params &parameters)     \
+        const                                                                  \
+    {                                                                          \
+        return DoBufferMaxSize(dataIn, dimensions, GetType<T>(), parameters);  \
+    }
+ADIOS2_FOREACH_ZFP_TYPE_1ARG(declare_type)
+#undef declare_type
+
+} // end namespace adios2
+
+#endif // ADIOS2_CORE_TRANSFORM_TCC_
diff --git a/source/adios2/core/VariableBase.cpp b/source/adios2/core/VariableBase.cpp
index 3a13c739ad5ea212d8f00815c85d6170f01e95ed..07759db41f82a76badab8a28635159d417befadf 100644
--- a/source/adios2/core/VariableBase.cpp
+++ b/source/adios2/core/VariableBase.cpp
@@ -125,18 +125,31 @@ void VariableBase::SetStepSelection(const unsigned int startStep,
     m_ReadNSteps = countStep;
 }
 
-void VariableBase::AddTransform(
-    Transform &transform, const std::vector<std::string> &parametersVector)
+// transforms related functions
+unsigned int VariableBase::AddTransform(Transform &transform,
+                                        const Params &parameters) noexcept
 {
+    m_TransformsInfo.push_back(TransformInfo{transform, parameters});
+    return static_cast<unsigned int>(m_TransformsInfo.size() - 1);
 }
 
-void VariableBase::AddTransform(Transform &transform,
-                                const Params &parametersVector)
+void VariableBase::ResetTransformParameters(const unsigned int transformIndex,
+                                            const Params &parameters)
 {
+    if (m_DebugMode)
+    {
+        if (transformIndex < m_TransformsInfo.size())
+        {
+            m_TransformsInfo[transformIndex].Parameters = parameters;
+        }
+    }
+    else
+    {
+        m_TransformsInfo[transformIndex].Parameters = parameters;
+    }
 }
 
-// transforms related functions
-void VariableBase::ClearTransforms() { m_TransformsInfo.clear(); }
+void VariableBase::ClearTransforms() noexcept { m_TransformsInfo.clear(); }
 
 // PRIVATE
 void VariableBase::InitShapeType()
diff --git a/source/adios2/core/VariableBase.h b/source/adios2/core/VariableBase.h
index 424a93892bd4142e1db38622909afc7c99a1f5c6..39c4367a00654c6cd9ceaecfb0388ffb2e49e4e2 100644
--- a/source/adios2/core/VariableBase.h
+++ b/source/adios2/core/VariableBase.h
@@ -105,44 +105,46 @@ public:
     void SetStepSelection(const unsigned int startStep,
                           const unsigned int countStep);
 
-    void AddTransform(Transform &transform,
-                      const std::vector<std::string> &parametersVector);
+    /**
+     * Pushed a new transform to a sequence of transports
+     * @param transform reference to an object derived from the Transform class
+     * @param parameters transform specific parameters
+     * @return transformID handler
+     */
+    unsigned int AddTransform(Transform &transform,
+                              const Params &parameters = Params()) noexcept;
 
-    void AddTransform(Transform &transform,
-                      const Params &parametersVector = Params());
-
-    /** Apply current sequence of transforms defined by AddTransform */
-    virtual void ApplyTransforms() = 0;
+    void ResetTransformParameters(const unsigned int transformIndex,
+                                  const Params &parameters = Params());
 
     /** Clears out the transform sequence defined by AddTransform */
-    void ClearTransforms();
+    void ClearTransforms() noexcept;
 
-    /** Self-check dims according to type, called from Engine before Write
-     * @param hint extra debugging info for the exception */
-    void CheckDims(const std::string hint) const;
-
-private:
-    const bool m_DebugMode = false;
-
-    void InitShapeType();
+    /** Apply current sequence of transforms defined by AddTransform */
+    virtual void ApplyTransforms() = 0;
 
     /** Transforms metadata info */
     struct TransformInfo
     {
         /** reference to object derived from Transform class */
-        Transform &Object;
+        Transform &Operator;
         /** parameters from AddTransform */
         Params Parameters;
         /** resulting sizes from transformation */
         Dims Sizes;
     };
 
-    /**
-     * Sequence determines application order, e.g.
-     * first Transforms[0] then Transforms[1]. Pointer used as
-     * reference (no memory management).
-     */
+    /** Registered transforms */
     std::vector<TransformInfo> m_TransformsInfo;
+
+    /** Self-check dims according to type, called from Engine before Write
+     * @param hint extra debugging info for the exception */
+    void CheckDims(const std::string hint) const;
+
+private:
+    const bool m_DebugMode = false;
+
+    void InitShapeType();
 };
 
 } // end namespace
diff --git a/source/adios2/helper/adiosString.cpp b/source/adios2/helper/adiosString.cpp
index 7ef54bdde13deaf22b16f2ee9b4ba2570c1d07c7..1f0c85d0cad367ce2ae88c1c7be4e59653d4dee6 100644
--- a/source/adios2/helper/adiosString.cpp
+++ b/source/adios2/helper/adiosString.cpp
@@ -129,4 +129,83 @@ void SetParameterValue(const std::string key, const Params &parameters,
     }
 }
 
+void SetParameterValueInt(const std::string key, const Params &parameters,
+                          int &value, const bool debugMode,
+                          const std::string hint)
+{
+    auto itKey = parameters.find(key);
+
+    if (itKey == parameters.end())
+    {
+        return;
+    }
+
+    if (debugMode)
+    {
+        try
+        {
+            value = std::stoi(itKey->second);
+        }
+        catch (...)
+        {
+            std::throw_with_nested(std::invalid_argument(
+                "ERROR: could not cast " + itKey->second +
+                " to int from key parameter: " + itKey->first + ", " + hint));
+        }
+    }
+    else
+    {
+        value = std::stoi(itKey->second);
+    }
+}
+
+double StringToDouble(const std::string value, const bool debugMode,
+                      const std::string hint)
+{
+    double valueDouble = -1.;
+
+    if (debugMode)
+    {
+        try
+        {
+            valueDouble = std::stod(value);
+        }
+        catch (...)
+        {
+            std::throw_with_nested(std::invalid_argument(
+                "ERROR: could not cast " + value + " to double, " + hint));
+        }
+    }
+    else
+    {
+        valueDouble = std::stod(value);
+    }
+    return valueDouble;
+}
+
+unsigned int StringToUInt(const std::string value, const bool debugMode,
+                          const std::string hint)
+{
+    unsigned int valueUInt = 0;
+
+    if (debugMode)
+    {
+        try
+        {
+            valueUInt = static_cast<unsigned int>(std::stoul(value));
+        }
+        catch (...)
+        {
+            std::throw_with_nested(
+                std::invalid_argument("ERROR: could not cast " + value +
+                                      " to unsigned int, " + hint));
+        }
+    }
+    else
+    {
+        valueUInt = static_cast<unsigned int>(std::stoul(value));
+    }
+    return valueUInt;
+}
+
 } // end namespace adios
diff --git a/source/adios2/helper/adiosString.h b/source/adios2/helper/adiosString.h
index c89c87e5bfaf0f0c2b6eb5f4af5bb02653703aff..5f795bc4e918b9dddff49245427ad621f44acee3 100644
--- a/source/adios2/helper/adiosString.h
+++ b/source/adios2/helper/adiosString.h
@@ -67,6 +67,40 @@ GetParametersValues(const std::string &key,
  */
 void SetParameterValue(const std::string key, const Params &parameters,
                        std::string &value) noexcept;
+
+/**
+ * Sets int value if found in parameters for input key
+ * @param key input
+ * @param parameters map with key: field, value: value
+ * @param value to be modified if key is found in parameters
+ * @param debugMode check for string conversion
+ * @param hint passed for extra debugging info if exception is thrown
+ */
+void SetParameterValueInt(const std::string key, const Params &parameters,
+                          int &value, const bool debugMode,
+                          const std::string hint);
+
+/**
+ * function that cast a string to a double verifying validity of the cast with
+ * exceptions in debugMode
+ * @param value string to be casted
+ * @param debugMode check for string conversion
+ * @param hint passed for extra debugging info if exception is thrown
+ * @return value as a double
+ */
+double StringToDouble(const std::string value, const bool debugMode,
+                      const std::string hint);
+
+/**
+ * function that cast a string to unsigned int verifying validity of the cast
+ * with exceptions in debugMode
+ * @param value string to be casted
+ * @param debugMode check for string conversion
+ * @param hint passed for extra debugging info if exception is thrown
+ * @return value as unsigned int
+ */
+unsigned int StringToUInt(const std::string value, const bool debugMode,
+                          const std::string hint);
 }
 
 #endif /* ADIOS2_HELPER_ADIOSSTRING_H_ */
diff --git a/source/adios2/helper/adiosXML.cpp b/source/adios2/helper/adiosXML.cpp
index 65d1cdd4c9fd2577687275a2542fdb8c0b5af8f7..25bae1343c05e09b5776f9ca7af4ecf07f3ae6ae 100644
--- a/source/adios2/helper/adiosXML.cpp
+++ b/source/adios2/helper/adiosXML.cpp
@@ -62,9 +62,9 @@ Params InitParametersXML(const pugi::xml_node &node, const bool debugMode)
     return params;
 }
 
-void InitIOXML(const pugi::xml_node &ioNode, const MPI_Comm mpiComm,
+void InitIOXML(const pugi::xml_node &ioNode, MPI_Comm mpiComm,
                const bool debugMode,
-               std::vector<std::shared_ptr<Transform>> &transforms,
+               std::map<std::string, std::shared_ptr<Transform>> &transforms,
                std::map<std::string, IO> &ios)
 {
     // Extract <io name=""> attribute
@@ -147,9 +147,9 @@ void InitIOXML(const pugi::xml_node &ioNode, const MPI_Comm mpiComm,
     }
 }
 
-void InitXML(const std::string configXML, const MPI_Comm mpiComm,
+void InitXML(const std::string configXML, MPI_Comm mpiComm,
              const bool debugMode,
-             std::vector<std::shared_ptr<Transform>> &transforms,
+             std::map<std::string, std::shared_ptr<Transform>> &transforms,
              std::map<std::string, IO> &ios)
 {
     int mpiRank;
diff --git a/source/adios2/helper/adiosXML.h b/source/adios2/helper/adiosXML.h
index 055c14605f43259a71783c4727c015ea4a34d476..0746eb47708041c3b19aef93a1aa3ee3c11b98fd 100644
--- a/source/adios2/helper/adiosXML.h
+++ b/source/adios2/helper/adiosXML.h
@@ -16,7 +16,6 @@
 #include <memory> //std::shared_ptr
 #include <string>
 #include <utility> //std::pair
-#include <vector>
 /// \endcond
 
 #include "adios2/core/IO.h"
@@ -34,9 +33,9 @@ namespace adios2
  * @param transforms
  * @param ios
  */
-void InitXML(const std::string configXML, const MPI_Comm mpiComm,
+void InitXML(const std::string configXML, MPI_Comm mpiComm,
              const bool debugMode,
-             std::vector<std::shared_ptr<Transform>> &transforms,
+             std::map<std::string, std::shared_ptr<Transform>> &transforms,
              std::map<std::string, IO> &ios);
 }
 
diff --git a/source/adios2/transform/compress/CompressBZip2.cpp b/source/adios2/transform/compress/CompressBZip2.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..59c378422c42f25edf77e0dd4d99f30da3c180b0
--- /dev/null
+++ b/source/adios2/transform/compress/CompressBZip2.cpp
@@ -0,0 +1,170 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * CompressBZip2.cpp
+ *
+ *  Created on: Jul 24, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+
+#include "CompressBZip2.h"
+
+/// \cond EXCLUDE_FROM_DOXYGEN
+#include <cmath>     //std::ceil
+#include <ios>       //std::ios_base::failure
+#include <stdexcept> //std::invalid_argument
+/// \endcond
+
+#include <bzlib.h>
+
+#include "adios2/helper/adiosFunctions.h"
+
+namespace adios2
+{
+namespace transform
+{
+
+CompressBZip2::CompressBZip2(const bool debugMode)
+: Transform("bzip2", debugMode)
+{
+}
+
+size_t CompressBZip2::BufferMaxSize(const size_t sizeIn) const
+{
+    return static_cast<size_t>(std::ceil(1.1 * sizeIn) + 600);
+}
+
+size_t CompressBZip2::Compress(const void *dataIn, const Dims &dimensions,
+                               const size_t elementSize, const std::string type,
+                               void *bufferOut, const Params &parameters) const
+{
+    // defaults
+    int blockSize100k = 1;
+    int verbosity = 0;
+    int workFactor = 0;
+
+    if (!parameters.empty())
+    {
+        const std::string hint(" in call to CompressBZip2 Compress " + type +
+                               "\n");
+        SetParameterValueInt("BlockSize100K", parameters, blockSize100k,
+                             m_DebugMode, hint);
+        SetParameterValueInt("Verbosity", parameters, verbosity, m_DebugMode,
+                             hint);
+        SetParameterValueInt("WorkFactor", parameters, workFactor, m_DebugMode,
+                             hint);
+        if (m_DebugMode == true)
+        {
+
+            if (blockSize100k < 1 || blockSize100k > 9)
+            {
+                throw std::invalid_argument(
+                    "ERROR: BlockSize100K must be an "
+                    "integer between 1 (less "
+                    "compression, less memory) and 9 "
+                    "(more compression, more memory) inclusive, " +
+                    hint);
+            }
+        }
+    }
+
+    const size_t sizeIn =
+        static_cast<const size_t>(GetTotalSize(dimensions) * elementSize);
+    // Build inputs to BZip2 compression function
+    char *dest = const_cast<char *>(reinterpret_cast<const char *>(bufferOut));
+    unsigned int destLen = static_cast<unsigned int>(BufferMaxSize(sizeIn));
+
+    char *source = const_cast<char *>(reinterpret_cast<const char *>(dataIn));
+    unsigned int sourceLen = static_cast<unsigned int>(sizeIn);
+
+    int status = BZ2_bzBuffToBuffCompress(dest, &destLen, source, sourceLen,
+                                          blockSize100k, verbosity, workFactor);
+
+    if (m_DebugMode)
+    {
+        CheckStatus(status, "in call to CompressBZip2 Compress\n");
+    }
+
+    return static_cast<size_t>(destLen);
+}
+
+size_t CompressBZip2::Decompress(const void *bufferIn, const size_t sizeIn,
+                                 void *dataOut, const size_t sizeOut) const
+{
+    // TODO: leave defaults at zero?
+    int small = 0;
+    int verbosity = 0;
+
+    char *dest = reinterpret_cast<char *>(dataOut);
+    unsigned int destLen = static_cast<unsigned int>(sizeOut);
+
+    char *source = const_cast<char *>(reinterpret_cast<const char *>(bufferIn));
+    unsigned int sourceLen = static_cast<unsigned int>(sizeIn);
+
+    int status = BZ2_bzBuffToBuffDecompress(dest, &destLen, source, sourceLen,
+                                            small, verbosity);
+
+    if (m_DebugMode)
+    {
+        CheckStatus(status, "in call to CompressBZip2 Decompress\n");
+    }
+
+    return static_cast<size_t>(destLen);
+}
+
+void CompressBZip2::CheckStatus(const int status, const std::string hint) const
+{
+    switch (status)
+    {
+
+    case (BZ_CONFIG_ERROR):
+        throw std::invalid_argument(
+            "ERROR: BZ_CONFIG_ERROR, bzip2 library is not configured "
+            "correctly" +
+            hint);
+        break;
+
+    case (BZ_PARAM_ERROR):
+        throw std::invalid_argument(
+            "ERROR: BZ_PARAM_ERROR bufferOut stream might be null" + hint);
+        break;
+
+    case (BZ_MEM_ERROR):
+        throw std::ios_base::failure(
+            "ERROR: BZ_MEM_ERROR bzip2 detected insufficient memory " + hint);
+        break;
+
+    case (BZ_OUTBUFF_FULL):
+        throw std::ios_base::failure("ERROR: BZ_OUTBUFF_FULL bzip2 detected "
+                                     "size of compressed data is larger than "
+                                     "destination length " +
+                                     hint);
+        break;
+
+    // decompression
+    case (BZ_DATA_ERROR):
+        throw std::invalid_argument("ERROR: BZ_DATA_ERROR, bzip2 library "
+                                    "detected integrity errors in compressed "
+                                    "data " +
+                                    hint);
+        break;
+
+    case (BZ_DATA_ERROR_MAGIC):
+        throw std::invalid_argument("ERROR: BZ_DATA_ERROR_MAGIC, bzip2 library "
+                                    "detected wrong magic numbers in "
+                                    "compressed data " +
+                                    hint);
+        break;
+
+    case (BZ_UNEXPECTED_EOF):
+        throw std::invalid_argument("ERROR: BZ_UNEXPECTED_EOF, bzip2 library "
+                                    "detected unexpected end of "
+                                    "compressed data " +
+                                    hint);
+        break;
+    }
+}
+
+} // end namespace transform
+} // end namespace adios2
diff --git a/source/adios2/transform/compress/CompressBZip2.h b/source/adios2/transform/compress/CompressBZip2.h
new file mode 100644
index 0000000000000000000000000000000000000000..81cd28759a041a0feca1408c80a2e1ab784cb194
--- /dev/null
+++ b/source/adios2/transform/compress/CompressBZip2.h
@@ -0,0 +1,74 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * CompressBZip2.h : wrapper to BZip2 compression library
+ *
+ *  Created on: Jul 24, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+
+#ifndef ADIOS2_TRANSFORM_COMPRESSION_COMPRESSBZIP2_H_
+#define ADIOS2_TRANSFORM_COMPRESSION_COMPRESSBZIP2_H_
+
+#include "adios2/core/Transform.h"
+
+namespace adios2
+{
+namespace transform
+{
+
+class CompressBZip2 : public Transform
+{
+
+public:
+    /**
+     * Unique constructor
+     * @param debugMode
+     */
+    CompressBZip2(const bool debugMode);
+
+    ~CompressBZip2() = default;
+
+    size_t BufferMaxSize(const size_t sizeIn) const final;
+
+    /**
+     * Compression signature for legacy libraries that use void*
+     * @param dataIn
+     * @param dimensions
+     * @param type
+     * @param bufferOut
+     * @param parameters
+     * @return size of compressed buffer in bytes
+     */
+    size_t Compress(const void *dataIn, const Dims &dimensions,
+                    const size_t elementSize, const std::string type,
+                    void *bufferOut,
+                    const Params &parameters = Params()) const final;
+
+    /**
+     * Decompression signature for legacy libraries that use void*
+     * @param bufferIn
+     * @param sizeIn
+     * @param dataOut
+     * @param dimensions
+     * @param type
+     * @return size of decompressed buffer in bytes
+     */
+    size_t Decompress(const void *bufferIn, const size_t sizeIn, void *dataOut,
+                      const size_t sizeOut) const final;
+
+private:
+    /**
+     * In debug mode, check status from BZip compression and decompression
+     * functions
+     * @param status returned by BZip2 library
+     * @param hint extra exception information
+     */
+    void CheckStatus(const int status, const std::string hint) const;
+};
+
+} // end namespace transform
+} // end namespace adios2
+
+#endif /* ADIOS2_TRANSFORM_COMPRESSION_COMPRESSBZIP2_H_ */
diff --git a/source/adios2/transform/compress/CompressZfp.cpp b/source/adios2/transform/compress/CompressZfp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b53f18c4f82e55281fb69e1cf210b3f5df8b6428
--- /dev/null
+++ b/source/adios2/transform/compress/CompressZfp.cpp
@@ -0,0 +1,278 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * CompressZfp.cpp
+ *
+ *  Created on: Jul 25, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+
+#include "CompressZfp.h"
+
+#include "adios2/helper/adiosFunctions.h"
+
+namespace adios2
+{
+namespace transform
+{
+
+CompressZfp::CompressZfp(const bool debugMode) : Transform("zfp", debugMode) {}
+
+size_t CompressZfp::DoBufferMaxSize(const void *dataIn, const Dims &dimensions,
+                                    const std::string type,
+                                    const Params &parameters) const
+{
+    zfp_field *field = GetZFPField(dataIn, dimensions, type);
+    zfp_stream *stream = GetZFPStream(dimensions, type, parameters);
+    const size_t maxSize = zfp_stream_maximum_size(stream, field);
+    zfp_field_free(field);
+    zfp_stream_close(stream);
+    return maxSize;
+}
+
+size_t CompressZfp::Compress(const void *dataIn, const Dims &dimensions,
+                             const size_t elementSize, const std::string type,
+                             void *bufferOut, const Params &parameters) const
+{
+
+    zfp_field *field = GetZFPField(dataIn, dimensions, type);
+    zfp_stream *stream = GetZFPStream(dimensions, type, parameters);
+    size_t maxSize = zfp_stream_maximum_size(stream, field);
+    // associate bitstream
+    bitstream *bitstream = stream_open(bufferOut, maxSize);
+    zfp_stream_set_bit_stream(stream, bitstream);
+    zfp_stream_rewind(stream);
+
+    size_t sizeOut = zfp_compress(stream, field);
+
+    if (m_DebugMode == true)
+    {
+        if (sizeOut == 0)
+        {
+            throw std::invalid_argument("ERROR: zfp failed, compressed buffer "
+                                        "size is 0, in call to Compress");
+        }
+    }
+
+    zfp_field_free(field);
+    zfp_stream_close(stream);
+    return sizeOut;
+}
+
+size_t CompressZfp::Decompress(const void *bufferIn, const size_t sizeIn,
+                               void *dataOut, const Dims &dimensions,
+                               const std::string type,
+                               const Params &parameters) const
+{
+    auto lf_GetTypeSize = [](const zfp_type zfpType) -> size_t {
+
+        size_t size = 0;
+        if (zfpType == zfp_type_int32 || zfpType == zfp_type_float)
+        {
+            size = 4;
+        }
+        else if (zfpType == zfp_type_int64 || zfpType == zfp_type_double)
+        {
+            size = 8;
+        }
+        return size;
+    };
+
+    zfp_field *field = GetZFPField(dataOut, dimensions, type);
+    zfp_stream *stream = GetZFPStream(dimensions, type, parameters);
+
+    // associate bitstream
+    bitstream *bitstream = stream_open(const_cast<void *>(bufferIn), sizeIn);
+    zfp_stream_set_bit_stream(stream, bitstream);
+    zfp_stream_rewind(stream);
+
+    int status = zfp_decompress(stream, field);
+
+    if (m_DebugMode)
+    {
+        if (!status)
+        {
+            throw std::invalid_argument(
+                "ERROR: zfp failed with status " + std::to_string(status) +
+                ", in call to CompressZfp Decompress\n");
+        }
+    }
+
+    zfp_field_free(field);
+    zfp_stream_close(stream);
+    stream_close(bitstream);
+
+    const size_t typeSizeBytes = lf_GetTypeSize(GetZfpType(type));
+    const size_t dataSizeBytes = GetTotalSize(dimensions) * typeSizeBytes;
+
+    return dataSizeBytes;
+}
+
+// PRIVATE
+zfp_type CompressZfp::GetZfpType(const std::string type) const
+{
+    zfp_type zfpType = zfp_type_none;
+
+    if (type == GetType<double>())
+    {
+        zfpType = zfp_type_double;
+    }
+    else if (type == GetType<float>())
+    {
+        zfpType = zfp_type_float;
+    }
+    else if (type == GetType<int64_t>())
+    {
+        zfpType = zfp_type_int64;
+    }
+    else if (type == GetType<int32_t>())
+    {
+        zfpType = zfp_type_int32;
+    }
+    else
+    {
+        if (m_DebugMode)
+        {
+
+            throw std::invalid_argument(
+                "ERROR: type " + type +
+                " not supported by zfp, only "
+                "signed int32_t, signed int64_t, float, and "
+                "double types are acceptable, from class "
+                "CompressZfp Transform\n");
+        }
+    }
+
+    return zfpType;
+}
+
+zfp_field *CompressZfp::GetZFPField(const void *data, const Dims &dimensions,
+                                    const std::string type) const
+{
+    auto lf_CheckField = [](const zfp_field *field,
+                            const std::string zfpFieldFunction,
+                            const std::string type) {
+
+        if (field == nullptr || field == NULL)
+        {
+            throw std::invalid_argument(
+                "ERROR: " + zfpFieldFunction + " failed for data of type " +
+                type + ", data pointer might be corrupted, from "
+                       "class CompressZfp Transform\n");
+        }
+    };
+
+    zfp_type zfpType = GetZfpType(type);
+    zfp_field *field = nullptr;
+
+    if (dimensions.size() == 1)
+    {
+        field = zfp_field_1d(const_cast<void *>(data), zfpType, dimensions[0]);
+        if (m_DebugMode)
+        {
+            lf_CheckField(field, "zfp_field_1d", type);
+        }
+    }
+    else if (dimensions.size() == 2)
+    {
+        field = zfp_field_2d(const_cast<void *>(data), zfpType, dimensions[0],
+                             dimensions[1]);
+        if (m_DebugMode)
+        {
+            lf_CheckField(field, "zfp_field_2d", type);
+        }
+    }
+    else if (dimensions.size() == 3)
+    {
+        field = zfp_field_3d(const_cast<void *>(data), zfpType, dimensions[0],
+                             dimensions[1], dimensions[2]);
+        if (m_DebugMode)
+        {
+            lf_CheckField(field, "zfp_field_3d", type);
+        }
+    }
+    else
+    {
+        if (m_DebugMode)
+        {
+            throw std::invalid_argument(
+                "ERROR: zfp_field* failed for data of type " + type +
+                ", only 1D, 2D and 3D dimensions are supported, from "
+                "class CompressZfp Transform\n");
+        }
+    }
+
+    return field;
+}
+
+zfp_stream *CompressZfp::GetZFPStream(const Dims &dimensions,
+                                      const std::string type,
+                                      const Params &parameters) const
+{
+    auto lf_HasKey = [](Params::const_iterator itKey,
+                        const Params &parameters) -> bool {
+
+        bool hasKey = false;
+        if (itKey != parameters.end())
+        {
+            hasKey = true;
+        }
+        return hasKey;
+    };
+
+    zfp_stream *stream = zfp_stream_open(NULL);
+
+    auto itTolerance = parameters.find("Tolerance");
+    const bool hasTolerance = lf_HasKey(itTolerance, parameters);
+
+    auto itRate = parameters.find("Rate");
+    const bool hasRate = lf_HasKey(itRate, parameters);
+
+    auto itPrecision = parameters.find("Precision");
+    const bool hasPrecision = lf_HasKey(itPrecision, parameters);
+
+    if (m_DebugMode)
+    {
+        if ((hasTolerance && hasRate) || (hasTolerance && hasPrecision) ||
+            (hasRate && hasPrecision) ||
+            !(hasTolerance || hasRate || hasPrecision))
+        {
+            throw std::invalid_argument("ERROR: zfp parameters Tolerance, "
+                                        "Rate, Precision are mutually "
+                                        "exclusive, only one of them is "
+                                        "mandatory, from "
+                                        "class CompressZfp Transform\n");
+        }
+    }
+
+    if (hasTolerance)
+    {
+        const double tolerance = StringToDouble(
+            itTolerance->second, m_DebugMode,
+            "setting Tolerance in call to CompressZfp class Transform\n");
+
+        zfp_stream_set_accuracy(stream, tolerance);
+    }
+    else if (hasRate)
+    {
+        const double rate = StringToDouble(
+            itRate->second, m_DebugMode,
+            "setting Rate in call to CompressZfp class Transform\n");
+        // TODO support last argument write random access?
+        zfp_stream_set_rate(stream, rate, GetZfpType(type),
+                            static_cast<unsigned int>(dimensions.size()), 0);
+    }
+    else if (hasPrecision)
+    {
+        const unsigned int precision = StringToUInt(
+            itPrecision->second, m_DebugMode,
+            "setting Precision in call to CompressZfp class Transform\n");
+        zfp_stream_set_precision(stream, precision);
+    }
+
+    return stream;
+}
+
+} // end namespace transform
+} // end namespace adios2
diff --git a/source/adios2/transform/compress/CompressZfp.h b/source/adios2/transform/compress/CompressZfp.h
new file mode 100644
index 0000000000000000000000000000000000000000..251d14b455a86b8d7dd86b8bf4cc756e912cd312
--- /dev/null
+++ b/source/adios2/transform/compress/CompressZfp.h
@@ -0,0 +1,101 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * CompressZfp.h : wrapper to Zfp compression library
+ *
+ *  Created on: Jul 25, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+
+#ifndef ADIOS2_TRANSFORM_COMPRESS_COMPRESSZFP_H_
+#define ADIOS2_TRANSFORM_COMPRESS_COMPRESSZFP_H_
+
+#include <zfp.h>
+
+#include "adios2/core/Transform.h"
+
+namespace adios2
+{
+
+namespace transform
+{
+
+class CompressZfp : public Transform
+{
+
+public:
+    /**
+     * Unique constructor
+     * @param debugMode
+     */
+    CompressZfp(const bool debugMode);
+
+    ~CompressZfp() = default;
+
+    /**
+     * Wrapper around zfp compression
+     * @param dataIn
+     * @param dimensions
+     * @param type
+     * @param bufferOut
+     * @param parameters
+     * @return size of compressed buffer in bytes
+     */
+    size_t Compress(const void *dataIn, const Dims &dimensions,
+                    const size_t elementSize, const std::string type,
+                    void *bufferOut, const Params &parameters) const final;
+
+    /**
+     * Wrapper around zfp decompression
+     * @param bufferIn
+     * @param sizeIn
+     * @param dataOut
+     * @param dimensions
+     * @param type
+     * @return size of decompressed data in dataOut
+     */
+    size_t Decompress(const void *bufferIn, const size_t sizeIn, void *dataOut,
+                      const Dims &dimensions, const std::string type,
+                      const Params &parameters) const final;
+
+private:
+    /**
+     * Returns Zfp supported zfp_type based on adios string type
+     * @param type adios type as string, see GetType<T> in
+     * helper/adiosType.inl
+     * @return zfp_type
+     */
+    zfp_type GetZfpType(const std::string type) const;
+
+    /**
+     * Constructor Zfp zfp_field based on input information around the data
+     * pointer
+     * @param data
+     * @param shape
+     * @param type
+     * @return zfp_field*
+     */
+    zfp_field *GetZFPField(const void *data, const Dims &shape,
+                           const std::string type) const;
+
+    zfp_stream *GetZFPStream(const Dims &dimensions, const std::string type,
+                             const Params &parameters) const;
+
+    size_t DoBufferMaxSize(const void *dataIn, const Dims &dimensions,
+                           const std::string type,
+                           const Params &parameters) const final;
+
+    /**
+     * In debug mode, check status from BZip compression and decompression
+     * functions
+     * @param status returned by BZip2 library
+     * @param hint extra exception information
+     */
+    void CheckStatus(const int status, const std::string hint) const;
+};
+
+} // end namespace transform
+} // end namespace adios2
+
+#endif /* ADIOS2_TRANSFORM_COMPRESS_COMPRESSZFP_H_ */
diff --git a/source/adios2/transform/compression/BZip2.cpp b/source/adios2/transform/compression/BZip2.cpp
deleted file mode 100644
index 89a61737a93408a1d44660cd32bda558be6443cb..0000000000000000000000000000000000000000
--- a/source/adios2/transform/compression/BZip2.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Distributed under the OSI-approved Apache License, Version 2.0.  See
- * accompanying file Copyright.txt for details.
- *
- * BZIP2.cpp
- *
- *  Created on: Oct 19, 2016
- *      Author: William F Godoy godoywf@ornl.gov
- */
-
-#include "BZip2.h"
-
-namespace adios2
-{
-namespace transform
-{
-
-BZip2::BZip2() : Transform("bzip2") {}
-
-void BZip2::Compress(const std::vector<char> & /*bufferIn*/,
-                     std::vector<char> & /*bufferOut*/)
-{
-}
-
-void BZip2::Decompress(const std::vector<char> & /*bufferIn*/,
-                       std::vector<char> & /*bufferOut*/)
-{
-}
-
-} // end namespace transform
-} // end namespace adios
diff --git a/source/adios2/transform/compression/BZip2.h b/source/adios2/transform/compression/BZip2.h
deleted file mode 100644
index 1da04ed6d1656e954f5f99f966eca63300a407bc..0000000000000000000000000000000000000000
--- a/source/adios2/transform/compression/BZip2.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Distributed under the OSI-approved Apache License, Version 2.0.  See
- * accompanying file Copyright.txt for details.
- *
- * BZip2.h not yet implemented
- *
- *  Created on: Oct 17, 2016
- *      Author: William F Godoy godoywf@ornl.gov
- */
-
-#ifndef ADIOS2_TRANSFORM_COMPRESSION_BZIP2_H_
-#define ADIOS2_TRANSFORM_COMPRESSION_BZIP2_H_
-
-#include "adios2/ADIOSConfig.h"
-#include "adios2/core/Transform.h"
-
-namespace adios2
-{
-namespace transform
-{
-
-class BZip2 : public Transform
-{
-
-public:
-    /**
-     * Initialize parent method
-     * @param compressionLevel
-     * @param variable
-     */
-    BZip2();
-
-    virtual ~BZip2() = default;
-
-    void Compress(const std::vector<char> &bufferIn,
-                  std::vector<char> &bufferOut);
-
-    void Decompress(const std::vector<char> &bufferIn,
-                    std::vector<char> &bufferOut);
-};
-
-} // end namespace transform
-} // end namespace adios
-
-#endif /* ADIOS2_TRANSFORM_BZIP2_H_ */
diff --git a/testing/adios2/CMakeLists.txt b/testing/adios2/CMakeLists.txt
index 544e4099f8a6d3d309e8d97dbbf80c3deff1c91c..2115e42d9a8d60498548be59448f610ec898ff22 100644
--- a/testing/adios2/CMakeLists.txt
+++ b/testing/adios2/CMakeLists.txt
@@ -7,3 +7,4 @@ add_subdirectory(interface)
 add_subdirectory(engine)
 add_subdirectory(bindings)
 add_subdirectory(xml)
+add_subdirectory(transform)
diff --git a/testing/adios2/transform/CMakeLists.txt b/testing/adios2/transform/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c99f2964056c867be880f00c70fde1b219b9668e
--- /dev/null
+++ b/testing/adios2/transform/CMakeLists.txt
@@ -0,0 +1,19 @@
+#------------------------------------------------------------------------------#
+# Distributed under the OSI-approved Apache License, Version 2.0.  See
+# accompanying file Copyright.txt for details.
+#------------------------------------------------------------------------------#
+
+
+if(ADIOS2_HAVE_BZip2)
+  add_executable(TestBZip2Wrapper TestBZip2Wrapper.cpp)
+  target_link_libraries(TestBZip2Wrapper adios2 gtest gtest_main ${BZIP2_LIBRARIES})
+
+  gtest_add_tests(TARGET TestBZip2Wrapper ${BZIP2_LIBRARIES})
+endif()
+
+if(ADIOS2_HAVE_ZFP)
+  add_executable(TestZfpWrapper TestZfpWrapper.cpp)
+  target_link_libraries(TestZfpWrapper adios2 gtest gtest_main zfp::zfp)
+
+  gtest_add_tests(TARGET TestZfpWrapper zfp::zfp)
+endif()
\ No newline at end of file
diff --git a/testing/adios2/transform/TestBZip2Wrapper.cpp b/testing/adios2/transform/TestBZip2Wrapper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..57f506ded62083af2155cf8588df67d454d4db7b
--- /dev/null
+++ b/testing/adios2/transform/TestBZip2Wrapper.cpp
@@ -0,0 +1,125 @@
+#include <cstdint>
+#include <iostream>
+#include <numeric> //std::iota
+#include <stdexcept>
+
+#include <adios2.h>
+
+#include <gtest/gtest.h>
+
+class ADIOSBZip2Wrapper : public ::testing::Test
+{
+public:
+    ADIOSBZip2Wrapper() : adios(true), io(adios.DeclareIO("TestADIOSBZip2")) {}
+
+protected:
+    adios2::ADIOS adios;
+    adios2::IO &io;
+};
+
+TEST_F(ADIOSBZip2Wrapper, UInt100)
+{
+    /** Application variable uints from 0 to 1000 */
+    std::vector<unsigned int> myUInts(100);
+    std::iota(myUInts.begin(), myUInts.end(), 0.f);
+    const std::size_t Nx = myUInts.size();
+    const std::size_t inputBytes = Nx * sizeof(unsigned int);
+
+    // Define ADIOS variable
+    auto &var_UInt = io.DefineVariable<unsigned int>("myUInts", {}, {}, {Nx},
+                                                     adios2::ConstantDims);
+
+    // Verify the return type is as expected
+    ::testing::StaticAssertTypeEq<decltype(var_UInt),
+                                  adios2::Variable<unsigned int> &>();
+
+    // Define bzip2 transform
+    adios2::Transform &adiosBZip2 = adios.GetTransform("BZip2");
+
+    const unsigned int bzip2ID =
+        var_UInt.AddTransform(adiosBZip2, {{"BlockSize100K", "2"}});
+
+    const std::size_t estimatedSize =
+        adiosBZip2.BufferMaxSize(Nx * var_UInt.m_ElementSize);
+    std::vector<char> compressedBuffer(estimatedSize);
+    size_t compressedSize = adiosBZip2.Compress(
+        myUInts.data(), var_UInt.m_Count, var_UInt.m_ElementSize,
+        var_UInt.m_Type, compressedBuffer.data(),
+        var_UInt.m_TransformsInfo[bzip2ID].Parameters);
+
+    EXPECT_LE(compressedSize, estimatedSize);
+
+    compressedBuffer.resize(compressedSize);
+
+    // Allocate original data size
+    std::vector<unsigned int> decompressedBuffer(Nx);
+    size_t decompressedSize = adiosBZip2.Decompress(
+        compressedBuffer.data(), compressedSize, decompressedBuffer.data(),
+        decompressedBuffer.size() * sizeof(unsigned int));
+
+    // testing data recovery
+    for (size_t i = 0; i < Nx; ++i)
+    {
+        ASSERT_EQ(decompressedBuffer[i], myUInts[i]);
+    }
+}
+
+TEST_F(ADIOSBZip2Wrapper, WrongParameterValue)
+{
+    /** Application variable uints from 0 to 1000 */
+    std::vector<unsigned int> myUInts(100);
+    std::iota(myUInts.begin(), myUInts.end(), 0.f);
+    const std::size_t Nx = myUInts.size();
+    const std::size_t inputBytes = Nx * sizeof(unsigned int);
+
+    // Define ADIOS variable
+    auto &var_UInt = io.DefineVariable<unsigned int>("myUInts", {}, {}, {Nx},
+                                                     adios2::ConstantDims);
+
+    // Verify the return type is as expected
+    ::testing::StaticAssertTypeEq<decltype(var_UInt),
+                                  adios2::Variable<unsigned int> &>();
+
+    // Define bzip2 transform
+    adios2::Transform &adiosBZip2 = adios.GetTransform("BZip2");
+
+    const unsigned int bzip2ID =
+        var_UInt.AddTransform(adiosBZip2, {{"BlockSize100K", "10"}});
+
+    const std::size_t estimatedSize =
+        adiosBZip2.BufferMaxSize(Nx * var_UInt.m_ElementSize);
+    std::vector<char> compressedBuffer(estimatedSize);
+
+    EXPECT_THROW(size_t compressedSize = adiosBZip2.Compress(
+                     myUInts.data(), var_UInt.m_Count, var_UInt.m_ElementSize,
+                     var_UInt.m_Type, compressedBuffer.data(),
+                     var_UInt.m_TransformsInfo[bzip2ID].Parameters),
+                 std::invalid_argument);
+}
+
+TEST_F(ADIOSBZip2Wrapper, WrongBZip2Name)
+{
+    /** Application variable uints from 0 to 1000 */
+    std::vector<unsigned int> myUInts(100);
+    std::iota(myUInts.begin(), myUInts.end(), 0.f);
+    const std::size_t Nx = myUInts.size();
+    const std::size_t inputBytes = Nx * sizeof(unsigned int);
+
+    // Define ADIOS variable
+    auto &var_UInt = io.DefineVariable<unsigned int>("myUInts", {}, {}, {Nx},
+                                                     adios2::ConstantDims);
+
+    // Verify the return type is as expected
+    ::testing::StaticAssertTypeEq<decltype(var_UInt),
+                                  adios2::Variable<unsigned int> &>();
+
+    // Check bzip2 lower case and camel case
+    EXPECT_NO_THROW(adios2::Transform &adiosBZip2 =
+                        adios.GetTransform("bzip2"));
+    EXPECT_NO_THROW(adios2::Transform &adiosBZip2 =
+                        adios.GetTransform("BZip2"));
+    EXPECT_THROW(adios2::Transform &adiosBZip2 = adios.GetTransform("bzip"),
+                 std::invalid_argument);
+    EXPECT_THROW(adios2::Transform &adiosBZip2 = adios.GetTransform("BZIP2"),
+                 std::invalid_argument);
+}
diff --git a/testing/adios2/transform/TestZfpWrapper.cpp b/testing/adios2/transform/TestZfpWrapper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..db2a2d2b09a00e91939feb977253952003348c91
--- /dev/null
+++ b/testing/adios2/transform/TestZfpWrapper.cpp
@@ -0,0 +1,123 @@
+#include <cmath> //std::abs
+#include <iostream>
+#include <numeric> //std::iota
+#include <stdexcept>
+
+#include <adios2.h>
+
+#include <gtest/gtest.h>
+
+class ADIOSZfpWrapper : public ::testing::Test
+{
+public:
+    ADIOSZfpWrapper() : adios(true), io(adios.DeclareIO("TestADIOSZfp")) {}
+
+protected:
+    adios2::ADIOS adios;
+    adios2::IO &io;
+};
+
+TEST_F(ADIOSZfpWrapper, Float100)
+{
+    /** Application variable uints from 0 to 1000 */
+    std::vector<float> myFloats(100);
+    std::iota(myFloats.begin(), myFloats.end(), 0.f);
+    const std::size_t Nx = myFloats.size();
+    const std::size_t inputBytes = Nx * sizeof(float);
+
+    // Define ADIOS variable
+    auto &var_Floats = io.DefineVariable<float>("myFloats", {}, {}, {Nx},
+                                                adios2::ConstantDims);
+
+    // Verify the return type is as expected
+    ::testing::StaticAssertTypeEq<decltype(var_Floats),
+                                  adios2::Variable<float> &>();
+
+    // Define bzip2 transform
+    adios2::Transform &adiosZfp = adios.GetTransform("Zfp");
+
+    const unsigned int zfpID =
+        var_Floats.AddTransform(adiosZfp, {{"Rate", "8"}});
+
+    const std::size_t estimatedSize =
+        adiosZfp.BufferMaxSize(myFloats.data(), var_Floats.m_Count,
+                               var_Floats.m_TransformsInfo[zfpID].Parameters);
+
+    std::vector<char> compressedBuffer(estimatedSize);
+
+    size_t compressedSize = adiosZfp.Compress(
+        myFloats.data(), var_Floats.m_Count, var_Floats.m_ElementSize,
+        var_Floats.m_Type, compressedBuffer.data(),
+        var_Floats.m_TransformsInfo[zfpID].Parameters);
+
+    compressedBuffer.resize(compressedSize);
+
+    // Allocate original data size
+    std::vector<float> decompressedBuffer(Nx);
+
+    size_t decompressedSize = adiosZfp.Decompress(
+        compressedBuffer.data(), compressedBuffer.size(),
+        decompressedBuffer.data(), var_Floats.m_Count, var_Floats.m_Type,
+        var_Floats.m_TransformsInfo[zfpID].Parameters);
+
+    // testing data recovery for rate = 8
+    for (size_t i = 0; i < Nx; ++i)
+    {
+        ASSERT_LT(std::abs(decompressedBuffer[i] - myFloats[i]), 1E-6);
+    }
+}
+
+TEST_F(ADIOSZfpWrapper, UnsupportedCall)
+{
+    /** Application variable uints from 0 to 1000 */
+    std::vector<float> myFloats(100);
+    std::iota(myFloats.begin(), myFloats.end(), 0.f);
+    const std::size_t Nx = myFloats.size();
+    const std::size_t inputBytes = Nx * sizeof(float);
+
+    // Define ADIOS variable
+    auto &var_Floats = io.DefineVariable<float>("myFloats", {}, {}, {Nx},
+                                                adios2::ConstantDims);
+
+    // Verify the return type is as expected
+    ::testing::StaticAssertTypeEq<decltype(var_Floats),
+                                  adios2::Variable<float> &>();
+
+    // Define bzip2 transform
+    adios2::Transform &adiosZfp = adios.GetTransform("zfp");
+
+    const unsigned int zfpID =
+        var_Floats.AddTransform(adiosZfp, {{"Rate", "8"}});
+
+    // Wrong signature for Zfp
+    EXPECT_THROW(const std::size_t estimatedSize =
+                     adiosZfp.BufferMaxSize(Nx * var_Floats.m_ElementSize),
+                 std::invalid_argument);
+}
+
+TEST_F(ADIOSZfpWrapper, MissingMandatoryParameter)
+{
+    /** Application variable uints from 0 to 1000 */
+    std::vector<float> myFloats(100);
+    std::iota(myFloats.begin(), myFloats.end(), 0.f);
+    const std::size_t Nx = myFloats.size();
+    const std::size_t inputBytes = Nx * sizeof(float);
+
+    // Define ADIOS variable
+    auto &var_Floats = io.DefineVariable<float>("myFloats", {}, {}, {Nx},
+                                                adios2::ConstantDims);
+
+    // Verify the return type is as expected
+    ::testing::StaticAssertTypeEq<decltype(var_Floats),
+                                  adios2::Variable<float> &>();
+
+    // Define bzip2 transform
+    adios2::Transform &adiosZfp = adios.GetTransform("zfp");
+
+    const unsigned int zfpID = var_Floats.AddTransform(adiosZfp);
+
+    EXPECT_THROW(const std::size_t estimatedSize = adiosZfp.BufferMaxSize(
+                     myFloats.data(), var_Floats.m_Count,
+                     var_Floats.m_TransformsInfo[zfpID].Parameters),
+                 std::invalid_argument);
+}