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
This commit is contained in:
Yegor Kozlov 2011-06-11 14:58:50 +00:00
parent faf7437a1e
commit 9e8dd1a859
4 changed files with 120 additions and 32 deletions

View File

@ -34,6 +34,7 @@
<changes> <changes>
<release version="3.8-beta4" date="2011-??-??"> <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">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">51265 - Enhanced Handling of Picture Parts in XWPF</action>
<action dev="poi-developers" type="add">51292 - Additional HWPF Table Cell Descriptor values</action> <action dev="poi-developers" type="add">51292 - Additional HWPF Table Cell Descriptor values</action>

View File

@ -41,7 +41,14 @@ public final class Picture
static final int PICT_HEADER_OFFSET = 0x4; static final int PICT_HEADER_OFFSET = 0x4;
static final int MFPMM_OFFSET = 0x6; static final int MFPMM_OFFSET = 0x6;
static final int PICF_SHAPE_OFFSET = 0xE; 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; static final int UNKNOWN_HEADER_SIZE = 0x49;
public static final byte[] GIF = new byte[]{'G', 'I', 'F'}; public static final byte[] GIF = new byte[]{'G', 'I', 'F'};
@ -74,6 +81,13 @@ public final class Picture
private int height = -1; private int height = -1;
private int width = -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) public Picture(int dataBlockStartOfsset, byte[] _dataStream, boolean fillBytes)
{ {
@ -87,8 +101,16 @@ public final class Picture
} }
this.aspectRatioX = extractAspectRatioX(_dataStream, dataBlockStartOfsset); this.dxaGoal = LittleEndian.getShort(_dataStream, dataBlockStartOfsset+DXAGOAL_OFFSET);
this.aspectRatioY = extractAspectRatioY(_dataStream, dataBlockStartOfsset); 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) 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 * 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. * is tried to determine from first byte of picture's content.
@ -154,7 +166,7 @@ public final class Picture
out.write(_dataStream, pictureBytesStartOffset, size); out.write(_dataStream, pictureBytesStartOffset, size);
} }
} }
/** /**
* @return The offset of this picture in the picture bytes, used * @return The offset of this picture in the picture bytes, used
* when matching up with {@link CharacterRun#getPicOffset()} * when matching up with {@link CharacterRun#getPicOffset()}
@ -193,22 +205,67 @@ public final class Picture
return size; return size;
} }
/** /**
* returns horizontal aspect ratio for picture provided by user * @return the horizontal aspect ratio for picture provided by user
*/ */
public int getAspectRatioX() public int getAspectRatioX() {
{ return aspectRatioX;
return aspectRatioX; }
}
/**
* returns vertical aspect ratio for picture provided by user
*/
public int getAspectRatioY()
{
return aspectRatioY;
}
/** /**
* @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 * tries to suggest extension for picture's file by matching signatures of popular image formats to first bytes
* of picture's contents * of picture's contents
* @return suggested file extension * @return suggested file extension
@ -222,7 +279,7 @@ public final class Picture
} }
return extension; return extension;
} }
/** /**
* Returns the mime type for the image * Returns the mime type for the image
*/ */
@ -361,10 +418,10 @@ public final class Picture
{ {
int realPicoffset = dataBlockStartOffset; int realPicoffset = dataBlockStartOffset;
final int dataBlockEndOffset = dataBlockSize + dataBlockStartOffset; final int dataBlockEndOffset = dataBlockSize + dataBlockStartOffset;
// Skip over the PICT block // Skip over the PICT block
int PICTFBlockSize = LittleEndian.getShort(_dataStream, dataBlockStartOffset +PICT_HEADER_OFFSET); // Should be 68 bytes int PICTFBlockSize = LittleEndian.getShort(_dataStream, dataBlockStartOffset +PICT_HEADER_OFFSET); // Should be 68 bytes
// Now the PICTF1 // Now the PICTF1
int PICTF1BlockOffset = PICTFBlockSize + PICT_HEADER_OFFSET; int PICTF1BlockOffset = PICTFBlockSize + PICT_HEADER_OFFSET;
short MM_TYPE = LittleEndian.getShort(_dataStream, dataBlockStartOffset + PICT_HEADER_OFFSET + 2); short MM_TYPE = LittleEndian.getShort(_dataStream, dataBlockStartOffset + PICT_HEADER_OFFSET + 2);

View File

@ -302,4 +302,34 @@ public final class TestPictures extends TestCase {
assertEquals(4, escher8s); assertEquals(4, escher8s);
assertEquals(0, plain8s); 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());
}
} }

Binary file not shown.