]> source.dussan.org Git - poi.git/commitdiff
Unify PNG extraction
authorAndreas Beeker <kiwiwings@apache.org>
Wed, 11 Sep 2019 21:24:34 +0000 (21:24 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Wed, 11 Sep 2019 21:24:34 +0000 (21:24 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1866809 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java
src/java/org/apache/poi/sl/image/ImageHeaderPNG.java [new file with mode: 0644]
src/java/org/apache/poi/util/PngUtils.java [deleted file]
src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java
src/scratchpad/src/org/apache/poi/hwpf/usermodel/Picture.java

index 267bd2e1d670781ada244dfd0174fbfd96e9a4e9..0bac1af0f6f24349a0115623ea5a7b65865bacc0 100644 (file)
 
 package org.apache.poi.hssf.usermodel;
 
-import org.apache.poi.ddf.EscherBitmapBlip;
 import org.apache.poi.ddf.EscherBlipRecord;
-import org.apache.poi.ddf.EscherMetafileBlip;
+import org.apache.poi.ddf.EscherRecordTypes;
+import org.apache.poi.sl.image.ImageHeaderPNG;
 import org.apache.poi.ss.usermodel.PictureData;
 import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.util.PngUtils;
 
 /**
  * Represents binary data stored in the file.  Eg. A GIF, JPEG etc...
@@ -58,20 +57,8 @@ public class HSSFPictureData implements PictureData
     /* (non-Javadoc)
      * @see org.apache.poi.hssf.usermodel.PictureData#getData()
      */
-    public byte[] getData()
-    {
-        byte[] pictureData = blip.getPicturedata();
-
-        //PNG created on MAC may have a 16-byte prefix which prevents successful reading.
-        //Just cut it off!.
-        if (PngUtils.matchesPngHeader(pictureData, 16))
-        {
-            byte[] png = new byte[pictureData.length-16];
-            System.arraycopy(pictureData, 16, png, 0, png.length);
-            pictureData = png;
-        }
-
-        return pictureData;
+    public byte[] getData() {
+        return new ImageHeaderPNG(blip.getPicturedata()).extractPNG();
     }
 
     /**
@@ -93,18 +80,18 @@ public class HSSFPictureData implements PictureData
     * @return 'wmf', 'jpeg' etc depending on the format. never <code>null</code>
     */
     public String suggestFileExtension() {
-        switch (blip.getRecordId()) {
-            case EscherMetafileBlip.RECORD_ID_WMF:
+        switch (EscherRecordTypes.forTypeID(blip.getRecordId())) {
+            case BLIP_WMF:
                 return "wmf";
-            case EscherMetafileBlip.RECORD_ID_EMF:
+            case BLIP_EMF:
                 return "emf";
-            case EscherMetafileBlip.RECORD_ID_PICT:
+            case BLIP_PICT:
                 return "pict";
-            case EscherBitmapBlip.RECORD_ID_PNG:
+            case BLIP_PNG:
                 return "png";
-            case EscherBitmapBlip.RECORD_ID_JPEG:
+            case BLIP_JPEG:
                 return "jpeg";
-            case EscherBitmapBlip.RECORD_ID_DIB:
+            case BLIP_DIB:
                 return "dib";
             default:
                 return "";
@@ -115,18 +102,18 @@ public class HSSFPictureData implements PictureData
      * Returns the mime type for the image
      */
     public String getMimeType() {
-       switch (blip.getRecordId()) {
-           case EscherMetafileBlip.RECORD_ID_WMF:
+       switch (EscherRecordTypes.forTypeID(blip.getRecordId())) {
+           case BLIP_WMF:
                return "image/x-wmf";
-           case EscherMetafileBlip.RECORD_ID_EMF:
+           case BLIP_EMF:
                return "image/x-emf";
-           case EscherMetafileBlip.RECORD_ID_PICT:
+           case BLIP_PICT:
                return "image/x-pict";
-           case EscherBitmapBlip.RECORD_ID_PNG:
+           case BLIP_PNG:
                return "image/png";
-           case EscherBitmapBlip.RECORD_ID_JPEG:
+           case BLIP_JPEG:
                return "image/jpeg";
-           case EscherBitmapBlip.RECORD_ID_DIB:
+           case BLIP_DIB:
                return "image/bmp";
            default:
                return "image/unknown";
@@ -144,18 +131,18 @@ public class HSSFPictureData implements PictureData
      * @see Workbook#PICTURE_TYPE_WMF
      */
     public int getPictureType() {
-        switch (blip.getRecordId()) {
-            case EscherMetafileBlip.RECORD_ID_WMF:
+        switch (EscherRecordTypes.forTypeID(blip.getRecordId())) {
+            case BLIP_WMF:
                 return Workbook.PICTURE_TYPE_WMF;
-            case EscherMetafileBlip.RECORD_ID_EMF:
+            case BLIP_EMF:
                 return Workbook.PICTURE_TYPE_EMF;
-            case EscherMetafileBlip.RECORD_ID_PICT:
+            case BLIP_PICT:
                 return Workbook.PICTURE_TYPE_PICT;
-            case EscherBitmapBlip.RECORD_ID_PNG:
+            case BLIP_PNG:
                 return Workbook.PICTURE_TYPE_PNG;
-            case EscherBitmapBlip.RECORD_ID_JPEG:
+            case BLIP_JPEG:
                 return Workbook.PICTURE_TYPE_JPEG;
-            case EscherBitmapBlip.RECORD_ID_DIB:
+            case BLIP_DIB:
                 return Workbook.PICTURE_TYPE_DIB;
             default:
                 return -1;
diff --git a/src/java/org/apache/poi/sl/image/ImageHeaderPNG.java b/src/java/org/apache/poi/sl/image/ImageHeaderPNG.java
new file mode 100644 (file)
index 0000000..400bedd
--- /dev/null
@@ -0,0 +1,59 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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 org.apache.poi.sl.image;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.poi.poifs.filesystem.FileMagic;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.RecordFormatException;
+
+public final class ImageHeaderPNG {
+
+    private static final int MAGIC_OFFSET = 16;
+
+    private byte[] data;
+
+    /**
+     * @param data The raw image data
+     */
+    public ImageHeaderPNG(byte[] data) {
+        this.data = data;
+    }
+
+    /**
+     * PNG created on MAC may have a 16-byte prefix which prevents successful reading.
+     * @return the trimmed PNG data
+     */
+    public byte[] extractPNG() {
+        //
+        //Just cut it off!.
+        try (InputStream is = new ByteArrayInputStream(data)) {
+            if (is.skip(MAGIC_OFFSET) == MAGIC_OFFSET && FileMagic.valueOf(is) == FileMagic.PNG) {
+                return IOUtils.toByteArray(is);
+            }
+        } catch (IOException e) {
+            throw new RecordFormatException("Unable to parse PNG header", e);
+        }
+
+        return data;
+    }
+}
diff --git a/src/java/org/apache/poi/util/PngUtils.java b/src/java/org/apache/poi/util/PngUtils.java
deleted file mode 100644 (file)
index f9126c9..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You 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 org.apache.poi.util;
-
-
-public final class PngUtils {
-
-    /**
-     * File header for PNG format.
-     */
-    private static final byte[] PNG_FILE_HEADER =
-        new byte[] { (byte) 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
-
-    private PngUtils() {
-        // no instances of this class
-    }
-
-    /**
-     * Checks if the offset matches the PNG header.
-     *
-     * @param data the data to check.
-     * @param offset the offset to check at.
-     * @return {@code true} if the offset matches.
-     */
-    public static boolean matchesPngHeader(byte[] data, int offset) {
-        if (data == null || data.length - offset < PNG_FILE_HEADER.length) {
-            return false;
-        }
-
-        for (int i = 0; i < PNG_FILE_HEADER.length; i++) {
-            if (PNG_FILE_HEADER[i] != data[i + offset]) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-}
index f2abc4068dd581e6ebc30304e5725dc06a46dc56..8e05aa76115e32d3c3b440373f613aa9c42e40a3 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.apache.poi.hslf.blip;
 
-import org.apache.poi.util.PngUtils;
+import org.apache.poi.sl.image.ImageHeaderPNG;
 
 /**
  * Represents a PNG picture data in a PPT file
@@ -26,17 +26,7 @@ public final class PNG extends Bitmap {
 
     @Override
     public byte[] getData() {
-        byte[] data = super.getData();
-
-        //PNG created on MAC may have a 16-byte prefix which prevents successful reading.
-        //Just cut it off!.
-        if (PngUtils.matchesPngHeader(data, 16)) {
-            byte[] png = new byte[data.length-16];
-            System.arraycopy(data, 16, png, 0, png.length);
-            data = png;
-        }
-
-        return data;
+        return new ImageHeaderPNG(super.getData()).extractPNG();
     }
 
     @Override
index a7ed1adc4b42b4d3920fa9bf1dce37939259f745..d8ab165f033e735e5fab3d48a248661f83190ded 100644 (file)
@@ -34,7 +34,7 @@ import org.apache.poi.ddf.EscherProperty;
 import org.apache.poi.ddf.EscherRecord;
 import org.apache.poi.hwpf.model.PICF;
 import org.apache.poi.hwpf.model.PICFAndOfficeArtData;
-import org.apache.poi.util.PngUtils;
+import org.apache.poi.sl.image.ImageHeaderPNG;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 import org.apache.poi.util.StringUtil;
@@ -169,16 +169,7 @@ public final class Picture {
         else
         {
             // Raw data is not compressed.
-            content = rawContent;
-
-            //PNG created on MAC may have a 16-byte prefix which prevents successful reading.
-            //Just cut it off!.
-            if (PngUtils.matchesPngHeader(content, 16))
-            {
-                byte[] png = new byte[content.length-16];
-                System.arraycopy(content, 16, png, 0, png.length);
-                content = png;
-            }
+            content = new ImageHeaderPNG(rawContent).extractPNG();
         }
     }