mirror of
https://github.com/apache/poi.git
synced 2026-02-27 20:40:08 +08:00
Unify PNG extraction
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1866809 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
1d4b05ff60
commit
8f051a0b88
@ -18,12 +18,11 @@
|
||||
|
||||
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;
|
||||
|
||||
59
src/java/org/apache/poi/sl/image/ImageHeaderPNG.java
Normal file
59
src/java/org/apache/poi/sl/image/ImageHeaderPNG.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user