Skip to content

Build Photon from source and improve demos. #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/graalwasm-micronaut-photon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ jobs:
github-token: ${{ secrets.GITHUB_TOKEN }}
cache: 'maven'
native-image-job-reports: 'true'
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Package 'graalwasm-micronaut-photon'
run: |
cd graalwasm/graalwasm-micronaut-photon
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/graalwasm-spring-boot-photon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ jobs:
github-token: ${{ secrets.GITHUB_TOKEN }}
cache: 'maven'
native-image-job-reports: 'true'
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Package 'graalwasm-spring-boot-photon'
run: |
cd graalwasm/graalwasm-spring-boot-photon
Expand Down
1 change: 0 additions & 1 deletion graalwasm/graalwasm-micronaut-photon/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ To start the demo, simply run:

When the demo runs, open the following URLs in a browser:

- http://localhost:8080/photo/default
- http://localhost:8080/photo/grayscale
- http://localhost:8080/photo/colorize
- http://localhost:8080/photo/fliph
Expand Down
56 changes: 56 additions & 0 deletions graalwasm/graalwasm-micronaut-photon/build-photon.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env bash
#
# Copyright (c) 2025, Oracle and/or its affiliates.
#
# Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL.
#

set -o errexit
set -o nounset

PHOTON_COMMIT="e95eccf886897c2efe8c2461fae9c6bf1375ff49"

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

if [[ -d "${SCRIPT_DIR}/target/classes/photon" ]]; then
echo "Photon already built from source. Nothing to do."
exit 0
fi

function ensure_command() {
local cmd=$1
if ! command -v "${cmd}" > /dev/null; then
cat <<EOF
${cmd} not found.

Please install '${cmd}' on your system and restart.
EOF
fail ""
fi
}

ensure_command "curl"
ensure_command "unzip"
ensure_command "wasm-pack"

echo "Building Photon from source..."

mkdir -p target/photon
pushd target/photon > /dev/null

if [[ ! -f photon-src.zip ]]; then
curl -sL -o photon-src.zip "https://github.com/silvia-odwyer/photon/archive/${PHOTON_COMMIT}.zip"
fi
if [[ ! -d "photon-${PHOTON_COMMIT}" ]]; then
unzip -q photon-src.zip
fi
pushd "photon-${PHOTON_COMMIT}" > /dev/null

wasm-pack build --release --target bundler --out-name photon --out-dir "${SCRIPT_DIR}"/target/classes/photon ./crate

echo "Copying example image..."

cp crate/examples/input_images/daisies_fuji.jpg "${SCRIPT_DIR}"/target/classes

popd > /dev/null
popd > /dev/null
51 changes: 10 additions & 41 deletions graalwasm/graalwasm-micronaut-photon/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
</parent>
<properties>
<graal.languages.version>24.2.0</graal.languages.version>
<photon.download.url>
https://raw.githubusercontent.com/fineshopdesign/cf-wasm/dca69477657fe80e36989f1fe7dcc17700d81ee2/packages/photon/src/lib
</photon.download.url>
<packaging>jar</packaging>
<jdk.version>21</jdk.version>
<release.version>21</release.version>
Expand Down Expand Up @@ -100,51 +97,23 @@

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>2.0.2</version>
<artifactId>exec-maven-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>download-photon-js</id>
<id>build-photon</id>
<phase>process-resources</phase>
<goals>
<goal>download-single</goal>
<goal>exec</goal>
</goals>
<configuration>
<url>${photon.download.url}</url>
<fromFile>photon_rs.js</fromFile>
<toDir>${project.build.outputDirectory}/photon</toDir>
<skipIfExists>true</skipIfExists>
</configuration>
</execution>
<execution>
<id>download-photon-wasm</id>
<phase>process-resources</phase>
<goals>
<goal>download-single</goal>
</goals>
<configuration>
<url>${photon.download.url}</url>
<fromFile>photon_rs_bg.wasm</fromFile>
<toDir>${project.build.outputDirectory}/photon</toDir>
<skipIfExists>true</skipIfExists>
</configuration>
</execution>
<execution>
<id>download-example-image</id>
<phase>process-resources</phase>
<goals>
<goal>download-single</goal>
</goals>
<configuration>
<url>
https://raw.githubusercontent.com/silvia-odwyer/photon/d084f6842c29bbb4838bf97bc98fd8c45b892cba/crate/examples/input_images
</url>
<fromFile>daisies_fuji.jpg</fromFile>
<toDir>${project.build.outputDirectory}</toDir>
<skipIfExists>true</skipIfExists>
</configuration>
</execution>
</executions>
<configuration>
<executable>bash</executable>
<arguments>
<argument>build-photon.sh</argument>
</arguments>
</configuration>
</plugin>

<plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import org.graalvm.polyglot.Value;
import org.graalvm.polyglot.io.ByteSequence;

public record Photon(Value module, Value imageContent) {
public record Photon(Value module, Uint8Array imageContent) {

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

PhotonImage createImage() {
return module.getMember("PhotonImage").invokeMember("new_from_byteslice", imageContent).as(PhotonImage.class);
PhotonImage photonImage = module.getMember("PhotonImage").as(PhotonImage.class);
return photonImage.new_from_byteslice(imageContent);
}

public interface PhotonImage {
void free();

Uint8Array get_bytes();

PhotonImage new_from_byteslice(Uint8Array imageContent);
}

public interface Uint8Array {
ByteSequence buffer();
}

public static byte[] toByteArray(PhotonImage photonImage) {
return Value.asValue(photonImage).invokeMember("get_bytes").getMember("buffer").as(ByteSequence.class).toByteArray();
return photonImage.get_bytes().buffer().toByteArray();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

package com.example;

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

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

int maxThreads = Runtime.getRuntime().availableProcessors();
photons = new LinkedBlockingQueue<>(maxThreads);
for (int i = 0; i < maxThreads; i++) {
photons.add(createPhoton(sharedEngine, photonSource, wasmBytes, imageBytes));
photons.add(createPhoton(sharedEngine, photonSource, imageBytes));
}
}

Expand All @@ -53,25 +53,21 @@ public void close() {
sharedEngine.close();
}

private static Photon createPhoton(Engine engine, Source photonSource, Object wasmBytes, Object imageBytes) {
org.graalvm.polyglot.Context context = org.graalvm.polyglot.Context.newBuilder("js", "wasm")
private static Photon createPhoton(Engine engine, Source photonSource, Object imageBytes) {
var context = org.graalvm.polyglot.Context.newBuilder("js", "wasm")
.engine(engine)
.allowAllAccess(true)
.allowExperimentalOptions(true)
.option("js.webassembly", "true")
.option("js.esm-eval-returns-exports", "true")
.option("js.text-encoding", "true")
.option("js.webassembly", "true")
.build();

// Get Uint8Array class from JavaScript
Value uint8Array = context.eval("js", "Uint8Array");
// Load Photon module and initialize with wasm content
Value photonModule = context.eval(photonSource);
// Create Uint8Array with wasm bytes
Value wasmContent = uint8Array.newInstance(wasmBytes);
// Initialize Photon module with wasm content
photonModule.invokeMember("default", wasmContent);

// Create Uint8Array with image bytes
Value imageContent = uint8Array.newInstance(imageBytes);
Uint8Array imageContent = context.getBindings("js").getMember("Uint8Array").newInstance(imageBytes).as(Uint8Array.class);

return new Photon(photonModule, imageContent);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class DemoTest {

@Test
void testEffectEquality() {
for (String effectName : new String[]{"default", "grayscale", "flipv", "fliph"}) {
for (String effectName : new String[]{"grayscale", "flipv", "fliph", "obsidian"}) {
byte[] imageContent1 = photonService.processImage(effectName);
byte[] imageContent2 = photonService.processImage(effectName);
Assertions.assertArrayEquals(imageContent1, imageContent2, "Two processed images not identical when effect '%s' is used".formatted(effectName));
Expand Down
1 change: 0 additions & 1 deletion graalwasm/graalwasm-spring-boot-photon/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ To start the demo, simply run:

When the demo runs, open the following URLs in a browser:

- http://localhost:8080/photo/default
- http://localhost:8080/photo/grayscale
- http://localhost:8080/photo/colorize
- http://localhost:8080/photo/fliph
Expand Down
56 changes: 56 additions & 0 deletions graalwasm/graalwasm-spring-boot-photon/build-photon.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env bash
#
# Copyright (c) 2025, Oracle and/or its affiliates.
#
# Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL.
#

set -o errexit
set -o nounset

PHOTON_COMMIT="e95eccf886897c2efe8c2461fae9c6bf1375ff49"

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

if [[ -d "${SCRIPT_DIR}/target/classes/photon" ]]; then
echo "Photon already built from source. Nothing to do."
exit 0
fi

function ensure_command() {
local cmd=$1
if ! command -v "${cmd}" > /dev/null; then
cat <<EOF
${cmd} not found.

Please install '${cmd}' on your system and restart.
EOF
fail ""
fi
}

ensure_command "curl"
ensure_command "unzip"
ensure_command "wasm-pack"

echo "Building Photon from source..."

mkdir -p target/photon
pushd target/photon > /dev/null

if [[ ! -f photon-src.zip ]]; then
curl -sL -o photon-src.zip "https://github.com/silvia-odwyer/photon/archive/${PHOTON_COMMIT}.zip"
fi
if [[ ! -d "photon-${PHOTON_COMMIT}" ]]; then
unzip -q photon-src.zip
fi
pushd "photon-${PHOTON_COMMIT}" > /dev/null

wasm-pack build --release --target bundler --out-name photon --out-dir "${SCRIPT_DIR}"/target/classes/photon ./crate

echo "Copying example image..."

cp crate/examples/input_images/daisies_fuji.jpg "${SCRIPT_DIR}"/target/classes

popd > /dev/null
popd > /dev/null
51 changes: 10 additions & 41 deletions graalwasm/graalwasm-spring-boot-photon/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@
</scm>
<properties>
<graal.languages.version>24.2.0</graal.languages.version>
<photon.download.url>
https://raw.githubusercontent.com/fineshopdesign/cf-wasm/dca69477657fe80e36989f1fe7dcc17700d81ee2/packages/photon/src/lib
</photon.download.url>
<java.version>21</java.version>
</properties>
<dependencies>
Expand Down Expand Up @@ -81,51 +78,23 @@
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>2.0.2</version>
<artifactId>exec-maven-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>download-photon-js</id>
<id>build-photon</id>
<phase>process-resources</phase>
<goals>
<goal>download-single</goal>
<goal>exec</goal>
</goals>
<configuration>
<url>${photon.download.url}</url>
<fromFile>photon_rs.js</fromFile>
<toDir>${project.build.outputDirectory}/photon</toDir>
<skipIfExists>true</skipIfExists>
</configuration>
</execution>
<execution>
<id>download-photon-wasm</id>
<phase>process-resources</phase>
<goals>
<goal>download-single</goal>
</goals>
<configuration>
<url>${photon.download.url}</url>
<fromFile>photon_rs_bg.wasm</fromFile>
<toDir>${project.build.outputDirectory}/photon</toDir>
<skipIfExists>true</skipIfExists>
</configuration>
</execution>
<execution>
<id>download-example-image</id>
<phase>process-resources</phase>
<goals>
<goal>download-single</goal>
</goals>
<configuration>
<url>
https://raw.githubusercontent.com/silvia-odwyer/photon/d084f6842c29bbb4838bf97bc98fd8c45b892cba/crate/examples/input_images
</url>
<fromFile>daisies_fuji.jpg</fromFile>
<toDir>${project.build.outputDirectory}</toDir>
<skipIfExists>true</skipIfExists>
</configuration>
</execution>
</executions>
<configuration>
<executable>bash</executable>
<arguments>
<argument>build-photon.sh</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
Expand Down
Loading
Loading