Package org.apache.sanselan.formats.jpeg.exif

Source Code of org.apache.sanselan.formats.jpeg.exif.ExifRewriteTest$Rewriter

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/

package org.apache.sanselan.formats.jpeg.exif;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;

import org.apache.sanselan.ImageReadException;
import org.apache.sanselan.ImageWriteException;
import org.apache.sanselan.Sanselan;
import org.apache.sanselan.common.byteSources.ByteSource;
import org.apache.sanselan.common.byteSources.ByteSourceArray;
import org.apache.sanselan.common.byteSources.ByteSourceFile;
import org.apache.sanselan.formats.jpeg.JpegImageMetadata;
import org.apache.sanselan.formats.jpeg.JpegUtils;
import org.apache.sanselan.formats.jpeg.exifRewrite.ExifRewriter;
import org.apache.sanselan.formats.tiff.TiffField;
import org.apache.sanselan.formats.tiff.TiffImageMetadata;
import org.apache.sanselan.formats.tiff.constants.AllTagConstants;
import org.apache.sanselan.formats.tiff.write.TiffOutputSet;
import org.apache.sanselan.util.Debug;
import org.apache.sanselan.util.IOUtils;

public class ExifRewriteTest extends ExifBaseTest implements AllTagConstants
{
    //    public ExifRewriteTest(String name)
    //    {
    //        super(name);
    //    }

    public void testRemove() throws IOException, ImageReadException,
            ImageWriteException
    {
        List images = getImagesWithExifData();
        for (int i = 0; i < images.size(); i++)
        {
            if(i%10==0)
            Debug.purgeMemory();

            File imageFile = (File) images.get(i);
            Debug.debug("imageFile", imageFile);

            boolean ignoreImageData = isPhilHarveyTestImage(imageFile);
            if (ignoreImageData)
                continue;

            ByteSource byteSource = new ByteSourceFile(imageFile);
            Debug.debug("Source Segments:");
            new JpegUtils().dumpJFIF(byteSource);

            {
                JpegImageMetadata metadata = (JpegImageMetadata) Sanselan
                        .getMetadata(imageFile);
                //                assertNotNull(metadata.getExif());
            }

            {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                new ExifRewriter().removeExifMetadata(byteSource, baos);
                byte bytes[] = baos.toByteArray();
                File tempFile = createTempFile("test", ".jpg");
                Debug.debug("tempFile", tempFile);
                IOUtils.writeToFile(bytes, tempFile);

                Debug.debug("Output Segments:");
                new JpegUtils().dumpJFIF(new ByteSourceArray(bytes));

                assertTrue(!hasExifData(tempFile));
            }
        }
    }

    public void testInsert() throws IOException, ImageReadException,
            ImageWriteException
    {
        List images = getImagesWithExifData();
        for (int i = 0; i < images.size(); i++)
        {
            if(i%10==0)
            Debug.purgeMemory();

            File imageFile = (File) images.get(i);
            Debug.debug("imageFile", imageFile);

            // This test image contains invalid EXIF and would break the test.
            if (imageFile.getName().equals("Oregon Scientific DS6639 - DSC_0307.JPG")) {
                continue;
            }

            boolean ignoreImageData = isPhilHarveyTestImage(imageFile);
            if (ignoreImageData)
                continue;

            ByteSource byteSource = new ByteSourceFile(imageFile);
            Debug.debug("Source Segments:");
            new JpegUtils().dumpJFIF(byteSource);

            JpegImageMetadata originalMetadata = (JpegImageMetadata) Sanselan
                    .getMetadata(imageFile);
            assertNotNull(originalMetadata);

            TiffImageMetadata oldExifMetadata = originalMetadata.getExif();
            assertNotNull(oldExifMetadata);

            ByteSource stripped;
            {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                new ExifRewriter().removeExifMetadata(byteSource, baos);
                byte bytes[] = baos.toByteArray();
                File tempFile = createTempFile("removed", ".jpg");
                Debug.debug("tempFile", tempFile);
                IOUtils.writeToFile(bytes, tempFile);

                Debug.debug("Output Segments:");
                stripped = new ByteSourceArray(bytes);
                new JpegUtils().dumpJFIF(stripped);

                assertTrue(!hasExifData(tempFile));
            }

            {
                TiffOutputSet outputSet = oldExifMetadata.getOutputSet();
                //            outputSet.dump();

                ByteArrayOutputStream baos = new ByteArrayOutputStream();

                new ExifRewriter().updateExifMetadataLossy(stripped, baos,
                        outputSet);

                byte bytes[] = baos.toByteArray();
                File tempFile = createTempFile("inserted" + "_", ".jpg");
                Debug.debug("tempFile", tempFile);
                IOUtils.writeToFile(bytes, tempFile);

                Debug.debug("Output Segments:");
                new JpegUtils().dumpJFIF(new ByteSourceArray(bytes));

                //                assertTrue(!hasExifData(tempFile));

                JpegImageMetadata newMetadata = (JpegImageMetadata) Sanselan
                        .getMetadata(tempFile);
                assertNotNull(newMetadata);
                TiffImageMetadata newExifMetadata = newMetadata.getExif();
                assertNotNull(newExifMetadata);
                //                newMetadata.dump();

                compare(imageFile, oldExifMetadata, newExifMetadata);
            }

        }
    }

