2

I am using Cygwin - no, don't close yet - and I am having trouble with the <() syntax. A program refuses to accept the file descriptor that I am passing it, but other programs will accept it fine. My hypothesis is that the program is passing the file descriptor to one of its helper programs, which then does not receive the pipe (just the usual 0, 1 and 2, of which 0 and 2 are probably closed). This works fine with cat, just not with this program.

MCVE:

./jpegtran -copy all -drop +16+16 <(echo "JPEG FILE") -outfile out.jpeg out.jpeg

This produces the error message:

C:\path\to\jpegtran.exe: can't open /dev/fd/63 for reading

Is there a way to do this? Or will I have to resort to... temporary files? *shudder*


As far as I know, Cygwin simulates a POSIX environment for all intents and purposes. If it can't create a pseudo-file using named pipes (something I know is possible using the Windows API under //./pipe/pipename, which should be able to be handled using whatever name-rewriting is currently being used for when I pass a Windows program a /cygdrive/c/ path) then I'm happy with answers that will work on an actual 'nix box.

wizzwizz4
  • 527
  • 1
    I dont have Cygwin right here. Can you edit the question with the command echo <(echo "JPEG") and the output. That will show the filename. – hschou Nov 13 '17 at 20:34
  • @hschou Cygwin takes ages to start and my computer isn't stable at the moment. It's /proc/63 or something like that - the same as on Debian. – wizzwizz4 Nov 13 '17 at 22:19
  • I'll integrate this information in ~20 hours, but /dev/stdin has the same issue, with an identical error message. – wizzwizz4 Nov 13 '17 at 22:21
  • You have out.jpeg twice in your command...typo presumably...? So what does "refuse to accept" mean? Is there an error message? – B Layer Nov 13 '17 at 22:39
  • The jpegtran manpage (for Cygwin) doesn't indicate that you can pass it all those files. It says "reads the named JPEG/JFIF file, or the standard input if no file is named, and produces a JPEG/JFIF file on the standard output." Source code indicates same: it accepts 0 or 1 filename. Are you using a standard build here? – B Layer Nov 13 '17 at 22:50
  • @BLayer It's not a typo - I have created the output file with ImageMagick earlier, then I use jpegtran to add other images to the output file in a for loop. – wizzwizz4 Nov 14 '17 at 16:42
  • @BLayer Pelles C is about as far as I can compile at the moment - I haven't got a working Debian box and can't use the complicated GUIs of Windows. It's a standard build. :-( – wizzwizz4 Nov 14 '17 at 16:43
  • Your response doesn't match up with what I'm asking. I'm not suggesting you build anything. I asked what kind of response jpegtran is giving. And I'm saying that according to the man page and source code you aren't using jpegtran correctly. You would need something like this: ./jpegtran -copy all -drop +16+16 <(echo "JPEG FILE") > out.jpeg (assuming process substitution works with jpegtran...which is not guaranteed). – B Layer Nov 14 '17 at 19:55
  • @BLayer You were right - there was a typo. :-/ It matches my actual code now. – wizzwizz4 Nov 14 '17 at 20:08
  • It's still not a valid command for the same reason as I explained two comments ago...you can specify 0 or 1 file. You had 3. Now you have 2. I'm trying to help you but if you're not going to read everything I write and reply to all my questions I'm going to have to bail out. – B Layer Nov 15 '17 at 01:57
  • @BLayer One of the files is the one to -drop. The next is the one to write to. The next is the one to drop onto. I think this is right. – wizzwizz4 Nov 15 '17 at 19:11
  • If you have ./jpegtran -copy all -drop +16+16 A -outfile B C, C is the file to open, A is the file given as the input to the -drop "tool" and B is the file to write to. – wizzwizz4 Nov 15 '17 at 19:13

1 Answers1

1

Note: After a lot of back and forth it's been determined that OP is using a non-standard version of jpegtran that supports "crop-and-drop" (copy a portion of one image into another image).

