Skip to content

Commit c6dfd35

Browse files
committed
Build Photon from source and improve demos.
1 parent 2d51ce9 commit c6dfd35

File tree

13 files changed

+188
-117
lines changed

13 files changed

+188
-117
lines changed

.github/workflows/graalwasm-micronaut-photon.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ jobs:
2525
github-token: ${{ secrets.GITHUB_TOKEN }}
2626
cache: 'maven'
2727
native-image-job-reports: 'true'
28+
- name: Install wasm-pack
29+
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
2830
- name: Package 'graalwasm-micronaut-photon'
2931
run: |
3032
cd graalwasm/graalwasm-micronaut-photon

.github/workflows/graalwasm-spring-boot-photon.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ jobs:
2525
github-token: ${{ secrets.GITHUB_TOKEN }}
2626
cache: 'maven'
2727
native-image-job-reports: 'true'
28+
- name: Install wasm-pack
29+
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
2830
- name: Package 'graalwasm-spring-boot-photon'
2931
run: |
3032
cd graalwasm/graalwasm-spring-boot-photon
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Copyright (c) 2025, Oracle and/or its affiliates.
4+
#
5+
# Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL.
6+
#
7+
8+
set -o errexit
9+
set -o nounset
10+
11+
PHOTON_COMMIT="e95eccf886897c2efe8c2461fae9c6bf1375ff49"
12+
13+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
14+
15+
if [[ -d "${SCRIPT_DIR}/target/classes/photon" ]]; then
16+
echo "Photon already built from source. Nothing to do."
17+
exit 0
18+
fi
19+
20+
function ensure_command() {
21+
local cmd=$1
22+
if ! command -v "${cmd}" > /dev/null; then
23+
cat <<EOF
24+
${cmd} not found.
25+
26+
Please install '${cmd}' on your system and restart.
27+
EOF
28+
fail ""
29+
fi
30+
}
31+
32+
ensure_command "curl"
33+
ensure_command "unzip"
34+
ensure_command "wasm-pack"
35+
36+
echo "Building Photon from source..."
37+
38+
mkdir -p target/photon
39+
pushd target/photon > /dev/null
40+
41+
if [[ ! -f photon-src.zip ]]; then
42+
curl -sL -o photon-src.zip "https://github.com/silvia-odwyer/photon/archive/${PHOTON_COMMIT}.zip"
43+
fi
44+
if [[ ! -d "photon-${PHOTON_COMMIT}" ]]; then
45+
unzip -q photon-src.zip
46+
fi
47+
pushd "photon-${PHOTON_COMMIT}" > /dev/null
48+
49+
wasm-pack build --release --target bundler --out-name photon --out-dir "${SCRIPT_DIR}"/target/classes/photon ./crate
50+
51+
echo "Copying example image..."
52+
53+
cp crate/examples/input_images/daisies_fuji.jpg "${SCRIPT_DIR}"/target/classes
54+
55+
popd > /dev/null
56+
popd > /dev/null

graalwasm/graalwasm-micronaut-photon/pom.xml

Lines changed: 10 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@
1414
</parent>
1515
<properties>
1616
<graal.languages.version>24.2.2</graal.languages.version>
17-
<photon.version>0.1.30</photon.version>
18-
<photon.download.url>
19-
https://raw.githubusercontent.com/fineshopdesign/cf-wasm/refs/tags/%40cf-wasm/satori%40${photon.version}/packages/photon/src/lib
20-
</photon.download.url>
2117
<packaging>jar</packaging>
2218
<jdk.version>24</jdk.version>
2319
<release.version>24</release.version>
@@ -101,51 +97,23 @@
10197

