]> source.dussan.org Git - poi.git/commitdiff
#64213 - Picture.resize(double scale) scales width wrong for small pictures and when...
authorAndreas Beeker <kiwiwings@apache.org>
Mon, 16 Mar 2020 18:46:48 +0000 (18:46 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Mon, 16 Mar 2020 18:46:48 +0000 (18:46 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1875266 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/ss/util/ImageUtils.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFPicture.java
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPicture.java
src/testcases/org/apache/poi/ss/usermodel/BaseTestPicture.java

index ba355ebb0f7c2ec5326d9b20a46d524b16b735e8..fdd8ee89654bdf09ed0c54a1f3ee149690f34f6d 100644 (file)
@@ -24,6 +24,8 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
 
 import javax.imageio.ImageIO;
 import javax.imageio.ImageReader;
@@ -38,18 +40,26 @@ import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
+import org.apache.poi.util.Removal;
 import org.apache.poi.util.Units;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
-/**
- * @author Yegor Kozlov
- */
-public class ImageUtils {
+public final class ImageUtils {
     private static final POILogger logger = POILogFactory.getLogger(ImageUtils.class);
 
+    /**
+     * @deprecated use {@link Units#PIXEL_DPI}
+     */
+    @Deprecated
+    @Removal(version = "5.0.0")
     public static final int PIXEL_DPI = 96;
 
+    private static final int WIDTH_UNITS = 1024;
+    private static final int HEIGHT_UNITS = 256;
+
+    private ImageUtils() {}
+
     /**
      * Return the dimension of this image
      *
@@ -82,11 +92,11 @@ public class ImageUtils {
 
                                 //if DPI is zero then assume standard 96 DPI
                                 //since cannot divide by zero
-                                if (dpi[0] == 0) dpi[0] = PIXEL_DPI;
-                                if (dpi[1] == 0) dpi[1] = PIXEL_DPI;
+                                if (dpi[0] == 0) dpi[0] = Units.PIXEL_DPI;
+                                if (dpi[1] == 0) dpi[1] = Units.PIXEL_DPI;
 
-                                size.width = img.getWidth()*PIXEL_DPI/dpi[0];
-                                size.height = img.getHeight()*PIXEL_DPI/dpi[1];
+                                size.width = img.getWidth()*Units.PIXEL_DPI/dpi[0];
+                                size.height = img.getHeight()*Units.PIXEL_DPI/dpi[1];
                             } finally {
                                 r.dispose();
                             }
@@ -148,76 +158,25 @@ public class ImageUtils {
         Sheet sheet = picture.getSheet();
 
         // in pixel
-        Dimension imgSize = getImageDimension(new ByteArrayInputStream(data.getData()), data.getPictureType());
+        final Dimension imgSize = (scaleX == Double.MAX_VALUE || scaleY == Double.MAX_VALUE)
+            ? getImageDimension(new ByteArrayInputStream(data.getData()), data.getPictureType())
+            : new Dimension();
+
         // in emus
-        Dimension anchorSize = ImageUtils.getDimensionFromAnchor(picture);
+        final Dimension anchorSize = (scaleX != Double.MAX_VALUE || scaleY != Double.MAX_VALUE)
+            ? ImageUtils.getDimensionFromAnchor(picture)
+            : new Dimension();
+
         final double scaledWidth = (scaleX == Double.MAX_VALUE)
             ? imgSize.getWidth() : anchorSize.getWidth()/EMU_PER_PIXEL * scaleX;
         final double scaledHeight = (scaleY == Double.MAX_VALUE)
             ? imgSize.getHeight() : anchorSize.getHeight()/EMU_PER_PIXEL * scaleY;
 
-        double w = 0;
-        int col2 = anchor.getCol1();
-        int dx2 = 0;
-
-        //space in the leftmost cell
-        w = sheet.getColumnWidthInPixels(col2++);
-        if (isHSSF) {
-            w *= 1d - anchor.getDx1()/1024d;
-        } else {
-            w -= anchor.getDx1()/(double)EMU_PER_PIXEL;
-        }
-
-        while(w < scaledWidth){
-            w += sheet.getColumnWidthInPixels(col2++);
-        }
-
-        if(w > scaledWidth) {
-            //calculate dx2, offset in the rightmost cell
-            double cw = sheet.getColumnWidthInPixels(--col2);
-            double delta = w - scaledWidth;
-            if (isHSSF) {
-                dx2 = (int)((cw-delta)/cw*1024);
-            } else {
-                dx2 = (int)((cw-delta)*EMU_PER_PIXEL);
-            }
-            if (dx2 < 0) {
-                dx2 = 0;
-            }
-        }
-        anchor.setCol2(col2);
-        anchor.setDx2(dx2);
-
-        double h = 0;
-        int row2 = anchor.getRow1();
-        int dy2 = 0;
-
-        h = getRowHeightInPixels(sheet,row2++);
-        if (isHSSF) {
-            h *= 1 - anchor.getDy1()/256d;
-        } else {
-            h -= anchor.getDy1()/(double)EMU_PER_PIXEL;
-        }
-
-        while(h < scaledHeight){
-            h += getRowHeightInPixels(sheet,row2++);
-        }
-
-        if(h > scaledHeight) {
-            double ch = getRowHeightInPixels(sheet,--row2);
-            double delta = h - scaledHeight;
-            if (isHSSF) {
-                dy2 = (int)((ch-delta)/ch*256);
-            } else {
-                dy2 = (int)((ch-delta)*EMU_PER_PIXEL);
-            }
-            if (dy2 < 0) {
-                dy2 = 0;
-            }
-        }
+        scaleCell(scaledWidth, anchor.getCol1(), anchor.getDx1(), anchor::setCol2, anchor::setDx2,
+             isHSSF ? WIDTH_UNITS : 0, sheet::getColumnWidthInPixels);
 
-        anchor.setRow2(row2);
-        anchor.setDy2(dy2);
+        scaleCell(scaledHeight, anchor.getRow1(), anchor.getDy1(), anchor::setRow2, anchor::setDy2,
+                  isHSSF ? HEIGHT_UNITS : 0, (row) -> getRowHeightInPixels(sheet, row));
 
         return new Dimension(
             (int)Math.round(scaledWidth*EMU_PER_PIXEL),
@@ -236,57 +195,100 @@ public class ImageUtils {
         boolean isHSSF = (anchor instanceof HSSFClientAnchor);
         Sheet sheet = picture.getSheet();
 
-        double w = 0;
-        int col2 = anchor.getCol1();
-
-        //space in the leftmost cell
-        w = sheet.getColumnWidthInPixels(col2++);
-        if (isHSSF) {
-            w *= 1 - anchor.getDx1()/1024d;
-        } else {
-            w -= anchor.getDx1()/(double)EMU_PER_PIXEL;
+        // default to image size (in pixel), if the anchor is only specified for Col1/Row1
+        Dimension imgSize = null;
+        if (anchor.getCol2() < anchor.getCol1() || anchor.getRow2() < anchor.getRow1()) {
+            PictureData data = picture.getPictureData();
+            imgSize = getImageDimension(new ByteArrayInputStream(data.getData()), data.getPictureType());
         }
 
-        while(col2 < anchor.getCol2()){
-            w += sheet.getColumnWidthInPixels(col2++);
-        }
+        int w = getDimFromCell(imgSize == null ? 0 : imgSize.getWidth(), anchor.getCol1(), anchor.getDx1(), anchor.getCol2(), anchor.getDx2(),
+            isHSSF ? WIDTH_UNITS : 0, sheet::getColumnWidthInPixels);
 
-        if (isHSSF) {
-            w += anchor.getDx2()/1024d * sheet.getColumnWidthInPixels(col2);
-        } else {
-            w += anchor.getDx2()/(double)EMU_PER_PIXEL;
-        }
+        int h = getDimFromCell(imgSize == null ? 0 : imgSize.getHeight(), anchor.getRow1(), anchor.getDy1(), anchor.getRow2(), anchor.getDy2(),
+                               isHSSF ? HEIGHT_UNITS : 0, (row) -> getRowHeightInPixels(sheet, row));
 
-        double h = 0;
-        int row2 = anchor.getRow1();
+        return new Dimension(w, h);
+    }
 
-        h = getRowHeightInPixels(sheet,row2++);
-        if (isHSSF) {
-            h *= 1 - anchor.getDy1()/256d;
-        } else {
-            h -= anchor.getDy1()/(double)EMU_PER_PIXEL;
+
+    public static double getRowHeightInPixels(Sheet sheet, int rowNum) {
+        Row r = sheet.getRow(rowNum);
+        double points = (r == null) ? sheet.getDefaultRowHeightInPoints() : r.getHeightInPoints();
+        return Units.toEMU(points)/(double)EMU_PER_PIXEL;
+    }
+
+    private static void scaleCell(final double targetSize,
+                                  final int startCell,
+                                  final int startD,
+                                  Consumer<Integer> endCell,
+                                  Consumer<Integer> endD,
+                                  final int hssfUnits,
+                                  Function<Integer,Number> nextSize) {
+        if (targetSize < 0) {
+            throw new IllegalArgumentException("target size < 0");
         }
 
-        while(row2 < anchor.getRow2()){
-            h += getRowHeightInPixels(sheet,row2++);
+        int cellIdx = startCell;
+        double dim, delta;
+        for (double totalDim = 0, remDim;; cellIdx++, totalDim += remDim) {
+            dim = nextSize.apply(cellIdx).doubleValue();
+            remDim = dim;
+            if (cellIdx == startCell) {
+                if (hssfUnits > 0) {
+                    remDim *= 1 - startD/(double)hssfUnits;
+                } else {
+                    remDim -= startD/(double)EMU_PER_PIXEL;
+                }
+            }
+            delta = targetSize - totalDim;
+            if (delta < remDim) {
+                break;
+            }
         }
 
-        if (isHSSF) {
-            h += getRowHeightInPixels(sheet,row2) * anchor.getDy2()/256;
+        double endDval;
+        if (hssfUnits > 0) {
+            endDval = delta/dim * (double)hssfUnits;
         } else {
-            h += anchor.getDy2()/(double)EMU_PER_PIXEL;
+            endDval = delta * EMU_PER_PIXEL;
+        }
+        if (cellIdx == startCell) {
+            endDval += startD;
         }
 
-        w *= EMU_PER_PIXEL;
-        h *= EMU_PER_PIXEL;
-
-        return new Dimension((int)Math.rint(w), (int)Math.rint(h));
+        endCell.accept(cellIdx);
+        endD.accept((int)Math.rint(endDval));
     }
 
+    private static int getDimFromCell(double imgSize, int startCell, int startD, int endCell, int endD, int hssfUnits,
+         Function<Integer,Number> nextSize) {
+        double targetSize;
+        if (endCell < startCell) {
+            targetSize = imgSize * EMU_PER_PIXEL;
+        } else {
+            targetSize = 0;
+            for (int cellIdx = startCell; cellIdx<=endCell; cellIdx++) {
+                final double dim = nextSize.apply(cellIdx).doubleValue() * EMU_PER_PIXEL;
+                double leadSpace = 0;
+                if (cellIdx == startCell) {
+                    //space in the leftmost cell
+                    leadSpace = (hssfUnits > 0)
+                        ? dim * startD/(double)hssfUnits
+                        : startD;
+                }
 
-    public static double getRowHeightInPixels(Sheet sheet, int rowNum) {
-        Row r = sheet.getRow(rowNum);
-        double points = (r == null) ? sheet.getDefaultRowHeightInPoints() : r.getHeightInPoints();
-        return Units.toEMU(points)/(double)EMU_PER_PIXEL;
+                double trailSpace = 0;
+                if (cellIdx == endCell) {
+                    // space after the rightmost cell
+                    trailSpace = (hssfUnits > 0)
+                        ? dim * (hssfUnits-endD)/(double)hssfUnits
+                        : dim - endD;
+                }
+                targetSize += dim - leadSpace - trailSpace;
+            }
+        }
+
+        return (int)Math.rint(targetSize);
     }
 }
index 885b3d55c73a6f15b6463a11f1f28c7c69deadc0..e5599479cf7fde7f513f61f5dbea04fc96401ced 100644 (file)
@@ -17,7 +17,9 @@
 
 package org.apache.poi.xssf.usermodel;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 import java.io.IOException;
 import java.util.List;
@@ -31,59 +33,56 @@ import org.junit.Test;
 import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor;
 import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.STEditAs;
 
-/**
- * @author Yegor Kozlov
- */
 public final class TestXSSFPicture extends BaseTestPicture {
 
     public TestXSSFPicture() {
         super(XSSFITestDataProvider.instance);
     }
 
+
     @Test
     public void resize() throws Exception {
-        XSSFWorkbook wb = XSSFITestDataProvider.instance.openSampleWorkbook("resize_compare.xlsx");
-        XSSFDrawing dp = wb.getSheetAt(0).createDrawingPatriarch();
-        List<XSSFShape> pics = dp.getShapes();
-        XSSFPicture inpPic = (XSSFPicture)pics.get(0);
-        XSSFPicture cmpPic = (XSSFPicture)pics.get(0);
-        
-        baseTestResize(inpPic, cmpPic, 2.0, 2.0);
-        wb.close();
+        try (XSSFWorkbook wb = XSSFITestDataProvider.instance.openSampleWorkbook("resize_compare.xlsx")) {
+            XSSFDrawing dp = wb.getSheetAt(0).createDrawingPatriarch();
+            List<XSSFShape> pics = dp.getShapes();
+            XSSFPicture inpPic = (XSSFPicture) pics.get(0);
+            XSSFPicture cmpPic = (XSSFPicture) pics.get(0);
+
+            baseTestResize(inpPic, cmpPic, 2.0, 2.0);
+        }
     }
 
 
     @Test
     public void create() throws IOException {
-        XSSFWorkbook wb = new XSSFWorkbook();
-        XSSFSheet sheet = wb.createSheet();
-        XSSFDrawing drawing = sheet.createDrawingPatriarch();
-
-        byte[] jpegData = "test jpeg data".getBytes(LocaleUtil.CHARSET_1252);
-
-        List<XSSFPictureData> pictures = wb.getAllPictures();
-        assertEquals(0, pictures.size());
-
-        int jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG);
-        assertEquals(1, pictures.size());
-        assertEquals("jpeg", pictures.get(jpegIdx).suggestFileExtension());
-        assertArrayEquals(jpegData, pictures.get(jpegIdx).getData());
-
-        XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30);
-        assertEquals(AnchorType.MOVE_AND_RESIZE, anchor.getAnchorType());
-        anchor.setAnchorType(AnchorType.DONT_MOVE_AND_RESIZE);
-        assertEquals(AnchorType.DONT_MOVE_AND_RESIZE, anchor.getAnchorType());
-
-        XSSFPicture shape = drawing.createPicture(anchor, jpegIdx);
-        assertEquals(anchor, shape.getAnchor());
-        assertNotNull(shape.getPictureData());
-        assertArrayEquals(jpegData, shape.getPictureData().getData());
-
-        CTTwoCellAnchor ctShapeHolder = drawing.getCTDrawing().getTwoCellAnchorArray(0);
-        // STEditAs.ABSOLUTE corresponds to ClientAnchor.DONT_MOVE_AND_RESIZE
-        assertEquals(STEditAs.ABSOLUTE, ctShapeHolder.getEditAs());
-        
-        wb.close();
+        try (XSSFWorkbook wb = new XSSFWorkbook()) {
+            XSSFSheet sheet = wb.createSheet();
+            XSSFDrawing drawing = sheet.createDrawingPatriarch();
+
+            byte[] jpegData = "test jpeg data".getBytes(LocaleUtil.CHARSET_1252);
+
+            List<XSSFPictureData> pictures = wb.getAllPictures();
+            assertEquals(0, pictures.size());
+
+            int jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG);
+            assertEquals(1, pictures.size());
+            assertEquals("jpeg", pictures.get(jpegIdx).suggestFileExtension());
+            assertArrayEquals(jpegData, pictures.get(jpegIdx).getData());
+
+            XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30);
+            assertEquals(AnchorType.MOVE_AND_RESIZE, anchor.getAnchorType());
+            anchor.setAnchorType(AnchorType.DONT_MOVE_AND_RESIZE);
+            assertEquals(AnchorType.DONT_MOVE_AND_RESIZE, anchor.getAnchorType());
+
+            XSSFPicture shape = drawing.createPicture(anchor, jpegIdx);
+            assertEquals(anchor, shape.getAnchor());
+            assertNotNull(shape.getPictureData());
+            assertArrayEquals(jpegData, shape.getPictureData().getData());
+
+            CTTwoCellAnchor ctShapeHolder = drawing.getCTDrawing().getTwoCellAnchorArray(0);
+            // STEditAs.ABSOLUTE corresponds to ClientAnchor.DONT_MOVE_AND_RESIZE
+            assertEquals(STEditAs.ABSOLUTE, ctShapeHolder.getEditAs());
+        }
     }
 
     /**
@@ -93,71 +92,69 @@ public final class TestXSSFPicture extends BaseTestPicture {
      */
     @Test
     public void incrementShapeId() throws IOException {
-        XSSFWorkbook wb = new XSSFWorkbook();
-        XSSFSheet sheet = wb.createSheet();
-        XSSFDrawing drawing = sheet.createDrawingPatriarch();
-
-        XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30);
-        byte[] jpegData = "picture1".getBytes(LocaleUtil.CHARSET_1252);
-        int jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG);
-
-        XSSFPicture shape1 = drawing.createPicture(anchor, jpegIdx);
-        assertEquals(1, shape1.getCTPicture().getNvPicPr().getCNvPr().getId());
-
-        jpegData = "picture2".getBytes(LocaleUtil.CHARSET_1252);
-        jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG);
-        XSSFPicture shape2 = drawing.createPicture(anchor, jpegIdx);
-        assertEquals(2, shape2.getCTPicture().getNvPicPr().getCNvPr().getId());
-        wb.close();
+        try (XSSFWorkbook wb = new XSSFWorkbook()) {
+            XSSFSheet sheet = wb.createSheet();
+            XSSFDrawing drawing = sheet.createDrawingPatriarch();
+
+            XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30);
+            byte[] jpegData = "picture1".getBytes(LocaleUtil.CHARSET_1252);
+            int jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG);
+
+            XSSFPicture shape1 = drawing.createPicture(anchor, jpegIdx);
+            assertEquals(1, shape1.getCTPicture().getNvPicPr().getCNvPr().getId());
+
+            jpegData = "picture2".getBytes(LocaleUtil.CHARSET_1252);
+            jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG);
+            XSSFPicture shape2 = drawing.createPicture(anchor, jpegIdx);
+            assertEquals(2, shape2.getCTPicture().getNvPicPr().getCNvPr().getId());
+        }
     }
 
     /**
      * same image refrerred by mulitple sheets
      */
