1cc1dc7a3Sopenharmony_ci#!/usr/bin/env python3
2cc1dc7a3Sopenharmony_ci# SPDX-License-Identifier: Apache-2.0
3cc1dc7a3Sopenharmony_ci# -----------------------------------------------------------------------------
4cc1dc7a3Sopenharmony_ci# Copyright 2019-2020 Arm Limited
5cc1dc7a3Sopenharmony_ci#
6cc1dc7a3Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); you may not
7cc1dc7a3Sopenharmony_ci# use this file except in compliance with the License. You may obtain a copy
8cc1dc7a3Sopenharmony_ci# of the License at:
9cc1dc7a3Sopenharmony_ci#
10cc1dc7a3Sopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
11cc1dc7a3Sopenharmony_ci#
12cc1dc7a3Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software
13cc1dc7a3Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14cc1dc7a3Sopenharmony_ci# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15cc1dc7a3Sopenharmony_ci# License for the specific language governing permissions and limitations
16cc1dc7a3Sopenharmony_ci# under the License.
17cc1dc7a3Sopenharmony_ci# -----------------------------------------------------------------------------
18cc1dc7a3Sopenharmony_ci"""
19cc1dc7a3Sopenharmony_ciThe ``astc_test_image_dl`` utility provides a means to programatically download
20cc1dc7a3Sopenharmony_citest images that are available online, avoiding the need to duplicate them in
21cc1dc7a3Sopenharmony_cithe git repository.
22cc1dc7a3Sopenharmony_ci"""
23cc1dc7a3Sopenharmony_ci
24cc1dc7a3Sopenharmony_ci
25cc1dc7a3Sopenharmony_ciimport os
26cc1dc7a3Sopenharmony_ciimport sys
27cc1dc7a3Sopenharmony_ciimport urllib.request
28cc1dc7a3Sopenharmony_ci
29cc1dc7a3Sopenharmony_cifrom PIL import Image
30cc1dc7a3Sopenharmony_ci
31cc1dc7a3Sopenharmony_ci
32cc1dc7a3Sopenharmony_ciTEST_IMAGE_DIR = os.path.join("Test", "Images")
33cc1dc7a3Sopenharmony_ci
34cc1dc7a3Sopenharmony_ci
35cc1dc7a3Sopenharmony_cidef download(testSet, index, srcUrl, dstPath):
36cc1dc7a3Sopenharmony_ci    """
37cc1dc7a3Sopenharmony_ci    Download a single image.
38cc1dc7a3Sopenharmony_ci
39cc1dc7a3Sopenharmony_ci    Args:
40cc1dc7a3Sopenharmony_ci        testSet (str): The test set name.
41cc1dc7a3Sopenharmony_ci        index (int): The download index.
42cc1dc7a3Sopenharmony_ci        srcUrl (str): The download URL.
43cc1dc7a3Sopenharmony_ci        dstPath (str): The destination path.
44cc1dc7a3Sopenharmony_ci    """
45cc1dc7a3Sopenharmony_ci    dirName = os.path.dirname(dstPath)
46cc1dc7a3Sopenharmony_ci    if not os.path.exists(dirName):
47cc1dc7a3Sopenharmony_ci        os.makedirs(dirName)
48cc1dc7a3Sopenharmony_ci
49cc1dc7a3Sopenharmony_ci    # Skip downloads if the file already exists
50cc1dc7a3Sopenharmony_ci    if not os.path.exists(dstPath):
51cc1dc7a3Sopenharmony_ci        print("%s image %u: Downloading" % (testSet, index))
52cc1dc7a3Sopenharmony_ci        urllib.request.urlretrieve(srcUrl, dstPath)
53cc1dc7a3Sopenharmony_ci    else:
54cc1dc7a3Sopenharmony_ci        print("%s image %u: Skipping" % (testSet, index))
55cc1dc7a3Sopenharmony_ci
56cc1dc7a3Sopenharmony_ci
57cc1dc7a3Sopenharmony_cidef make_landscape(imgPath):
58cc1dc7a3Sopenharmony_ci    """
59cc1dc7a3Sopenharmony_ci    Make an image on disk landscape aspect (edit in place)
60cc1dc7a3Sopenharmony_ci
61cc1dc7a3Sopenharmony_ci    Args:
62cc1dc7a3Sopenharmony_ci        imgPath: The pth of the image on disk.
63cc1dc7a3Sopenharmony_ci    """
64cc1dc7a3Sopenharmony_ci    img = Image.open(imgPath)
65cc1dc7a3Sopenharmony_ci    if img.size[0] < img.size[1]:
66cc1dc7a3Sopenharmony_ci        img = img.rotate(90, expand=True)
67cc1dc7a3Sopenharmony_ci        img.save(imgPath)
68cc1dc7a3Sopenharmony_ci
69cc1dc7a3Sopenharmony_ci
70cc1dc7a3Sopenharmony_cidef make_mixed_image(imgPathA, imgPathB, dstPath):
71cc1dc7a3Sopenharmony_ci    """
72cc1dc7a3Sopenharmony_ci    Make image consisting of RGB from A's RGB, and alpha from B's luminance.
73cc1dc7a3Sopenharmony_ci
74cc1dc7a3Sopenharmony_ci    Args:
75cc1dc7a3Sopenharmony_ci        imgPathA: The path of input A on disk.
76cc1dc7a3Sopenharmony_ci        imgPathB: The path of input B on disk.
77cc1dc7a3Sopenharmony_ci        dstPath: The path of the destination.
78cc1dc7a3Sopenharmony_ci    """
79cc1dc7a3Sopenharmony_ci    imgA = Image.open(imgPathA)
80cc1dc7a3Sopenharmony_ci    imgB = Image.open(imgPathB).convert("L")
81cc1dc7a3Sopenharmony_ci
82cc1dc7a3Sopenharmony_ci    imgA.putalpha(imgB)
83cc1dc7a3Sopenharmony_ci
84cc1dc7a3Sopenharmony_ci    dirs = os.path.dirname(dstPath)
85cc1dc7a3Sopenharmony_ci    if not os.path.exists(dirs):
86cc1dc7a3Sopenharmony_ci        os.makedirs(dirs)
87cc1dc7a3Sopenharmony_ci
88cc1dc7a3Sopenharmony_ci    imgA.save(dstPath)
89cc1dc7a3Sopenharmony_ci
90cc1dc7a3Sopenharmony_ci
91cc1dc7a3Sopenharmony_cidef make_montage(imageDir, dstPath):
92cc1dc7a3Sopenharmony_ci    """
93cc1dc7a3Sopenharmony_ci    Make a single mosaic montage consisting of all of the Kodak images.
94cc1dc7a3Sopenharmony_ci
95cc1dc7a3Sopenharmony_ci    Args:
96cc1dc7a3Sopenharmony_ci        imgDir: The directory path of the Kodak images on disk.
97cc1dc7a3Sopenharmony_ci        dstPth: The file path of the resulting montage.
98cc1dc7a3Sopenharmony_ci    """
99cc1dc7a3Sopenharmony_ci    cols = 6
100cc1dc7a3Sopenharmony_ci    rows = 4
101cc1dc7a3Sopenharmony_ci
102cc1dc7a3Sopenharmony_ci    width = 768
103cc1dc7a3Sopenharmony_ci    height = 512
104cc1dc7a3Sopenharmony_ci
105cc1dc7a3Sopenharmony_ci    images = os.listdir(imageDir)
106cc1dc7a3Sopenharmony_ci    images.sort()
107cc1dc7a3Sopenharmony_ci
108cc1dc7a3Sopenharmony_ci    montage = Image.new('RGB', (width * cols, height * rows))
109cc1dc7a3Sopenharmony_ci
110cc1dc7a3Sopenharmony_ci    for i, src in enumerate(images):
111cc1dc7a3Sopenharmony_ci        im = Image.open(os.path.join(imageDir, src))
112cc1dc7a3Sopenharmony_ci        col = i % cols
113cc1dc7a3Sopenharmony_ci        row = i // cols
114cc1dc7a3Sopenharmony_ci        montage.paste(im, (width * col, height * row))
115cc1dc7a3Sopenharmony_ci
116cc1dc7a3Sopenharmony_ci    dirs = os.path.dirname(dstPath)
117cc1dc7a3Sopenharmony_ci    if not os.path.exists(dirs):
118cc1dc7a3Sopenharmony_ci        os.makedirs(dirs)
119cc1dc7a3Sopenharmony_ci
120cc1dc7a3Sopenharmony_ci    montage.save(dstPath)
121cc1dc7a3Sopenharmony_ci
122cc1dc7a3Sopenharmony_ci
123cc1dc7a3Sopenharmony_cidef retrieve_kodak_set():
124cc1dc7a3Sopenharmony_ci    """
125cc1dc7a3Sopenharmony_ci    Download the public domain Kodak image set.
126cc1dc7a3Sopenharmony_ci
127cc1dc7a3Sopenharmony_ci    To make test set mosaics easier to build we rotate images to make
128cc1dc7a3Sopenharmony_ci    everything landscape.
129cc1dc7a3Sopenharmony_ci    """
130cc1dc7a3Sopenharmony_ci    testSet = "Kodak"
131cc1dc7a3Sopenharmony_ci
132cc1dc7a3Sopenharmony_ci    # Download the original RGB images
133cc1dc7a3Sopenharmony_ci    for i in range(1, 25):
134cc1dc7a3Sopenharmony_ci        fle = "ldr-rgb-kodak%02u.png" % i
135cc1dc7a3Sopenharmony_ci        dst = os.path.join(TEST_IMAGE_DIR, "Kodak", "LDR-RGB", fle)
136cc1dc7a3Sopenharmony_ci        src = "http://r0k.us/graphics/kodak/kodak/kodim%02u.png" % i
137cc1dc7a3Sopenharmony_ci        download(testSet, i, src, dst)
138cc1dc7a3Sopenharmony_ci
139cc1dc7a3Sopenharmony_ci        # Canonicalize image aspect
140cc1dc7a3Sopenharmony_ci        make_landscape(dst)
141cc1dc7a3Sopenharmony_ci
142cc1dc7a3Sopenharmony_ci    # Make some correlated alpha RGBA images
143cc1dc7a3Sopenharmony_ci    fle = "ldr-rgb-kodak%02u.png"  # Expand later
144cc1dc7a3Sopenharmony_ci    pattern = os.path.join(TEST_IMAGE_DIR, "Kodak", "LDR-RGB", fle)
145cc1dc7a3Sopenharmony_ci
146cc1dc7a3Sopenharmony_ci    for i in (22, 23):
147cc1dc7a3Sopenharmony_ci        imgA = pattern % i
148cc1dc7a3Sopenharmony_ci        fle = "ldr-rgba-kodak%02u+ca.png" % i
149cc1dc7a3Sopenharmony_ci        dst = os.path.join(TEST_IMAGE_DIR, "KodakSim", "LDR-RGBA", fle)
150cc1dc7a3Sopenharmony_ci        make_mixed_image(imgA, imgA, dst)
151cc1dc7a3Sopenharmony_ci
152cc1dc7a3Sopenharmony_ci    # Make some non-correlated alpha RGBA images
153cc1dc7a3Sopenharmony_ci    for i, j in ((22, 24), (23, 20)):
154cc1dc7a3Sopenharmony_ci        imgA = pattern % i
155cc1dc7a3Sopenharmony_ci        imgB = pattern % j
156cc1dc7a3Sopenharmony_ci        fle = "ldr-rgba-kodak%02u+%02u+nca.png" % (i, j)
157cc1dc7a3Sopenharmony_ci        dst = os.path.join(TEST_IMAGE_DIR, "KodakSim", "LDR-RGBA", fle)
158cc1dc7a3Sopenharmony_ci        make_mixed_image(imgA, imgB, dst)
159cc1dc7a3Sopenharmony_ci
160cc1dc7a3Sopenharmony_ci    # Make a large montage
161cc1dc7a3Sopenharmony_ci    srcDir = os.path.join(TEST_IMAGE_DIR, "Kodak", "LDR-RGB")
162cc1dc7a3Sopenharmony_ci    fle = "ldr-rgb-montage.png"
163cc1dc7a3Sopenharmony_ci    dst = os.path.join(TEST_IMAGE_DIR, "KodakMnt", "LDR-RGB", fle)
164cc1dc7a3Sopenharmony_ci    make_montage(srcDir, dst)
165cc1dc7a3Sopenharmony_ci
166cc1dc7a3Sopenharmony_ci
167cc1dc7a3Sopenharmony_cidef main():
168cc1dc7a3Sopenharmony_ci    """
169cc1dc7a3Sopenharmony_ci    The main function.
170cc1dc7a3Sopenharmony_ci
171cc1dc7a3Sopenharmony_ci    Returns:
172cc1dc7a3Sopenharmony_ci        int: The process return code.
173cc1dc7a3Sopenharmony_ci    """
174cc1dc7a3Sopenharmony_ci    retrieve_kodak_set()
175cc1dc7a3Sopenharmony_ci    return 0
176cc1dc7a3Sopenharmony_ci
177cc1dc7a3Sopenharmony_ci
178cc1dc7a3Sopenharmony_ciif __name__ == "__main__":
179cc1dc7a3Sopenharmony_ci    sys.exit(main())
180