So why doesn't process substitution (aka PS) work with this feature? Short of looking at the code we can't say with absolute, 100% confidence but there's a highly likely explanation. PS creates a special file that is effectively a read-only pipe from which the data is accessed in a streaming manner. When using it you cannot, of course, write to the file and, more importantly, you cannot seek in it (random access). Try using PS with any tool you can think of that doesn't use a streaming model (vim is one example). You'll either be restricted in what you can do or it just won't work at all.

Given that for this feature jpegtran is extracting a rectangular subset of the source image (JPEG) it seems highly unlikely that whoever implemented the feature imposed a constraint on themselves that restricted access to one-way streaming. Pulling out a portion of an image is clearly an operation where seek would be very useful if not mandatory. As such, PS is not allowed.

B Layer
  • 5,171
  • I suspect that I read pages about a fork of jpegtran. However, jpegtran didn't complain about the invalid argument -drop and it corrected some of my other syntax (messing up the +X+Y bit) so I think I have the same version of the program that -drop exists in. – wizzwizz4 Nov 15 '17 at 21:07
  • What does your man page say? – B Layer Nov 15 '17 at 21:08
  • BTW, even if you are using a fork there are still potentially critical details in my answer. E.g. the point about <(echo "JPEG FILE") likely acting as an input file since it's not associated with -drop (due to intervening +16+16). Of course, unless you can post some documentation it's all guess work on my part at this point. – B Layer Nov 15 '17 at 21:43
  • I've finally found something mentioning this. https://stackoverflow.com/a/29615714/5223757 I found this by using searching for the original problem I solved with this parameter. – wizzwizz4 Nov 15 '17 at 21:59
  • I think this man page might be out of date - I have weak recollections of this being on the new features list of the page I downloaded the build I used from. – wizzwizz4 Nov 15 '17 at 22:00
  • Updated answer addresses your question, I believe. BTW, the man page I'm using is not out-of-date...you're using a non-standard flavor of jpegtran ... I was able to find links to this and other flavors. – B Layer Nov 15 '17 at 23:29
  • Your second paragraph sounds like a reasonable hypothesis. I'll check the source. – wizzwizz4 Nov 16 '17 at 07:34
  • Me to have enough contiguous time to get my convoluted setup up and running to test my script and run it. I might have enough now... but there's a power surge where I am so my PSU might cut off. – wizzwizz4 Nov 16 '17 at 16:52
  • Saved some time by using the MCVE, which didn't occur to me earlier. :-/ It's done now. – wizzwizz4 Nov 16 '17 at 17:00
  • Did you look at the code? Hey FYI an upvote is okay for any answer that is helpful/useful or even just to say "thanks"....I spent a non-trivial amount of time here. (Course I don't expect it to be accepted unless one of us finds a seek or rewind or other proof in the code.). Thanks. – B Layer Nov 18 '17 at 11:19
  • Sorry - I forgot I hadn't upvoted the answer. :-/ – wizzwizz4 Nov 18 '17 at 11:21
  • So far I haven't found the place I downloaded the program from. – wizzwizz4 Nov 18 '17 at 11:21
  • Thanks! Was it here by any chance? http://jpegclub.org/jpegtran/ (Section 3, droppatch9 files)? It specifically mentions a crop and drop feature with params that look very similar to yours. – B Layer Nov 18 '17 at 11:25
  • That page is in my internet history and is the right site. Thanks! I must have overlooked it. – wizzwizz4 Nov 18 '17 at 11:26
  • It's opened with drop_file = fopen(dropfilename, READ_BINARY). I assume READ_BINARY is "rb" but I'm not sure. – wizzwizz4 Nov 18 '17 at 11:30
  • It's then used in jpeg_stdio_src, which is probably in jpeglib.h. – wizzwizz4 Nov 18 '17 at 11:35
  • I tried moving this convo to chat but not having any luck. Anyways, I'm sure that's "rb"...which brings up an interesting point. This is harder to analyze because it's Cygwin. "rb" is not different than "r" on Linux...but it is different on Cygwin! I have zero Windows system knowledge to figure out the nuances here. But I think any kind of seek, rewind, memory mapping, etc. would be an indicator. – B Layer Nov 18 '17 at 11:35