Author: damjan Date: Sat Oct 15 05:38:29 2011 New Revision: 1183584 URL: http://svn.apache.org/viewvc?rev=1183584&view=rev Log: "Tiff (exif) tags of type double written in wrong byte order" patch from Gary Lucas, with my tests and fix to convertByteArrayToDouble().
Jira issue key: SANSELAN-54 Submitted by: Gary Lucas <gwlucas at sonalysts dot com> Added: commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/common/BinaryFileFunctionsTest.java Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileFunctions.java Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileFunctions.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileFunctions.java?rev=1183584&r1=1183583&r2=1183584&view=diff ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileFunctions.java (original) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileFunctions.java Sat Oct 15 05:38:29 2011 @@ -857,12 +857,11 @@ public class BinaryFileFunctions impleme protected final byte[] convertFloatToByteArray(float value, int byteOrder) { - // TODO: not tested; probably wrong. byte result[] = new byte[4]; int bits = Float.floatToRawIntBits(value); - if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian + if (byteOrder == BYTE_ORDER_INTEL) // intel, big endian { result[0] = (byte) (0xff & (bits >> 0)); result[1] = (byte) (0xff & (bits >> 8)); @@ -882,7 +881,6 @@ public class BinaryFileFunctions impleme protected final byte[] convertFloatArrayToByteArray(float values[], int byteOrder) { - // TODO: not tested; probably wrong. byte result[] = new byte[values.length * 4]; for (int i = 0; i < values.length; i++) { @@ -890,7 +888,7 @@ public class BinaryFileFunctions impleme int bits = Float.floatToRawIntBits(value); int start = i * 4; - if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian + if (byteOrder == BYTE_ORDER_INTEL) // intel, little endian { result[start + 0] = (byte) (0xff & (bits >> 0)); result[start + 1] = (byte) (0xff & (bits >> 8)); @@ -909,12 +907,11 @@ public class BinaryFileFunctions impleme protected final byte[] convertDoubleToByteArray(double value, int byteOrder) { - // TODO: not tested; probably wrong. byte result[] = new byte[8]; long bits = Double.doubleToRawLongBits(value); - if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian + if (byteOrder == BYTE_ORDER_INTEL) // intel, little endian { result[0] = (byte) (0xff & (bits >> 0)); result[1] = (byte) (0xff & (bits >> 8)); @@ -942,7 +939,6 @@ public class BinaryFileFunctions impleme protected final byte[] convertDoubleArrayToByteArray(double values[], int byteOrder) { - // TODO: not tested; probably wrong. byte result[] = new byte[values.length * 8]; for (int i = 0; i < values.length; i++) { @@ -950,7 +946,7 @@ public class BinaryFileFunctions impleme long bits = Double.doubleToRawLongBits(value); int start = i * 8; - if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian + if (byteOrder == BYTE_ORDER_INTEL) // intel, little endian { result[start + 0] = (byte) (0xff & (bits >> 0)); result[start + 1] = (byte) (0xff & (bits >> 8)); @@ -984,8 +980,6 @@ public class BinaryFileFunctions impleme protected final double convertByteArrayToDouble(String name, byte bytes[], int start, int byteOrder) { - // TODO: not tested; probably wrong. - byte byte0 = bytes[start + 0]; byte byte1 = bytes[start + 1]; byte byte2 = bytes[start + 2]; @@ -999,18 +993,18 @@ public class BinaryFileFunctions impleme if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian { - bits = ((0xff & byte0) << 56) | ((0xff & byte1) << 48) - | ((0xff & byte2) << 40) | ((0xff & byte3) << 32) - | ((0xff & byte4) << 24) | ((0xff & byte5) << 16) - | ((0xff & byte6) << 8) | ((0xff & byte7) << 0); + bits = ((0xffL & byte0) << 56) | ((0xffL & byte1) << 48) + | ((0xffL & byte2) << 40) | ((0xffL & byte3) << 32) + | ((0xffL & byte4) << 24) | ((0xffL & byte5) << 16) + | ((0xffL & byte6) << 8) | ((0xffL & byte7) << 0); } else { // intel, little endian - bits = ((0xff & byte7) << 56) | ((0xff & byte6) << 48) - | ((0xff & byte5) << 40) | ((0xff & byte4) << 32) - | ((0xff & byte3) << 24) | ((0xff & byte2) << 16) - | ((0xff & byte1) << 8) | ((0xff & byte0) << 0); + bits = ((0xffL & byte7) << 56) | ((0xffL & byte6) << 48) + | ((0xffL & byte5) << 40) | ((0xffL & byte4) << 32) + | ((0xffL & byte3) << 24) | ((0xffL & byte2) << 16) + | ((0xffL & byte1) << 8) | ((0xffL & byte0) << 0); } double result = Double.longBitsToDouble(bits); Added: commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/common/BinaryFileFunctionsTest.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/common/BinaryFileFunctionsTest.java?rev=1183584&view=auto ============================================================================== --- commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/common/BinaryFileFunctionsTest.java (added) +++ commons/proper/sanselan/trunk/src/test/java/org/apache/sanselan/common/BinaryFileFunctionsTest.java Sat Oct 15 05:38:29 2011 @@ -0,0 +1,52 @@ +/* + * Licensed 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. + * under the License. + */ + +package org.apache.sanselan.common; + +import org.apache.sanselan.SanselanTest; + +public class BinaryFileFunctionsTest extends SanselanTest { + // Work around that pesky "protected"... + private static class Extender extends BinaryFileFunctions { + public void testFloatToByteConversion() { + byte[] bytesLE = convertFloatToByteArray(1.0f, BYTE_ORDER_LITTLE_ENDIAN); + assertEquals(convertByteArrayToFloat("bytes", bytesLE, BYTE_ORDER_LITTLE_ENDIAN), + 1.0f, 0f); + + byte[] bytesBE = convertFloatToByteArray(1.0f, BYTE_ORDER_BIG_ENDIAN); + assertEquals(convertByteArrayToFloat("bytes", bytesBE, BYTE_ORDER_BIG_ENDIAN), + 1.0f, 0f); + } + + public void testDoubleToByteConversion() { + byte[] bytesLE = convertDoubleToByteArray(1.0, BYTE_ORDER_LITTLE_ENDIAN); + assertEquals(convertByteArrayToDouble("bytes", bytesLE, BYTE_ORDER_LITTLE_ENDIAN), + 1.0, 0); + + byte[] bytesBE = convertDoubleToByteArray(1.0, BYTE_ORDER_BIG_ENDIAN); + assertEquals(convertByteArrayToDouble("bytes", bytesBE, BYTE_ORDER_BIG_ENDIAN), + 1.0, 0); + } + } + private Extender extender = new Extender(); + + public void testFloatToByteConversion() { + extender.testFloatToByteConversion(); + } + + public void testDoubleToByteConversion() { + extender.testDoubleToByteConversion(); + } +}