10298
<plugin>
10399
<groupId>org.codehaus.mojo</groupId>
104-
<artifactId>wagon-maven-plugin</artifactId>
105-
<version>2.0.2</version>
100+
<artifactId>exec-maven-plugin</artifactId>
101+
<version>3.5.0</version>
106102
<executions>
107103
<execution>
108-
<id>download-photon-js</id>
104+
<id>build-photon</id>
109105
<phase>process-resources</phase>
110106
<goals>
111-
<goal>download-single</goal>
107+
<goal>exec</goal>
112108
</goals>
113-
<configuration>
114-
<url>${photon.download.url}</url>
115-
<fromFile>photon_rs.js</fromFile>
116-
<toDir>${project.build.outputDirectory}/photon</toDir>
117-
<skipIfExists>true</skipIfExists>
118-
</configuration>
119-
</execution>
120-
<execution>
121-
<id>download-photon-wasm</id>
122-
<phase>process-resources</phase>
123-
<goals>
124-
<goal>download-single</goal>
125-
</goals>
126-
<configuration>
127-
<url>${photon.download.url}</url>
128-
<fromFile>photon_rs_bg.wasm</fromFile>
129-
<toDir>${project.build.outputDirectory}/photon</toDir>
130-
<skipIfExists>true</skipIfExists>
131-
</configuration>
132-
</execution>
133-
<execution>
134-
<id>download-example-image</id>
135-
<phase>process-resources</phase>
136-
<goals>
137-
<goal>download-single</goal>
138-
</goals>
139-
<configuration>
140-
<url>
141-
https://raw.githubusercontent.com/silvia-odwyer/photon/d084f6842c29bbb4838bf97bc98fd8c45b892cba/crate/examples/input_images
142-
</url>
143-
<fromFile>daisies_fuji.jpg</fromFile>
144-
<toDir>${project.build.outputDirectory}</toDir>
145-
<skipIfExists>true</skipIfExists>
146-
</configuration>
147109
</execution>
148110
</executions>
111+
<configuration>
112+
<executable>bash</executable>
113+
<arguments>
114+
<argument>build-photon.sh</argument>
115+
</arguments>
116+
</configuration>
149117
</plugin>
150118

151119
<plugin>

graalwasm/graalwasm-micronaut-photon/src/main/java/com/example/Photon.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import org.graalvm.polyglot.Value;
1010
import org.graalvm.polyglot.io.ByteSequence;
1111