-    @SuppressWarnings("resource")
     @Test
     public void multiRelationShips() throws IOException {
-        XSSFWorkbook wb = new XSSFWorkbook();
-
-        byte[] pic1Data = "test jpeg data".getBytes(LocaleUtil.CHARSET_1252);
-        byte[] pic2Data = "test png data".getBytes(LocaleUtil.CHARSET_1252);
-
-        List<XSSFPictureData> pictures = wb.getAllPictures();
-        assertEquals(0, pictures.size());
-
-        int pic1 = wb.addPicture(pic1Data, XSSFWorkbook.PICTURE_TYPE_JPEG);
-        int pic2 = wb.addPicture(pic2Data, XSSFWorkbook.PICTURE_TYPE_PNG);
-
-        XSSFSheet sheet1 = wb.createSheet();
-        XSSFDrawing drawing1 = sheet1.createDrawingPatriarch();
-        XSSFPicture shape1 = drawing1.createPicture(new XSSFClientAnchor(), pic1);
-        XSSFPicture shape2 = drawing1.createPicture(new XSSFClientAnchor(), pic2);
-
-        XSSFSheet sheet2 = wb.createSheet();
-        XSSFDrawing drawing2 = sheet2.createDrawingPatriarch();
-        XSSFPicture shape3 = drawing2.createPicture(new XSSFClientAnchor(), pic2);
-        XSSFPicture shape4 = drawing2.createPicture(new XSSFClientAnchor(), pic1);
-
-        assertEquals(2, pictures.size());
-
-        wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
-        pictures = wb.getAllPictures();
-        assertEquals(2, pictures.size());
-
-        sheet1 = wb.getSheetAt(0);
-        drawing1 = sheet1.createDrawingPatriarch();
-        XSSFPicture shape11 = (XSSFPicture)drawing1.getShapes().get(0);
-        assertArrayEquals(shape1.getPictureData().getData(), shape11.getPictureData().getData());
-        XSSFPicture shape22 = (XSSFPicture)drawing1.getShapes().get(1);
-        assertArrayEquals(shape2.getPictureData().getData(), shape22.getPictureData().getData());
-
-        sheet2 = wb.getSheetAt(1);
-        drawing2 = sheet2.createDrawingPatriarch();
-        XSSFPicture shape33 = (XSSFPicture)drawing2.getShapes().get(0);
-        assertArrayEquals(shape3.getPictureData().getData(), shape33.getPictureData().getData());
-        XSSFPicture shape44 = (XSSFPicture)drawing2.getShapes().get(1);
-        assertArrayEquals(shape4.getPictureData().getData(), shape44.getPictureData().getData());
-
-        wb.close();
+        try (XSSFWorkbook wb1 = new XSSFWorkbook()) {
+            byte[] pic1Data = "test jpeg data".getBytes(LocaleUtil.CHARSET_1252);
+            byte[] pic2Data = "test png data".getBytes(LocaleUtil.CHARSET_1252);
+
+            List<XSSFPictureData> pictures = wb1.getAllPictures();
+            assertEquals(0, pictures.size());
+
+            int pic1 = wb1.addPicture(pic1Data, XSSFWorkbook.PICTURE_TYPE_JPEG);
+            int pic2 = wb1.addPicture(pic2Data, XSSFWorkbook.PICTURE_TYPE_PNG);
+
+            XSSFSheet sheet1 = wb1.createSheet();
+            XSSFDrawing drawing1 = sheet1.createDrawingPatriarch();
+            XSSFPicture shape1 = drawing1.createPicture(new XSSFClientAnchor(), pic1);
+            XSSFPicture shape2 = drawing1.createPicture(new XSSFClientAnchor(), pic2);
+
+            XSSFSheet sheet2 = wb1.createSheet();
+            XSSFDrawing drawing2 = sheet2.createDrawingPatriarch();
+            XSSFPicture shape3 = drawing2.createPicture(new XSSFClientAnchor(), pic2);
+            XSSFPicture shape4 = drawing2.createPicture(new XSSFClientAnchor(), pic1);
+
+            assertEquals(2, pictures.size());
+
+            try (XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1)) {
+                pictures = wb2.getAllPictures();
+                assertEquals(2, pictures.size());
+
+                sheet1 = wb2.getSheetAt(0);
+                drawing1 = sheet1.createDrawingPatriarch();
+                XSSFPicture shape11 = (XSSFPicture) drawing1.getShapes().get(0);
+                assertArrayEquals(shape1.getPictureData().getData(), shape11.getPictureData().getData());
+                XSSFPicture shape22 = (XSSFPicture) drawing1.getShapes().get(1);
+                assertArrayEquals(shape2.getPictureData().getData(), shape22.getPictureData().getData());
+
+                sheet2 = wb2.getSheetAt(1);
+                drawing2 = sheet2.createDrawingPatriarch();
+                XSSFPicture shape33 = (XSSFPicture) drawing2.getShapes().get(0);
+                assertArrayEquals(shape3.getPictureData().getData(), shape33.getPictureData().getData());
+                XSSFPicture shape44 = (XSSFPicture) drawing2.getShapes().get(1);
+                assertArrayEquals(shape4.getPictureData().getData(), shape44.getPictureData().getData());
+            }
+        }
     }
 }
