--- src/org/openstreetmap/josm/gui/layer/geoimage/ImageDisplay.java	2017-12-05 15:15:07.603502172 +0100
+++ src/org/openstreetmap/josm/gui/layer/geoimage/ImageDisplay.java	2017-12-05 15:14:30.419876659 +0100
@@ -24,10 +24,14 @@
 import java.awt.image.BufferedImage;
 import java.awt.image.ImageObserver;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
 
 import javax.swing.JComponent;
 import javax.swing.SwingUtilities;
 
+import org.libjpegturbo.turbojpeg.TJDecompressor;
+import org.libjpegturbo.turbojpeg.TJException;
 import org.openstreetmap.josm.data.preferences.BooleanProperty;
 import org.openstreetmap.josm.data.preferences.DoubleProperty;
 import org.openstreetmap.josm.spi.preferences.Config;
@@ -320,6 +324,64 @@
                 img = null;
             }
 
+            if (img == null && file.getPath().matches(".*\\.[jJ][pP][eE]?[gG]$")) {
+                TJDecompressor tjd = null;
+                FileInputStream fis = null;
+                try {
+                    tjd = new TJDecompressor();
+                    fis = new FileInputStream(file);
+
+                    Logging.info("Loading {0} ({1}x{2}) using turbojpeg", file.getPath(), width, height);
+                    final byte[] buf = new byte[(int) file.length()];
+                    int off = 0;
+                    while (fis.available() > 0) {
+                        off += fis.read(buf, off, Math.min(512*1024, buf.length-off));
+                        if (this.entry != ImageDisplay.this.entry)
+                            return;
+                    }
+                    tjd.setSourceImage(buf, buf.length);
+
+                    while (width > 0 && height > 0) {
+                        if (mayFitMemory(((long) width)*height*4*2)) {
+                            BufferedImage bi = new BufferedImage(
+                                    tjd.getScaledWidth(width, height),
+                                    tjd.getScaledHeight(width, height),
+                                    BufferedImage.TYPE_INT_RGB);
+                            if (this.entry != ImageDisplay.this.entry)
+                                return;
+                            try {
+                                tjd.decompress(bi, 0);
+                                width = bi.getWidth(null);
+                                height = bi.getHeight(null);
+                                img = bi;
+                                break;
+                            } catch (OutOfMemoryError oom) {
+                                bi = null;
+                            }
+                        }
+                        width = (width*4)/5;
+                        height = (height*4)/5;
+                    }
+                } catch (UnsatisfiedLinkError ule) {
+                    Logging.warn("turbojpeg not found in {0}", System.getProperty("java.library.path"));
+                } catch (TJException e) {
+                    Logging.warn("turbojpeg unusable or error decoding {0}", file.getPath());
+                } catch (IOException e) {
+                    Logging.warn("error reading file {0} for turbojpeg decoding", file.getPath());
+                } finally {
+                    try {
+                        if (tjd != null) {
+                            tjd.close();
+                        }
+                        if (fis != null) {
+                            fis.close();
+                        }
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+
             synchronized (ImageDisplay.this) {
                 if (this.entry != ImageDisplay.this.entry) {
                     // The file has changed
