1#!/usr/bin/env python
2
3from __future__ import print_function
4from __future__ import absolute_import
5import OpenImageIO as oiio
6import numpy as np
7
8
9# Read the one subimage from input then write it to output using
10# write_image, write_scanlines, write_scanline, write_tile, or write_tiles,
11# depending on the 'method' argument).  (Just copy one subimage, one MIP
12# level.)
13def copy_subimage (input, output, method="image",
14                   memformat=oiio.TypeFloat) :
15    spec = input.spec ()
16    if method == "image" :
17        pixels = input.read_image (memformat)
18        if pixels is None :
19            print ("Error reading input pixels in", in_filename)
20            return False
21        output.write_image (pixels)
22    elif method == "scanlines" and spec.tile_width == 0 :
23        pixels = input.read_image (memformat)
24        if pixels is None :
25            print ("Error reading input pixels in", in_filename)
26            return False
27        output.write_scanlines (spec.y, spec.y+spec.height, spec.z,
28                                pixels)
29    elif method == "scanline" and spec.tile_width == 0 :
30        for z in range(spec.z, spec.z+spec.depth) :
31            for y in range(spec.y, spec.y+spec.height) :
32                pixels = input.read_scanline (y, z, memformat)
33                if pixels is None :
34                    print ("Error reading input pixels in", in_filename)
35                    return False
36                output.write_scanline (y, z, pixels)
37    elif method == "tiles" and spec.tile_width != 0 :
38        pixels = input.read_image (memformat)
39        if pixels is None :
40            print ("Error reading input pixels in", in_filename)
41            return False
42        output.write_tiles (spec.x, spec.x+spec.width,
43                            spec.y, spec.y+spec.height,
44                            spec.z, spec.z+spec.depth,
45                            pixels)
46    elif method == "tile" and spec.tile_width != 0 :
47        for z in range(spec.z, spec.z+spec.depth, spec.tile_depth) :
48            for y in range(spec.y, spec.y+spec.height, spec.tile_height) :
49                for x in range(spec.x, spec.x+spec.width, spec.tile_width) :
50                    pixels = input.read_tile (x, y, z, memformat)
51                    if pixels is None :
52                        print ("Error reading input pixels in", in_filename)
53                        return False
54                    output.write_tile (x, y, z, pixels)
55    else :
56        print ("Unknown method:", method)
57        return False
58    return True
59
60
61# Read the whole image then write using write_image, write_scanlines,
62# write_scanline, write_tile, or write_tiles, depending on the 'method'
63# argument).  (Just copy one subimage, one MIP level.)
64def copy_image (in_filename, out_filename, method="image",
65                memformat=oiio.TypeFloat, outformat=oiio.TypeUnknown) :
66    input = oiio.ImageInput.open (in_filename)
67    if not input :
68        print ('Could not open "' + filename + '"')
69        print ("\tError: ", oiio.geterror())
70        print ()
71        return
72    outspec = input.spec()
73    if outformat != oiio.TypeUnknown :
74        outspec.format = outformat
75    output = oiio.ImageOutput.create (out_filename)
76    if not output :
77        print ("Could not create ImageOutput for", out_filename)
78        return
79    ok = output.open (out_filename, outspec)
80    if not ok :
81        print ("Could not open", out_filename)
82        return
83    ok = copy_subimage (input, output, method, memformat)
84    input.close ()
85    output.close ()
86    if ok :
87        print ("Copied", in_filename, "to", out_filename, "as", method,
88               "(memformat", memformat, "outformat", outformat, ")")
89
90
91def test_subimages (out_filename="multipart.exr") :
92    output = oiio.ImageOutput.create (out_filename)
93    spec = oiio.ImageSpec (64, 64, 3, "half")
94    specs = (spec, spec, spec)
95    output.open (out_filename, specs)
96    buffer = np.zeros ((64, 64, 3), dtype=float)
97    for i in range(3) :
98        if i != 0 :
99            output.open (out_filename, specs[i], "AppendSubimage")
100        output.write_image (buffer)
101    output.close ()
102
103######################################################################
104# main test starts here
105
106try:
107
108    copy_image ("scanline.tif", "grid-image.tif", method="image")
109    copy_image ("scanline.tif", "grid-scanline.tif", method="scanline")
110    copy_image ("scanline.tif", "grid-scanlines.tif", method="scanlines")
111    copy_image ("tiled.tif", "grid-timage.tif", method="image")
112    copy_image ("tiled.tif", "grid-tile.tif", method="tile")
113    copy_image ("tiled.tif", "grid-tiles.tif", method="tiles")
114
115    # Regression test for crash when changing formats
116    copy_image ("scanline.tif", "grid-image.tif",
117                memformat=oiio.TypeUInt8, outformat=oiio.TypeUInt16)
118
119    # Exercise 'half'
120    copy_image ("scanline.tif", "grid-half.exr",
121                memformat='half', outformat='half')
122
123    # Ensure we can write multiple subimages
124    test_subimages ()
125
126    print ("Done.")
127except Exception as detail:
128    print ("Unknown exception:", detail)
129
130