Skip to content

Commit

Permalink
Initial implementation of WebP converter
Browse files Browse the repository at this point in the history
  • Loading branch information
apangin committed Jun 23, 2016
1 parent be1cb66 commit d263d82
Show file tree
Hide file tree
Showing 10 changed files with 800 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/build
local.properties

.idea
*.iml
129 changes: 129 additions & 0 deletions build.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<project name="one-webp" default="build" basedir=".">
<property file="${basedir}/local.properties"/>

<property name="build.dir" value="build"/>
<property name="src.dir" value="src"/>

<property name="libjpeg-turbo.dir" value="/usr"/>
<property name="libpng.dir" value="/usr"/>
<property name="libwebp.dir" value="/usr"/>

<property name="build.native.dir" value="${build.dir}/native"/>
<property name="src.native.dir" value="${src.dir}/one/webp/native"/>
<property name="gcc.extra.args" value=""/>

<target name="init">
<mkdir dir="${build.dir}"/>
</target>

<target name="clean">
<delete dir="${build.dir}"/>
</target>

<target name="build" depends="compile-classes, webp-exe, webp-dll"/>

<target name="compile-classes" depends="init">
<echo message="Compiling classes..."/>
<mkdir dir="${build.dir}/classes"/>
<javac srcdir="${src.dir}" destdir="${build.dir}/classes" includeantruntime="false"/>
</target>

<target name="webp-dll">
<mkdir dir="${build.native.dir}"/>

<property name="cl" value="cl.exe"/>
<exec osfamily="Windows" executable="${cl}" dir="${build.native.dir}">
<arg value="/O2"/>
<arg value="/LD"/>
<arg value="/I"/>
<arg path="${java.home}/../include"/>
<arg value="/I"/>
<arg path="${java.home}/../include/win32"/>
<arg value="/I"/>
<arg path="${libjpeg-turbo.dir}/include"/>
<arg value="/I"/>
<arg path="${libpng.dir}/include"/>
<arg value="/I"/>
<arg path="${libwebp.dir}/include"/>
<arg path="${src.native.dir}/onewebp.c"/>
<arg path="${src.native.dir}/jniwrapper.c"/>
<arg path="${libjpeg-turbo.dir}/lib/turbojpeg-static.lib"/>
<arg path="${libpng.dir}/lib/libpng.lib"/>
<arg path="${libpng.dir}/lib/libz.lib"/>
<arg path="${libwebp.dir}/lib/libwebp.lib"/>
</exec>

<property name="gcc" value="gcc"/>
<exec os="Linux" executable="${gcc}" dir="${build.native.dir}">
<arg value="-O3"/>
<arg value="-shared"/>
<arg value="-fPIC"/>
<arg value="-I"/>
<arg path="${java.home}/../include"/>
<arg value="-I"/>
<arg path="${java.home}/../include/linux"/>
<arg value="-I"/>
<arg path="${libjpeg-turbo.dir}/include"/>
<arg value="-I"/>
<arg path="${libpng.dir}/include"/>
<arg value="-I"/>
<arg path="${libwebp.dir}/include"/>
<arg path="${src.native.dir}/onewebp.c"/>
<arg path="${src.native.dir}/jniwrapper.c"/>
<arg path="${libjpeg-turbo.dir}/lib64/libturbojpeg.a"/>
<arg path="${libpng.dir}/lib/libpng.a"/>
<arg path="${libwebp.dir}/lib/libwebp.a"/>
<arg line="-o libonewebp.so"/>
<arg value="-Wl,-soname,libonewebp.so"/>
</exec>
</target>

<target name="webp-exe">
<mkdir dir="${build.native.dir}"/>

<property name="cl" value="cl.exe"/>
<exec osfamily="Windows" executable="${cl}" dir="${build.native.dir}">
<arg value="/O2"/>
<arg value="/I"/>
<arg path="${java.home}/../include"/>
<arg value="/I"/>
<arg path="${java.home}/../include/win32"/>
<arg value="/I"/>
<arg path="${libjpeg-turbo.dir}/include"/>
<arg value="/I"/>
<arg path="${libpng.dir}/include"/>
<arg value="/I"/>
<arg path="${libwebp.dir}/include"/>
<arg path="${src.native.dir}/onewebp.c"/>
<arg path="${src.native.dir}/main.c"/>
<arg path="${libjpeg-turbo.dir}/lib/turbojpeg-static.lib"/>
<arg path="${libpng.dir}/lib/libpng.lib"/>
<arg path="${libpng.dir}/lib/libz.lib"/>
<arg path="${libwebp.dir}/lib/libwebp.lib"/>
</exec>