    private interface Rewriter
    {
        public void rewrite(ByteSource byteSource, OutputStream os,
                TiffOutputSet outputSet) throws ImageReadException,
                IOException, ImageWriteException;
    }

    private void rewrite(Rewriter rewriter, String name) throws IOException,
            ImageReadException, ImageWriteException
    {
        List images = getImagesWithExifData();
        for (int i = 0; i < images.size(); i++)
        {
            if(i%10==0)
            Debug.purgeMemory();

            File imageFile = (File) images.get(i);

            // This test image contains invalid EXIF and would break the test.
            if (imageFile.getName().equals("Oregon Scientific DS6639 - DSC_0307.JPG")) {
                continue;
            }

            try
            {

                Debug.debug("imageFile", imageFile);

                boolean ignoreImageData = isPhilHarveyTestImage(imageFile);
                if (ignoreImageData)
                    continue;

                ByteSource byteSource = new ByteSourceFile(imageFile);
                Debug.debug("Source Segments:");
                new JpegUtils().dumpJFIF(byteSource);

                JpegImageMetadata oldMetadata = (JpegImageMetadata) Sanselan
                        .getMetadata(imageFile);
                if (null == oldMetadata)
                    continue;
                assertNotNull(oldMetadata);

                TiffImageMetadata oldExifMetadata = oldMetadata.getExif();
                if (null == oldExifMetadata)
                    continue;
                assertNotNull(oldExifMetadata);
                oldMetadata.dump();

                //            TiffImageMetadata tiffImageMetadata = metadata.getExif();
                //            Photoshop photoshop = metadata.getPhotoshop();

                TiffOutputSet outputSet = oldExifMetadata.getOutputSet();
                //            outputSet.dump();

                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                rewriter.rewrite(byteSource, baos, outputSet);
                byte bytes[] = baos.toByteArray();
                File tempFile = createTempFile(name + "_", ".jpg");
                Debug.debug("tempFile", tempFile);
                IOUtils.writeToFile(bytes, tempFile);

                Debug.debug("Output Segments:");
                new JpegUtils().dumpJFIF(new ByteSourceArray(bytes));

                //                assertTrue(!hasExifData(tempFile));

                JpegImageMetadata newMetadata = (JpegImageMetadata) Sanselan
                        .getMetadata(tempFile);
                assertNotNull(newMetadata);
                TiffImageMetadata newExifMetadata = newMetadata.getExif();
                assertNotNull(newExifMetadata);
                //                newMetadata.dump();

                compare(imageFile, oldExifMetadata, newExifMetadata);
            }
            catch (IOException e)
            {
                Debug.debug("imageFile", imageFile.getAbsoluteFile());
                Debug.debug(e);
                throw e;
            }
            catch (ImageReadException e)
            {
                Debug.debug("imageFile", imageFile.getAbsoluteFile());
                Debug.debug(e);
                throw e;
            }
            catch (ImageWriteException e)
            {
                Debug.debug("imageFile", imageFile.getAbsoluteFile());
                Debug.debug(e);
                throw e;
            }

        }
    }

    public void testRewriteLossy() throws IOException, ImageReadException,
            ImageWriteException
    {
        Rewriter rewriter = new Rewriter()
        {
            public void rewrite(ByteSource byteSource, OutputStream os,
                    TiffOutputSet outputSet) throws ImageReadException,
                    IOException, ImageWriteException
            {
                new ExifRewriter().updateExifMetadataLossy(byteSource, os,
                        outputSet);
            }
        };

        rewrite(rewriter, "lossy");
    }

    public void testRewriteLossless() throws IOException, ImageReadException,
            ImageWriteException
    {
        Rewriter rewriter = new Rewriter()
        {
            public void rewrite(ByteSource byteSource, OutputStream os,
                    TiffOutputSet outputSet) throws ImageReadException,
                    IOException, ImageWriteException
            {
                new ExifRewriter().updateExifMetadataLossless(byteSource, os,
                        outputSet);
            }
        };

        rewrite(rewriter, "lossless");
    }

    private Hashtable makeDirectoryMap(ArrayList directories)
    {
        Hashtable directoryMap = new Hashtable();
        for (int i = 0; i < directories.size(); i++)
        {
            TiffImageMetadata.Directory directory = (TiffImageMetadata.Directory) directories
                    .get(i);
            directoryMap.put(new Integer(directory.type), directory);
        }
        return directoryMap;
    }

