Rpixpack: R Bindings for PixPack

Turn any file into a single PNG whose pixels carry the data - now from R! Feed that PNG back in to recover the exact original with strong integrity checks.

This package provides R bindings for the excellent PixPack utility, allowing you to encode and decode files directly from R.

Installation

You’ll need Rust installed on your system. Install from rustup.rs.

install.packages('Rpixpack', repos = c('https://sounkou-bioinfo.r-universe.dev', 'https://cloud.r-project.org'))

Quick Start

library(Rpixpack)

Text Encoding Example

# Encode text to PNG
png_file <- tempfile(fileext = ".png")
result <- pixpack_text("Hello, PixPack from R! 🚀📊", png_file)
#> Encoding text to PNG...
#> Created PNG: /tmp/Rtmpg9eDU1/fileaed97c9ae70b.png
cat("Created PNG:", result, "\n")
#> Created PNG: /tmp/Rtmpg9eDU1/fileaed97c9ae70b.png

# Decode PNG back to text
decoded <- pixpack_text(png_path = png_file)
#> Decoding PNG to text...
#> Decoded 25 characters
cat("Decoded text:", decoded, "\n")
#> Decoded text: Hello, PixPack from R! 🚀📊
cat("Text preserved:", identical("Hello, PixPack from R! 🚀📊", decoded), "\n")
#> Text preserved: TRUE

# Show file info
info <- pixpack_info(png_file)
print(info)
#> PixPack File Info:
#>   File: fileaed97c9ae70b.png 
#>   Size: 26.29 KB
#>   Type: Possibly PixPack PNG (use pixpack_plot for visualization) 
#>   Modified: 2025-08-14 20:09:51

File Encoding Example

# Create a test file with some content
test_file <- tempfile(fileext = ".txt")
test_content <- c(
  "# Sample Data File",
  "timestamp,value,category", 
  "2024-01-01,42.5,A",
  "2024-01-02,38.1,B", 
  "2024-01-03,51.2,A"
)
writeLines(test_content, test_file)

# Encode file to PNG
png_result <- pixpack_convert(test_file, verbose = TRUE)
#> Encoding file to PNG...
#> Output: /tmp/Rtmpg9eDU1/fileaed91309fa7d.txt.png

# Decode PNG back to original file
decoded_file <- pixpack_convert(png_result, verbose = TRUE)
#> Decoding PNG to original file...
#> Output: /tmp/Rtmpg9eDU1/fileaed91309fa7d.txt

# Verify the content is preserved
original_content <- readLines(test_file)
decoded_content <- readLines(decoded_file)
cat("Content preserved:", identical(original_content, decoded_content), "\n")
#> Content preserved: TRUE

Visualization

# Visualize the PixPack PNG structure
pixpack_plot(png_result, show_grid = TRUE)
#> PixPack PNG visualized. Dimensions: 1160x1140

Binary File Testing

# Test with binary data
binary_data <- as.raw(c(0:255, 255:0, rep(42, 100)))
binary_file <- tempfile(fileext = ".bin")
writeBin(binary_data, binary_file)

# Encode binary file
png_binary <- pixpack_convert(binary_file, verbose = TRUE)
#> Encoding file to PNG...
#> Output: /tmp/Rtmpg9eDU1/fileaed91f666812.bin.png

# Decode and verify
decoded_binary <- pixpack_convert(png_binary, verbose = TRUE)
#> Decoding PNG to original file...
#> Output: /tmp/Rtmpg9eDU1/fileaed91f666812.bin
original_binary <- readBin(binary_file, "raw", n = length(binary_data))
restored_binary <- readBin(decoded_binary, "raw", n = length(binary_data))

cat("Binary data preserved:", identical(original_binary, restored_binary), "\n")
#> Binary data preserved: TRUE
cat("Original length:", length(original_binary), "bytes\n")
#> Original length: 612 bytes
cat("Restored length:", length(restored_binary), "bytes\n")
#> Restored length: 612 bytes

Low-level API Testing

# Test direct API functions
test_text <- "Direct API test with special chars: Hello World! @#$%^&*()"
direct_png <- tempfile(fileext = ".png")

# Use StringConversion directly
result_path <- StringConversion(test_text, direct_png)
cat("StringConversion result:", result_path, "\n")
#> StringConversion result: /tmp/Rtmpg9eDU1/fileaed947960f7a.png

# Decode using StringConversion
decoded_text <- StringConversion("", direct_png)
cat("Decoded text:", decoded_text, "\n")
#> Decoded text: Direct API test with special chars: Hello World! @#$%^&*()
cat("Roundtrip success:", identical(test_text, decoded_text), "\n")
#> Roundtrip success: TRUE

# Test fileConversion directly
test_doc <- tempfile(fileext = ".txt")
writeLines(c("# Test Document", "This is a test.", "Line 3"), test_doc)

direct_png2 <- fileConversion(test_doc)
cat("fileConversion created:", direct_png2, "\n")
#> fileConversion created: /tmp/Rtmpg9eDU1/fileaed96bed8a47.txt.png

# Decode back
restored_doc <- fileConversion(direct_png2)
cat("fileConversion restored:", restored_doc, "\n")
#> fileConversion restored: /tmp/Rtmpg9eDU1/fileaed96bed8a47.txt

# Verify content
original_lines <- readLines(test_doc)
restored_lines <- readLines(restored_doc)
cat("File content preserved:", identical(original_lines, restored_lines), "\n")
#> File content preserved: TRUE

Large File Testing

# Test with larger content
large_text <- paste(rep("This is a longer test string with more content to encode. ", 50), collapse = "")
large_png <- tempfile(fileext = ".png")

# Measure encoding time
start_time <- Sys.time()
large_result <- pixpack_text(large_text, large_png, verbose = TRUE)
#> Encoding text to PNG...
#> Created PNG: /tmp/Rtmpg9eDU1/fileaed93240be5a.png
encode_time <- Sys.time() - start_time

# Measure decoding time
start_time <- Sys.time()
large_decoded <- pixpack_text(png_path = large_png, verbose = TRUE)
#> Decoding PNG to text...
#> Decoded 2900 characters
decode_time <- Sys.time() - start_time

cat("Large text length:", nchar(large_text), "characters\n")
#> Large text length: 2900 characters
cat("Encoding time:", round(as.numeric(encode_time, units = "secs"), 3), "seconds\n")
#> Encoding time: 0.359 seconds
cat("Decoding time:", round(as.numeric(decode_time, units = "secs"), 3), "seconds\n")
#> Decoding time: 0.206 seconds
cat("Large text preserved:", identical(large_text, large_decoded), "\n")
#> Large text preserved: TRUE

# Show file sizes
png_size <- file.info(large_png)$size
cat("PNG file size:", round(png_size / 1024, 1), "KB\n")
#> PNG file size: 257.4 KB
cat("Compression ratio:", round(nchar(large_text) / png_size, 2), "\n")
#> Compression ratio: 0.01

# Additional verification - ensure byte-for-byte accuracy
original_bytes <- charToRaw(large_text)
decoded_bytes <- charToRaw(large_decoded)
cat("Byte-level identical:", identical(original_bytes, decoded_bytes), "\n")
#> Byte-level identical: TRUE

Core Functions

Low-level Functions

How PixPack Works

Testing

Run the test suite:

# Run tests
tinytest::run_test_dir(system.file("tinytest", package = "Rpixpack"))

Credits

License

MIT License - see LICENSE file for details.

Repository