12-
public record Photon(Value module, Value imageContent) {
12+
public record Photon(Value module, Uint8Array imageContent) {
1313

1414
boolean implementsEffect(String effectName) {
1515
return module.hasMember(effectName);
@@ -20,14 +20,23 @@ void applyEffect(String effectName, PhotonImage image) {
2020
}
2121

2222
PhotonImage createImage() {
23-
return module.getMember("PhotonImage").invokeMember("new_from_byteslice", imageContent).as(PhotonImage.class);
23+
PhotonImage photonImage = module.getMember("PhotonImage").as(PhotonImage.class);
24+
return photonImage.new_from_byteslice(imageContent);
2425
}
2526

2627
public interface PhotonImage {
2728
void free();
29+
30+
Uint8Array get_bytes();
31+
32+
PhotonImage new_from_byteslice(Uint8Array imageContent);
33+
}
34+
35+
public interface Uint8Array {
36+
ByteSequence buffer();
2837
}
2938

3039
public static byte[] toByteArray(PhotonImage photonImage) {
31-
return Value.asValue(photonImage).invokeMember("get_bytes").getMember("buffer").as(ByteSequence.class).toByteArray();
40+
return photonImage.get_bytes().buffer().toByteArray();
3241
}
3342
}

graalwasm/graalwasm-micronaut-photon/src/main/java/com/example/PhotonPool.java

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
package com.example;
88

9+
import com.example.Photon.Uint8Array;
910
import io.micronaut.context.annotation.Context;
1011
import io.micronaut.core.io.ResourceResolver;
1112
import jakarta.annotation.PreDestroy;
@@ -24,15 +25,14 @@ public class PhotonPool {
2425
private final BlockingQueue<Photon> photons;
2526

2627
PhotonPool(ResourceResolver resourceResolve) throws IOException {
27-
URL photonModuleURL = resourceResolve.getResource("classpath:photon/photon_rs.js").get();
28+
URL photonModuleURL = resourceResolve.getResource("classpath:photon/photon.js").get();
2829
Source photonSource = Source.newBuilder("js", photonModuleURL).mimeType("application/javascript+module").build();
29-
byte[] wasmBytes = resourceResolve.getResourceAsStream("classpath:photon/photon_rs_bg.wasm").get().readAllBytes();
3030
byte[] imageBytes = resourceResolve.getResourceAsStream("classpath:daisies_fuji.jpg").get().readAllBytes();
3131

3232
int maxThreads = Runtime.getRuntime().availableProcessors();
3333
photons = new LinkedBlockingQueue<>(maxThreads);
3434
for (int i = 0; i < maxThreads; i++) {
35-
photons.add(createPhoton(sharedEngine, photonSource, wasmBytes, imageBytes));
35+
photons.add(createPhoton(sharedEngine, photonSource, imageBytes));
3636
}
3737
}
3838

@@ -53,25 +53,21 @@ public void close() {
5353
sharedEngine.close();
5454
}
5555

56-
private static Photon createPhoton(Engine engine, Source photonSource, Object wasmBytes, Object imageBytes) {
57-
org.graalvm.polyglot.Context context = org.graalvm.polyglot.Context.newBuilder("js", "wasm")
56+
private static Photon createPhoton(Engine engine, Source photonSource, Object imageBytes) {
57+
var context = org.graalvm.polyglot.Context.newBuilder("js", "wasm")
5858
.engine(engine)
5959
.allowAllAccess(true)
6060
.allowExperimentalOptions(true)
61-
.option("js.webassembly", "true")
6261
.option("js.esm-eval-returns-exports", "true")
62+
.option("js.text-encoding", "true")
63+
.option("js.webassembly", "true")
6364
.build();
6465

65-
// Get Uint8Array class from JavaScript
66-
Value uint8Array = context.eval("js", "Uint8Array");
6766
// Load Photon module and initialize with wasm content
6867
Value photonModule = context.eval(photonSource);
69-
// Create Uint8Array with wasm bytes
70-
Value wasmContent = uint8Array.newInstance(wasmBytes);
71-
// Initialize Photon module with wasm content
72-
photonModule.invokeMember("default", wasmContent);
68+
7369
// Create Uint8Array with image bytes
74-
Value imageContent = uint8Array.newInstance(imageBytes);
70+
Uint8Array imageContent = context.getBindings("js").getMember("Uint8Array").newInstance(imageBytes).as(Uint8Array.class);
7571

7672
return new Photon(photonModule, imageContent);
7773
}

graalwasm/graalwasm-micronaut-photon/src/test/java/com/example/DemoTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class DemoTest {
1919

2020
@Test
2121
void testEffectEquality() {
22-
for (String effectName : new String[]{"default", "grayscale", "flipv", "fliph"}) {
22+
for (String effectName : new String[]{"grayscale", "flipv", "fliph", "obsidian"}) {
2323
byte[] imageContent1 = photonService.processImage(effectName);
2424
byte[] imageContent2 = photonService.processImage(effectName);
2525
Assertions.assertArrayEquals(imageContent1, imageContent2, "Two processed images not identical when effect '%s' is used".formatted(effectName));

graalwasm/graalwasm-spring-boot-photon/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ To start the demo, simply run:
2323
When the demo runs, open http://localhost:8080/ in a browser.
2424
To apply a specific effect, navigate to `http://localhost:8080/photo/<effect name>` (e.g., http://localhost:8080/photo/colorize).
2525

26-
2726
To compile the application with GraalVM Native Image, run:
2827

2928
```bash
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Copyright (c) 2025, Oracle and/or its affiliates.
4+
#
5+
# Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL.
6+
#
7+
8+
set -o errexit
9+
set -o nounset
10+
11+
PHOTON_COMMIT="e95eccf886897c2efe8c2461fae9c6bf1375ff49"
12+
13+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
14+
15+
if [[ -d "${SCRIPT_DIR}/target/classes/photon" ]]; then
16+
echo "Photon already built from source. Nothing to do."
17+
exit 0
18+
fi
19+
20+
function ensure_command() {
21+
local cmd=$1
22+
if ! command -v "${cmd}" > /dev/null; then
23+
cat <<EOF
24+
${cmd} not found.
25+
26+
Please install '${cmd}' on your system and restart.
27+
EOF
28+
fail ""
29+
fi
30+
}
31+
32+
ensure_command "curl"
33+
ensure_command "unzip"
34+
ensure_command "wasm-pack"
35+
36+
echo "Building Photon from source..."
37+
38+
mkdir -p target/photon
39+
pushd target/photon > /dev/null
40+
41+
if [[ ! -f photon-src.zip ]]; then
42+
curl -sL -o photon-src.zip "https://github.com/silvia-odwyer/photon/archive/${PHOTON_COMMIT}.zip"
43+
fi
44+
if [[ ! -d "photon-${PHOTON_COMMIT}" ]]; then
45+
unzip -q photon-src.zip
46+
fi
47+
pushd "photon-${PHOTON_COMMIT}" > /dev/null
48+
49+
wasm-pack build --release --target bundler --out-name photon --out-dir "${SCRIPT_DIR}"/target/classes/photon ./crate
50+
51+
echo "Copying example image..."
52+
53+
cp crate/examples/input_images/daisies_fuji.jpg "${SCRIPT_DIR}"/target/classes
54+
55+
popd > /dev/null
56+
popd > /dev/null

graalwasm/graalwasm-spring-boot-photon/pom.xml

Lines changed: 10 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@
2828
</scm>
2929
<properties>
3030
<graal.languages.version>24.2.2</graal.languages.version>
31-
<photon.download.url>
32-
https://raw.githubusercontent.com/fineshopdesign/cf-wasm/dca69477657fe80e36989f1fe7dcc17700d81ee2/packages/photon/src/lib
33-
</photon.download.url>
3431
<java.version>21</java.version>
3532
</properties>
3633
<dependencies>
@@ -81,51 +78,23 @@
8178
</plugin>
8279
<plugin>
8380
<groupId>org.codehaus.mojo</groupId>
84-
<artifactId>wagon-maven-plugin</artifactId>
85-
<version>2.0.2</version>
81+
<artifactId>exec-maven-plugin</artifactId>
82+
<version>3.5.0</version>
8683
<executions>
8784
<execution>
88-
<id>download-photon-js</id>
85+
<id>build-photon</id>
8986
<phase>process-resources</phase>
9087
<goals>
91-
<goal>download-single</goal>
88+
<goal>exec</goal>
9289
</goals>
93-
<configuration>
94-
<url>${photon.download.url}</url>
95-
<fromFile>photon_rs.js</fromFile>
96-
<toDir>${project.build.outputDirectory}/photon</toDir>
97-
<skipIfExists>true</skipIfExists>
98-
</configuration>
99-
</execution>
100-
<execution>
101-
<id>download-photon-wasm</id>
102-
<phase>process-resources</phase>
103-
<goals>
104-
<goal>download-single</goal>
105-
</goals>
106-
<configuration>
107-
<url>${photon.download.url}</url>
108-
<fromFile>photon_rs_bg.wasm</fromFile>
109-
<toDir>${project.build.outputDirectory}/photon</toDir>
110-
<skipIfExists>true</skipIfExists>
111-
</configuration>
112-
</execution>
113-
<execution>
114-
<id>download-example-image</id>
115-
<phase>process-resources</phase>
116-
<goals>
117-
<goal>download-single</goal>
118-
</goals>
119-
<configuration>
120-
<url>
121-
https://raw.githubusercontent.com/silvia-odwyer/photon/d084f6842c29bbb4838bf97bc98fd8c45b892cba/crate/examples/input_images
122-
</url>
123-
<fromFile>daisies_fuji.jpg</fromFile>
124-
<toDir>${project.build.outputDirectory}</toDir>
125-
<skipIfExists>true</skipIfExists>
126-
</configuration>
12790
</execution>
12891
</executions>
92+
<configuration>
93+
<executable>bash</executable>
94+
<arguments>
95+
<argument>build-photon.sh</argument>
96+
</arguments>
97+
</configuration>
12998
</plugin>
13099
</plugins>
131100
</build>

0 commit comments

Comments
 (0)