Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rawtherapee accepts only regular files but not named pipes #3746

Open
SarenT opened this issue Mar 9, 2017 · 5 comments
Open

Rawtherapee accepts only regular files but not named pipes #3746

SarenT opened this issue Mar 9, 2017 · 5 comments
Labels
type: enhancement Something could be better than it currently is

Comments

@SarenT
Copy link

SarenT commented Mar 9, 2017

Hi,

This is related to my previous issue on rawtherapee not being able to read from standard input.
As a workaround I have tried to use a fifo named pipe. The problem seems to be that this code in rtgui/main.cc prevents pipes being used:
if (Glib::file_test (argument, Glib::FILE_TEST_IS_REGULAR)) { inputFiles.emplace_back (argument); continue; }
Is Glib::file_test (argument, Glib::FILE_TEST_IS_REGULAR) really necessary? Why does rawtherapee care about the file being special, if raw data could also come from pipes, devices etc?

Version: 5.0-r1-gtk3
Branch: releases
Commit: 50114c1
Commit date: 2017-02-01
Compiler: x86_64-linux-gnu-gcc 5.4.0
Processor: x86_64
System: Linux
Bit depth: 64 bits
Gtkmm: V3.18.0
Build type: Release
Build flags: -O3 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas
Link flags: -Wl,-Bsymbolic-functions -Wl,-z,relro
OpenMP support: ON
MMAP support: ON

@Floessie
Copy link
Collaborator

Floessie commented Mar 9, 2017

There are fewer options for Glib::file_test() than I expected. Could it be, your named pipe is executable? Maybe we could change it to

if (Glib::file_test(argument, Glib::FILE_EXISTS) && !Glib::file_test(argument, Glib::FILE_TEST_IS_DIR))

@Beep6581 Beep6581 added the type: enhancement Something could be better than it currently is label Mar 9, 2017
@SarenT
Copy link
Author

SarenT commented Mar 9, 2017

Not really, but I can make it executable.
prw-rw-r-- 1 user group 0 Mar 9 23:07 raw.nef

I think this (your suggestion) is a better alternative. Some people may even concider device files (/dev/... stuff) such as drivers etc. to provide raw input.
I have now cloned the project. I was actually hoping to add standard input option to get raw input, which would simplify my code a lot. But that might require more expertise and my C/C++ knowledge is very limited.

@SarenT
Copy link
Author

SarenT commented Mar 10, 2017

Update here... I have tried to replace it but obviously it didn't work. It seems to be that image IO relies on fseek to move to the end of the file and getting the current position to find the size of the file. All of which cannot be done with named pipes. But it seems to be that fopen call from gfopen in myfile.cc seems to fail. I am still investigating it. Simply allowing pipes is therefore not a good idea yet. One needs a dedicated handling of pipes, where all data can be loaded into memory before being used. But then implementing stdio seems to be easier or more straight forward than that. I will try to implement that...

PS: As for my purpose of not writing bunch of data onto my SSD, I have found ramfs as a workaround. ramfs in Linux basically mounts some space from memory, which is very fast and bypasses any disk IO. Rest is usual regular file IO, which rawtherapee can handle. But this requires root access, which is not very suitable for end users.

@heckflosse
Copy link
Collaborator

@SarenT Did you try building RT without MMAP support?

@Floessie
Copy link
Collaborator

@heckflosse The problem is a bit different: Pipes like stdin or FIFOs can (by their streaming nature) only be read once. RT on the other hand opens a file multiple times during startup. One example is to obtain the EXIF. This will hang. So it's not a problem of MMAP or not.

I've investigated a bit (and even made rtexif use myfile.h) and it looks as if a solution is possible. It will change myfile.h to return std::shared_ptr<IMFILE> (also for future caching, maybe) and is thus a little invasive. I think I'll come up with a proof of concept within a few days.

Best,
Flössie

Floessie added a commit that referenced this issue Mar 13, 2017
Pipes cannot be read multiple times, but RT relies on reading a file
at least twice to get the EXIF data. I made all file reads go through
`myfile.h` and added an `IrretrievableFileStore` singleton to recover
files on which `ftell()` failed from memory. To do so, I made the
`myfile.h` functions return and deal with `std::shared_ptr<IMFILE>`.
That would also open a possibility to add a cache for e.g. small files,
although then we would have to return new `IMFILE`s with a shared
`data` member, because `eof` and `pos` could be different.

This does not work for `/dev/stdin` right now, because we don't get a
thumbnail for it from `CacheManager::getEntry()`. But we need some
special handling for `STDIN` anyway.

For now, this is just a proof of concept.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement Something could be better than it currently is
Projects
None yet
Development

No branches or pull requests

4 participants