index 21e47f8a56b3287ae580ea6a0cef3d43d17345d1..ed18bf34ee97b654fd8459b76f2174587ca97fda 100644 (file)
@@ -35,11 +35,6 @@ import org.apache.poi.ss.usermodel.PictureData;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.junit.Test;
 
-/**
- * Test <code>HSSFPicture</code>.
- *
- * @author Yegor Kozlov (yegor at apache.org)
- */
 public final class TestHSSFPicture extends BaseTestPicture {
 
     public TestHSSFPicture() {
@@ -48,248 +43,248 @@ public final class TestHSSFPicture extends BaseTestPicture {
 
     @Test
     public void resize() throws Exception {
-        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("resize_compare.xls");
-        HSSFPatriarch dp = wb.getSheetAt(0).createDrawingPatriarch();
-        List<HSSFShape> pics = dp.getChildren();
-        HSSFPicture inpPic = (HSSFPicture)pics.get(0);
-        HSSFPicture cmpPic = (HSSFPicture)pics.get(1);
-        
-        baseTestResize(inpPic, cmpPic, 2.0, 2.0);
-        wb.close();
+        try (HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("resize_compare.xls")) {
+            HSSFPatriarch dp = wb.getSheetAt(0).createDrawingPatriarch();
+            List<HSSFShape> pics = dp.getChildren();
+            HSSFPicture inpPic = (HSSFPicture) pics.get(0);
+            HSSFPicture cmpPic = (HSSFPicture) pics.get(1);
+
+            baseTestResize(inpPic, cmpPic, 2.0, 2.0);
+        }
     }
-    
+
     /**
      * Bug # 45829 reported ArithmeticException (/ by zero) when resizing png with zero DPI.
      */
     @Test
     public void bug45829() throws IOException {
-        HSSFWorkbook wb = new HSSFWorkbook();
-        HSSFSheet sh1 = wb.createSheet();
-        HSSFPatriarch p1 = sh1.createDrawingPatriarch();
-
-        byte[] pictureData = HSSFTestDataSamples.getTestDataFileContent("45829.png");
-        int idx1 = wb.addPicture( pictureData, HSSFWorkbook.PICTURE_TYPE_PNG );
-        HSSFPicture pic = p1.createPicture(new HSSFClientAnchor(), idx1);
-        pic.resize();
-        
-        wb.close();
+        try (HSSFWorkbook wb = new HSSFWorkbook()) {
+            HSSFSheet sh1 = wb.createSheet();
+            HSSFPatriarch p1 = sh1.createDrawingPatriarch();
+
+            byte[] pictureData = HSSFTestDataSamples.getTestDataFileContent("45829.png");
+            int idx1 = wb.addPicture(pictureData, HSSFWorkbook.PICTURE_TYPE_PNG);
+            HSSFPicture pic = p1.createPicture(new HSSFClientAnchor(), idx1);
+            pic.resize();
+        }
     }
 
 
-    @SuppressWarnings("resource")
     @Test
     public void addPictures() throws IOException {
-        HSSFWorkbook wb = new HSSFWorkbook();
-        
-        HSSFSheet sh = wb.createSheet("Pictures");
-        HSSFPatriarch dr = sh.createDrawingPatriarch();
-        assertEquals(0, dr.getChildren().size());
-        HSSFClientAnchor anchor = wb.getCreationHelper().createClientAnchor();
-
-        //register a picture
-        byte[] data1 = new byte[]{1, 2, 3};
-        int idx1 = wb.addPicture(data1, Workbook.PICTURE_TYPE_JPEG);
-        assertEquals(1, idx1);
-        HSSFPicture p1 = dr.createPicture(anchor, idx1);
-        assertArrayEquals(data1, p1.getPictureData().getData());
-
-        // register another one
-        byte[] data2 = new byte[]{4, 5, 6};
-        int idx2 = wb.addPicture(data2, Workbook.PICTURE_TYPE_JPEG);
-        assertEquals(2, idx2);
-        HSSFPicture p2 = dr.createPicture(anchor, idx2);
-        assertEquals(2, dr.getChildren().size());
-        assertArrayEquals(data2, p2.getPictureData().getData());
-
-        // confirm that HSSFPatriarch.getChildren() returns two picture shapes 
-        assertArrayEquals(data1, ((HSSFPicture)dr.getChildren().get(0)).getPictureData().getData());
-        assertArrayEquals(data2, ((HSSFPicture)dr.getChildren().get(1)).getPictureData().getData());
-
-        // write, read back and verify that our pictures are there
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
-        List<? extends PictureData> lst2 =  wb.getAllPictures();
-        assertEquals(2, lst2.size());
-        assertArrayEquals(data1, lst2.get(0).getData());
-        assertArrayEquals(data2, lst2.get(1).getData());
-
-        // confirm that the pictures are in the Sheet's drawing
-        sh = wb.getSheet("Pictures");
-        dr = sh.createDrawingPatriarch();
-        assertEquals(2, dr.getChildren().size());
-        assertArrayEquals(data1, ((HSSFPicture)dr.getChildren().get(0)).getPictureData().getData());
-        assertArrayEquals(data2, ((HSSFPicture)dr.getChildren().get(1)).getPictureData().getData());
-
-        // add a third picture
-        byte[] data3 = new byte[]{7, 8, 9};
-        // picture index must increment across write-read
-        int idx3 = wb.addPicture(data3, Workbook.PICTURE_TYPE_JPEG);
-        assertEquals(3, idx3);
-        HSSFPicture p3 = dr.createPicture(anchor, idx3);
-        assertArrayEquals(data3, p3.getPictureData().getData());
-        assertEquals(3, dr.getChildren().size());
-        assertArrayEquals(data1, ((HSSFPicture)dr.getChildren().get(0)).getPictureData().getData());
-        assertArrayEquals(data2, ((HSSFPicture)dr.getChildren().get(1)).getPictureData().getData());
-        assertArrayEquals(data3, ((HSSFPicture)dr.getChildren().get(2)).getPictureData().getData());
-
-        // write and read again
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
-        List<? extends PictureData> lst3 =  wb.getAllPictures();
-        // all three should be there
-        assertEquals(3, lst3.size());
-        assertArrayEquals(data1, lst3.get(0).getData());
-        assertArrayEquals(data2, lst3.get(1).getData());
-        assertArrayEquals(data3, lst3.get(2).getData());
-
-        sh = wb.getSheet("Pictures");
-        dr = sh.createDrawingPatriarch();
-        assertEquals(3, dr.getChildren().size());
-
-        // forth picture
-        byte[] data4 = new byte[]{10, 11, 12};
-        int idx4 = wb.addPicture(data4, Workbook.PICTURE_TYPE_JPEG);
-        assertEquals(4, idx4);
-        dr.createPicture(anchor, idx4);
-        assertEquals(4, dr.getChildren().size());
-        assertArrayEquals(data1, ((HSSFPicture)dr.getChildren().get(0)).getPictureData().getData());
-        assertArrayEquals(data2, ((HSSFPicture)dr.getChildren().get(1)).getPictureData().getData());
-        assertArrayEquals(data3, ((HSSFPicture)dr.getChildren().get(2)).getPictureData().getData());
-        assertArrayEquals(data4, ((HSSFPicture)dr.getChildren().get(3)).getPictureData().getData());
-
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
-        List<? extends PictureData> lst4 =  wb.getAllPictures();
-        assertEquals(4, lst4.size());
-        assertArrayEquals(data1, lst4.get(0).getData());
-        assertArrayEquals(data2, lst4.get(1).getData());
-        assertArrayEquals(data3, lst4.get(2).getData());
-        assertArrayEquals(data4, lst4.get(3).getData());
-        sh = wb.getSheet("Pictures");
-        dr = sh.createDrawingPatriarch();
-        assertEquals(4, dr.getChildren().size());
-        assertArrayEquals(data1, ((HSSFPicture)dr.getChildren().get(0)).getPictureData().getData());
-        assertArrayEquals(data2, ((HSSFPicture)dr.getChildren().get(1)).getPictureData().getData());
-        assertArrayEquals(data3, ((HSSFPicture)dr.getChildren().get(2)).getPictureData().getData());
-        assertArrayEquals(data4, ((HSSFPicture)dr.getChildren().get(3)).getPictureData().getData());
-        
-        wb.close();
+        try (HSSFWorkbook wb1 = new HSSFWorkbook()) {
+
+            HSSFSheet sh = wb1.createSheet("Pictures");
+            HSSFPatriarch dr = sh.createDrawingPatriarch();
+            assertEquals(0, dr.getChildren().size());
+            HSSFClientAnchor anchor = wb1.getCreationHelper().createClientAnchor();
+
+            //register a picture
+            byte[] data1 = {1, 2, 3};
+            int idx1 = wb1.addPicture(data1, Workbook.PICTURE_TYPE_JPEG);
+            assertEquals(1, idx1);
+            HSSFPicture p1 = dr.createPicture(anchor, idx1);
+            assertArrayEquals(data1, p1.getPictureData().getData());
+
+            // register another one
+            byte[] data2 = {4, 5, 6};
+            int idx2 = wb1.addPicture(data2, Workbook.PICTURE_TYPE_JPEG);
+            assertEquals(2, idx2);
+            HSSFPicture p2 = dr.createPicture(anchor, idx2);
+            assertEquals(2, dr.getChildren().size());
+            assertArrayEquals(data2, p2.getPictureData().getData());
+
+            // confirm that HSSFPatriarch.getChildren() returns two picture shapes
+            assertArrayEquals(data1, ((HSSFPicture) dr.getChildren().get(0)).getPictureData().getData());
+            assertArrayEquals(data2, ((HSSFPicture) dr.getChildren().get(1)).getPictureData().getData());
+
+            // write, read back and verify that our pictures are there
+            try (HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1)) {
+                List<? extends PictureData> lst2 = wb2.getAllPictures();
+                assertEquals(2, lst2.size());
+                assertArrayEquals(data1, lst2.get(0).getData());
+                assertArrayEquals(data2, lst2.get(1).getData());
+
+                // confirm that the pictures are in the Sheet's drawing
+                sh = wb2.getSheet("Pictures");
+                dr = sh.createDrawingPatriarch();
+                assertEquals(2, dr.getChildren().size());
+                assertArrayEquals(data1, ((HSSFPicture) dr.getChildren().get(0)).getPictureData().getData());
+                assertArrayEquals(data2, ((HSSFPicture) dr.getChildren().get(1)).getPictureData().getData());
+
+                // add a third picture
+                byte[] data3 = {7, 8, 9};
+                // picture index must increment across write-read
+                int idx3 = wb2.addPicture(data3, Workbook.PICTURE_TYPE_JPEG);
+                assertEquals(3, idx3);
+                HSSFPicture p3 = dr.createPicture(anchor, idx3);
+                assertArrayEquals(data3, p3.getPictureData().getData());
+                assertEquals(3, dr.getChildren().size());
+                assertArrayEquals(data1, ((HSSFPicture) dr.getChildren().get(0)).getPictureData().getData());
+                assertArrayEquals(data2, ((HSSFPicture) dr.getChildren().get(1)).getPictureData().getData());
+                assertArrayEquals(data3, ((HSSFPicture) dr.getChildren().get(2)).getPictureData().getData());
+
+                // write and read again
+                try (HSSFWorkbook wb3 = HSSFTestDataSamples.writeOutAndReadBack(wb2)) {
+                    List<? extends PictureData> lst3 = wb3.getAllPictures();
+                    // all three should be there
+                    assertEquals(3, lst3.size());
+                    assertArrayEquals(data1, lst3.get(0).getData());
+                    assertArrayEquals(data2, lst3.get(1).getData());
+                    assertArrayEquals(data3, lst3.get(2).getData());
+
+                    sh = wb3.getSheet("Pictures");
+                    dr = sh.createDrawingPatriarch();
+                    assertEquals(3, dr.getChildren().size());
+
+                    // forth picture
+                    byte[] data4 = {10, 11, 12};
+                    int idx4 = wb3.addPicture(data4, Workbook.PICTURE_TYPE_JPEG);
+                    assertEquals(4, idx4);
+                    dr.createPicture(anchor, idx4);
+                    assertEquals(4, dr.getChildren().size());
+                    assertArrayEquals(data1, ((HSSFPicture) dr.getChildren().get(0)).getPictureData().getData());
+                    assertArrayEquals(data2, ((HSSFPicture) dr.getChildren().get(1)).getPictureData().getData());
+                    assertArrayEquals(data3, ((HSSFPicture) dr.getChildren().get(2)).getPictureData().getData());
+                    assertArrayEquals(data4, ((HSSFPicture) dr.getChildren().get(3)).getPictureData().getData());
+
+                    try (HSSFWorkbook wb4 = HSSFTestDataSamples.writeOutAndReadBack(wb3)) {
+                        List<? extends PictureData> lst4 = wb4.getAllPictures();
+                        assertEquals(4, lst4.size());
+                        assertArrayEquals(data1, lst4.get(0).getData());
+                        assertArrayEquals(data2, lst4.get(1).getData());
+                        assertArrayEquals(data3, lst4.get(2).getData());
+                        assertArrayEquals(data4, lst4.get(3).getData());
+                        sh = wb4.getSheet("Pictures");
+                        dr = sh.createDrawingPatriarch();
+                        assertEquals(4, dr.getChildren().size());
+                        assertArrayEquals(data1, ((HSSFPicture) dr.getChildren().get(0)).getPictureData().getData());
+                        assertArrayEquals(data2, ((HSSFPicture) dr.getChildren().get(1)).getPictureData().getData());
+                        assertArrayEquals(data3, ((HSSFPicture) dr.getChildren().get(2)).getPictureData().getData());
+                        assertArrayEquals(data4, ((HSSFPicture) dr.getChildren().get(3)).getPictureData().getData());
+                    }
+                }
+            }
+        }
     }
 
     @SuppressWarnings("unused")
     @Test
     public void bsePictureRef() throws IOException {
-        HSSFWorkbook wb = new HSSFWorkbook();
-
-        HSSFSheet sh = wb.createSheet("Pictures");
-        HSSFPatriarch dr = sh.createDrawingPatriarch();
-        HSSFClientAnchor anchor = new HSSFClientAnchor();
+        try (HSSFWorkbook wb = new HSSFWorkbook()) {
+            HSSFSheet sh = wb.createSheet("Pictures");
+            HSSFPatriarch dr = sh.createDrawingPatriarch();
+            HSSFClientAnchor anchor = new HSSFClientAnchor();
 
-        InternalSheet ish = HSSFTestHelper.getSheetForTest(sh);
+            InternalSheet ish = HSSFTestHelper.getSheetForTest(sh);
 
-        //register a picture
-        byte[] data1 = new byte[]{1, 2, 3};
-        int idx1 = wb.addPicture(data1, Workbook.PICTURE_TYPE_JPEG);
-        assertEquals(1, idx1);
-        HSSFPicture p1 = dr.createPicture(anchor, idx1);
+            //register a picture
+            byte[] data1 = {1, 2, 3};
+            int idx1 = wb.addPicture(data1, Workbook.PICTURE_TYPE_JPEG);
+            assertEquals(1, idx1);
+            HSSFPicture p1 = dr.createPicture(anchor, idx1);
 
-        EscherBSERecord bse = wb.getWorkbook().getBSERecord(idx1);
+            EscherBSERecord bse = wb.getWorkbook().getBSERecord(idx1);
 
-        assertEquals(bse.getRef(), 1);
-        dr.createPicture(new HSSFClientAnchor(), idx1);
-        assertEquals(bse.getRef(), 2);
+            assertEquals(bse.getRef(), 1);
+            dr.createPicture(new HSSFClientAnchor(), idx1);
+            assertEquals(bse.getRef(), 2);
 
-        HSSFShapeGroup gr = dr.createGroup(new HSSFClientAnchor());
-        gr.createPicture(new HSSFChildAnchor(), idx1);
-        assertEquals(bse.getRef(), 3);
-        
-        wb.close();
+            HSSFShapeGroup gr = dr.createGroup(new HSSFClientAnchor());
+            gr.createPicture(new HSSFChildAnchor(), idx1);
+            assertEquals(bse.getRef(), 3);
+        }
     }
 
     @Test
-    public void readExistingImage(){
-        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
-        HSSFSheet sheet = wb.getSheet("picture");
-        HSSFPatriarch drawing = sheet.getDrawingPatriarch();
-        assertEquals(1, drawing.getChildren().size());
-
-        HSSFPicture picture = (HSSFPicture) drawing.getChildren().get(0);
-        assertEquals(picture.getFileName(), "test");
+    public void readExistingImage() throws IOException {
+        try (HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls")) {
+            HSSFSheet sheet = wb.getSheet("picture");
+            HSSFPatriarch drawing = sheet.getDrawingPatriarch();
+            assertEquals(1, drawing.getChildren().size());
+
+            HSSFPicture picture = (HSSFPicture) drawing.getChildren().get(0);
+            assertEquals(picture.getFileName(), "test");
+        }
     }
 
     @SuppressWarnings("resource")
     @Test
     public void setGetProperties() throws IOException {
-        HSSFWorkbook wb = new HSSFWorkbook();
+        try (HSSFWorkbook wb1 = new HSSFWorkbook()) {
 
-        HSSFSheet sh = wb.createSheet("Pictures");
-        HSSFPatriarch dr = sh.createDrawingPatriarch();
-        HSSFClientAnchor anchor = new HSSFClientAnchor();
+            HSSFSheet sh = wb1.createSheet("Pictures");
+            HSSFPatriarch dr = sh.createDrawingPatriarch();
+            HSSFClientAnchor anchor = new HSSFClientAnchor();
 
-        //register a picture
-        byte[] data1 = new byte[]{1, 2, 3};
-        int idx1 = wb.addPicture(data1, Workbook.PICTURE_TYPE_JPEG);
-        HSSFPicture p1 = dr.createPicture(anchor, idx1);
+            //register a picture
+            byte[] data1 = {1, 2, 3};
+            int idx1 = wb1.addPicture(data1, Workbook.PICTURE_TYPE_JPEG);
+            HSSFPicture p1 = dr.createPicture(anchor, idx1);
 
-        assertEquals(p1.getFileName(), "");
-        p1.setFileName("aaa");
-        assertEquals(p1.getFileName(), "aaa");
+            assertEquals(p1.getFileName(), "");
+            p1.setFileName("aaa");
+            assertEquals(p1.getFileName(), "aaa");
 
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
-        sh = wb.getSheet("Pictures");
-        dr = sh.getDrawingPatriarch();
+            try (HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1)) {
+                sh = wb2.getSheet("Pictures");
+                dr = sh.getDrawingPatriarch();
 
-        p1 = (HSSFPicture) dr.getChildren().get(0);
-        assertEquals(p1.getFileName(), "aaa");
-        wb.close();
+                p1 = (HSSFPicture) dr.getChildren().get(0);
+                assertEquals(p1.getFileName(), "aaa");
+            }
+        }
     }
 
     @SuppressWarnings("resource")
     @Test
     public void bug49658() 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);
-        byte[] pictureDataWmf = POIDataSamples.getSlideShowInstance().readFile("santa.wmf");
-        int indexWmf = wb.addPicture(pictureDataWmf, HSSFWorkbook.PICTURE_TYPE_WMF);
-
-        HSSFSheet sheet = wb.createSheet();
-        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
-        CreationHelper ch = wb.getCreationHelper();
-
-        ClientAnchor anchor = ch.createClientAnchor();
-        anchor.setCol1(2);
-        anchor.setCol2(5);
-        anchor.setRow1(1);
-        anchor.setRow2(6);
-        patriarch.createPicture(anchor, indexEmf);
-        
-        anchor = ch.createClientAnchor();
-        anchor.setCol1(2);
-        anchor.setCol2(5);
-        anchor.setRow1(10);
-        anchor.setRow2(16);
-        patriarch.createPicture(anchor, indexPng);
-
-        anchor = ch.createClientAnchor();
-        anchor.setCol1(6);
-        anchor.setCol2(9);
-        anchor.setRow1(1);
-        anchor.setRow2(6);
-        patriarch.createPicture(anchor, indexWmf);
-        
-        
-        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
-        byte[] pictureDataOut = wb.getAllPictures().get(0).getData();
-        assertArrayEquals(pictureDataEmf, pictureDataOut);
-
-        byte[] wmfNoHeader = new byte[pictureDataWmf.length - 22];
-        System.arraycopy(pictureDataWmf, 22, wmfNoHeader, 0, pictureDataWmf.length-22);
-        pictureDataOut = wb.getAllPictures().get(2).getData();
-        assertArrayEquals(wmfNoHeader, pictureDataOut);
-
-        wb.close();
+        try (HSSFWorkbook wb1 = new HSSFWorkbook()) {
+
+            byte[] pictureDataEmf = POIDataSamples.getDocumentInstance().readFile("vector_image.emf");
+            int indexEmf = wb1.addPicture(pictureDataEmf, HSSFWorkbook.PICTURE_TYPE_EMF);
+            byte[] pictureDataPng = POIDataSamples.getSpreadSheetInstance().readFile("logoKarmokar4.png");
+            int indexPng = wb1.addPicture(pictureDataPng, HSSFWorkbook.PICTURE_TYPE_PNG);
+            byte[] pictureDataWmf = POIDataSamples.getSlideShowInstance().readFile("santa.wmf");
+            int indexWmf = wb1.addPicture(pictureDataWmf, HSSFWorkbook.PICTURE_TYPE_WMF);
+
+            HSSFSheet sheet = wb1.createSheet();
+            HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
+            CreationHelper ch = wb1.getCreationHelper();
+
+            ClientAnchor anchor = ch.createClientAnchor();
+            anchor.setCol1(2);
+            anchor.setCol2(5);
+            anchor.setRow1(1);
+            anchor.setRow2(6);
+            patriarch.createPicture(anchor, indexEmf);
+
+            anchor = ch.createClientAnchor();
+            anchor.setCol1(2);
+            anchor.setCol2(5);
+            anchor.setRow1(10);
+            anchor.setRow2(16);
+            patriarch.createPicture(anchor, indexPng);
+
+            anchor = ch.createClientAnchor();
+            anchor.setCol1(6);
+            anchor.setCol2(9);
+            anchor.setRow1(1);
+            anchor.setRow2(6);
+            patriarch.createPicture(anchor, indexWmf);
+
+
+            try (HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1)) {
+                byte[] pictureDataOut = wb2.getAllPictures().get(0).getData();
+                assertArrayEquals(pictureDataEmf, pictureDataOut);
+
+                byte[] wmfNoHeader = new byte[pictureDataWmf.length - 22];
+                System.arraycopy(pictureDataWmf, 22, wmfNoHeader, 0, pictureDataWmf.length - 22);
+                pictureDataOut = wb2.getAllPictures().get(2).getData();
+                assertArrayEquals(wmfNoHeader, pictureDataOut);
+            }
+        }
     }
 
 }
