Index: src/java/org/apache/poi/ddf/EscherMetafileBlip.java =================================================================== --- src/java/org/apache/poi/ddf/EscherMetafileBlip.java (revision 1523427) +++ src/java/org/apache/poi/ddf/EscherMetafileBlip.java (working copy) @@ -17,18 +17,19 @@ package org.apache.poi.ddf; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - import java.awt.Dimension; import java.awt.Rectangle; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.zip.DeflaterOutputStream; import java.util.zip.InflaterInputStream; +import org.apache.poi.util.HexDump; +import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; + /** * @author Daniel Noll */ @@ -295,4 +296,30 @@ log.log(POILogger.WARN, "Unknown metafile: " + getRecordId()); return 0; } + + public void setPictureData(byte[] pictureData) { + super.setPictureData(pictureData); + setUncompressedSize(pictureData.length); + + // info of chicago project: + // "... LZ compression algorithm in the format used by GNU Zip deflate/inflate with a 32k window ..." + // not sure what to do, when lookup tables exceed 32k ... + + try { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DeflaterOutputStream dos = new DeflaterOutputStream(bos); + dos.write(pictureData); + dos.close(); + raw_pictureData = bos.toByteArray(); + } catch (IOException e) { + throw new RuntimeException("Can't compress metafile picture data", e); + } + + setCompressedSize(raw_pictureData.length); + setCompressed(true); + } + + public void setFilter(byte filter) { + field_7_fFilter = filter; + } } Index: src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java =================================================================== --- src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java (revision 1523427) +++ src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java (working copy) @@ -34,6 +34,7 @@ import org.apache.poi.ddf.EscherBSERecord; import org.apache.poi.ddf.EscherBitmapBlip; import org.apache.poi.ddf.EscherBlipRecord; +import org.apache.poi.ddf.EscherMetafileBlip; import org.apache.poi.ddf.EscherRecord; import org.apache.poi.hssf.OldExcelFormatException; import org.apache.poi.hssf.model.DrawingManager2; @@ -1587,7 +1588,28 @@ initDrawings(); byte[] uid = DigestUtils.md5(pictureData); - EscherBitmapBlip blipRecord = new EscherBitmapBlip(); + EscherBlipRecord blipRecord; + int blipSize; + short escherTag; + if (format == PICTURE_TYPE_EMF) { + EscherMetafileBlip blipRecordMeta = new EscherMetafileBlip(); + blipRecord = blipRecordMeta; + blipRecordMeta.setUID(uid); + blipRecordMeta.setPictureData(pictureData); + // taken from libre office export, it won't open, if this is left to 0 + blipRecordMeta.setFilter((byte)-2); + blipSize = blipRecordMeta.getCompressedSize() + 58; + escherTag = 0; + } else { + EscherBitmapBlip blipRecordBitmap = new EscherBitmapBlip(); + blipRecord = blipRecordBitmap; + blipRecordBitmap.setUID( uid ); + blipRecordBitmap.setMarker( (byte) 0xFF ); + blipRecordBitmap.setPictureData( pictureData ); + blipSize = pictureData.length + 25; + escherTag = (short) 0xFF; + } + blipRecord.setRecordId( (short) ( EscherBitmapBlip.RECORD_ID_START + format ) ); switch (format) { @@ -1610,11 +1632,7 @@ blipRecord.setOptions(HSSFPictureData.MSOBI_DIB); break; } - - blipRecord.setUID( uid ); - blipRecord.setMarker( (byte) 0xFF ); - blipRecord.setPictureData( pictureData ); - + EscherBSERecord r = new EscherBSERecord(); r.setRecordId( EscherBSERecord.RECORD_ID ); r.setOptions( (short) ( 0x0002 | ( format << 4 ) ) ); @@ -1621,12 +1639,12 @@ r.setBlipTypeMacOS( (byte) format ); r.setBlipTypeWin32( (byte) format ); r.setUid( uid ); - r.setTag( (short) 0xFF ); - r.setSize( pictureData.length + 25 ); + r.setTag( escherTag ); + r.setSize( blipSize ); r.setRef( 0 ); r.setOffset( 0 ); r.setBlipRecord( blipRecord ); - + return workbook.addBSERecord( r ); } Index: src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPicture.java =================================================================== --- src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPicture.java (revision 1523427) +++ src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPicture.java (working copy) @@ -17,17 +17,21 @@ package org.apache.poi.hssf.usermodel; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import org.apache.poi.POIDataSamples; import org.apache.poi.ddf.EscherBSERecord; +import org.apache.poi.hssf.HSSFITestDataProvider; import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.hssf.HSSFITestDataProvider; import org.apache.poi.hssf.model.InternalSheet; import org.apache.poi.ss.usermodel.BaseTestPicture; +import org.apache.poi.ss.usermodel.ClientAnchor; +import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.ss.usermodel.PictureData; import org.apache.poi.ss.usermodel.Workbook; -import java.util.Arrays; -import java.util.List; - /** * Test HSSFPicture. * @@ -210,4 +214,40 @@ p1 = (HSSFPicture) dr.getChildren().get(0); assertEquals(p1.getFileName(), "aaa"); } + + public void testInsertBugzillaIdHere() throws IOException { + // test if inserted EscherMetafileBlip will be read again + HSSFWorkbook wb = new HSSFWorkbook(); + + byte pictureDataEmf[] = POIDataSamples.getDocumentInstance().readFile("vector_image.emf"); + int indexEmf = wb.addPicture(pictureDataEmf, HSSFWorkbook.PICTURE_TYPE_EMF); + byte pictureDataPng[] = POIDataSamples.getSpreadSheetInstance().readFile("logoKarmokar4.png"); + int indexPng = wb.addPicture(pictureDataPng, HSSFWorkbook.PICTURE_TYPE_PNG); + + CreationHelper ch = wb.getCreationHelper(); + ClientAnchor anchor = ch.createClientAnchor(); + anchor.setCol1(2); + anchor.setCol2(6); + anchor.setRow1(1); + anchor.setRow2(6); + + HSSFSheet sheet = wb.createSheet(); + HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); + patriarch.createPicture(anchor, indexEmf); + + anchor = ch.createClientAnchor(); + anchor.setCol1(2); + anchor.setCol2(6); + anchor.setRow1(10); + anchor.setRow2(16); + patriarch.createPicture(anchor, indexPng); + + wb = HSSFTestDataSamples.writeOutAndReadBack(wb); + byte pictureDataOut[] = wb.getAllPictures().get(0).getData(); + assertTrue(Arrays.equals(pictureDataEmf, pictureDataOut)); + + // FileOutputStream fos = new FileOutputStream("vect.xls"); + // wb.write(fos); + // fos.close(); + } }