    private Hashtable makeFieldMap(ArrayList items)
    {
        Hashtable fieldMap = new Hashtable();
        for (int i = 0; i < items.size(); i++)
        {
            TiffImageMetadata.Item item = (TiffImageMetadata.Item) items.get(i);
            TiffField field = item.getTiffField();
            Object key = new Integer(field.tag);
            if (!fieldMap.containsKey(key))
                fieldMap.put(key, field);
        }
        return fieldMap;
    }

    private void compare(File imageFile, TiffImageMetadata oldExifMetadata,
            TiffImageMetadata newExifMetadata) throws ImageReadException
    {
        assertNotNull(oldExifMetadata);
        assertNotNull(newExifMetadata);

        ArrayList oldDirectories = oldExifMetadata.getDirectories();
        ArrayList newDirectories = newExifMetadata.getDirectories();

        assertTrue(oldDirectories.size() == newDirectories.size());

        Hashtable oldDirectoryMap = makeDirectoryMap(oldDirectories);
        Hashtable newDirectoryMap = makeDirectoryMap(newDirectories);

        assertEquals(oldDirectories.size(), oldDirectoryMap.keySet().size());
        ArrayList oldDirectoryTypes = new ArrayList(oldDirectoryMap.keySet());
        Collections.sort(oldDirectoryTypes);
        ArrayList newDirectoryTypes = new ArrayList(newDirectoryMap.keySet());
        Collections.sort(newDirectoryTypes);
        assertEquals(oldDirectoryTypes, newDirectoryTypes);

        for (int i = 0; i < oldDirectoryTypes.size(); i++)
        {
            Integer dirType = (Integer) oldDirectoryTypes.get(i);

            //            Debug.debug("dirType", dirType);

            TiffImageMetadata.Directory oldDirectory = (TiffImageMetadata.Directory) oldDirectoryMap
                    .get(dirType);
            TiffImageMetadata.Directory newDirectory = (TiffImageMetadata.Directory) newDirectoryMap
                    .get(dirType);
            assertNotNull(oldDirectory);
            assertNotNull(newDirectory);

            ArrayList oldItems = oldDirectory.getItems();
            ArrayList newItems = newDirectory.getItems();

            //            Debug.debug("oldItems.size()", oldItems.size());
            //            Debug.debug("newItems.size()", newItems.size());
            //            dump("oldItems", oldItems);
            //            dump("newItems", newItems);

            //            if (oldItems.size() != newItems.size())
            //                ;
            //            {
            //            dump("oldItems", oldItems);
            //            dump("newItems", newItems);
            //            }
            //            assertTrue(oldItems.size() == newItems.size());

            Hashtable oldFieldMap = makeFieldMap(oldItems);
            Hashtable newFieldMap = makeFieldMap(newItems);

            Set missingInNew = new HashSet(oldFieldMap.keySet());
            missingInNew.removeAll(newFieldMap.keySet());

            Set missingInOld = new HashSet(newFieldMap.keySet());
            missingInOld.removeAll(oldFieldMap.keySet());

            //            dump("missingInNew", missingInNew);
            //            dump("missingInOld", missingInOld);
            //            dump("newFieldMap.keySet()", newFieldMap.keySet());
            //            dump("oldFieldMap.keySet()", oldFieldMap.keySet());

            assertTrue(missingInNew.size() == 0);
            assertTrue(missingInOld.size() == 0);

            //            Debug.debug("oldItems.size()", oldItems.size());
            //            Debug.debug("oldFieldMap.keySet().size()", oldFieldMap.keySet().size());

            //            assertEquals(oldItems.size(), oldFieldMap.keySet().size());
            //            assertEquals(oldFieldMap.keySet(), newFieldMap.keySet());
            //            assertEquals(oldFieldMap.keySet(), newFieldMap.keySet());

            ArrayList oldFieldTags = new ArrayList(oldFieldMap.keySet());
            Collections.sort(oldFieldTags);
            ArrayList newFieldTags = new ArrayList(newFieldMap.keySet());
            Collections.sort(newFieldTags);
            assertEquals(oldFieldTags, newFieldTags);

            for (int j = 0; j < oldFieldTags.size(); j++)
            {
                Integer fieldTag = (Integer) oldFieldTags.get(j);

                TiffField oldField = (TiffField) oldFieldMap.get(fieldTag);
                TiffField newField = (TiffField) newFieldMap.get(fieldTag);

                //                Debug.debug("fieldTag", fieldTag);
                //                Debug.debug("oldField", oldField);
                //                Debug.debug("newField", newField);

                //                fieldTag.
                assertNotNull(oldField);
                assertNotNull(newField);

                assertEquals(oldField.tag, newField.tag);
                assertEquals(dirType.intValue(), newField.directoryType);
                assertEquals(oldField.directoryType, newField.directoryType);
                assertEquals(oldField.length, newField.length);
                assertEquals(oldField.isLocalValue(), newField.isLocalValue());

                if (oldField.tag == 0x202)
                {
                    // ignore "jpg from raw length" value. may have off-by-one bug in certain cameras.
                    // i.e. Sony DCR-PC110
                    continue;
                }

                if (!oldField.tagInfo.isOffset())
                {
                    if (oldField.tagInfo.isText())
                        ;
                    else if (oldField.isLocalValue())
                    {
                        //                        Debug.debug("oldField.tag", oldField.tag);
                        //                        Debug.debug("newField.tag", newField.tag);
                        //                        Debug.debug("oldField.tagInfo", oldField.tagInfo);
                        //                        Debug.debug("newField.tagInfo", newField.tagInfo);
                        //                        Debug.debug("oldField.fieldType", oldField.fieldType);
                        //                        Debug.debug("newField.fieldType", newField.fieldType);
                        //                        Debug.debug("oldField.getBytesLength", oldField
                        //                                .getBytesLength());
                        //                        Debug.debug("newField.getBytesLength", newField
                        //                                .getBytesLength());
                        //
                        //                        Debug.debug("oldField.valueOffsetBytes",
                        //                                oldField.valueOffsetBytes);
                        //                        Debug.debug("newField.valueOffsetBytes",
                        //                                newField.valueOffsetBytes);

                        String label = imageFile.getName() +
                                       ", dirType[" + i + "]=" + dirType +
                                       ", fieldTag[" + j + "]=" + fieldTag;
                        if (oldField.tag == 0x116 || oldField.tag == 0x117)
                            compare(label, oldField, newField);
                        else {
                            compare(label, oldField.valueOffsetBytes,
                                           newField.valueOffsetBytes,
                                           oldField.getBytesLength(),
                                           newField.getBytesLength());
                        }
                    }
                    else
                    {
                        //                        Debug.debug("oldField.tagInfo", oldField.tagInfo);
                        //                        Debug.debug("oldField.fieldType", oldField.fieldType);
                        //                        Debug.debug("newField.fieldType", newField.fieldType);
                        //                        Debug.debug("oldField.getBytesLength", oldField
                        //                                .getBytesLength());
                        //                        Debug.debug("newField.getBytesLength", newField
                        //                                .getBytesLength());

                        //                        Debug.debug("oldField.oversizeValue", oldField.oversizeValue);
                        //                        Debug.debug("newField.oversizeValue", newField.oversizeValue);

                        compare(oldField.oversizeValue, newField.oversizeValue);
                    }
                }

            }

            //            Debug.debug();
        }
    }

