1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4# DISTRHO Plugin Framework (DPF)
5# Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com>
6#
7# Permission to use, copy, modify, and/or distribute this software for any purpose with
8# or without fee is hereby granted, provided that the above copyright notice and this
9# permission notice appear in all copies.
10#
11# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
12# TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
13# NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
15# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18import os, numpy, sys
19try:
20    import Image
21except:
22    from PIL import Image
23
24# -----------------------------------------------------
25
26formats = {
27    2: "GL_LUMINANCE",
28    3: "GL_BGR",
29    4: "GL_BGRA"
30}
31
32def png2rgba(namespace, filenames):
33
34    fdH = open("%s.hpp" % namespace, "w")
35    fdH.write("/* (Auto-generated binary data file). */\n")
36    fdH.write("\n")
37    fdH.write("#ifndef BINARY_%s_HPP\n" % namespace.upper())
38    fdH.write("#define BINARY_%s_HPP\n" % namespace.upper())
39    fdH.write("\n")
40    fdH.write("namespace %s\n" % namespace)
41    fdH.write("{\n")
42
43    fdC = open("%s.cpp" % namespace, "w")
44    fdC.write("/* (Auto-generated binary data file). */\n")
45    fdC.write("\n")
46    fdC.write("#include \"%s.hpp\"\n" % namespace)
47    fdC.write("\n")
48
49    tempIndex = 1
50
51    for filename in filenames:
52        shortFilename = filename.rsplit(os.sep, 1)[-1].split(".", 1)[0]
53        shortFilename = shortFilename.replace("-", "_")
54
55        png = Image.open(filename)
56        if png.getpalette():
57            png = png.convert()
58
59        pngNumpy = numpy.array(png)
60        pngData  = pngNumpy.tolist()
61        #pngData.reverse()
62
63        height = len(pngData)
64        for dataBlock in pngData:
65            width = len(dataBlock)
66            if isinstance(dataBlock[0], int):
67                channels = 2
68            else:
69                channels = len(dataBlock[0])
70            break
71        else:
72            print("Invalid image found, cannot continue!")
73            quit()
74
75        if channels not in formats.keys():
76            print("Invalid image channel count, cannot continue!")
77            quit()
78
79        print("Generating data for \"%s\" using '%s' type" % (filename, formats[channels]))
80        #print("  Width:    %i" % width)
81        #print("  Height:   %i" % height)
82        #print("  DataSize: %i" % (width * height * channels))
83
84        fdH.write("    extern const char* %sData;\n" % shortFilename)
85        fdH.write("    const unsigned int %sDataSize = %i;\n" % (shortFilename, width * height * channels))
86        fdH.write("    const unsigned int %sWidth    = %i;\n" % (shortFilename, width))
87        fdH.write("    const unsigned int %sHeight   = %i;\n" % (shortFilename, height))
88
89        if tempIndex != len(filenames):
90            fdH.write("\n")
91
92        fdC.write("static const unsigned char temp_%s_%i[] = {\n" % (shortFilename, tempIndex))
93
94        curColumn = 1
95        fdC.write(" ")
96
97        for dataBlock in pngData:
98            if curColumn == 0:
99                fdC.write(" ")
100
101            for data in dataBlock:
102                if channels == 2:
103                    fdC.write(" %3u," % data)
104
105                elif channels == 3:
106                    r, g, b = data
107                    fdC.write(" %3u, %3u, %3u," % (b, g, r))
108
109                else:
110                    r, g, b, a = data
111
112                    if filename in ("artwork/claw1.png",
113                                    "artwork/claw2.png",
114                                    "artwork/run1.png",
115                                    "artwork/run2.png",
116                                    "artwork/run3.png",
117                                    "artwork/run4.png",
118                                    "artwork/scratch1.png",
119                                    "artwork/scratch2.png",
120                                    "artwork/sit.png",
121                                    "artwork/tail.png"):
122                        if r == 255:
123                            a -= 38
124                            if a < 0: a = 0
125                            #a = 0
126                        #else:
127                            #r = g = b = 255
128
129                    fdC.write(" %3u, %3u, %3u, %3u," % (b, g, r, a))
130
131                if curColumn > 20:
132                    fdC.write("\n ")
133                    curColumn = 1
134                else:
135                    curColumn += 1
136
137        fdC.write("};\n")
138        fdC.write("const char* %s::%sData = (const char*)temp_%s_%i;\n" % (namespace, shortFilename, shortFilename, tempIndex))
139
140        if tempIndex != len(filenames):
141            fdC.write("\n")
142
143        tempIndex += 1
144
145    fdH.write("}\n")
146    fdH.write("\n")
147    fdH.write("#endif // BINARY_%s_HPP\n" % namespace.upper())
148    fdH.write("\n")
149    fdH.close()
150
151    fdC.write("\n")
152    fdC.close()
153
154# -----------------------------------------------------
155
156if __name__ == '__main__':
157    if len(sys.argv) != 3:
158        print("Usage: %s <namespace> <artwork-folder>" % sys.argv[0])
159        quit()
160
161    namespace = sys.argv[1].replace("-","_")
162    artFolder = sys.argv[2]
163
164    if not os.path.exists(artFolder):
165        print("Folder '%s' does not exist" % artFolder)
166        quit()
167
168    # find png files
169    pngFiles = []
170
171    for root, dirs, files in os.walk(artFolder):
172        for name in [name for name in files if name.lower().endswith(".png")]:
173            pngFiles.append(os.path.join(root, name))
174
175    pngFiles.sort()
176
177    # create code now
178    png2rgba(namespace, pngFiles)
179