001/**
002 * Copyright (c) 2011, The University of Southampton and the individual contributors.
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification,
006 * are permitted provided that the following conditions are met:
007 *
008 *   *  Redistributions of source code must retain the above copyright notice,
009 *      this list of conditions and the following disclaimer.
010 *
011 *   *  Redistributions in binary form must reproduce the above copyright notice,
012 *      this list of conditions and the following disclaimer in the documentation
013 *      and/or other materials provided with the distribution.
014 *
015 *   *  Neither the name of the University of Southampton nor the names of its
016 *      contributors may be used to endorse or promote products derived from this
017 *      software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package org.openimaj.tools.imagecollection.tool;
031
032import java.util.ArrayList;
033import java.util.List;
034
035import org.openimaj.image.Image;
036import org.openimaj.tools.imagecollection.collection.ImageCollection;
037import org.openimaj.tools.imagecollection.collection.ImageCollectionEntry;
038import org.openimaj.tools.imagecollection.metamapper.MetaMapper;
039import org.openimaj.tools.imagecollection.processor.ImageCollectionProcessor;
040
041public class ImageCollectionProcessorJob <T extends Image<?,T>> implements Runnable{
042        
043        public static class ProcessorJobEvent{
044                public int imagesDone;
045                public int imagesTotal;
046                public boolean validTotal;
047        }
048        
049        public static interface ProcessorJobListener{
050                public void progressUpdate(ProcessorJobEvent event);
051        }
052        
053        private ImageCollection<T> collection;
054        private ImageCollectionProcessor<T> processor;
055        private List<ProcessorJobListener> listeners;
056        private MetaMapper mapper;
057
058        public ImageCollectionProcessorJob(
059                        ImageCollection<T> collection,
060                        ImageCollectionProcessor<T> sink,
061                        MetaMapper mapper
062        ){
063                this.collection = collection;
064                this.processor = sink;
065                this.listeners = new ArrayList<ProcessorJobListener>();
066                this.mapper = mapper;
067        }
068        
069        public void addListener(ProcessorJobListener listener){
070                this.listeners.add(listener);
071        }
072
073        @Override
074        public void run() {
075                int done = 0;
076                try {
077                        this.processor.start();
078                        this.mapper.start();
079                } catch (Exception e) {
080                        return;
081                }
082                for(ImageCollectionEntry<T> entry: collection){
083                        try {
084                                if(entry.accepted)
085                                {
086                                        String sinkOutput = this.processor.process(entry);
087                                        mapper.mapItem(sinkOutput, entry);
088                                }
089                                ProcessorJobEvent event = new ProcessorJobEvent();
090                                event.imagesDone = ++done;
091                                event.imagesTotal = collection.countImages();
092                                if(event.imagesTotal < 0) event.validTotal = false;
093                                else event.validTotal = true;
094                                fireProgressUpdate(event);
095                        } catch (Exception e) {
096                        }
097                }
098                try {
099                        this.mapper.end();
100                        this.processor.end();
101                } catch (Exception e) {
102                }
103        }
104        
105        
106        
107        private void fireProgressUpdate(ProcessorJobEvent event) {
108                for (ProcessorJobListener listener : this.listeners) {
109                        listener.progressUpdate(event);
110                }
111        }
112        
113        
114}