    private void compare(String label, byte a[], byte b[], int aLength, int bLength)
    {
        //        Debug.debug("c0 a", a);
        //        Debug.debug("c0 b", b);
        assertEquals(aLength, bLength);
        assertTrue(a.length >= aLength);
        assertTrue(b.length >= bLength);
        assertNotNull(a);
        assertNotNull(b);
        assertEquals(a.length, b.length);
        int length = aLength;
        for (int i = 0; i < length; i++)
        {
            //            byte ba = a[i];
            //            byte bb = b[i];
            //            boolean eq = ba == bb;
            //            Debug.debug("i: " + i + ", a[i]: " + ba + ", b[i]: " + bb + " = "
            //                    + (ba == bb) + " " + eq);
            //            if(ba != bb)
            //                assertFalse(true);
            //
            //            Debug.debug("i: " + i + ", a[i]: " + ba + ", b[i]: " + bb + " = "
            //                    + (ba == bb) + " " + eq);
            //            assertTrue(eq == true);
            assertEquals(label + ", byte[" + i + "]", a[i], b[i]);
            //            Debug.debug("c");
            //            assertTrue((0xff & a[i]) == (0xff & b[i]));
        }
    }

    private void compare(String label, TiffField a, TiffField b) throws ImageReadException
    {
        Object v1 = a.getValue();
        Object v2 = b.getValue();

        //        Debug.debug("v1", v1 + " (" + Debug.getType(v1) + ")");
        //        Debug.debug("v2", v2 + " (" + Debug.getType(v2) + ")");
        assertEquals(label, v1, v2);
    }

    private void compare(byte a[], byte b[])
    {
        //        Debug.debug("c1 a", a);
        //        Debug.debug("c1 b", b);
        assertNotNull(a);
        assertNotNull(b);
        assertEquals(a.length, b.length);
        for (int i = 0; i < a.length; i++)
            assertEquals(a[i], b[i]);
    }
}
TOP

Related Classes of org.apache.sanselan.formats.jpeg.exif.ExifRewriteTest$Rewriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.