Bugzilla 53446 - Fixed some problems extracting PNGs
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1369263 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ef89213fd5
commit
fb1719c85d
@ -34,7 +34,8 @@
|
||||
|
||||
<changes>
|
||||
<release version="3.9-beta1" date="2012-??-??">
|
||||
<action dev="poi-developers" type="fix">53205 - Fix some parsing errors and encoding issues in HDGF </action>
|
||||
<action dev="poi-developers" type="add">53446 - Fixed some problems extracting PNGs </action>
|
||||
<action dev="poi-developers" type="fix">53205 - Fixed some parsing errors and encoding issues in HDGF </action>
|
||||
<action dev="poi-developers" type="add">53204 - Improved performanceof PageSettingsBlock in HSSF </action>
|
||||
<action dev="poi-developers" type="add">53500 - Getter for repeating rows and columns</action>
|
||||
<action dev="poi-developers" type="fix">53369 - Fixed tests failing on JDK 1.7</action>
|
||||
|
@ -22,6 +22,7 @@ import org.apache.poi.ddf.EscherBitmapBlip;
|
||||
import org.apache.poi.ddf.EscherBlipRecord;
|
||||
import org.apache.poi.ddf.EscherMetafileBlip;
|
||||
import org.apache.poi.ss.usermodel.PictureData;
|
||||
import org.apache.poi.util.PngUtils;
|
||||
|
||||
/**
|
||||
* Represents binary data stored in the file. Eg. A GIF, JPEG etc...
|
||||
@ -60,7 +61,18 @@ public class HSSFPictureData implements PictureData
|
||||
*/
|
||||
public byte[] getData()
|
||||
{
|
||||
return blip.getPicturedata();
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
57
src/java/org/apache/poi/util/PngUtils.java
Normal file
57
src/java/org/apache/poi/util/PngUtils.java
Normal file
@ -0,0 +1,57 @@
|
||||
/* ====================================================================
|
||||
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;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
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,6 +17,7 @@
|
||||
|
||||
package org.apache.poi.hslf.blip;
|
||||
|
||||
import org.apache.poi.util.PngUtils;
|
||||
import org.apache.poi.hslf.model.Picture;
|
||||
import org.apache.poi.hslf.exceptions.HSLFException;
|
||||
|
||||
@ -35,22 +36,19 @@ public final class PNG extends Bitmap {
|
||||
/**
|
||||
* @return PNG data
|
||||
*/
|
||||
public byte[] getData(){
|
||||
byte[] data = super.getData();
|
||||
try {
|
||||
//PNG created on MAC may have a 16-byte prefix which prevents successful reading.
|
||||
//Just cut it off!.
|
||||
BufferedImage bi = ImageIO.read(new ByteArrayInputStream(data));
|
||||
if (bi == null){
|
||||
byte[] png = new byte[data.length-16];
|
||||
System.arraycopy(data, 16, png, 0, png.length);
|
||||
data = png;
|
||||
}
|
||||
} catch (IOException e){
|
||||
throw new HSLFException(e);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
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 type of this picture
|
||||
|
@ -34,6 +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.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
@ -191,6 +192,15 @@ public final class Picture
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,10 +20,13 @@ package org.apache.poi.hslf.model;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.ddf.EscherBSERecord;
|
||||
import org.apache.poi.hslf.HSLFSlideShow;
|
||||
import org.apache.poi.hslf.usermodel.PictureData;
|
||||
import org.apache.poi.hslf.usermodel.SlideShow;
|
||||
import org.apache.poi.POIDataSamples;
|
||||
@ -88,4 +91,41 @@ public final class TestPicture extends TestCase {
|
||||
Graphics2D graphics = img.createGraphics();
|
||||
pict.draw(graphics);
|
||||
}
|
||||
|
||||
public void testMacImages() throws Exception {
|
||||
HSLFSlideShow hss = new HSLFSlideShow(_slTests.openResourceAsStream("53446.ppt"));
|
||||
|
||||
PictureData[] pictures = hss.getPictures();
|
||||
assertEquals(15, pictures.length);
|
||||
|
||||
int[][] expectedSizes = {
|
||||
null, // WMF
|
||||
{ 427, 428 }, // PNG
|
||||
{ 371, 370 }, // PNG
|
||||
{ 288, 183 }, // PNG
|
||||
{ 285, 97 }, // PNG
|
||||
{ 288, 168 }, // PNG
|
||||
null, // WMF
|
||||
null, // WMF
|
||||
{ 199, 259 }, // PNG
|
||||
{ 432, 244 }, // PNG
|
||||
{ 261, 258 }, // PNG
|
||||
null, // WMF
|
||||
null, // WMF
|
||||
null, // WMF
|
||||
null // EMF
|
||||
};
|
||||
|
||||
for (int i = 0; i < pictures.length; i++) {
|
||||
BufferedImage image = ImageIO.read(new ByteArrayInputStream(pictures[i].getData()));
|
||||
|
||||
if (pictures[i].getType() != Picture.WMF && pictures[i].getType() != Picture.EMF) {
|
||||
assertNotNull(image);
|
||||
|
||||
int[] dimensions = expectedSizes[i];
|
||||
assertEquals(dimensions[0], image.getWidth());
|
||||
assertEquals(dimensions[1], image.getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,10 +17,14 @@
|
||||
|
||||
package org.apache.poi.hwpf;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.POIDataSamples;
|
||||
import org.apache.poi.hwpf.model.PicturesTable;
|
||||
import org.apache.poi.hwpf.usermodel.Picture;
|
||||
import org.apache.poi.POIDataSamples;
|
||||
@ -128,6 +132,30 @@ public final class TestHWPFPictures extends TestCase {
|
||||
assertBytesSame(picBytes, pic.getContent());
|
||||
}
|
||||
|
||||
public void testMacImages() throws Exception {
|
||||
HWPFDocument docC = HWPFTestDataSamples.openSampleFile("53446.doc");
|
||||
PicturesTable picturesTable = docC.getPicturesTable();
|
||||
List<Picture> pictures = picturesTable.getAllPictures();
|
||||
|
||||
assertEquals(4, pictures.size());
|
||||
|
||||
int[][] expectedSizes = {
|
||||
{ 185, 42 }, // PNG
|
||||
{ 260, 114 }, // PNG
|
||||
{ 185, 42 }, // PNG
|
||||
{ 260, 114 }, // PNG
|
||||
};
|
||||
|
||||
for (int i = 0; i < pictures.size(); i++) {
|
||||
BufferedImage image = ImageIO.read(new ByteArrayInputStream(pictures.get(i).getContent()));
|
||||
assertNotNull(image);
|
||||
|
||||
int[] dimensions = expectedSizes[i];
|
||||
assertEquals(dimensions[0], image.getWidth());
|
||||
assertEquals(dimensions[1], image.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pending the missing files being uploaded to
|
||||
* bug #44937
|
||||
|
@ -72,6 +72,29 @@ public final class TestHSSFPictureData extends TestCase{
|
||||
}
|
||||
}
|
||||
|
||||
public void testMacPicture() throws IOException {
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("53446.xls");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<HSSFPictureData> lst = (List<HSSFPictureData>)(List<?>)wb.getAllPictures();
|
||||
assertEquals(1, lst.size());
|
||||
|
||||
HSSFPictureData pict = lst.get(0);
|
||||
String ext = pict.suggestFileExtension();
|
||||
if (!ext.equals("png")) {
|
||||
fail("Expected a PNG.");
|
||||
}
|
||||
|
||||
//try to read image data using javax.imageio.* (JDK 1.4+)
|
||||
byte[] data = pict.getData();
|
||||
BufferedImage png = ImageIO.read(new ByteArrayInputStream(data));
|
||||
assertNotNull(png);
|
||||
assertEquals(78, png.getWidth());
|
||||
assertEquals(76, png.getHeight());
|
||||
assertEquals(HSSFWorkbook.PICTURE_TYPE_PNG, pict.getFormat());
|
||||
assertEquals("image/png", pict.getMimeType());
|
||||
}
|
||||
|
||||
public void testNotNullPictures() throws IOException {
|
||||
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("SheetWithDrawing.xls");
|
||||
|
BIN
test-data/document/53446.doc
Normal file
BIN
test-data/document/53446.doc
Normal file
Binary file not shown.
BIN
test-data/slideshow/53446.ppt
Normal file
BIN
test-data/slideshow/53446.ppt
Normal file
Binary file not shown.
BIN
test-data/spreadsheet/53446.xls
Normal file
BIN
test-data/spreadsheet/53446.xls
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user