fixing scaling images -> nullpointer, patch by yossarian
authorngu <ngu>
Sun, 27 May 2007 12:17:10 +0000 (12:17 +0000)
committerngu <ngu>
Sun, 27 May 2007 12:17:10 +0000 (12:17 +0000)
source/mir/media/image/ImageMagickImageProcessor.java
source/mir/media/image/ImageProcessor.java
source/mircoders/media/MediaHandlerImagesExtern.java
source/mircoders/media/MediaHandlerImagesExternScaling.java

index bb9a3dc..460f76f 100755 (executable)
-/*
- * Copyright (C) 2005 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Mir is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License.
- * You must obey the GNU General Public License in all respects for all of the code used
- * other than the above mentioned libraries.  If you modify this file, you may extend this
- * exception to your version of the file, but you are not obligated to do so.
- * If you do not wish to do so, delete this exception statement from your version.
- */
-package mir.media.image;
-
-import mir.log.LoggerWrapper;
-import mir.media.MediaExc;
-import mir.media.MediaFailure;
-import mir.util.StreamCopier;
-import mir.util.ShellRoutines;
-import mir.config.MirPropertiesConfiguration;
-
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.StringTokenizer;
-
-
-/**
- * Image processing by calling the ImageMagick command line progrmas
- * "convert" and "identify". The main task of this class is to scale
- * images. The path to ImageMagick commandline programs can be
- * specified in the coonfiguration file.
- *
- * @author <grok@no-log.org>, the Mir-coders group
- */
-public class ImageMagickImageProcessor implements ImageProcessor {
-  protected static MirPropertiesConfiguration configuration =
-      MirPropertiesConfiguration.instance();
-  static final LoggerWrapper logger =
-      new LoggerWrapper("media.image.imagemagick");
-
-  private ImageFile sourceImage;
-  private ImageFile scaledImage;
-
-  /**
-   * ImageFile  is a  thin  wrapper  around a  file  that contains  an
-   * image.  It uses  ImageMagick  to retreive  information about  the
-   * image. It  can also scale images using  ImageMagick. Intended for
-   * use in the ImageMagickImageProcessor class.
-   */
-  static class ImageFile {
-    /**
-     * path to the file represented by this class
-     */
-    File file;
-    /**
-     * whether the file must be deleted on cleanup
-     */
-    boolean fileIsTemp = false;
-    /**
-     * image information is stored here to avoid multiple costly calls to
-     * "identify"
-     */
-    int width;
-    int height;
-    int fileSize;
-    
-    /**
-     * Image type as returned by identify %m : "PNG", "GIF", ...
-     */
-    String type;
-    /**
-     * number of scenes in image >1 (typically animated gif)
-     */
-    boolean isAnimation;
-
-    /**
-     * Empty constructor automatically creates a temporary file
-     * that will later hold an image
-     */
-    ImageFile() throws IOException {
-      file = File.createTempFile("mirimage", "");
-      fileIsTemp = true;
-    }
-
-    /**
-     * if the file doesn't already have an image in it
-     * we don't want to read its information
-     */
-    ImageFile(File file, boolean doReadInfo) throws IOException {
-      this.file = file;
-      if (doReadInfo) {
-        readInfo();
-      }
-    }
-
-    ImageFile(File file) throws IOException {
-      this(file, true);
-    }
-
-    /**
-     * delete temporary files
-     */
-    public void cleanup() {
-      logger.debug("ImageFile.cleanup()");
-      if (fileIsTemp) {
-        logger.debug("deleting:" + file);
-        file.delete();
-        file = null;
-        fileIsTemp = false;
-      }
-    }
-
-    void debugOutput() {
-      logger.debug(" filename:" + file +
-          " Info:" +
-          " width:" + width +
-          " height:" + height +
-          " type:" + type +
-          " isAnimation:" + isAnimation);
-    }
-
-    private void checkFile() throws IOException {
-      if (file == null || !file.exists()) {
-        String message = "ImageFile.checkFile file \"" + file +
-            "\" does not exist";
-        logger.error(message);
-        throw new IOException(message);
-      }
-    }
-
-    /**
-     * Uses the imagemagick "identify" command to retreive image information
-     */
-    public void readInfo() throws IOException {
-      checkFile();
-      String infoString = ShellRoutines.execIntoString
-          (getImageMagickPath() +
-              "identify " + "-format \"%w %h %m %n %b \" " + 
-              file.getAbsolutePath()); // extra space, for multiframe (animations)              
-      StringTokenizer st = new StringTokenizer(infoString);
-      width = Integer.parseInt(st.nextToken());
-      height = Integer.parseInt(st.nextToken());
-      type = st.nextToken();
-      isAnimation = Integer.parseInt(st.nextToken()) > 1;
-      // yoss: different versions of ImageMagick produce different formatted output file sizes
-      // for example, Version: ImageMagick 6.2.4 (Ubuntu Dapper 6.06) produces a byte value, i.e. 67013
-      // Version: ImageMagick 6.0.6 (Debian Sarge) produces output like 67kb or 500mb.
-      // Trying to do an int.parse in Sarge fails for obvious reasons.
-      /*String sFileSize = st.nextToken();
-      if (sFileSize.endsWith("kb") || sFileSize.endsWith("Kb") || sFileSize.endsWith("KB") || sFileSize.endsWith("kB")){
-         sFileSize = sFileSize.substring(0, sFileSize.length() - 2);
-         fileSize = 1024 * Integer.parseInt(sFileSize);
-      } else if (sFileSize.endsWith("mb") || sFileSize.endsWith("Mb") || sFileSize.endsWith("MB") || sFileSize.endsWith("mB")){
-         sFileSize = sFileSize.substring(0, sFileSize.length() - 2);
-         fileSize = 1048576 * Integer.parseInt(sFileSize);       
-      } else {
-         fileSize = Integer.parseInt(sFileSize);
-      }*/
-      fileSize = (int)file.length();
-    }
-
-    public ImageFile scale(float aScalingFactor) throws IOException {
-      logger.debug("ImageFile.scale");
-      checkFile();
-      ImageFile result = new ImageFile();
-      String command = getImageMagickPath() + "convert " +
-          file.getAbsolutePath() + " " +
-          "-scale " +
-          Float.toString(aScalingFactor * 100) + "% " +
-          result.file.getAbsolutePath();
-      logger.debug("ImageFile.scale:command:" + command);
-      ShellRoutines.simpleExec(command);
-      result.readInfo();
-      return result;
-    }
-  }
-
-  public ImageMagickImageProcessor(InputStream inputImageStream)
-      throws IOException {
-    logger.debug("ImageMagickImageProcessor(stream)");
-    sourceImage = new ImageFile();
-    // copy stream into temporary file
-
-    FileOutputStream outputStream = new FileOutputStream(sourceImage.file);
-    try {
-      StreamCopier.copy(inputImageStream, outputStream);
-    }
-    finally {
-      outputStream.close();
-    }
-    sourceImage.readInfo();
-    sourceImage.debugOutput();
-  }
-
-
-  public ImageMagickImageProcessor(File aFile) throws IOException {
-    logger.debug("ImageMagickImageProcessor(file)");
-    sourceImage = new ImageFile(aFile);
-    sourceImage.debugOutput();
-  }
-
-  /**
-   * Deletes temporary files
-   */
-  public void cleanup() {
-    logger.debug("ImageMagickImageProcessor.cleanup()");
-    sourceImage.cleanup();
-    scaledImage.cleanup();
-  }
-
-  /**
-   * Path to ImageMagick commandline programs
-   */
-  private static String getImageMagickPath() {
-    String result = configuration.getString("Producer.Image.ImageMagickPath");
-    // we want the path to finish by "/", so add it if it's missing
-    if (result.length() != 0 && !result.endsWith("/")) {
-      result = result.concat("/");
-    }
-    logger.debug("getImageMagickPath:" + result);
-    return result;
-  }
-
-  public void descaleImage(int aMaxSize) throws MediaExc {
-    descaleImage(aMaxSize, 0);
-  }
-
-  public void descaleImage(int aMaxSize, float aMinDescale) throws MediaExc {
-    descaleImage(aMaxSize, aMaxSize, aMinDescale, 0);
-  }
-
-  public void descaleImage(int aMaxSize, int aMinResize) throws MediaExc {
-    descaleImage(aMaxSize, aMaxSize, 0, aMinResize);
-  }
-
-  public void descaleImage(int aMaxSize, float aMinDescale, int aMinResize)
-      throws MediaExc {
-    descaleImage(aMaxSize, aMaxSize, aMinDescale, aMinResize);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  public void descaleImage(int aMaxWidth, int aMaxHeight,
-                           float aMinDescale, int aMinResize) throws MediaExc {
-    float scale;
-    logger.debug("descaleImage:" +
-        "  aMaxWidth:" + aMaxWidth +
-        ", aMaxHeight:" + aMaxHeight +
-        ", aMinDescale:" + aMinDescale +
-        ", aMinResize:" + aMinResize);
-    if ((aMaxWidth > 0 && getWidth() > aMaxWidth + aMinResize - 1) ||
-        (aMaxHeight > 0 && getHeight() > aMaxHeight + aMinResize - 1)) {
-      logger.debug("descaleImage: image needs scaling");
-
-      scale = 1;
-
-      if (aMaxWidth > 0 && getWidth() > aMaxWidth) {
-        scale = Math.min(scale, (float) aMaxWidth / (float) getWidth());
-      }
-      if (aMaxHeight > 0 && getHeight() > aMaxHeight) {
-        scale = Math.min(scale, (float) aMaxHeight / (float) getHeight());
-      }
-
-      if (1 - scale > aMinDescale) {
-        scaleImage(scale);
-
-        return;
-      }
-    }
-    logger.debug("descaleImage: image size is ok, not scaling image");
-    try {
-      scaledImage = new ImageFile(sourceImage.file);
-    }
-    catch (IOException e) {
-      throw new MediaExc(e.toString());
-    }
-  }
-
-
-  /**
-   * Scales image by a factor using the convert ImageMagick command
-   */
-  public void scaleImage(float aScalingFactor)
-      throws MediaExc {
-    logger.debug("scaleImage:" + aScalingFactor);
-    try {
-      // first cleanup previous temp scaledimage file if necesary
-      if (scaledImage != null) {
-        scaledImage.cleanup();
-      }
-      // now create temp file and execute convert
-      scaledImage = sourceImage.scale(aScalingFactor);
-    }
-    catch (Exception e) {
-      throw new MediaExc(e.toString());
-    }
-    logger.debug(" scaledImage:");
-    scaledImage.debugOutput();
-  }
-
-  public int getWidth() {
-    return sourceImage.width;
-  }
-
-  public int getHeight() {
-    return sourceImage.height;
-  }
-  
-  public int getSourceFileSize() {
-         return sourceImage.fileSize;
-  }
-  
-  public int getScaledFileSize() {
-         return scaledImage.fileSize;
-  }
-
-  public int getScaledWidth() {
-    return scaledImage.width;
-  }
-
-  public int getScaledHeight() {
-    return scaledImage.height;
-  }
-
-  public void writeScaledData(OutputStream aStream, String anImageType)
-      throws MediaExc {
-    // we can't asume that requested "anImageType" is the same as the
-    // scaled image type, so we have to convert 
-    try {
-      // if image is an animation and target type doesn't support
-      // animations, then just use first frame
-      String frame = "";
-      scaledImage.debugOutput();
-      if (scaledImage.isAnimation && !anImageType.equals("GIF")) {
-        frame = "[0]";
-      }
-      // ImageMagick "convert" into temp file
-      File temp = File.createTempFile("mirimage", "");
-      String command = getImageMagickPath() + "convert " +
-          scaledImage.file.getAbsolutePath() + frame + " " +
-          anImageType + ":" + temp.getAbsolutePath();
-      logger.debug("writeScaledData command:" + command);
-      ShellRoutines.simpleExec(command);
-      // copy temp file into stream
-      StreamCopier.copy(new FileInputStream(temp), aStream);
-      temp.delete();
-    }
-    catch (Exception e) {
-      throw new MediaExc(e.toString());
-    }
-  }
-
-  public byte[] getScaledData(String anImageType) throws MediaExc {
-    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-    writeScaledData(outputStream, anImageType);
-    return outputStream.toByteArray();
-  }
-
-  public void writeScaledData(File aFile, String anImageType) throws MediaExc {
-    try {
-      OutputStream stream = new BufferedOutputStream(new FileOutputStream(aFile), 8192);
-
-      try {
-        writeScaledData(stream, anImageType);
-      }
-      finally {
-        try {
-          stream.close();
-        }
-        catch (Throwable t) {
-               logger.debug("Unable to close stream when writing scaled data.");
-        }
-      }
-    }
-    catch (FileNotFoundException f) {
-      throw new MediaFailure(f);
-    }
-    catch (Exception e) {
-       logger.debug("Exception caught while trying to write scaled data: " + e.toString());
-    }
-  }
-}
+/*\r
+ * Copyright (C) 2005 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License.\r
+ * You must obey the GNU General Public License in all respects for all of the code used\r
+ * other than the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+package mir.media.image;\r
+\r
+import mir.config.MirPropertiesConfiguration;\r
+import mir.log.LoggerWrapper;\r
+import mir.media.MediaExc;\r
+import mir.util.ShellRoutines;\r
+import mir.util.StreamCopier;\r
+\r
+import java.io.BufferedOutputStream;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileNotFoundException;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+import java.util.StringTokenizer;\r
+\r
+\r
+/**\r
+ * Image processing by calling the ImageMagick command line progrmas\r
+ * "convert" and "identify". The main task of this class is to scale\r
+ * images. The path to ImageMagick commandline programs can be\r
+ * specified in the configuration file.\r
+ *\r
+ * @author <grok@no-log.org>, the Mir-coders group\r
+ */\r
+public class ImageMagickImageProcessor implements ImageProcessor {\r
+  protected static MirPropertiesConfiguration configuration =\r
+      MirPropertiesConfiguration.instance();\r
+  static final LoggerWrapper logger =\r
+      new LoggerWrapper("media.image.imagemagick");\r
+\r
+  private ImageFile sourceImage;\r
+  private ImageFile scaledImage;\r
+\r
+  public ImageMagickImageProcessor(InputStream inputImageStream)\r
+      throws IOException {\r
+    logger.debug("ImageMagickImageProcessor(stream)");\r
+    sourceImage = new ImageFile();\r
+    // copy stream into temporary file\r
+\r
+    FileOutputStream outputStream = new FileOutputStream(sourceImage.file);\r
+    try {\r
+      StreamCopier.copy(inputImageStream, outputStream);\r
+    }\r
+    finally {\r
+      outputStream.close();\r
+    }\r
+    sourceImage.readInfo();\r
+    sourceImage.debugOutput();\r
+  }\r
+\r
+\r
+  public ImageMagickImageProcessor(File aFile) throws IOException {\r
+    logger.debug("ImageMagickImageProcessor(file)");\r
+    sourceImage = new ImageFile(aFile);\r
+    sourceImage.debugOutput();\r
+  }\r
+\r
+  /**\r
+   * Deletes temporary files\r
+   */\r
+  public void cleanup() {\r
+    logger.debug("ImageMagickImageProcessor.cleanup()");\r
+    sourceImage.cleanup();\r
+    scaledImage.cleanup();\r
+  }\r
+\r
+  /**\r
+   * Path to ImageMagick commandline programs\r
+   */\r
+  private static String getImageMagickPath() {\r
+    String result = configuration.getString("Producer.Image.ImageMagickPath");\r
+    // we want the path to finish by "/", so add it if it's missing\r
+    if (result.length() != 0 && !result.endsWith("/")) {\r
+      result = result.concat("/");\r
+    }\r
+    logger.debug("getImageMagickPath:" + result);\r
+    return result;\r
+  }\r
+\r
+  public void descaleImage(int aMaxSize) throws MediaExc {\r
+    descaleImage(aMaxSize, 0);\r
+  }\r
+\r
+  public void descaleImage(int aMaxSize, float aMinDescale) throws MediaExc {\r
+    descaleImage(aMaxSize, aMaxSize, aMinDescale, 0);\r
+  }\r
+\r
+  public void descaleImage(int aMaxSize, int aMinResize) throws MediaExc {\r
+    descaleImage(aMaxSize, aMaxSize, 0, aMinResize);\r
+  }\r
+\r
+  public void descaleImage(int aMaxSize, float aMinDescale, int aMinResize)\r
+      throws MediaExc {\r
+    descaleImage(aMaxSize, aMaxSize, aMinDescale, aMinResize);\r
+  }\r
+\r
+  /**\r
+   * {@inheritDoc}\r
+   */\r
+  public void descaleImage(int aMaxWidth, int aMaxHeight,\r
+                           float aMinDescale, int aMinResize) throws MediaExc {\r
+    float scale;\r
+    logger.debug("descaleImage:" +\r
+        "  aMaxWidth:" + aMaxWidth +\r
+        ", aMaxHeight:" + aMaxHeight +\r
+        ", aMinDescale:" + aMinDescale +\r
+        ", aMinResize:" + aMinResize);\r
+    if ((aMaxWidth > 0 && getWidth() > aMaxWidth + aMinResize - 1) ||\r
+        (aMaxHeight > 0 && getHeight() > aMaxHeight + aMinResize - 1)) {\r
+      logger.debug("descaleImage: image needs scaling");\r
+\r
+      scale = 1;\r
+\r
+      if (aMaxWidth > 0 && getWidth() > aMaxWidth) {\r
+        scale = Math.min(scale, (float) aMaxWidth / (float) getWidth());\r
+      }\r
+      if (aMaxHeight > 0 && getHeight() > aMaxHeight) {\r
+        scale = Math.min(scale, (float) aMaxHeight / (float) getHeight());\r
+      }\r
+\r
+      if (1 - scale > aMinDescale) {\r
+        scaleImage(scale);\r
+\r
+        return;\r
+      }\r
+    }\r
+\r
+    // the image didn't need to be scaled: scaledImage = original image\r
+    try {\r
+      scaledImage = new ImageFile(sourceImage.file);\r
+    }\r
+    catch (IOException e) {\r
+      throw new MediaExc(e.toString());\r
+    }\r
+\r
+  }\r
+\r
+\r
+  /**\r
+   * Scales image by a factor using the convert ImageMagick command\r
+   */\r
+  public void scaleImage(float aScalingFactor) throws MediaExc {\r
+    logger.debug("scaleImage:" + aScalingFactor);\r
+    try {\r
+      // first cleanup previous temp scaledimage file if necesary\r
+      if (scaledImage != null) {\r
+        scaledImage.cleanup();\r
+      }\r
+      // now create temp file and execute convert\r
+      scaledImage = sourceImage.scale(aScalingFactor);\r
+    }\r
+    catch (Exception e) {\r
+      throw new MediaExc(e.toString());\r
+    }\r
+    logger.debug(" scaledImage:");\r
+    scaledImage.debugOutput();\r
+  }\r
+\r
+  public int getWidth() {\r
+    return sourceImage.width;\r
+  }\r
+\r
+  public int getHeight() {\r
+    return sourceImage.height;\r
+  }\r
+\r
+  public int getScaledWidth() {\r
+    return scaledImage.width;\r
+  }\r
+\r
+  public int getScaledHeight() {\r
+    return scaledImage.height;\r
+  }\r
+  \r
+  public int getScaledFileSize() {\r
+         return scaledImage.fileSize;\r
+  }\r
+\r
+  public void writeScaledData(OutputStream aStream, String anImageType) throws MediaExc, IOException {\r
+    // we can't asume that requested "anImageType" is the same as the\r
+    // scaled image type, so we have to convert \r
+    // if image is an animation and target type doesn't support\r
+    // animations, then just use first frame\r
+    String frame = "";\r
+    scaledImage.debugOutput();\r
+\r
+    if (scaledImage.isAnimation && !anImageType.equals("GIF")) {\r
+      frame = "[0]";\r
+    }\r
+    // ImageMagick "convert" into temp file\r
+    File temp = File.createTempFile("mirimage", "");\r
+    String command = getImageMagickPath() + "convert " +\r
+        scaledImage.file.getAbsolutePath() + frame + " " +\r
+        anImageType + ":" + temp.getAbsolutePath();\r
+    logger.debug("writeScaledData command:" + command);\r
+    ShellRoutines.simpleExec(command);\r
+    // copy temp file into stream\r
+    StreamCopier.copy(new FileInputStream(temp), aStream);\r
+    temp.delete();\r
+  }\r
+\r
+  public void writeScaledData(File aFile, String anImageType) throws MediaExc, IOException, FileNotFoundException {\r
+    OutputStream stream = new BufferedOutputStream(new FileOutputStream(aFile), 8192);\r
+\r
+    try {\r
+      writeScaledData(stream, anImageType);\r
+    }\r
+    finally {\r
+      try {\r
+        stream.close();\r
+      }\r
+      catch (Throwable t) {\r
+      }\r
+    }\r
+  }\r
+\r
+  /**\r
+   * ImageFile  is a  thin  wrapper  around a  file  that contains  an\r
+   * image.  It uses  ImageMagick  to retreive  information about  the\r
+   * image. It  can also scale images using  ImageMagick. Intended for\r
+   * use in the ImageMagickImageProcessor class.\r
+   */\r
+  static class ImageFile {\r
+    /**\r
+     * path to the file represented by this class\r
+     */\r
+    File file;\r
+    /**\r
+     * whether the file must be deleted on cleanup\r
+     */\r
+    boolean fileIsTemp = false;\r
+    /**\r
+     * image information is stored here to avoid multiple costly calls to\r
+     * "identify"\r
+     */\r
+    int width;\r
+    int height;\r
+    int fileSize;\r
+    \r
+    /**\r
+     * Image type as returned by identify %m : "PNG", "GIF", ...\r
+     */\r
+    String type;\r
+    /**\r
+     * number of scenes in image >1 (typically animated gif)\r
+     */\r
+    boolean isAnimation;\r
+\r
+    /**\r
+     * Empty constructor automatically creates a temporary file\r
+     * that will later hold an image\r
+     */\r
+    ImageFile() throws IOException {\r
+      file = File.createTempFile("mirimage", "");\r
+      fileIsTemp = true;\r
+    }\r
+\r
+    /**\r
+     * if the file doesn't already have an image in it\r
+     * we don't want to read its information\r
+     */\r
+    ImageFile(File file, boolean doReadInfo) throws IOException {\r
+      this.file = file;\r
+      if (doReadInfo) {\r
+        readInfo();\r
+      }\r
+    }\r
+\r
+    ImageFile(File file) throws IOException {\r
+      this(file, true);\r
+    }\r
+\r
+    /**\r
+     * delete temporary files\r
+     */\r
+    public void cleanup() {\r
+      logger.debug("ImageFile.cleanup()");\r
+      if (fileIsTemp) {\r
+        logger.debug("deleting:" + file);\r
+        file.delete();\r
+        file = null;\r
+        fileIsTemp = false;\r
+      }\r
+    }\r
+\r
+    void debugOutput() {\r
+      logger.debug(" filename:" + file +\r
+          " Info:" +\r
+          " width:" + width +\r
+          " height:" + height +\r
+          " type:" + type +\r
+          " isAnimation:" + isAnimation);\r
+    }\r
+\r
+    private void checkFile() throws IOException {\r
+      if (file == null || !file.exists()) {\r
+        String message = "ImageFile.checkFile file \"" + file +\r
+            "\" does not exist";\r
+        logger.error(message);\r
+        throw new IOException(message);\r
+      }\r
+    }\r
+\r
+    /**\r
+     * Uses the imagemagick "identify" command to retreive image information\r
+     */\r
+    public void readInfo() throws IOException {\r
+      checkFile();\r
+      String infoString = ShellRoutines.execIntoString\r
+          (getImageMagickPath() +\r
+              "identify " + "-format \"%w %h %m %n \" " +\r
+              file.getAbsolutePath()); // extra space, for multiframe (animations)\r
+      StringTokenizer st = new StringTokenizer(infoString);\r
+      width = Integer.parseInt(st.nextToken());\r
+      height = Integer.parseInt(st.nextToken());\r
+      type = st.nextToken();\r
+      isAnimation = Integer.parseInt(st.nextToken()) > 1;\r
+      fileSize = (int)file.length();\r
+    }\r
+\r
+    public ImageFile scale(float aScalingFactor) throws IOException {\r
+      logger.debug("ImageFile.scale");\r
+\r
+      checkFile();\r
+      ImageFile result = new ImageFile();\r
+      String command = getImageMagickPath() + "convert " +\r
+          file.getAbsolutePath() + " " +\r
+          "-scale " +\r
+          Float.toString(aScalingFactor * 100) + "% " +\r
+          result.file.getAbsolutePath();\r
+      logger.debug("ImageFile.scale:command:" + command);\r
+      ShellRoutines.simpleExec(command);\r
+      result.readInfo();\r
+\r
+      return result;\r
+    }\r
+  }\r
+}
\ No newline at end of file
index 7ed0983..2879d54 100755 (executable)
@@ -1,87 +1,85 @@
-/*
- * Copyright (C) 2005 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Mir is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License.
- * You must obey the GNU General Public License in all respects for all of the code used
- * other than the above mentioned libraries.  If you modify this file, you may extend this
- * exception to your version of the file, but you are not obligated to do so.
- * If you do not wish to do so, delete this exception statement from your version.
- */
-package mir.media.image;
-
-import mir.media.MediaExc;
-
-import java.io.File;
-import java.io.OutputStream;
-
-public interface ImageProcessor {
-  public void descaleImage(int aMaxSize) throws MediaExc;
-
-  public void descaleImage(int aMaxSize, float aMinDescale) throws MediaExc;
-
-  public void descaleImage(int aMaxSize, int aMinResize) throws MediaExc;
-
-  public void descaleImage(int aMaxSize, float aMinDescale, int aMinResize) throws MediaExc;
-
-  /**
-   * Resizes an image to fit inside <code>aMaxWidth</code> and <code>aMaxHeight</code>, provided
-   *    this requires at least <code>aMinResize</code> pixels will be removed from either the width or
-   *    the height
-   */
-  public void descaleImage(int aMaxWidth, int aMaxHeight, float aMinDescale, int aMinResize) throws MediaExc;
-
-  public void scaleImage(float aScalingFactor) throws MediaExc;
-
-  public int getWidth();
-  public int getHeight();
-  public int getSourceFileSize();
-  public int getScaledFileSize();
-  public int getScaledWidth();
-  public int getScaledHeight();
-  public void writeScaledData(OutputStream aStream, String anImageType) 
-    throws MediaExc;
-  public byte[] getScaledData(String anImageType) throws MediaExc;
-  public void writeScaledData(File aFile, String anImageType) throws MediaExc;
-
-  /**
-   * call this when you're over using this object (removes temp files)
-   */
-  public void cleanup();
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*\r
+ * Copyright (C) 2005 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License.\r
+ * You must obey the GNU General Public License in all respects for all of the code used\r
+ * other than the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+package mir.media.image;\r
+\r
+import mir.media.MediaExc;\r
+\r
+import java.io.File;\r
+import java.io.OutputStream;\r
+import java.io.FileNotFoundException;\r
+import java.io.IOException;\r
+\r
+public interface ImageProcessor {\r
+  void descaleImage(int aMaxSize) throws MediaExc;\r
+\r
+  void descaleImage(int aMaxSize, float aMinDescale) throws MediaExc;\r
+\r
+  void descaleImage(int aMaxSize, int aMinResize) throws MediaExc;\r
+\r
+  void descaleImage(int aMaxSize, float aMinDescale, int aMinResize) throws MediaExc;\r
+\r
+  /**\r
+   * Resizes an image to fit inside <code>aMaxWidth</code> and <code>aMaxHeight</code>, provided\r
+   *    this requires at least <code>aMinResize</code> pixels will be removed from either the width or\r
+   *    the height\r
+   */\r
+  void descaleImage(int aMaxWidth, int aMaxHeight, float aMinDescale, int aMinResize) throws MediaExc;\r
+\r
+  void scaleImage(float aScalingFactor) throws MediaExc;\r
+\r
+  int getWidth();\r
+  int getHeight();\r
+  int getScaledFileSize();\r
+  int getScaledWidth();\r
+  int getScaledHeight();\r
+  void writeScaledData(OutputStream aStream, String anImageType) throws MediaExc, IOException;\r
+  void writeScaledData(File aFile, String anImageType) throws MediaExc, IOException, FileNotFoundException;\r
+\r
+  /**\r
+   * call this when you're over using this object (removes temp files)\r
+   */\r
+  void cleanup();\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
index bb00c94..61f6017 100755 (executable)
-/*
- * Copyright (C) 2001, 2002 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Mir is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License,
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
- * (or with modified versions of the above that use the same license as the above),
- * and distribute linked combinations including the two.  You must obey the
- * GNU General Public License in all respects for all of the code used other than
- * the above mentioned libraries.  If you modify this file, you may extend this
- * exception to your version of the file, but you are not obligated to do so.
- * If you do not wish to do so, delete this exception statement from your version.
- */
-package mircoders.media;
-
-
-import mir.entity.Entity;
-import mir.log.LoggerWrapper;
-import mir.media.MediaExc;
-import mir.media.MediaFailure;
-import mir.media.image.ImageMagickImageProcessor;
-import mir.media.image.ImageProcessor;
-import mir.misc.StringUtil;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Image handler that stores images outside of the database.
- * 
- * @author Zapata
- * @version 1.0
- */
-
-public class MediaHandlerImagesExtern extends MediaHandlerGeneric {
-  private int maxIconSize;
-  private float minDescaleRatio;
-  private int minDescaleReduction;
-
-  public MediaHandlerImagesExtern() {
-
-    logger = new LoggerWrapper("Media.Images.Extern");
-
-    maxIconSize = configuration.getInt("Producer.Image.MaxIconSize");
-    minDescaleRatio = configuration.getFloat("Producer.Image.MinDescalePercentage")/100;
-    minDescaleReduction = configuration.getInt("Producer.Image.MinDescaleReduction");
-  }
-
-  public void produce(Entity anImageEntity, Entity aMediaTypeEntity) throws MediaExc, MediaFailure {
-      String date = anImageEntity.getFieldValue("date");
-      String datePath = StringUtil.webdbDate2path(date);
-      String ext = "." + aMediaTypeEntity.getFieldValue("name");
-      String fileBasePath = datePath + anImageEntity.getId();
-      String filePath = fileBasePath + ext;
-      String iconPath = getBaseIconStoragePath() + fileBasePath + ".jpg";
-      String iconStoragePath = configuration.getString("Producer.StorageRoot") + iconPath;
-      String imageFilePath = getBaseStoragePath() + File.separator + filePath;
-
-      File imageFile = new File(imageFilePath);
-      File iconFile = new File(iconStoragePath);
-
-      if (!imageFile.exists()) {
-        throw new MediaExc("error in MediaHandlerImagesExtern.execute(): " + filePath + " does not exist!");
-      }
-      else {
-        ImageProcessor processor;
-        try {
-          processor = new ImageMagickImageProcessor(imageFile);
-        }
-        catch (IOException e) {
-          throw new MediaFailure(e);
-        }
-
-        processor.descaleImage(maxIconSize, minDescaleRatio, minDescaleReduction);
-        File dir = new File(iconFile.getParent());
-        if (dir!=null && !dir.exists()){
-          dir.mkdirs();
-        }
-        processor.writeScaledData(iconFile, "JPEG");
-
-        anImageEntity.setFieldValue("img_height",
-            Integer.toString(processor.getHeight()));
-        anImageEntity.setFieldValue("img_width",
-            Integer.toString(processor.getWidth()));
-
-        anImageEntity.setFieldValue("icon_height",
-            Integer.toString(processor.getScaledHeight()));
-        anImageEntity.setFieldValue("icon_width",
-            Integer.toString(processor.getScaledWidth()));
-
-        processor.cleanup();
-        anImageEntity.setFieldValue("icon_path", iconPath);
-        anImageEntity.setFieldValue("publish_path", filePath);
-
-        anImageEntity.update();
-        reportChange(iconStoragePath);
-        reportChange(imageFilePath);
-      }
-  }
-
-
-  /** {@inheritDoc} */
-  public InputStream getThumbnail(Entity anImageEntity) throws MediaExc, MediaFailure {
-    try {
-      File file = new File(configuration.getString("Producer.StorageRoot") + anImageEntity.getFieldValue("icon_path"));
-
-      if (!file.exists()) {
-        // hackish
-        file = new File(configuration.getHome(), "../img/photo_big.gif");
-      }
-
-      return new BufferedInputStream(
-        new FileInputStream(file),8192);
-    }
-    catch (Throwable t) {
-      return null;
-    }
-  }
-
-  public String getIconMimeType(Entity anImageEntity, Entity aMediaType) {
-    return "image/jpeg";
-  }
-
-  public String getBaseStoragePath()
-  {
-    return configuration.getString("Producer.Image.Path");
-  }
-
-  public String getBaseIconStoragePath()
-  {
-    return configuration.getString("Producer.Image.IconPath");
-  }
-
-  public String getPublishHost()
-  {
-    return StringUtil.removeSlash(configuration.getString("Producer.Image.Host"));
-  }
-
-  public String getTinyIconName()
-  {
-    return configuration.getString("Producer.Icon.TinyImage");
-  }
-
-  public String getBigIconName()
-  {
-    return configuration.getString("Producer.Icon.BigImage");
-  }
-
-  public String getIconAltName()
-  {
-    return "Image";
-  }
-
-  public String getDescr(Entity mediaType)
-  {
-     return "image/jpeg";
-  }
-}
+/*\r
+ * Copyright (C) 2001, 2002 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License,\r
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
+ * (or with modified versions of the above that use the same license as the above),\r
+ * and distribute linked combinations including the two.  You must obey the\r
+ * GNU General Public License in all respects for all of the code used other than\r
+ * the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+package mircoders.media;\r
+\r
+\r
+import mir.entity.Entity;\r
+import mir.log.LoggerWrapper;\r
+import mir.media.MediaExc;\r
+import mir.media.MediaFailure;\r
+import mir.media.image.ImageMagickImageProcessor;\r
+import mir.media.image.ImageProcessor;\r
+import mir.misc.StringUtil;\r
+\r
+import java.io.BufferedInputStream;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileNotFoundException;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+\r
+/**\r
+ * Image handler that stores images outside of the database.\r
+ * \r
+ * @author Zapata\r
+ * @version 1.0\r
+ */\r
+\r
+public class MediaHandlerImagesExtern extends MediaHandlerGeneric {\r
+  private int maxIconSize;\r
+  private float minDescaleRatio;\r
+  private int minDescaleReduction;\r
+\r
+  public MediaHandlerImagesExtern() {\r
+\r
+    logger = new LoggerWrapper("Media.Images.Extern");\r
+\r
+    maxIconSize = configuration.getInt("Producer.Image.MaxIconSize");\r
+    minDescaleRatio = configuration.getFloat("Producer.Image.MinDescalePercentage")/100;\r
+    minDescaleReduction = configuration.getInt("Producer.Image.MinDescaleReduction");\r
+  }\r
+\r
+  public void produce(Entity anImageEntity, Entity aMediaTypeEntity) throws MediaExc, MediaFailure {\r
+      String date = anImageEntity.getFieldValue("date");\r
+      String datePath = StringUtil.webdbDate2path(date);\r
+      String ext = "." + aMediaTypeEntity.getFieldValue("name");\r
+      String fileBasePath = datePath + anImageEntity.getId();\r
+      String filePath = fileBasePath + ext;\r
+      String iconPath = getBaseIconStoragePath() + fileBasePath + ".jpg";\r
+      String iconStoragePath = configuration.getString("Producer.StorageRoot") + iconPath;\r
+      String imageFilePath = getBaseStoragePath() + File.separator + filePath;\r
+\r
+      File imageFile = new File(imageFilePath);\r
+      File iconFile = new File(iconStoragePath);\r
+\r
+      if (!imageFile.exists()) {\r
+        throw new MediaExc("error in MediaHandlerImagesExtern.execute(): " + filePath + " does not exist!");\r
+      }\r
+      else {\r
+        ImageProcessor processor;\r
+        try {\r
+          processor = new ImageMagickImageProcessor(imageFile);\r
+        }\r
+        catch (IOException e) {\r
+          throw new MediaFailure(e);\r
+        }\r
+\r
+        processor.descaleImage(maxIconSize, minDescaleRatio, minDescaleReduction);\r
+        File dir = new File(iconFile.getParent());\r
+        if (dir!=null && !dir.exists()){\r
+          dir.mkdirs();\r
+        }\r
+               try {\r
+                       processor.writeScaledData(iconFile, "JPEG");\r
+               } catch (FileNotFoundException e) {\r
+                       // TODO Auto-generated catch block\r
+                       e.printStackTrace();\r
+               } catch (IOException e) {\r
+                       // TODO Auto-generated catch block\r
+                       e.printStackTrace();\r
+               }\r
+\r
+\r
+        anImageEntity.setFieldValue("img_height",\r
+            Integer.toString(processor.getHeight()));\r
+        anImageEntity.setFieldValue("img_width",\r
+            Integer.toString(processor.getWidth()));\r
+\r
+        anImageEntity.setFieldValue("icon_height",\r
+            Integer.toString(processor.getScaledHeight()));\r
+        anImageEntity.setFieldValue("icon_width",\r
+            Integer.toString(processor.getScaledWidth()));\r
+\r
+        processor.cleanup();\r
+        anImageEntity.setFieldValue("icon_path", iconPath);\r
+        anImageEntity.setFieldValue("publish_path", filePath);\r
+\r
+        anImageEntity.update();\r
+        reportChange(iconStoragePath);\r
+        reportChange(imageFilePath);\r
+      }\r
+  }\r
+\r
+\r
+  /** {@inheritDoc} */\r
+  public InputStream getThumbnail(Entity anImageEntity) throws MediaExc, MediaFailure {\r
+    try {\r
+      File file = new File(configuration.getString("Producer.StorageRoot") + anImageEntity.getFieldValue("icon_path"));\r
+\r
+      if (!file.exists()) {\r
+        // hackish\r
+        file = new File(configuration.getHome(), "../img/photo_big.gif");\r
+      }\r
+\r
+      return new BufferedInputStream(\r
+        new FileInputStream(file),8192);\r
+    }\r
+    catch (Throwable t) {\r
+      return null;\r
+    }\r
+  }\r
+\r
+  public String getIconMimeType(Entity anImageEntity, Entity aMediaType) {\r
+    return "image/jpeg";\r
+  }\r
+\r
+  public String getBaseStoragePath()\r
+  {\r
+    return configuration.getString("Producer.Image.Path");\r
+  }\r
+\r
+  public String getBaseIconStoragePath()\r
+  {\r
+    return configuration.getString("Producer.Image.IconPath");\r
+  }\r
+\r
+  public String getPublishHost()\r
+  {\r
+    return StringUtil.removeSlash(configuration.getString("Producer.Image.Host"));\r
+  }\r
+\r
+  public String getTinyIconName()\r
+  {\r
+    return configuration.getString("Producer.Icon.TinyImage");\r
+  }\r
+\r
+  public String getBigIconName()\r
+  {\r
+    return configuration.getString("Producer.Icon.BigImage");\r
+  }\r
+\r
+  public String getIconAltName()\r
+  {\r
+    return "Image";\r
+  }\r
+\r
+  public String getDescr(Entity mediaType)\r
+  {\r
+     return "image/jpeg";\r
+  }\r
+}\r
index 5b48ec2..1afa019 100644 (file)
-/*
- * Copyright (C) 2001, 2002 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Mir is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License,
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
- * (or with modified versions of the above that use the same license as the above),
- * and distribute linked combinations including the two.  You must obey the
- * GNU General Public License in all respects for all of the code used other than
- * the above mentioned libraries.  If you modify this file, you may extend this
- * exception to your version of the file, but you are not obligated to do so.
- * If you do not wish to do so, delete this exception statement from your version.
- */
-package mircoders.media;
-
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import mir.entity.Entity;
-import mir.log.LoggerWrapper;
-import mir.media.MediaExc;
-import mir.media.MediaFailure;
-import mir.media.image.ImageMagickImageProcessor;
-import mir.media.image.ImageProcessor;
-import mir.misc.StringUtil;
-import mir.util.FileRoutines;
-
-/**
- * Image handler that stores images outside of the database.
- * 
- * @author Zapata
- * @version 1.0
- */
-
-public class MediaHandlerImagesExternScaling extends MediaHandlerGeneric
-{
-  private int maxSize;
-  private int maxIconSize;
-  private float minDescaleRatio;
-  private int minDescaleReduction;
-  public MediaHandlerImagesExternScaling() {
-    logger = new LoggerWrapper("Media.Images.Extern");
-    maxSize = configuration.getInt("Producer.Image.MaxSize");
-    maxIconSize = configuration.getInt("Producer.Image.MaxIconSize");
-    minDescaleRatio = configuration.getFloat("Producer.Image.MinDescalePercentage")/100;
-    minDescaleReduction = configuration.getInt("Producer.Image.MinDescaleReduction");
-  }
-  
-
-  
-  public void produce(Entity anImageEntity, Entity mediaTypeEnt) throws MediaExc, MediaFailure {
-    try {
-      String date = anImageEntity.getFieldValue("date");
-      String datePath = StringUtil.webdbDate2path(date);
-      String ext = "." + mediaTypeEnt.getFieldValue("name");
-      String fileBasePath = datePath + anImageEntity.getId();
-      String filePath = fileBasePath + ext;
-
-      String imageFilePath = getBaseStoragePath() + File.separator + filePath;
-      File imageFile = new File(imageFilePath);
-      
-      if (!imageFile.exists()) {
-        throw new MediaExc("error in MediaHandlerImagesExtern.execute(): "
-            + filePath + " does not exist!");
-      } else {
-        ImageProcessor processor = new ImageMagickImageProcessor(imageFile);
-        String iconPath = getBaseIconStoragePath() + fileBasePath + ".jpg";
-        String iconStoragePath = doIconScaling(processor, iconPath);
-        anImageEntity.setFieldValue("icon_height", new Integer(processor.getScaledHeight()).toString());
-        anImageEntity.setFieldValue("icon_width", new Integer(processor.getScaledWidth()).toString());
-        anImageEntity.setFieldValue("icon_path", iconPath);
-        
-        String imageOriginalRelPath = doImageScaling(filePath, imageFile, processor);
-        anImageEntity.setFieldValue("original_file_path", imageOriginalRelPath);
-        anImageEntity.setFieldValue("img_height", Integer.toString(processor.getScaledHeight()));
-        anImageEntity.setFieldValue("img_width", Integer.toString(processor.getScaledWidth()));
-
-        processor.cleanup();
-        anImageEntity.setFieldValue("publish_path", filePath);
-        anImageEntity.update();
-        reportChange(iconStoragePath);
-        reportChange(imageFilePath);
-      }
-    }
-    catch(Throwable t) {
-      logger.error("MediaHandlerImagesExtern.execute: " + t.getMessage(), t);
-      throw new MediaFailure(t.getMessage(), t);
-    }
-  }
-
-    /**
-     * Scale an icon image and write it to the file system.
-     * @param processor
-     * @param iconPath
-     * @return
-     * @throws MediaExc
-     */
-    private String doIconScaling(ImageProcessor processor, String iconPath) throws MediaExc {
-        String iconStoragePath = configuration.getString("Producer.StorageRoot") + iconPath;
-        File iconFile = new File(iconStoragePath);
-        processor.descaleImage(maxIconSize, minDescaleRatio, minDescaleReduction);
-        File dir = new File(iconFile.getParent());
-        if (dir != null && !dir.exists()) {
-          dir.mkdirs();
-        }
-        processor.writeScaledData(iconFile, "JPEG");
-        return iconStoragePath;
-    }
-
-    /**
-     * Make the resized file.
-     * @param filePath
-     * @param imageFile
-     * @param processor
-     * @return
-     * @throws MediaExc
-     * @throws IOException
-     */
-    private String doImageScaling(String filePath, File imageFile, ImageProcessor processor) throws MediaExc, IOException {
-        // get a file path where the the original image should be saved if image resizing is turned on
-          String imagesOriginalDir = configuration.getString("Producer.ImagesOriginalDir.Path");
-          String imagesOriginalDirRelPath = configuration.getString("Producer.ImagesOriginalDir.RelPath");
-          String imageOriginalFilePath = imagesOriginalDir + filePath;
-          String imageOriginalRelPath = imagesOriginalDirRelPath +  filePath;
-          File originalFile = new File(imageOriginalFilePath);   
-          processor.descaleImage(maxSize, minDescaleRatio, minDescaleReduction);
-          File originalDir = new File(originalFile.getParent());
-          if (originalDir != null && !originalDir.exists()) {
-            originalDir.mkdirs();
-          }
-          if (!originalFile.exists()) {
-            FileRoutines.copy(imageFile, originalFile);
-            reportChange(originalFile.getAbsolutePath());
-          }
-          // yoss: don't write the scaled data again if it's the same size as
-          // the file that's there right now. Image producer runs are 4 times
-          // faster this way.
-          if (processor.getScaledFileSize() != imageFile.length()) {
-              processor.writeScaledData(imageFile, "JPEG");
-          }
-        return imageOriginalRelPath;
-    }
-
-/** {@inheritDoc} */
-  public InputStream getThumbnail(Entity anImageEntity) throws MediaExc, MediaFailure {
-    try {
-      File file = new File(configuration.getString("Producer.StorageRoot") + anImageEntity.getFieldValue("icon_path"));
-
-      if (!file.exists()) {
-        // hackish
-        file = new File(configuration.getHome(), "../img/photo_big.gif");
-      }
-
-      return new BufferedInputStream(
-        new FileInputStream(file),8192);
-    }
-    catch (Throwable t) {
-      return null;
-    }
-  }
-
-  public String getIconMimeType(Entity anImageEntity, Entity aMediaType) {
-    return "image/jpeg";
-  }
-
-  public String getBaseStoragePath()
-  {
-    return configuration.getString("Producer.Image.Path");
-  }
-
-  public String getBaseIconStoragePath()
-  {
-    return configuration.getString("Producer.Image.IconPath");
-  }
-
-  public String getPublishHost()
-  {
-    return StringUtil.removeSlash(configuration.getString("Producer.Image.Host"));
-  }
-
-  public String getTinyIconName()
-  {
-    return configuration.getString("Producer.Icon.TinyImage");
-  }
-
-  public String getBigIconName()
-  {
-    return configuration.getString("Producer.Icon.BigImage");
-  }
-
-  public String getIconAltName()
-  {
-    return "Image";
-  }
-
-  public String getDescr(Entity mediaType)
-  {
-     return "image/jpeg";
-  }
-}
+/*\r
+ * Copyright (C) 2001, 2002 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License,\r
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
+ * (or with modified versions of the above that use the same license as the above),\r
+ * and distribute linked combinations including the two.  You must obey the\r
+ * GNU General Public License in all respects for all of the code used other than\r
+ * the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+package mircoders.media;\r
+\r
+\r
+import java.io.BufferedInputStream;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileNotFoundException;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+\r
+import mir.entity.Entity;\r
+import mir.log.LoggerWrapper;\r
+import mir.media.MediaExc;\r
+import mir.media.MediaFailure;\r
+import mir.media.image.ImageMagickImageProcessor;\r
+import mir.media.image.ImageProcessor;\r
+import mir.misc.StringUtil;\r
+import mir.util.FileRoutines;\r
+\r
+/**\r
+ * Image handler that stores images outside of the database.\r
+ * \r
+ * @author Zapata\r
+ * @version 1.0\r
+ */\r
+\r
+public class MediaHandlerImagesExternScaling extends MediaHandlerGeneric\r
+{\r
+  private int maxSize;\r
+  private int maxIconSize;\r
+  private float minDescaleRatio;\r
+  private int minDescaleReduction;\r
+  public MediaHandlerImagesExternScaling() {\r
+    logger = new LoggerWrapper("Media.Images.Extern");\r
+    maxSize = configuration.getInt("Producer.Image.MaxSize");\r
+    maxIconSize = configuration.getInt("Producer.Image.MaxIconSize");\r
+    minDescaleRatio = configuration.getFloat("Producer.Image.MinDescalePercentage")/100;\r
+    minDescaleReduction = configuration.getInt("Producer.Image.MinDescaleReduction");\r
+  }\r
+  \r
+\r
+  \r
+  public void produce(Entity anImageEntity, Entity mediaTypeEnt) throws MediaExc, MediaFailure {\r
+    try {\r
+      String date = anImageEntity.getFieldValue("date");\r
+      String datePath = StringUtil.webdbDate2path(date);\r
+      String ext = "." + mediaTypeEnt.getFieldValue("name");\r
+      String fileBasePath = datePath + anImageEntity.getId();\r
+      String filePath = fileBasePath + ext;\r
+\r
+      String imageFilePath = getBaseStoragePath() + File.separator + filePath;\r
+      File imageFile = new File(imageFilePath);\r
+      \r
+      if (!imageFile.exists()) {\r
+        throw new MediaExc("error in MediaHandlerImagesExtern.execute(): "\r
+            + filePath + " does not exist!");\r
+      } else {\r
+        ImageProcessor processor = new ImageMagickImageProcessor(imageFile);\r
+        String iconPath = getBaseIconStoragePath() + fileBasePath + ".jpg";\r
+        String iconStoragePath = doIconScaling(processor, iconPath);\r
+        anImageEntity.setFieldValue("icon_height", new Integer(processor.getScaledHeight()).toString());\r
+        anImageEntity.setFieldValue("icon_width", new Integer(processor.getScaledWidth()).toString());\r
+        anImageEntity.setFieldValue("icon_path", iconPath);\r
+        \r
+        String imageOriginalRelPath = doImageScaling(filePath, imageFile, processor);\r
+        anImageEntity.setFieldValue("original_file_path", imageOriginalRelPath);\r
+        anImageEntity.setFieldValue("img_height", Integer.toString(processor.getScaledHeight()));\r
+        anImageEntity.setFieldValue("img_width", Integer.toString(processor.getScaledWidth()));\r
+\r
+        processor.cleanup();\r
+        anImageEntity.setFieldValue("publish_path", filePath);\r
+        anImageEntity.update();\r
+        reportChange(iconStoragePath);\r
+        reportChange(imageFilePath);\r
+      }\r
+    }\r
+    catch(Throwable t) {\r
+      logger.error("MediaHandlerImagesExtern.execute: " + t.getMessage(), t);\r
+      throw new MediaFailure(t.getMessage(), t);\r
+    }\r
+  }\r
+\r
+    /**\r
+     * Scale an icon image and write it to the file system.\r
+     * @param processor\r
+     * @param iconPath\r
+     * @return\r
+     * @throws MediaExc\r
+     */\r
+    private String doIconScaling(ImageProcessor processor, String iconPath) throws MediaExc {\r
+        String iconStoragePath = configuration.getString("Producer.StorageRoot") + iconPath;\r
+        File iconFile = new File(iconStoragePath);\r
+        processor.descaleImage(maxIconSize, minDescaleRatio, minDescaleReduction);\r
+        File dir = new File(iconFile.getParent());\r
+        if (dir != null && !dir.exists()) {\r
+          dir.mkdirs();\r
+        }\r
+               try {\r
+                       processor.writeScaledData(iconFile, "JPEG");\r
+               } catch (FileNotFoundException e) {\r
+                       // TODO Auto-generated catch block\r
+                       e.printStackTrace();\r
+               } catch (IOException e) {\r
+                       // TODO Auto-generated catch block\r
+                       e.printStackTrace();\r
+               }\r
+        return iconStoragePath;\r
+    }\r
+\r
+    /**\r
+     * Make the resized file.\r
+     * @param filePath\r
+     * @param imageFile\r
+     * @param processor\r
+     * @return\r
+     * @throws MediaExc\r
+     * @throws IOException\r
+     */\r
+    private String doImageScaling(String filePath, File imageFile, ImageProcessor processor) throws MediaExc, IOException {\r
+        // get a file path where the the original image should be saved if image resizing is turned on\r
+          String imagesOriginalDir = configuration.getString("Producer.ImagesOriginalDir.Path");\r
+          String imagesOriginalDirRelPath = configuration.getString("Producer.ImagesOriginalDir.RelPath");\r
+          String imageOriginalFilePath = imagesOriginalDir + filePath;\r
+          String imageOriginalRelPath = imagesOriginalDirRelPath +  filePath;\r
+          File originalFile = new File(imageOriginalFilePath);   \r
+          processor.descaleImage(maxSize, minDescaleRatio, minDescaleReduction);\r
+          File originalDir = new File(originalFile.getParent());\r
+          if (originalDir != null && !originalDir.exists()) {\r
+            originalDir.mkdirs();\r
+          }\r
+          if (!originalFile.exists()) {\r
+            FileRoutines.copy(imageFile, originalFile);\r
+            reportChange(originalFile.getAbsolutePath());\r
+          }\r
+          // yoss: don't write the scaled data again if it's the same size as\r
+          // the file that's there right now. Image producer runs are 4 times\r
+          // faster this way.\r
+          if (processor.getScaledFileSize() != imageFile.length()) {\r
+              processor.writeScaledData(imageFile, "JPEG");\r
+          }\r
+        return imageOriginalRelPath;\r
+    }\r
+\r
+/** {@inheritDoc} */\r
+  public InputStream getThumbnail(Entity anImageEntity) throws MediaExc, MediaFailure {\r
+    try {\r
+      File file = new File(configuration.getString("Producer.StorageRoot") + anImageEntity.getFieldValue("icon_path"));\r
+\r
+      if (!file.exists()) {\r
+        // hackish\r
+        file = new File(configuration.getHome(), "../img/photo_big.gif");\r
+      }\r
+\r
+      return new BufferedInputStream(\r
+        new FileInputStream(file),8192);\r
+    }\r
+    catch (Throwable t) {\r
+      return null;\r
+    }\r
+  }\r
+\r
+  public String getIconMimeType(Entity anImageEntity, Entity aMediaType) {\r
+    return "image/jpeg";\r
+  }\r
+\r
+  public String getBaseStoragePath()\r
+  {\r
+    return configuration.getString("Producer.Image.Path");\r
+  }\r
+\r
+  public String getBaseIconStoragePath()\r
+  {\r
+    return configuration.getString("Producer.Image.IconPath");\r
+  }\r
+\r
+  public String getPublishHost()\r
+  {\r
+    return StringUtil.removeSlash(configuration.getString("Producer.Image.Host"));\r
+  }\r
+\r
+  public String getTinyIconName()\r
+  {\r
+    return configuration.getString("Producer.Icon.TinyImage");\r
+  }\r
+\r
+  public String getBigIconName()\r
+  {\r
+    return configuration.getString("Producer.Icon.BigImage");\r
+  }\r
+\r
+  public String getIconAltName()\r
+  {\r
+    return "Image";\r
+  }\r
+\r
+  public String getDescr(Entity mediaType)\r
+  {\r
+     return "image/jpeg";\r
+  }\r
+}\r