Browse Source

Bugzilla 51335: Parse picture goal and crop sizes

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1134663 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_3_8_BETA4
Yegor Kozlov 13 years ago
parent
commit
9e8dd1a859

+ 1
- 0
src/documentation/content/xdocs/status.xml View File

@@ -34,6 +34,7 @@

<changes>
<release version="3.8-beta4" date="2011-??-??">
<action dev="poi-developers" type="add">51335 - Parse picture goal and crop sizes in HWPF</action>
<action dev="poi-developers" type="add">51305 - Add sprmTCellPaddingDefault support in HWPF</action>
<action dev="poi-developers" type="add">51265 - Enhanced Handling of Picture Parts in XWPF</action>
<action dev="poi-developers" type="add">51292 - Additional HWPF Table Cell Descriptor values</action>

+ 89
- 32
src/scratchpad/src/org/apache/poi/hwpf/usermodel/Picture.java View File

@@ -41,7 +41,14 @@ public final class Picture
static final int PICT_HEADER_OFFSET = 0x4;
static final int MFPMM_OFFSET = 0x6;
static final int PICF_SHAPE_OFFSET = 0xE;
static final int PICMD_OFFSET = 0x1C;
static final int DXAGOAL_OFFSET = 0x1C;
static final int DYAGOAL_OFFSET = 0x1E;
static final int MX_OFFSET = 0x20;
static final int MY_OFFSET = 0x22;
static final int DXACROPLEFT_OFFSET = 0x24;
static final int DYACROPTOP_OFFSET = 0x26;
static final int DXACROPRIGHT_OFFSET = 0x28;
static final int DYACROPBOTTOM_OFFSET = 0x2A;
static final int UNKNOWN_HEADER_SIZE = 0x49;

public static final byte[] GIF = new byte[]{'G', 'I', 'F'};
@@ -74,6 +81,13 @@ public final class Picture
private int height = -1;
private int width = -1;

private int dxaGoal = -1;
private int dyaGoal = -1;

private int dxaCropLeft = -1;
private int dyaCropTop = -1;
private int dxaCropRight = -1;
private int dyaCropBottom = -1;

public Picture(int dataBlockStartOfsset, byte[] _dataStream, boolean fillBytes)
{
@@ -87,8 +101,16 @@ public final class Picture

}

this.aspectRatioX = extractAspectRatioX(_dataStream, dataBlockStartOfsset);
this.aspectRatioY = extractAspectRatioY(_dataStream, dataBlockStartOfsset);
this.dxaGoal = LittleEndian.getShort(_dataStream, dataBlockStartOfsset+DXAGOAL_OFFSET);
this.dyaGoal = LittleEndian.getShort(_dataStream, dataBlockStartOfsset+DYAGOAL_OFFSET);

this.aspectRatioX = LittleEndian.getShort(_dataStream, dataBlockStartOfsset+MX_OFFSET)/10;
this.aspectRatioY = LittleEndian.getShort(_dataStream, dataBlockStartOfsset+MY_OFFSET)/10;

this.dxaCropLeft = LittleEndian.getShort(_dataStream, dataBlockStartOfsset+DXACROPLEFT_OFFSET);
this.dyaCropTop = LittleEndian.getShort(_dataStream, dataBlockStartOfsset+DYACROPTOP_OFFSET);
this.dxaCropRight = LittleEndian.getShort(_dataStream, dataBlockStartOfsset+DXACROPRIGHT_OFFSET);
this.dyaCropBottom = LittleEndian.getShort(_dataStream, dataBlockStartOfsset+DYACROPBOTTOM_OFFSET);

if (fillBytes)
{
@@ -116,16 +138,6 @@ public final class Picture
}
}

private static int extractAspectRatioX(byte[] _dataStream, int dataBlockStartOffset)
{
return LittleEndian.getShort(_dataStream, dataBlockStartOffset+0x20)/10;
}

private static int extractAspectRatioY(byte[] _dataStream, int dataBlockStartOffset)
{
return LittleEndian.getShort(_dataStream, dataBlockStartOffset+0x22)/10;
}

