diff --git a/oss-internship-2020/sapi_lodepng/CMakeLists.txt b/oss-internship-2020/sapi_lodepng/CMakeLists.txt index 1499cef..34396b0 100644 --- a/oss-internship-2020/sapi_lodepng/CMakeLists.txt +++ b/oss-internship-2020/sapi_lodepng/CMakeLists.txt @@ -40,7 +40,12 @@ add_subdirectory("${SAPI_ROOT}" add_sapi_library( lodepng_sapi - FUNCTIONS lodepng_decode32_file lodepng_encode32_file + FUNCTIONS lodepng_decode32_file + lodepng_encode32_file + lodepng_encode32 + lodepng_save_file + lodepng_load_file + lodepng_decode32 INPUTS lodepng-master/lodepng.h LIBRARY lodepng LIBRARY_NAME Lodepng diff --git a/oss-internship-2020/sapi_lodepng/lodepng-master/lodepng.h b/oss-internship-2020/sapi_lodepng/lodepng-master/lodepng.h index 27e3e36..694c3d9 100644 --- a/oss-internship-2020/sapi_lodepng/lodepng-master/lodepng.h +++ b/oss-internship-2020/sapi_lodepng/lodepng-master/lodepng.h @@ -957,6 +957,8 @@ unsigned lodepng_deflate(unsigned char** out, size_t* outsize, #endif /*LODEPNG_COMPILE_ZLIB*/ #ifdef LODEPNG_COMPILE_DISK + +extern "C" { /* Load a file from disk into buffer. The function allocates the out buffer, and after usage you should free it. @@ -976,6 +978,7 @@ filename: the path to the file to save to return value: error code (0 means ok) */ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename); +} #endif /*LODEPNG_COMPILE_DISK*/ #ifdef LODEPNG_COMPILE_CPP diff --git a/oss-internship-2020/sapi_lodepng/main_sandboxed.cc b/oss-internship-2020/sapi_lodepng/main_sandboxed.cc index 1b312a6..3734f27 100644 --- a/oss-internship-2020/sapi_lodepng/main_sandboxed.cc +++ b/oss-internship-2020/sapi_lodepng/main_sandboxed.cc @@ -98,7 +98,7 @@ void test2(SapiLodepngSandbox &sandbox, LodepngApi &api, } } - sapi::v::Array image_(image, width * height); + sapi::v::Array image_(image, width * height * 4); sapi::v::UInt width_(width), height_(height); std::string filename = images_path + "/out/ok2.png"; sapi::v::ConstCStr filename_(filename.c_str()); diff --git a/oss-internship-2020/sapi_lodepng/main_unit_test.cc b/oss-internship-2020/sapi_lodepng/main_unit_test.cc index 445bbc6..019f8a0 100644 --- a/oss-internship-2020/sapi_lodepng/main_unit_test.cc +++ b/oss-internship-2020/sapi_lodepng/main_unit_test.cc @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include @@ -21,8 +22,8 @@ #include "lodepng_sapi.sapi.h" #include "sandbox.h" #include "sandboxed_api/util/flag.h" -#include -#include + +// #include // defining the flag does not work as intended (always has the default value) // ignore for now @@ -31,44 +32,194 @@ namespace { -// TODO change this into pwd/something else -std::string images_path = "/usr/local/google/home/amedar/internship/sandboxed-api/oss-internship-2020/sapi_lodepng/test_images"; +// use the current path + test_images +std::string images_path = + std::filesystem::current_path().string() + "/test_images"; TEST(initSandbox, basic) { - SapiLodepngSandbox sandbox(images_path); - ASSERT_TRUE(sandbox.Init().ok()); + SapiLodepngSandbox sandbox(images_path); + ASSERT_TRUE(sandbox.Init().ok()); } -TEST(encode32, generate_and_encode_one_step) { - // randomly generate pixels of an image and encode it into a file - SapiLodepngSandbox sandbox(images_path); - ASSERT_TRUE(sandbox.Init().ok()); - LodepngApi api(&sandbox); +// generate an image, encode it, decode it and compare the pixels with the +// initial values +TEST(generate_image, encode_decode_compare_one_step) { + SapiLodepngSandbox sandbox(images_path); + ASSERT_TRUE(sandbox.Init().ok()); + LodepngApi api(&sandbox); + // std::cout << "path = " << images_path << std::endl; + unsigned int width = 512, height = 512; + unsigned char *image = (unsigned char *)malloc(width * height * 4); - - srand(time(NULL)); // maybe use something else - unsigned int width = 512, height = 512; - unsigned char *image = (unsigned char*)malloc(width * height * 4); - - for(int y = 0; y < height; ++y) { - for(int x = 0; x < width; ++x) { - image[4 * width * y + 4 * x + 0] = 255 * !(x & y); - image[4 * width * y + 4 * x + 1] = x ^ y; - image[4 * width * y + 4 * x + 2] = x | y; - image[4 * width * y + 4 * x + 3] = 255; - } + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + image[4 * width * y + 4 * x + 0] = 255 * !(x & y); + image[4 * width * y + 4 * x + 1] = x ^ y; + image[4 * width * y + 4 * x + 2] = x | y; + image[4 * width * y + 4 * x + 3] = 255; } + } - sapi::v::Array image_(image, width * height); - sapi::v::UInt width_(width), height_(height); - std::string filename = images_path + "/out/generate_and_encode_one_step1.png"; - sapi::v::ConstCStr filename_(filename.c_str()); + sapi::v::Array sapi_image(image, width * height * 4); + sapi::v::UInt sapi_width(width), sapi_height(height); + std::string filename = images_path + "/out_generated1.png"; + sapi::v::ConstCStr sapi_filename(filename.c_str()); - ASSERT_TRUE(sandbox.Allocate(&image_).ok()); - ASSERT_TRUE(sandbox.TransferToSandboxee(&image_).ok()); + // ASSERT_TRUE(sandbox.Allocate(&image_).ok()); + // ASSERT_TRUE(sandbox.TransferToSandboxee(&image_).ok()); - auto res = api.lodepng_encode32_file(filename_.PtrBefore(), image_.PtrBefore(), width_.GetValue(), height_.GetValue()).value(); - free(image); + sapi::StatusOr result = api.lodepng_encode32_file( + sapi_filename.PtrBefore(), sapi_image.PtrBefore(), sapi_width.GetValue(), + sapi_height.GetValue()); + + ASSERT_TRUE(result.ok()); + ASSERT_EQ(result.value(), 0); + + sapi::v::UInt sapi_width2, sapi_height2; + sapi::v::IntBase sapi_image_ptr(0); + + result = api.lodepng_decode32_file( + sapi_image_ptr.PtrBoth(), sapi_width2.PtrBoth(), sapi_height2.PtrBoth(), + sapi_filename.PtrBefore()); + + ASSERT_TRUE(result.ok()); + ASSERT_EQ(result.value(), 0); + + ASSERT_EQ(sapi_width2.GetValue(), width); + ASSERT_EQ(sapi_height2.GetValue(), height); + + sapi::v::RemotePtr sapi_remote_out_ptr( + reinterpret_cast(sapi_image_ptr.GetValue())); + sapi::v::Array sapi_pixels(sapi_width2.GetValue() * + sapi_height2.GetValue() * 4); + sapi_pixels.SetRemote(sapi_remote_out_ptr.GetValue()); + + ASSERT_TRUE(sandbox.TransferFromSandboxee(&sapi_pixels).ok()); + + unsigned char *pixels_ptr = sapi_pixels.GetData(); + + for (size_t i = 0; i < width * height * 4; ++i) { + ASSERT_EQ(pixels_ptr[i], image[i]); + } + + free(image); +} + +// similar to the previous test, only that we use encoding by saving the data in +// memory and then writing it to the file and decoding by first decoding in +// memory and then getting the pixels. +TEST(generate_image, encode_decode_compare_two_step) { + SapiLodepngSandbox sandbox(images_path); + ASSERT_TRUE(sandbox.Init().ok()); + LodepngApi api(&sandbox); + + // generate the image + unsigned int width = 512, height = 512; + unsigned char *image = (unsigned char *)malloc(width * height * 4); + + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + image[4 * width * y + 4 * x + 0] = 255 * !(x & y); + image[4 * width * y + 4 * x + 1] = x ^ y; + image[4 * width * y + 4 * x + 2] = x | y; + image[4 * width * y + 4 * x + 3] = 255; + } + } + + sapi::v::Array sapi_image(image, width * height * 4); + sapi::v::UInt sapi_width(width), sapi_height(height); + std::string filename = images_path + "/out_generated2.png"; + sapi::v::ConstCStr sapi_filename(filename.c_str()); + + sapi::v::ULLong sapi_pngsize; + sapi::v::IntBase sapi_png_ptr(0); + + // encode it into memory + + sapi::StatusOr result = api.lodepng_encode32( + sapi_png_ptr.PtrBoth(), sapi_pngsize.PtrBoth(), sapi_image.PtrBefore(), + sapi_width.GetValue(), sapi_height.GetValue()); + + ASSERT_TRUE(result.ok()); + ASSERT_EQ(result.value(), 0); + + std::cout << "sapi_pngsize = " << sapi_pngsize.GetValue() << std::endl; + + // transfer the array from the sandboxed process + + sapi::v::RemotePtr sapi_remote_out_ptr( + reinterpret_cast(sapi_png_ptr.GetValue())); + sapi::v::Array sapi_png_array(sapi_pngsize.GetValue()); + + sapi_png_array.SetRemote(sapi_remote_out_ptr.GetValue()); + + ASSERT_TRUE(sandbox.TransferFromSandboxee(&sapi_png_array).ok()); + + // write the image into the file (from memory) + result = + api.lodepng_save_file(sapi_png_array.PtrBefore(), sapi_pngsize.GetValue(), + sapi_filename.PtrBefore()); + + ASSERT_TRUE(result.ok()); + ASSERT_EQ(result.value(), 0); + + // now, decode the image using the 2 steps + + sapi::v::UInt sapi_width2, sapi_height2; + sapi::v::IntBase sapi_png_ptr2(0); + sapi::v::ULLong sapi_pngsize2; + + result = + api.lodepng_load_file(sapi_png_ptr2.PtrBoth(), sapi_pngsize2.PtrBoth(), + sapi_filename.PtrBefore()); + + ASSERT_TRUE(result.ok()); + ASSERT_EQ(result.value(), 0); + + ASSERT_EQ(sapi_pngsize.GetValue(), sapi_pngsize2.GetValue()); + + sapi::v::RemotePtr sapi_remote_out_ptr2( + reinterpret_cast(sapi_png_ptr2.GetValue())); + sapi::v::Array sapi_png_array2(sapi_pngsize2.GetValue()); + + sapi_png_array2.SetRemote(sapi_remote_out_ptr2.GetValue()); + + ASSERT_TRUE(sandbox.TransferFromSandboxee(&sapi_png_array2).ok()); + + // after the file is loaded, decode it + sapi::v::IntBase sapi_png_ptr3(0); + // sapi::v::UInt sapi_width2, sapi_height2; + result = api.lodepng_decode32( + sapi_png_ptr3.PtrBoth(), sapi_width2.PtrBoth(), sapi_height2.PtrBoth(), + sapi_png_array2.PtrBefore(), sapi_pngsize2.GetValue()); + + ASSERT_TRUE(result.ok()); + ASSERT_EQ(result.value(), 0); + + std::cout << "w2 = " << sapi_width2.GetValue() + << " h2 = " << sapi_height2.GetValue() << std::endl; + + ASSERT_EQ(sapi_width2.GetValue(), width); + ASSERT_EQ(sapi_height2.GetValue(), height); + + // transfer the pixels so they can be used + sapi::v::RemotePtr sapi_remote_out_ptr3( + reinterpret_cast(sapi_png_ptr3.GetValue())); + sapi::v::Array sapi_pixels(sapi_width2.GetValue() * + sapi_height2.GetValue() * 4); + + sapi_pixels.SetRemote(sapi_remote_out_ptr3.GetValue()); + + ASSERT_TRUE(sandbox.TransferFromSandboxee(&sapi_pixels).ok()); + + unsigned char *pixels_ptr = sapi_pixels.GetData(); + + // compare values + for (size_t i = 0; i < width * height * 4; ++i) { + ASSERT_EQ(pixels_ptr[i], image[i]); + } + + free(image); } } // namespace \ No newline at end of file diff --git a/oss-internship-2020/sapi_lodepng/test_images/out/ok2.png b/oss-internship-2020/sapi_lodepng/test_images/out/ok2.png deleted file mode 100644 index e9045c9..0000000 Binary files a/oss-internship-2020/sapi_lodepng/test_images/out/ok2.png and /dev/null differ diff --git a/oss-internship-2020/sapi_lodepng/test_images/out/test1_1out.png b/oss-internship-2020/sapi_lodepng/test_images/out/test1_1out.png deleted file mode 100644 index 0f95097..0000000 Binary files a/oss-internship-2020/sapi_lodepng/test_images/out/test1_1out.png and /dev/null differ diff --git a/oss-internship-2020/sapi_lodepng/test_images/out/test1_2out.png b/oss-internship-2020/sapi_lodepng/test_images/out/test1_2out.png deleted file mode 100644 index 0f95097..0000000 Binary files a/oss-internship-2020/sapi_lodepng/test_images/out/test1_2out.png and /dev/null differ diff --git a/oss-internship-2020/sapi_lodepng/test_images/out/ok.png b/oss-internship-2020/sapi_lodepng/test_images/out_generated1.png similarity index 100% rename from oss-internship-2020/sapi_lodepng/test_images/out/ok.png rename to oss-internship-2020/sapi_lodepng/test_images/out_generated1.png diff --git a/oss-internship-2020/sapi_lodepng/test_images/out_generated2.png b/oss-internship-2020/sapi_lodepng/test_images/out_generated2.png new file mode 100644 index 0000000..51f307e Binary files /dev/null and b/oss-internship-2020/sapi_lodepng/test_images/out_generated2.png differ diff --git a/oss-internship-2020/sapi_lodepng/test_images/test1.png b/oss-internship-2020/sapi_lodepng/test_images/test1.png deleted file mode 100644 index 8790af8..0000000 Binary files a/oss-internship-2020/sapi_lodepng/test_images/test1.png and /dev/null differ