Skip to content

Commit

Permalink
improve caching for 12 Monkeys Coder and reading application settings
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeloffner committed Dec 14, 2022
1 parent 13f6610 commit 615c6e6
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 96 deletions.
4 changes: 2 additions & 2 deletions build.number
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#Build Number for ANT. Do not edit!
#Tue Dec 13 19:51:32 CET 2022
build.number=23
#Wed Dec 14 11:30:33 CET 2022
build.number=24
114 changes: 81 additions & 33 deletions source/java/src/org/lucee/extension/image/coder/AImageIOInterface.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
Expand Down Expand Up @@ -528,11 +529,13 @@ protected static class Codec {
private final Class<? extends ImageWriter> _writer;
private final Class<? extends ImageReaderSpi> readerSpi;
private final Class<? extends ImageWriterSpi> writerSpi;
private final Class<?>[] readerConstructor;
private final Class<?>[] writerConstructor;
private final Class<?>[] readerConstructorArgs;
private final Class<?>[] writerConstructorArgs;
public int writer = -1;
public int reader = -1;

public Codec(String[] formatNames, String[] suffixes, String[] mimeTypes, Class<? extends ImageReader> reader, Class<? extends ImageWriter> writer,
Class<? extends ImageReaderSpi> readerSpi, Class<? extends ImageWriterSpi> writerSpi, Class<?>[] readerConstructor, Class<?>[] writerConstructor) {
Class<? extends ImageReaderSpi> readerSpi, Class<? extends ImageWriterSpi> writerSpi, Class<?>[] readerConstructorArgs, Class<?>[] writerConstructorArgs) {
super();
this.formatNames = formatNames == null ? new String[0] : formatNames;
this.suffixes = suffixes == null ? new String[0] : suffixes;
Expand All @@ -541,8 +544,8 @@ public Codec(String[] formatNames, String[] suffixes, String[] mimeTypes, Class<
this._writer = writer;
this.readerSpi = readerSpi;
this.writerSpi = writerSpi;
this.readerConstructor = readerConstructor;
this.writerConstructor = writerConstructor;
this.readerConstructorArgs = readerConstructorArgs;
this.writerConstructorArgs = writerConstructorArgs;
}

protected static void newInstance(Map<String, Codec> codecs, String[] formatNames, String[] suffixes, String[] mimeTypes, Class<? extends ImageReader> reader,
Expand Down Expand Up @@ -661,27 +664,30 @@ public boolean canDecodeInput(Object source) throws IOException {
@Override
public ImageReader createReaderInstance(Object extension) throws IOException {
try {

// javax.imageio.spi.ImageReaderSpi
Constructor<? extends ImageReader> constr;
Class<?>[] constrArgs = codec.readerConstructor;
try {
Class<?>[] constrArgs = codec.readerConstructorArgs;

constr = clazz.getDeclaredConstructor(constrArgs != null && constrArgs.length == 1 ? constrArgs : READ_CONSTR1);
constr.setAccessible(true);
return constr.newInstance(this);
if (codec.reader == 0) return createReaderInstance0(constrArgs);
if (codec.reader == 1) return createReaderInstance1(constrArgs);
if (codec.reader == 2) return createReaderInstance2(constrArgs);

ImageReader ir;
try {
ir = createReaderInstance1(constrArgs);
codec.reader = 1;
return ir;
}
catch (NoSuchMethodException nsme) {
try {
constr = clazz.getDeclaredConstructor(constrArgs != null && constrArgs.length == 2 ? constrArgs : READ_CONSTR2);
constr.setAccessible(true);
return constr.newInstance(this, getDelegateImageReader());

ir = createReaderInstance2(constrArgs);
codec.reader = 2;
return ir;
}
catch (NoSuchMethodException nsme2) {
constr = clazz.getDeclaredConstructor(READ_CONSTR0);
constr.setAccessible(true);
return constr.newInstance();
ir = createReaderInstance0(constrArgs);
codec.reader = 0;
return ir;
}
}
}
Expand All @@ -690,6 +696,27 @@ public ImageReader createReaderInstance(Object extension) throws IOException {
}
}

public ImageReader createReaderInstance0(Class<?>[] constrArgs)
throws IOException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Constructor<? extends ImageReader> constr = clazz.getDeclaredConstructor(READ_CONSTR0);
constr.setAccessible(true);
return constr.newInstance();
}

public ImageReader createReaderInstance1(Class<?>[] constrArgs)
throws IOException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Constructor<? extends ImageReader> constr = clazz.getDeclaredConstructor(constrArgs != null && constrArgs.length == 1 ? constrArgs : READ_CONSTR1);
constr.setAccessible(true);
return constr.newInstance(this);
}

public ImageReader createReaderInstance2(Class<?>[] constrArgs)
throws IOException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Constructor<? extends ImageReader> constr = clazz.getDeclaredConstructor(constrArgs != null && constrArgs.length == 2 ? constrArgs : READ_CONSTR2);
constr.setAccessible(true);
return constr.newInstance(this, getDelegateImageReader());
}

@Override
public String getDescription(Locale locale) {
return "Lucee impl to handle OSGi enviroment";
Expand Down Expand Up @@ -835,30 +862,30 @@ public boolean canEncodeImage(ImageTypeSpecifier type) {

@Override
public ImageWriter createWriterInstance(Object extension) throws IOException {

try {
Constructor<? extends ImageWriter> constr;
Class<?>[] constrArgs = codec.writerConstructor;
Class<?>[] constrArgs = codec.writerConstructorArgs;

try {
constr = clazz.getDeclaredConstructor(constrArgs != null && constrArgs.length == 1 ? constrArgs : WRITE_CONSTR1);
constr.setAccessible(true);
return constr.newInstance(constrArgs != null && constrArgs.length == 1 ? null : this);
if (codec.writer == 0) return createWriterInstance0(constrArgs);
if (codec.writer == 1) return createWriterInstance1(constrArgs);
if (codec.writer == 2) return createWriterInstance2(constrArgs);

ImageWriter iw;
try {
iw = createWriterInstance1(constrArgs);
codec.writer = 1;
return iw;
}
catch (NoSuchMethodException nsme) {
nsme.printStackTrace();
try {
constr = clazz.getDeclaredConstructor(constrArgs != null && constrArgs.length == 2 ? constrArgs : WRITE_CONSTR2);
constr.setAccessible(true);
return constr.newInstance(constrArgs != null && constrArgs.length == 2 ? null : this, getDelegateImageWriter());
iw = createWriterInstance2(constrArgs);
codec.writer = 2;
return iw;

}
catch (NoSuchMethodException nsme2) {
nsme2.printStackTrace();
constr = clazz.getDeclaredConstructor(WRITE_CONSTR0);
constr.setAccessible(true);
return constr.newInstance();
iw = createWriterInstance0(constrArgs);
codec.writer = 3;
return iw;
}
}
}
Expand All @@ -867,6 +894,27 @@ public ImageWriter createWriterInstance(Object extension) throws IOException {
}
}

private ImageWriter createWriterInstance0(Class<?>[] constrArgs)
throws IOException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Constructor<? extends ImageWriter> constr = clazz.getDeclaredConstructor(WRITE_CONSTR0);
constr.setAccessible(true);
return constr.newInstance();
}

private ImageWriter createWriterInstance1(Class<?>[] constrArgs)
throws IOException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Constructor<? extends ImageWriter> constr = clazz.getDeclaredConstructor(constrArgs != null && constrArgs.length == 1 ? constrArgs : WRITE_CONSTR1);
constr.setAccessible(true);
return constr.newInstance(constrArgs != null && constrArgs.length == 1 ? null : this);
}

private ImageWriter createWriterInstance2(Class<?>[] constrArgs)
throws IOException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Constructor<? extends ImageWriter> constr = clazz.getDeclaredConstructor(constrArgs != null && constrArgs.length == 2 ? constrArgs : WRITE_CONSTR2);
constr.setAccessible(true);
return constr.newInstance(constrArgs != null && constrArgs.length == 2 ? null : this, getDelegateImageWriter());
}

@Override
public String getDescription(Locale locale) {
return "Lucee impl to handle OSGi enviroment";
Expand Down
30 changes: 19 additions & 11 deletions source/java/src/org/lucee/extension/image/coder/Coder.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,34 +24,42 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.lucee.extension.image.Image;
import org.lucee.extension.image.util.CommonUtil;

import lucee.commons.io.log.Log;
import lucee.commons.io.res.Resource;
import lucee.commons.lang.types.RefInteger;
import lucee.loader.engine.CFMLEngine;
import lucee.loader.engine.CFMLEngineFactory;
import lucee.runtime.PageContext;
import lucee.runtime.config.Config;
import lucee.runtime.type.Array;

public abstract class Coder {

private static Coder instance;
private static Map<Long, Coder> instances = new ConcurrentHashMap<>();

protected Coder() {
}

public static Coder getInstance(PageContext pc) {

if (true || instance == null) {
Config config = CFMLEngineFactory.getInstance().getThreadConfig();
Log log = config == null ? null : config.getLog("application");
CFMLEngine eng = CFMLEngineFactory.getInstance();

StringBuilder sb = new StringBuilder();
Set<String> coders = CommonUtil.getCoders(sb, pc);
long hash = eng.getStringUtil().create64BitHash(sb.toString());
Coder instance = instances.get(hash);

if (instance == null) {
Config config = eng.getThreadConfig();
Log log = config == null ? null : config.getLog("application");
MultiCoder mc = new MultiCoder();
Set<String> coders = CommonUtil.getCoders(pc);
if (coderAllowed(coders, "JDeli")) add(mc, "org.lucee.extension.image.coder.JDeliCoder", log);
if (coderAllowed(coders, "Gotson")) add(mc, "org.lucee.extension.image.coder.GotsonCoder", log);
if (coderAllowed(coders, "Aspose")) add(mc, "org.lucee.extension.image.coder.AsposeCoder", log);
Expand All @@ -60,8 +68,7 @@ public static Coder getInstance(PageContext pc) {
if (coderAllowed(coders, "Lucee")) add(mc, "org.lucee.extension.image.coder.LuceeCoder", log);
if (coderAllowed(coders, "ApacheImaging")) add(mc, "org.lucee.extension.image.coder.ApacheImagingCoder", log);
if (coderAllowed(coders, "JAI")) add(mc, "org.lucee.extension.image.coder.JAICoder", log);

instance = mc;
instances.put(hash, instance = mc);
}
return instance;
}
Expand All @@ -82,7 +89,6 @@ private static void add(MultiCoder mc, String className, Log log) {
}
catch (Exception e) {
if (log != null) log.error("image", e);
// else e.printStackTrace();
}
}

Expand All @@ -109,9 +115,11 @@ private static void add(MultiCoder mc, String className, Log log) {
public abstract void write(Image img, Resource destination, String format, float quality, boolean noMeta) throws IOException;

public static Log log() {
// FUTURE PageContext pc = CFMLEngineFactory.getInstance().getThreadPageContext();
// FUTURE if(pc!=null)pc.getLog("application");
Config config = CFMLEngineFactory.getInstance().getThreadConfig();
return log(null);
}

public static Log log(PageContext pc) {
Config config = pc != null ? pc.getConfig() : CFMLEngineFactory.getInstance().getThreadConfig();
if (config != null) return config.getLog("application");
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ public void write(Image img, Resource destination, String format, float quality,
write(img, destination, format, quality, noMeta, null);
}
catch (IOException e) {
e.printStackTrace();
throw e;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
package org.lucee.extension.image.coder;

import java.io.IOException;

import javax.imageio.ImageWriter;
import javax.imageio.spi.ImageWriterSpi;

import org.lucee.extension.image.util.print;

import com.twelvemonkeys.imageio.plugins.bmp.BMPImageReaderSpi;
import com.twelvemonkeys.imageio.plugins.bmp.BMPImageWriterSpi;
import com.twelvemonkeys.imageio.plugins.bmp.ICOImageReader;
Expand All @@ -25,15 +21,6 @@
public class TwelveMonkeysCoder extends AImageIOInterface {

public TwelveMonkeysCoder() {

try {
print.e(new WebPImageReaderSpi().createReaderInstance());
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Codec.newInstanceSpi(codecs, new String[] { "bmp", "BMP" }, new String[] { "bmp", "rle" }, new String[] { "image/bmp", "image/x-bmp", "image/vnd.microsoft.bitmap" },
BMPImageReaderSpi.class, BMPImageWriterSpi.class);
// Codec.newInstance(codecs, new String[] { "bmp", "BMP" }, new String[] { "bmp", "rle" }, new
Expand Down
15 changes: 10 additions & 5 deletions source/java/src/org/lucee/extension/image/util/CommonUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import javax.imageio.stream.ImageInputStream;

import org.lucee.extension.image.Image;
import org.lucee.extension.image.coder.Coder;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

Expand All @@ -33,6 +34,7 @@ public class CommonUtil {
private static final String _8220 = String.valueOf((char) 8220);

private static Map<Collection.Key, Coll> members;
private static BIF GetApplicationSettings;

public static String unwrap(String str) {
if (str == null) return "";
Expand Down Expand Up @@ -263,14 +265,16 @@ public static void close(ImageInputStream iis) {
}
}

public static Set<String> getCoders(PageContext pc) {
public static Set<String> getCoders(StringBuilder sb, PageContext pc) {
Set<String> result = null;
try {
CFMLEngine eng = CFMLEngineFactory.getInstance();
if (pc == null) pc = eng.getThreadPageContext();
if (pc == null) return null;
BIF bif = eng.getClassUtil().loadBIF(pc, "lucee.runtime.functions.system.GetApplicationSettings");
Struct sct = (Struct) bif.invoke(pc, new Object[] { Boolean.TRUE });
if (GetApplicationSettings == null) {
GetApplicationSettings = eng.getClassUtil().loadBIF(pc, "lucee.runtime.functions.system.GetApplicationSettings");
}
Struct sct = (Struct) GetApplicationSettings.invoke(pc, new Object[] { Boolean.TRUE });
Object o = sct.get("image", null);
if (o instanceof Struct) {
Struct image = (Struct) o;
Expand All @@ -283,13 +287,14 @@ public static Set<String> getCoders(PageContext pc) {
for (String c: coders) {
if (Util.isEmpty(c, true)) continue;
if (result == null) result = new HashSet<>();
result.add(c.trim().toLowerCase());
sb.append(c = c.trim().toLowerCase()).append(';');
result.add(c);
}
}
}
}
catch (Exception e) {
e.printStackTrace();
Coder.log(pc);
}

return result;
Expand Down
Loading

0 comments on commit 615c6e6

Please sign in to comment.