index 555a2324804e3a8678693e2b009b7811b2fecfe1..b7cfac900052c12dd469dd7336bd86b6ee7a1a53 100644 (file)
 
 package org.apache.poi.ss.usermodel;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
+import java.awt.BasicStroke;
+import java.awt.Color;
 import java.awt.Dimension;
+import java.awt.Graphics2D;
 import java.awt.Point;
+import java.awt.RenderingHints;
+import java.awt.geom.Area;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.util.Arrays;
 
 import javax.imageio.ImageIO;
 
 import org.apache.poi.hssf.HSSFITestDataProvider;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.ITestDataProvider;
 import org.apache.poi.ss.util.ImageUtils;
 import org.apache.poi.util.Units;
 import org.junit.Test;
 
-/**
- * @author Yegor Kozlov
- */
 public abstract class BaseTestPicture {
 
     private final ITestDataProvider _testDataProvider;
@@ -47,15 +55,15 @@ public abstract class BaseTestPicture {
 
     public void baseTestResize(Picture input, Picture compare, double scaleX, double scaleY) {
         input.resize(scaleX, scaleY);
-        
+
         ClientAnchor inpCA = input.getClientAnchor();
         ClientAnchor cmpCA = compare.getClientAnchor();
-        
+
         Dimension inpDim = ImageUtils.getDimensionFromAnchor(input);
         Dimension cmpDim = ImageUtils.getDimensionFromAnchor(compare);
 
         double emuPX = Units.EMU_PER_PIXEL;
-        
+
         assertEquals("the image height differs", inpDim.getHeight(), cmpDim.getHeight(), emuPX*6);
         assertEquals("the image width differs", inpDim.getWidth(),  cmpDim.getWidth(),  emuPX*6);
         assertEquals("the starting column differs", inpCA.getCol1(), cmpCA.getCol1());
@@ -63,10 +71,10 @@ public abstract class BaseTestPicture {
         assertEquals("the column y-offset differs", inpCA.getDy1(), cmpCA.getDy1(), 1);
         assertEquals("the ending columns differs", inpCA.getCol2(), cmpCA.getCol2());
         // can't compare row heights because of variable test heights
-        
+
         input.resize();
         inpDim = ImageUtils.getDimensionFromAnchor(input);
-        
+
         Dimension imgDim = input.getImageDimension();
 
         assertEquals("the image height differs", imgDim.getHeight(), inpDim.getHeight()/emuPX, 1);
@@ -103,29 +111,148 @@ public abstract class BaseTestPicture {
         CreationHelper createHelper = wb.getCreationHelper();
 
         final byte[] bytes = HSSFITestDataProvider.instance.getTestDataFileContent("logoKarmokar4.png");
-        
+
         row.setHeightInPoints(getImageSize(bytes).y);
-   
+
         int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
-   
+
         //add a picture shape
         ClientAnchor anchor = createHelper.createClientAnchor();
         //set top-left corner of the picture,
         //subsequent call of Picture#resize() will operate relative to it
         anchor.setCol1(0);
         anchor.setRow1(0);
-   
+
         Picture pict = drawing.createPicture(anchor, pictureIdx);
-   
+
         //auto-size picture relative to its top-left corner
         pict.resize();
     }
-    
+
     private static Point getImageSize( byte [] image) throws IOException {
         BufferedImage img = ImageIO.read(new ByteArrayInputStream(image));
-        
+
         assertNotNull(img);
-        
+
         return new Point(img.getWidth(), img.getHeight());
     }
+
+    @Test
+    public void bug64213() throws IOException {
+        int[] input = {
+            200, 50 * 256, -1,
+            400, 50 * 256, -1,
+            200, 50 * 256, 200,
+            400, 50 * 256, 200,
+            400, 50 * 256, 400,
+        };
+
+        int[] expXSSF = {
+            2, 952500, 2, 0, 2, 1905000, 7, 0,
+            2, 952500, 2, 0, 2, 2857500, 12, 0,
+            2, 952500, 2, 0, 2, 1905000, 2, 952500,
+            2, 952500, 2, 0, 2, 2857500, 3, 0,
+            2, 952500, 2, 0, 2, 2857500, 2, 1905000
+        };
+
+        int[] expHSSF = {
+            2, 292, 2, 0, 2, 584, 7, 226,
+            2, 292, 2, 0, 2, 877, 13, 196,
+            2, 292, 2, 0, 2, 584, 2, 128,
+            2, 292, 2, 0, 2, 877, 3, 0,
+            2, 292, 2, 0, 2, 877, 2, 128
+        };
+
+        int[] expected = "xls".equals(_testDataProvider.getStandardFileNameExtension()) ? expHSSF : expXSSF;
+
+        for (int i=0; i<5; i++) {
+            int[] inp = Arrays.copyOfRange(input, i*3, (i+1)*3);
+            int[] exp = Arrays.copyOfRange(expected, i*8, (i+1)*8);
+            int[] act = bug64213Helper(inp[0], inp[1], inp[2]);
+            assertArrayEquals(exp, act);
+        }
+    }
+
+    private int[] bug64213Helper(int imgDim, int colWidth, int rowHeight) throws IOException {
+        final int col1 = 2;
+        final int dx1Pixel = 100;
+        final int row1 = 2;
+        final float scale = 0.5f;
+
+        try (Workbook wb = _testDataProvider.createWorkbook()) {
+            Sheet sheet = wb.createSheet("Sheet1");
+
+            final byte[] bytes = createTestImage(imgDim, imgDim);
+            int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
+
+            sheet.setColumnWidth(col1, colWidth);
+            float col1px = sheet.getColumnWidthInPixels(col1);
+            if (rowHeight > -1) {
+                sheet.createRow(row1).setHeightInPoints((float) Units.pixelToPoints(rowHeight));
+            }
+
+            //create an anchor with upper left cell column/startRow, only one cell anchor since bottom right depends on resizing
+            CreationHelper helper = wb.getCreationHelper();
+            ClientAnchor anchor = helper.createClientAnchor();
+            anchor.setCol1(col1);
+            if (wb instanceof HSSFWorkbook) {
+                anchor.setDx1((int)(dx1Pixel * 1024 / col1px));
+            } else {
+                anchor.setDx1(dx1Pixel * Units.EMU_PER_PIXEL);
+            }
+            anchor.setRow1(row1);
+
+
+            //create a picture anchored to Col1 and Row1
+            Drawing<?> drawing = sheet.createDrawingPatriarch();
+            Picture pict = drawing.createPicture(anchor, pictureIdx);
+
+            //resize the picture to it's native size
+            pict.resize();
+
+            //resize the picture scaled proportional
+            pict.resize(scale);
+
+            ClientAnchor anc = (ClientAnchor)pict.getAnchor();
+            return new int[]{
+                anc.getCol1(), anc.getDx1(),
+                anc.getRow1(), anc.getDy1(),
+                anc.getCol2(), anc.getDx2(),
+                anc.getRow2(), anc.getDy2()
+            };
+        }
+    }
+
+    private static byte[] createTestImage(double width, double height) throws IOException {
+        BufferedImage bi = new BufferedImage((int)width, (int)height, BufferedImage.TYPE_INT_ARGB);
+        Graphics2D g = bi.createGraphics();
+
+        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+        g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+
+        g.scale((width-1)/width, (height-1)/height);
+
+        g.setStroke(new BasicStroke(1));
+
+        double ellSize = 5/6d;
+        Ellipse2D ell = new Ellipse2D.Double(width * (1-ellSize)/2d, height * (1-ellSize)/2d, width * ellSize, height * ellSize);
+        Color[] colors = { Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW };
+        Rectangle2D rect = new Rectangle2D.Double();
+        for (int i=0; i<4; i++) {
+            rect.setRect(width/2 * (i&1),height/2 * (i>>1&1), width/2, height/2);
+            Area a = new Area(rect);
+            a.subtract(new Area(ell));
+            g.setPaint(colors[i]);
+            g.fill(a);
+            g.setColor(java.awt.Color.BLACK);
+            g.draw(rect);
+        }
+        g.draw(ell);
+
+        g.dispose();
+        ByteArrayOutputStream bos = new ByteArrayOutputStream(2000);
+        ImageIO.write(bi, "PNG", bos);
+        return bos.toByteArray();
+    }
 }