0

I was playing with tesseract and magick ...

library(magick); #install.packages("magick", dependencies=TRUE);
library(tesseract); # install.packages("tesseract");
# https://github.com/ropensci/magick/issues/154

img.file = "iris-ocr.png";

img = magick::image_read( img.file );
img.txt = tesseract::image_ocr(img);

cat(img.txt);

Note: the img.file was in the same location as the notebook running the code. That is, setwd() was not used, nor a full file path. Yet it worked. To try, here is the PNG image file:

https://raw.githubusercontent.com/MonteShaffer/MasterClassDataAnalytics/main/-course-/02.020_hello-world-notebook/iris-ocr.png

So I dug into the source code of magick

rdx = readRDS("C:\\Users\\Monte J. Shaffer\\Documents\\R\\win-library\\4.1\\magick\\R\\magick.rdx");

info = rdx$variables$magick_image_readpath;


# # https://stackoverflow.com/questions/61841221/how-to-view-open-and-save-a-rdb-file-in-rstudio

readRDB <- function(filename, offset, size, type = 'gzip') {
        f <- file(filename, 'rb')
        on.exit(close(f))
        seek(f, offset + 4)
        unserialize(memDecompress(readBin(f, 'raw', size - 4), type))
}

obj = readRDB("C:\\Users\\Monte J. Shaffer\\Documents\\R\\win-library\\4.1\\magick\\R\\magick.rdb", offset=info[1], size=info[2]);

which shows the following:

function (paths, density, depth, strip, defines) 
{
    .Call("_magick_magick_image_readpath", PACKAGE = "magick", 
        paths, density, depth, strip, defines)
}

The source Rcpp code shows:

// magick_image_readpath
XPtrImage magick_image_readpath(Rcpp::CharacterVector paths, Rcpp::CharacterVector density, Rcpp::IntegerVector depth, bool strip, Rcpp::CharacterVector defines);
RcppExport SEXP _magick_magick_image_readpath(SEXP pathsSEXP, SEXP densitySEXP, SEXP depthSEXP, SEXP stripSEXP, SEXP definesSEXP) {
BEGIN_RCPP
    Rcpp::RObject rcpp_result_gen;
    Rcpp::RNGScope rcpp_rngScope_gen;
    Rcpp::traits::input_parameter< Rcpp::CharacterVector >::type paths(pathsSEXP);
    Rcpp::traits::input_parameter< Rcpp::CharacterVector >::type density(densitySEXP);
    Rcpp::traits::input_parameter< Rcpp::IntegerVector >::type depth(depthSEXP);
    Rcpp::traits::input_parameter< bool >::type strip(stripSEXP);
    Rcpp::traits::input_parameter< Rcpp::CharacterVector >::type defines(definesSEXP);
    rcpp_result_gen = Rcpp::wrap(magick_image_readpath(paths, density, depth, strip, defines));
    return rcpp_result_gen;
END_RCPP
}

I am familiar with the __FILE__ syntax of C++ (and PHP): https://www.tutorialspoint.com/what-are-file-line-and-function-in-cplusplus

Using R and Rcpp, how can I write a macro or function for __FILE__ ?

e.g.,

getFILE = function() { __FILE__; }

something similar to:

Rcpp::cppFunction("long long RShift(long long a, int b) { return a >> b;}");
Rcpp::cppFunction("long long LShift(long long a, int b) { return a << b;}");

The follow-up question would be, how to ENABLE those functions when the package installs?

Dharman
  • 30,962
  • 25
  • 85
  • 135
mshaffer
  • 959
  • 1
  • 9
  • 19
  • Related question https://stackoverflow.com/questions/14632521/are-there-any-equivalent-of-c-c-file-and-line-macros-in-r – 273K Jul 31 '22 at 21:53
  • I think you are confused. `__FILE__` is a gcc/g++ macros denoting the source file name of the file bing compiled (which can help in debugging). It has nothing to do with sourcing given files which you appear to want to implement. Filenames are just character variables so you can pass them around as you please. If I misunderstand please try to clarify in your question. – Dirk Eddelbuettel Jul 31 '22 at 21:53
  • @273K: Not really. One is R, one is C++. – Dirk Eddelbuettel Jul 31 '22 at 21:54
  • I believe you understand. For a given R `__FILE__` how can I get its full path? I understand that C++ compiles, but PHP has the same syntax that works at runtime. – mshaffer Jul 31 '22 at 21:59
  • You cannot, and that is language independent. The get a full and complete path you need the _directory_ and the _filename_ and you will have to request that from the user. It is the same in R: given a full filename and path, `basename()` and `dirname()` can take it apart. But _without extra information_ you can create a full path. You need to know _where_ you are. Simplest case (for the file from my answer): `file.path(getwd(), "answer.cpp")`. Zero C++ needed. You need a directory. – Dirk Eddelbuettel Jul 31 '22 at 22:12
  • In the `magick` code above, the path is "local" or could they have passed a global "path" with ```SEXP pathsSEXP``` – mshaffer Jul 31 '22 at 22:25
  • I think in the `magick` code example above, the file `iris-ocr.png` is _either_ in the current local directory for the example (meaning just the filename is a valid and sufficient path), or shipped with the package and hence has a computable path thanks to R tricks. – Dirk Eddelbuettel Jul 31 '22 at 22:28

1 Answers1

0

The narrow answer to your question (which may not have been what you wanted to ask, see my comment above) is below.

Code

This uses trick of embedded R code as a comment to the C++ source which sourceCpp() then runs for us.

#include <Rcpp/Lightest> // Rcpp 1.0.8 or newer

// [[Rcpp::export]]
std::string getFile() {
    const std::string filename = __FILE__;
    return filename;
}

/*** R
getFile()
*/

Output

As I saved this as a file answer.cpp this is what we get:

> Rcpp::sourceCpp("answer.cpp")

> getFile()
[1] "answer.cpp"
> 

Note that we do not pass the filename to the function, yet get it back.

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • Does this provide the FULL path, or just the FILENAME? – mshaffer Jul 31 '22 at 22:09
  • I am running ```Package: Rcpp Title: Seamless R and C++ Integration Version: 1.0.7 Date: 2021-07-06``` so it currently isn't compiling – mshaffer Jul 31 '22 at 22:11
  • See e.g. https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html, It seems to return only the file, not the full path. But while this is what you asked for, it is likely not the answer to underlying 'real' question you had. – Dirk Eddelbuettel Jul 31 '22 at 22:15
  • I got it working. You are correct, this is not what I am looking for. I am looking for something like https://www.tutorialrepublic.com/php-tutorial/php-magic-constants.php but for R, without the tidyverse, Rstudio, or here() functionality. – mshaffer Jul 31 '22 at 22:21
  • Got it -- like the `__DIR__` in there? I think there is a trick to let R tell you about the file it is currently sourcing but I do not have a reference handy. But in short, that is the tree you need to climb: Someone / something is consuming the file, and that entity knows the full path. You need a way to query that, and for that you need to query the interpreter (_i.e_ R) and not the OS hosting the file. So really not an Rcpp question. At least we got that squared away. – Dirk Eddelbuettel Jul 31 '22 at 22:25