Skip to content

Commit

Permalink
Support WebP input / PNG output
Browse files Browse the repository at this point in the history
  • Loading branch information
apangin committed Oct 5, 2016
1 parent 2d9738e commit 59cffa9
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 15 deletions.
5 changes: 4 additions & 1 deletion src/one/webp/Converter.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ private static int parseParams(String[] args, Params params) {
case "-mt":
params.multithreaded(true);
break;
case "-png":
params.png(true);
break;
}
}
return i;
Expand All @@ -58,7 +61,7 @@ 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>");
throw new IllegalArgumentException("[options] <input.jpg|png|webp> <output.webp|png>");
}

String inFile = args[paramCount];
Expand Down
9 changes: 8 additions & 1 deletion src/one/webp/Params.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class Params {
private boolean useJpegScaling;
private boolean lossless;
private boolean multithreaded;
private boolean png;

public Params quality(int quality) {
check(quality >= 0 && quality <= 100);
Expand Down Expand Up @@ -64,6 +65,11 @@ public Params multithreaded(boolean multithreaded) {
return this;
}

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

// See struct Params in onewebp.h
long longValue() {
return (long) maxWidth
Expand All @@ -72,7 +78,8 @@ long longValue() {
| (long) compression << 40
| (useJpegScaling ? 1L << 48 : 0)
| (lossless ? 1L << 49 : 0)
| (multithreaded ? 1L << 50 : 0);
| (multithreaded ? 1L << 50 : 0)
| (png ? 1L << 51 : 0);
}

private void check(boolean condition) {
Expand Down
4 changes: 2 additions & 2 deletions src/one/webp/native/jniwrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Java_one_webp_WebP_convert0(JNIEnv* env, jobject cls, jbyteArray srcArray, jbyte
jbyte* dst = (*env)->GetPrimitiveArrayCritical(env, dstArray, NULL);

Params params = paramsFromJava(options);
int result = convert_to_webp(src, srcSize, dst, dstSize, params);
int result = convert_image(src, srcSize, dst, dstSize, params);

(*env)->ReleasePrimitiveArrayCritical(env, srcArray, src, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, dstArray, dst, JNI_COMMIT);
Expand All @@ -79,7 +79,7 @@ Java_one_webp_WebP_convert1(JNIEnv* env, jobject cls, jbyteArray srcArray, jlong
jbyte dst[MAX_ON_STACK_OUTPUT];

Params params = paramsFromJava(options);
int result = convert_to_webp(src, srcSize, dst, sizeof(dst), params);
int result = convert_image(src, srcSize, dst, sizeof(dst), params);

(*env)->ReleasePrimitiveArrayCritical(env, srcArray, src, JNI_ABORT);

Expand Down
7 changes: 5 additions & 2 deletions src/one/webp/native/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,23 @@ static int parse_params(int argc, char** argv, Params* params) {
params->lossless = 1;
} else if (strcmp(arg, "-mt") == 0) {
params->multithreaded = 1;
} else if (strcmp(arg, "-png") == 0) {
params->png = 1;
}
}
return i;
}

static void show_usage() {
printf("Usage: onewebp [options] <input.jpg|png> <output.webp>\n"
printf("Usage: onewebp [options] <input.jpg|png|webp> <output.webp|png>\n"
" -q 0..100 : Output quality\n"
" -c 1..6 : Compression level\n"
" -w px : Max width\n"
" -h px : Max height\n"
" -j : Use JPEG scaling\n"
" -l : Lossless compression\n"
" -mt : Multithreaded encoding\n"
" -png : PNG output\n"
"\n");
}

Expand Down Expand Up @@ -123,7 +126,7 @@ int main(int argc, char** argv) {
return 1;
}

int result = convert_to_webp(src, srcSize, dst, sizeof(dst), params);
int result = convert_image(src, srcSize, dst, sizeof(dst), params);
if (result < 0) {
printf("Error (%d) converting %s\n", result, inFile);
free(src);
Expand Down
53 changes: 47 additions & 6 deletions src/one/webp/native/onewebp.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,49 @@ static int decompress_png(unsigned char* src, unsigned long srcSize, RawImage* r
return 0;
}

static int decompress_webp(unsigned char* src, unsigned long srcSize, RawImage* rawImage, Params params) {
int width, height;
if (!WebPGetInfo(src, srcSize, &width, &height)) {
return ERR_FORMAT;
}

rawImage->width = width;
rawImage->height = height;
rawImage->argb = (unsigned char*)malloc(width * height * 4);

if (!WebPDecodeBGRAInto(src, srcSize, rawImage->argb, width * height * 4, width * 4)) {
free(rawImage->argb);
return ERR_DECOMPRESS;
}

return 0;
}

int decompress_image(unsigned char* src, unsigned long srcSize, RawImage* rawImage, Params params) {
if (srcSize >= 4 && src[1] == 'P' && src[2] == 'N' && src[3] == 'G') {
return decompress_png(src, srcSize, rawImage, params);
} else {
} else if (srcSize >= 3 && src[0] == 0xff && src[1] == 0xd8 && src[2] == 0xff) {
return decompress_jpeg(src, srcSize, rawImage, params);
} else {
return decompress_webp(src, srcSize, rawImage, params);
}
}

int compress_png(unsigned char* dst, unsigned long dstSize, RawImage* rawImage) {
png_image png = { NULL };
png.version = PNG_IMAGE_VERSION;
png.width = rawImage->width;
png.height = rawImage->height;
png.format = PNG_FORMAT_BGRA;

png_alloc_size_t size = (png_alloc_size_t)dstSize;
if (!png_image_write_to_memory(&png, dst, &size, 0, rawImage->argb, 0, NULL)) {
return ERR_COMPRESS;
}

return (int)size;
}

int compress_webp(unsigned char* dst, unsigned long dstSize, RawImage* rawImage, Params params) {
Buffer buffer = { dst, dst + dstSize };
int maxWidth = params.maxWidth ? params.maxWidth : WEBP_MAX_DIMENSION;
Expand Down Expand Up @@ -162,17 +197,23 @@ int compress_webp(unsigned char* dst, unsigned long dstSize, RawImage* rawImage,
return (int)(buffer.ptr - dst);
}

int convert_to_webp(unsigned char* src, unsigned long srcSize,
unsigned char* dst, unsigned long dstSize,
Params params) {
int convert_image(unsigned char* src, unsigned long srcSize,
unsigned char* dst, unsigned long dstSize,
Params params) {
RawImage rawImage;

int result = decompress_image(src, srcSize, &rawImage, params);
if (result) {
return result;
}

if (result == 0) {
if (params.png) {
result = compress_png(dst, dstSize, &rawImage);
} else {
result = compress_webp(dst, dstSize, &rawImage, params);
free(rawImage.argb);
}

free(rawImage.argb);
return result;
}

Expand Down
8 changes: 5 additions & 3 deletions src/one/webp/native/onewebp.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ typedef struct {
unsigned int useJpegScaling : 1;
unsigned int lossless : 1;
unsigned int multithreaded : 1;
unsigned int png : 1;
} Params;

typedef struct {
Expand All @@ -40,9 +41,10 @@ typedef struct {

int decompress_image(unsigned char* src, unsigned long srcSize, RawImage* rawImage, Params params);
int compress_webp(unsigned char* dst, unsigned long dstSize, RawImage* rawImage, Params params);
int compress_png(unsigned char* dst, unsigned long dstSize, RawImage* rawImage);

int convert_to_webp(unsigned char* src, unsigned long srcSize,
unsigned char* dst, unsigned long dstSize,
Params params);
int convert_image(unsigned char* src, unsigned long srcSize,
unsigned char* dst, unsigned long dstSize,
Params params);

unsigned long long image_phash(unsigned char* src, unsigned long srcSize);

0 comments on commit 59cffa9

Please sign in to comment.