Skip to content

Commit 0b2e4a3

Browse files
authored
feat(oiiotool): allow easy splitting of subimages by name (AcademySoftwareFoundation#4874)
Say you need to take a multi-part exr file and split it into separate files for each part. (Note: what OpenEXR calls "parts", OIIO calls "subimages.") You could do this oiiotool multipart.exr --sisplit -o:all=1 "part.%04d.exr" But this would name the parts part.0001.exr, part.0002.exr, etc. Maybe you would prefer to split them into files that contain the subimage name rather than just the inscrutible index number (which may also not be consistent across files)? You could try this dance to loop over the subimages and write each one with a name extracted from its metadata: oiiotool multipart.exr --for i {TOP.SUBIMAGES} --dup --subimage {i} -o "subimage_{TOP.'oiio:subimagename'}.exr That works, but that's a little awkward and hard to remember off the top of your head. Perhaps instead we would prefer a simpler version: oiiotool multipart.exr --sisplit -o:all=1 "part.{TOP.'oiio:subimagename'}.exr" This PR makes that last command work. It actually only required a small change, which is that the function that handles the `-o` command needs to defer the evaluation of the expression subsitution in the filename to occur separately for each subimage being output, rather than just once for the whole `-o:all=1` (which would have baked the FIRST subimage name into all the output file names). Docs are updated to give examples of how to do this. Also fixed a silly typo in the test script. Signed-off-by: Larry Gritz <lg@larrygritz.com>
1 parent 7aabc2b commit 0b2e4a3

4 files changed

Lines changed: 39 additions & 12 deletions

File tree

src/doc/oiiotool.rst

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -868,11 +868,17 @@ Split a multi-image file into separate files
868868
--------------------------------------------
869869

870870
Take a multi-image TIFF file, split into its constituent subimages and
871-
output each one to a different file, with names `sub0001.tif`,
872-
`sub0002.tif`, etc.::
871+
output each one to a different file, with names `sub.0001.tif`,
872+
`sub.0002.tif`, etc.::
873873

874-
oiiotool multi.tif -sisplit -o:all=1 sub%04d.tif
874+
oiiotool multi.tif -sisplit -o:all=1 sub.%04d.tif
875875

876+
Take a multi-image OpenEXR file (called "multi-part" in OpenEXR parlance),
877+
split into its constituent subimages and output each one to a different file,
878+
with names `sub.beauty.exr`, `sub.albedo.exr`, etc., using the name of each
879+
subimage according to its metadata::
880+
881+
oiiotool multi.exr -sisplit -o:all=1 "sub.{TOP.'oiio:subimagename'}.exr"
876882

877883

878884
|
@@ -1498,17 +1504,25 @@ Writing images
14981504
Output all images currently on the stack using a pattern.
14991505
See further explanation below.
15001506

1501-
The `all=n` option causes *all* images on the image stack to be output,
1502-
with the filename argument used as a pattern assumed to contain a `%d`,
1503-
which will be substituted with the index of the image (beginning with
1504-
*n*). For example, to take a multi-image TIFF and extract all the
1505-
subimages and save them as separate files::
1507+
The `all=n` option causes *all* images on the image stack to be output. If
1508+
the *filename* argument contains expression substitution notation, the
1509+
substitution will be re-evaluated for each image output. Also, if the
1510+
*filename* argument contains a `%d`, that will be substituted with the
1511+
index of the image (beginning with *n*). For example, to take a
1512+
multi-image TIFF and extract all the subimages and save them as separate
1513+
files::
15061514
15071515
oiiotool multi.tif -sisplit -o:all=1 sub%04d.tif
15081516
15091517
This will output the subimges as separate files `sub0001.tif`,
15101518
`sub0002.tif`, and so on.
15111519

1520+
Expression substitution can be used to insert the subimage name
1521+
into each filename::
1522+
1523+
oiiotool multi.tif -sisplit -o:all=1 "sub.{TOP.'oiio:subimagename'}.tif"
1524+
1525+
15121526

15131527
.. option:: -otex <filename>
15141528
-oenv <filename>

src/oiiotool/oiiotool.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5556,6 +5556,9 @@ output_file(Oiiotool& ot, cspan<const char*> argv)
55565556
remove_all_cmd(newcmd);
55575557
new_argv[0] = newcmd.c_str();
55585558
ImageRecRef saved_curimg = ot.curimg; // because we'll overwrite it
5559+
// Revert back to the UN-expression-substituted filename. It will get
5560+
// expression substitution in the subsequent call to output_file.
5561+
filename = argv[1];
55595562
for (int i = 0; i < nimages; ++i) {
55605563
if (i < nimages - 1)
55615564
ot.curimg = ot.image_stack[i];

testsuite/oiiotool-subimage/ref/out.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1-
Reading gpgr.exr
2-
gpgr.exr : 64 x 64, 3 channel, half openexr
1+
subimage.layerA.exr : 64 x 64, 3 channel, half openexr
2+
SHA-1: 0C27059220A256F197900FB4EB8C7CF63349A26B
3+
subimage.layerB.exr : 64 x 64, 3 channel, half openexr
4+
SHA-1: 0E19BEFEF868E356A6A4C6450DA9A7B17DD11E12
5+
subimage.layerC.exr : 64 x 64, 3 channel, half openexr
6+
SHA-1: CFAF4AFC253320AC35B8E9014C6D750768354059
7+
subimage.layerD.exr : 64 x 64, 3 channel, half openexr
8+
SHA-1: 5FFA4616F46509627873D2C53744E47E2F492719
9+
Reading jpgr.exr
10+
jpgr.exr : 64 x 64, 3 channel, half openexr
311
4 subimages: 64x64 [h,h,h], 64x64 [h,h,h], 64x64 [h,h,h], 64x64 [h,h,h]
412
subimage 0: 64 x 64, 3 channel, half openexr
513
SHA-1: 0C27059220A256F197900FB4EB8C7CF63349A26B

testsuite/oiiotool-subimage/run.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424
command += oiiotool ("subimages-4.exr --subimage 3 -o subimageD3.exr")
2525
command += oiiotool ("subimages-4.exr --subimage layerB -o subimageB1.exr")
2626
command += oiiotool ("subimages-2.exr --sisplit -o:all=1 subimage%d.exr")
27+
command += oiiotool ("subimages-4.exr --sisplit -o:all=1 \"subimage.{TOP.'oiio:subimagename'}.exr\"")
28+
command += info_command ("subimage.layerA.exr subimage.layerB.exr subimage.layerC.exr subimage.layerD.exr", verbose=False)
2729

2830
# test that we can set attributes on individual subimages
29-
command += oiiotool ("subimages-4.exr --attrib:subimages=0 Beatle John --attrib:subimages=1 Beatle Paul --attrib:subimages=2 Beatle George --attrib:subimages=3 Beatle Ringo -o gpgr.exr")
30-
command += info_command ("-a -v gpgr.exr", safematch=1)
31+
command += oiiotool ("subimages-4.exr --attrib:subimages=0 Beatle John --attrib:subimages=1 Beatle Paul --attrib:subimages=2 Beatle George --attrib:subimages=3 Beatle Ringo -o jpgr.exr")
32+
command += info_command ("-a -v jpgr.exr", safematch=1)
3133

3234
# Test extraction of MIP levels
3335
command += oiiotool ("../common/textures/grid.tx --selectmip 4 -o mip4.tif")

0 commit comments

Comments
 (0)