<property name="gcc" value="gcc"/>
<exec os="Linux" executable="${gcc}" dir="${build.native.dir}">
<arg value="-O3"/>
<arg value="-I"/>
<arg path="${java.home}/../include"/>
<arg value="-I"/>
<arg path="${java.home}/../include/linux"/>
<arg value="-I"/>
<arg path="${libjpeg-turbo.dir}/include"/>
<arg value="-I"/>
<arg path="${libpng.dir}/include"/>
<arg value="-I"/>
<arg path="${libwebp.dir}/include"/>
<arg path="${src.native.dir}/onewebp.c"/>
<arg path="${src.native.dir}/main.c"/>
<arg path="${libjpeg-turbo.dir}/lib64/libturbojpeg.a"/>
<arg path="${libpng.dir}/lib/libpng.a"/>
<arg path="${libwebp.dir}/lib/libwebp.a"/>
<arg value="-lm"/>
<arg value="-lz"/>
<arg value="-lpthread"/>
<arg line="-o onewebp"/>
</exec>
</target>
</project>
72 changes: 72 additions & 0 deletions src/one/webp/Converter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2016 Odnoklassniki Ltd, Mail.Ru Group
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package one.webp;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;

import static java.nio.file.StandardOpenOption.*;

public class Converter {

private static int parseParams(String[] args, Params params) {
int i = 0;
while (i < args.length - 2) {
switch (args[i++]) {
case "-q":
params.quality(Integer.parseInt(args[i++]));
break;
case "-c":
params.compression(Integer.parseInt(args[i++]));
break;
case "-w":
params.maxWidth(Integer.parseInt(args[i++]));
break;
case "-h":
params.maxHeight(Integer.parseInt(args[i++]));
break;
case "-j":
params.useJpegScaling(true);
break;
case "-l":
params.lossless(true);
break;
case "-mt":
params.multithreaded(true);
break;
}
}
return i;
}

public static void main(String[] args) throws Exception {
Params params = new Params();
int paramCount = parseParams(args, params);
if (paramCount + 2 != args.length) {
throw new IllegalArgumentException("[options] <input.jpg|png> <output.webp>");
}

String inFile = args[paramCount];
String outFile = args[paramCount + 1];

byte[] src = Files.readAllBytes(Paths.get(inFile));
byte[] dst = new byte[4 * 1024 * 1024];
int dstSize = WebP.convert(src, dst, params);
Files.write(Paths.get(outFile), Arrays.copyOf(dst, dstSize), CREATE, TRUNCATE_EXISTING);
}
}
83 changes: 83 additions & 0 deletions src/one/webp/Params.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright 2016 Odnoklassniki Ltd, Mail.Ru Group
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package one.webp;

public class Params {
private byte quality = 80;
private byte compression = 5;
private short maxWidth;
private short maxHeight;
private boolean useJpegScaling;
private boolean lossless;
private boolean multithreaded;

public Params quality(int quality) {
check(quality >= 0 && quality <= 100);
this.quality = (byte) quality;
return this;
}

public Params compression(int compression) {
check(compression >= 1 && compression <= 6);
this.compression = (byte) compression;
return this;
}

public Params maxWidth(int maxWidth) {
check(maxWidth >= 1 && maxWidth <= 16383);
this.maxWidth = (short) maxWidth;
return this;
}

public Params maxHeight(int maxHeight) {
check(maxHeight >= 1 && maxHeight <= 16383);
this.maxHeight = (short) maxHeight;
return this;
}

public Params useJpegScaling(boolean useJpegScaling) {
this.useJpegScaling = useJpegScaling;
return this;
}

public Params lossless(boolean lossless) {
this.lossless = lossless;
return this;
}

public Params multithreaded(boolean multithreaded) {
this.multithreaded = multithreaded;
return this;
}

// See struct Params in onewebp.h
long longValue() {
return (long) maxWidth
| (long) maxHeight << 16
| (long) quality << 32
| (long) compression << 40
| (useJpegScaling ? 1L << 48 : 0)
| (lossless ? 1L << 49 : 0)
| (multithreaded ? 1L << 50 : 0);
}

private void check(boolean condition) {
if (!condition) {
throw new IllegalArgumentException();
}
}
}
35 changes: 35 additions & 0 deletions src/one/webp/WebP.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2016 Odnoklassniki Ltd, Mail.Ru Group
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package one.webp;

public class WebP {

public static int convert(byte[] src, byte[] dst, Params params) throws WebPException {
return convert0(src, dst, params.longValue());
}

public static byte[] convert(byte[] src, Params params) throws WebPException {
return convert1(src, params.longValue());
}

private static native int convert0(byte[] src, byte[] dst, long options);
private static native byte[] convert1(byte[] src, long options);

static {
System.loadLibrary("onewebp");
}
}
24 changes: 24 additions & 0 deletions src/one/webp/WebPException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright 2016 Odnoklassniki Ltd, Mail.Ru Group
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package one.webp;

public class WebPException extends RuntimeException {

public WebPException(String message) {
super(message);
}
}
Loading

0 comments on commit d263d82

Please sign in to comment.