/**
* Tries to suggest a filename: hex representation of picture structure offset in "Data" stream plus extension that
* is tried to determine from first byte of picture's content.
@@ -154,7 +166,7 @@ public final class Picture
out.write(_dataStream, pictureBytesStartOffset, size);
}
}
/**
* @return The offset of this picture in the picture bytes, used
* when matching up with {@link CharacterRun#getPicOffset()}
@@ -193,22 +205,67 @@ public final class Picture
return size;
}

/**
* returns horizontal aspect ratio for picture provided by user
*/
public int getAspectRatioX()
{
return aspectRatioX;
}
/**
* returns vertical aspect ratio for picture provided by user
*/
public int getAspectRatioY()
{
return aspectRatioY;
}
/**
* @return the horizontal aspect ratio for picture provided by user
*/
public int getAspectRatioX() {
return aspectRatioX;
}

/**
/**
* @retrn the vertical aspect ratio for picture provided by user
*/
public int getAspectRatioY() {
return aspectRatioY;
}

/**
* Gets the initial width of the picture, in twips, prior to cropping or scaling.
*
* @return the initial width of the picture in twips
*/
public int getDxaGoal() {
return dxaGoal;
}

/**
* Gets the initial height of the picture, in twips, prior to cropping or scaling.
*
* @return the initial width of the picture in twips
*/
public int getDyaGoal() {
return dyaGoal;
}

/**
* @return The amount the picture has been cropped on the left in twips
*/
public int getDxaCropLeft() {
return dxaCropLeft;
}

/**
* @return The amount the picture has been cropped on the top in twips
*/
public int getDyaCropTop() {
return dyaCropTop;
}

/**
* @return The amount the picture has been cropped on the right in twips
*/
public int getDxaCropRight() {
return dxaCropRight;
}

/**
* @return The amount the picture has been cropped on the bottom in twips
*/
public int getDyaCropBottom() {
return dyaCropBottom;
}

/**
* tries to suggest extension for picture's file by matching signatures of popular image formats to first bytes
* of picture's contents
* @return suggested file extension
@@ -222,7 +279,7 @@ public final class Picture
}
return extension;
}
/**
* Returns the mime type for the image
*/
@@ -361,10 +418,10 @@ public final class Picture
{
int realPicoffset = dataBlockStartOffset;
final int dataBlockEndOffset = dataBlockSize + dataBlockStartOffset;
// Skip over the PICT block
int PICTFBlockSize = LittleEndian.getShort(_dataStream, dataBlockStartOffset +PICT_HEADER_OFFSET); // Should be 68 bytes
// Now the PICTF1
int PICTF1BlockOffset = PICTFBlockSize + PICT_HEADER_OFFSET;
short MM_TYPE = LittleEndian.getShort(_dataStream, dataBlockStartOffset + PICT_HEADER_OFFSET + 2);

+ 30
- 0
src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestPictures.java View File

@@ -302,4 +302,34 @@ public final class TestPictures extends TestCase {
assertEquals(4, escher8s);
assertEquals(0, plain8s);
}

public void testCroppedPictures() {
HWPFDocument doc = HWPFTestDataSamples.openSampleFile("testCroppedPictures.doc");
List<Picture> pics = doc.getPicturesTable().getAllPictures();

assertNotNull(pics);
assertEquals(2, pics.size());

Picture pic1 = pics.get(0);
assertEquals(27, pic1.getAspectRatioX());
assertEquals(27, pic1.getAspectRatioY());
assertEquals(12000, pic1.getDxaGoal()); // 21.17 cm / 2.54 cm/inch * 72dpi * 20 = 12000
assertEquals(9000, pic1.getDyaGoal()); // 15.88 cm / 2.54 cm/inch * 72dpi * 20 = 9000
assertEquals(0, pic1.getDxaCropLeft());
assertEquals(0, pic1.getDxaCropRight());
assertEquals(0, pic1.getDyaCropTop());
assertEquals(0, pic1.getDyaCropBottom());

Picture pic2 = pics.get(1);
System.out.println(pic2.getWidth());
assertEquals(76, pic2.getAspectRatioX());
assertEquals(68, pic2.getAspectRatioY());
assertEquals(12000, pic2.getDxaGoal()); // 21.17 cm / 2.54 cm/inch * 72dpi * 20 = 12000
assertEquals(9000, pic2.getDyaGoal()); // 15.88 cm / 2.54 cm/inch * 72dpi * 20 = 9000
assertEquals(0, pic2.getDxaCropLeft()); // TODO YK: The Picture is cropped but HWPF reads the crop parameters all zeros
assertEquals(0, pic2.getDxaCropRight());
assertEquals(0, pic2.getDyaCropTop());
assertEquals(0, pic2.getDyaCropBottom());
}

}

BIN
test-data/document/testCroppedPictures.doc View File


Loading…
Cancel
Save