001    /*
002     * AwtOperationProcessor
003     * 
004     * Copyright (c) 2000, 2001, 2002, 2003, 2004 Marco Schmidt.
005     * All rights reserved.
006     */
007    
008    package net.sourceforge.jiu.gui.awt;
009    
010    import java.awt.*;
011    import java.io.*;
012    import net.sourceforge.jiu.apps.*;
013    import net.sourceforge.jiu.color.*;
014    import net.sourceforge.jiu.color.adjustment.*;
015    import net.sourceforge.jiu.color.analysis.*;
016    import net.sourceforge.jiu.color.data.*;
017    import net.sourceforge.jiu.color.dithering.*;
018    import net.sourceforge.jiu.color.io.*;
019    import net.sourceforge.jiu.color.promotion.*;
020    import net.sourceforge.jiu.color.quantization.*;
021    import net.sourceforge.jiu.color.reduction.*;
022    import net.sourceforge.jiu.gui.awt.dialogs.*;
023    import net.sourceforge.jiu.codecs.*;
024    import net.sourceforge.jiu.data.*;
025    import net.sourceforge.jiu.filters.*;
026    import net.sourceforge.jiu.geometry.*;
027    import net.sourceforge.jiu.ops.*;
028    import net.sourceforge.jiu.util.*;
029    
030    /**
031     * Performs operations specified by parent class {@link OperationProcessor},
032     * uses various AWT dialogs to get parameters from user in a GUI application.
033     * @author Marco Schmidt
034     * @since 0.8.0
035     */
036    public class AwtOperationProcessor extends OperationProcessor
037    {
038            private JiuAwtFrame frame;
039    
040            public AwtOperationProcessor(EditorState editorState, JiuAwtFrame awtFrame)
041            {
042                    super(editorState);
043                    frame = awtFrame;
044            }
045    
046            public void colorAdjustBrightness()
047            {
048                    EditorState state = getEditorState();
049                    Strings strings = state.getStrings();
050                    Integer value = Dialogs.getInteger(frame, 
051                            strings.get(StringIndexConstants.ADJUST_BRIGHTNESS), 
052                            strings.get(StringIndexConstants.ENTER_BRIGHTNESS_VALUE), 
053                            -100, 0, 100, 
054                            strings.get(StringIndexConstants.OK),
055                            strings.get(StringIndexConstants.CANCEL));
056                    if (value == null || value.intValue() == 0)
057                    {
058                            return;
059                    }
060                    Brightness brightness = new Brightness();
061                    brightness.setBrightness(value.intValue());
062                    process(brightness);
063            }
064    
065            public void colorAdjustContrast()
066            {
067                    EditorState state = getEditorState();
068                    Strings strings = state.getStrings();
069                    Integer value = Dialogs.getInteger(frame, 
070                            strings.get(StringIndexConstants.ADJUST_CONTRAST), 
071                            strings.get(StringIndexConstants.ENTER_CONTRAST_VALUE), 
072                            -100, 0, 100, 
073                            strings.get(StringIndexConstants.OK),
074                            strings.get(StringIndexConstants.CANCEL));
075                    if (value == null || value.intValue() == 0)
076                    {
077                            return;
078                    }
079                    Contrast contrast = new Contrast();
080                    contrast.setContrast(value.intValue());
081                    process(contrast);
082            }
083    
084            public void colorAdjustGamma()
085            {
086                    EditorState state = getEditorState();
087                    Strings strings = state.getStrings();
088                    GammaCorrectionDialog gcd = new GammaCorrectionDialog(frame, strings, 2.2, GammaCorrection.MAX_GAMMA);
089                    gcd.show();
090                    Double result = gcd.getValue();
091                    if (result == null)
092                    {
093                            return;
094                    }
095                    GammaCorrection gc = new GammaCorrection();
096                    gc.setGamma(result.doubleValue());
097                    process(gc);
098            }
099    
100            public void colorAdjustHueSaturationValue()
101            {
102                    EditorState state = getEditorState();
103                    Strings strings = state.getStrings();
104                    HueSaturationValueDialog hsvDialog = new HueSaturationValueDialog(frame, strings, false, 0, 0, 0);
105                    hsvDialog.show();
106                    if (!hsvDialog.hasPressedOk())
107                    {
108                            return;
109                    }
110                    boolean setHue = hsvDialog.isHueSet();
111                    int hue = hsvDialog.getHue();
112                    int saturation = hsvDialog.getSaturation();
113                    int value = hsvDialog.getValue();
114                    HueSaturationValue hsv = new HueSaturationValue();
115                    if (setHue)
116                    {
117                            hsv.setHueSaturationValue(hue, saturation, value);
118                    }
119                    else
120                    {
121                            hsv.setSaturationValue(saturation, value);
122                    }
123                    process(hsv);
124            }
125    
126            public void colorHistogramCountColorsUsed()
127            {
128                    EditorState state = getEditorState();
129                    Strings strings = state.getStrings();
130                    PixelImage image = state.getImage();
131                    int numColors = 0;
132                    frame.setWaitCursor();
133                    try
134                    {
135                            if (image instanceof RGBIntegerImage)
136                            {
137                                    Histogram3DCreator hc = new Histogram3DCreator();
138                                    hc.setImage((RGBIntegerImage)image);
139                                    hc.addProgressListeners(state.getProgressListeners());
140                                    hc.process();
141                                    Histogram3D hist = hc.getHistogram();
142                                    numColors = hist.getNumUsedEntries();
143                            }
144                            else
145                            if (image instanceof IntegerImage && image.getNumChannels() == 1)
146                            {       
147                                    Histogram1DCreator hc = new Histogram1DCreator();
148                                    hc.setImage((IntegerImage)image);
149                                    hc.addProgressListeners(state.getProgressListeners());
150                                    hc.process();
151                                    Histogram1D hist = hc.getHistogram();
152                                    numColors = hist.getNumUsedEntries();
153                            }
154                            else
155                            {
156                                    throw new UnsupportedTypeException("Not a supported image type for counting colors: " +
157                                            image.getImageType().getName());
158                            }
159                    }
160                    catch (OperationFailedException ofe)
161                    {
162                            frame.setDefaultCursor();
163                            frame.updateStatusBar();
164                            frame.showError(ofe.toString());
165                            return;
166                    }
167                    frame.setDefaultCursor();
168                    frame.updateStatusBar();
169                    frame.showInfo(
170                            strings.get(StringIndexConstants.COUNT_COLORS_USED), 
171                            strings.get(StringIndexConstants.NUMBER_OF_USED_COLORS) + ": " + numColors);
172            }
173    
174            public void colorHistogramEqualize()
175            {
176                    EditorState state = getEditorState();
177                    try
178                    {
179                            process(new EqualizeHistogram((IntegerImage)state.getImage()));
180                    }
181                    catch (OperationFailedException ofe)
182                    {
183                            frame.showError(ofe.toString());
184                    }
185            }
186    
187            public void colorHistogramNormalize()
188            {
189                    EditorState state = getEditorState();
190                    try
191                    {
192                            process(new NormalizeHistogram((IntegerImage)state.getImage()));
193                    }
194                    catch (OperationFailedException ofe)
195                    {
196                            frame.showError(ofe.toString());
197                    }
198            }
199    
200            public void colorHistogramTextureProperties()
201            {
202                    EditorState state = getEditorState();
203                    Strings strings = state.getStrings();
204                    PixelImage img = state.getImage();
205                    if (img == null || (!(img instanceof Gray8Image)))
206                    {
207                            return;
208                    }
209                    Gray8Image image = (Gray8Image)img;
210                    frame.setWaitCursor();
211                    CoOccurrenceMatrix matrix = MatrixCreator.createCoOccurrenceMatrix(image, 0);
212                    TextureAnalysis ta = new TextureAnalysis();
213                    ta.setMatrix(matrix);
214                    ta.addProgressListeners(state.getProgressListeners());
215                    try
216                    {
217                            ta.process();
218                    }
219                    catch (MissingParameterException mpe)
220                    {
221                    }
222                    StringBuffer text = new StringBuffer();
223                    text.append(strings.get(StringIndexConstants.CONTRAST) + "=" + ta.getContrast() + "\n");
224                    text.append(strings.get(StringIndexConstants.CORRELATION) + "=" + ta.getCorrelation() + "\n");
225                    text.append(strings.get(StringIndexConstants.DISSIMILARITY) + "=" + ta.getDissimilarity() + "\n");
226                    text.append(strings.get(StringIndexConstants.ENTROPY) + "=" + ta.getEntropy() + "\n");
227                    text.append(strings.get(StringIndexConstants.ENERGY) + "=" + ta.getEnergy() + "\n");
228                    text.append(strings.get(StringIndexConstants.HOMOGENEITY) + "=" + ta.getHomogeneity());
229                    frame.setDefaultCursor();
230                    frame.updateStatusBar();
231                    frame.showInfo(
232                            strings.get(StringIndexConstants.TEXTURE_PROPERTIES), 
233                            text.toString());
234            }
235    
236            public void colorHistogramSaveHistogramAs()
237            {
238                    EditorState state = getEditorState();
239                    PixelImage pi = state.getImage();
240                    if (pi == null || !(pi instanceof IntegerImage))
241                    {
242                            return;
243                    }
244                    String textFileName = getUserSaveAsFileName(".txt", StringIndexConstants.SAVE_HISTOGRAM_AS);
245                    if (textFileName == null)
246                    {
247                            return;
248                    }
249                    PrintStream out = null;
250                    try
251                    {
252                            out = new PrintStream(new BufferedOutputStream(new FileOutputStream(textFileName)), false);
253                    }
254                    catch (IOException ioe)
255                    {
256                            frame.showError(ioe.toString());
257                            return;
258                    }
259                    IntegerImage image = (IntegerImage)pi;
260                    frame.setWaitCursor();
261                    int numChannels = image.getNumChannels();
262                    if (numChannels == 1)
263                    {
264                            Histogram1D hist = null;
265                            try
266                            {
267                                    Histogram1DCreator hc = new Histogram1DCreator();
268                                    hc.setImage(image);
269                                    hc.addProgressListeners(state.getProgressListeners());
270                                    hc.process();
271                                    hist = hc.getHistogram();
272                            }
273                            catch(OperationFailedException ofe)
274                            {
275                                    frame.showError(ofe.toString());
276                                    frame.updateStatusBar();
277                                    return;
278                            }
279                            HistogramSerialization.save(hist, out);
280                    }
281                    else
282                    if (numChannels == 3)
283                    {
284                            Histogram3D hist = null;
285                            try
286                            {
287                                    Histogram3DCreator hc = new Histogram3DCreator();
288                                    hc.setImage(image, RGBIndex.INDEX_RED, RGBIndex.INDEX_GREEN, RGBIndex.INDEX_BLUE);
289                                    hc.addProgressListeners(state.getProgressListeners());
290                                    hc.process();
291                                    hist = hc.getHistogram();
292                            }
293                            catch(OperationFailedException ofe)
294                            {
295                                    frame.showError(ofe.toString());
296                                    frame.updateStatusBar();
297                                    return;
298                            }
299                            HistogramSerialization.save(hist, out);
300                    }
301                    out.close();
302                    frame.setDefaultCursor();
303                    frame.updateStatusBar();
304            }
305    
306            public void colorHistogramSaveCoOccurrenceMatrixAs()
307            {
308                    EditorState state = getEditorState();
309                    PixelImage image = state.getImage();
310                    String textFileName = getUserSaveAsFileName(".txt", StringIndexConstants.SAVE_COOCCURRENCE_MATRIX);
311                    if (textFileName == null)
312                    {
313                            return;
314                    }
315                    CoOccurrenceMatrix matrix = MatrixCreator.createCoOccurrenceMatrix((IntegerImage)image, 0);
316                    File textFile = new File(textFileName);
317                    try
318                    {
319                            PrintStream out = new PrintStream(new FileOutputStream(textFile));
320                            MatrixSerialization.save(matrix, out);
321                            out.close();
322                    }
323                    catch(IOException ioe)
324                    {
325                            frame.showError(ioe.toString());
326                    }
327            }
328    
329            public void colorHistogramSaveCoOccurrenceFrequencyMatrixAs()
330            {
331                    EditorState state = getEditorState();
332                    PixelImage image = state.getImage();
333                    String textFileName = getUserSaveAsFileName(".txt", StringIndexConstants.SAVE_COOCCURRENCE_FREQUENCY_MATRIX);
334                    if (textFileName == null)
335                    {
336                            return;
337                    }
338                    CoOccurrenceMatrix com = MatrixCreator.createCoOccurrenceMatrix((IntegerImage)image, 0);
339                    CoOccurrenceFrequencyMatrix matrix = MatrixCreator.createCoOccurrenceFrequencyMatrix(com);
340                    File textFile = new File(textFileName);
341                    try
342                    {
343                            PrintStream out = new PrintStream(new FileOutputStream(textFile));
344                            MatrixSerialization.save(matrix, out);
345                            out.close();
346                    }
347                    catch(IOException ioe)
348                    {
349                            frame.showError(ioe.toString());
350                    }
351            }
352    
353            public void colorPaletteSaveAs()
354            {
355                    EditorState state = getEditorState();
356                    PalettedImage image = (PalettedImage)state.getImage();
357                    Palette palette = image.getPalette();
358                    String paletteFileName = getUserSaveAsFileName(".ppm", StringIndexConstants.SAVE_PALETTE);
359                    if (paletteFileName == null)
360                    {
361                            return;
362                    }
363                    File paletteFile = new File(paletteFileName);
364                    try
365                    {
366                            PaletteSerialization.save(palette, paletteFile);
367                    }
368                    catch(IOException ioe)
369                    {
370                            frame.showError(ioe.toString());
371                    }
372            }
373    
374            public void colorPromotePromoteToPaletted()
375            {
376                    process(new PromotionPaletted8());
377            }
378    
379            public void colorPromotePromoteToGray8()
380            {
381                    process(new PromotionGray8());
382            }
383    
384            public void colorPromotePromoteToGray16()
385            {
386                    process(new PromotionGray16());
387            }
388    
389            public void colorPromotePromoteToRgb24()
390            {
391                    process(new PromotionRGB24());
392            }
393    
394            public void colorPromotePromoteToRgb48()
395            {
396                    process(new PromotionRGB48());
397            }
398    
399            public void colorReduceReduceNumberOfShadesOfGray()
400            {
401                    EditorState state = getEditorState();
402                    Strings strings = state.getStrings();
403                    PixelImage image = state.getImage();
404                    int maxBits = image.getBitsPerPixel() - 1;
405                    ReduceGrayscaleDialog rgd = new ReduceGrayscaleDialog(frame, strings, 1, maxBits, 
406                            ReduceGrayscaleDialog.TYPE_FLOYD_STEINBERG_ERROR_DIFFUSION);
407                    rgd.show();
408                    if (!rgd.hasPressedOk())
409                    {
410                            return;
411                    }
412                    int numBits = rgd.getNumBits();
413                    ImageToImageOperation op = null;
414                    switch (rgd.getDitheringMethod())
415                    {
416                            case(ReduceGrayscaleDialog.TYPE_DITHERING_NONE):
417                            {
418                                    ReduceShadesOfGray rsog;
419                                    rsog = new ReduceShadesOfGray();
420                                    rsog.setBits(numBits);
421                                    op = rsog;
422                                    break;
423                            }
424                            case(ReduceGrayscaleDialog.TYPE_ORDERED_DITHERING):
425                            {
426                                    OrderedDither od = new OrderedDither();
427                                    od.setOutputBits(numBits);
428                                    op = od;
429                                    break;
430                            }
431                            case(ReduceGrayscaleDialog.TYPE_FLOYD_STEINBERG_ERROR_DIFFUSION):
432                            {
433                                    ErrorDiffusionDithering ed = new ErrorDiffusionDithering();
434                                    ed.setTemplateType(ErrorDiffusionDithering.TYPE_FLOYD_STEINBERG);
435                                    ed.setGrayscaleOutputBits(numBits);
436                                    op = ed;
437                                    break;
438                            }
439                            case(ReduceGrayscaleDialog.TYPE_STUCKI_ERROR_DIFFUSION):
440                            {
441                                    ErrorDiffusionDithering ed = new ErrorDiffusionDithering();
442                                    ed.setTemplateType(ErrorDiffusionDithering.TYPE_STUCKI);
443                                    ed.setGrayscaleOutputBits(numBits);
444                                    op = ed;
445                                    break;
446                            }
447                            case(ReduceGrayscaleDialog.TYPE_BURKES_ERROR_DIFFUSION):
448                            {
449                                    ErrorDiffusionDithering ed = new ErrorDiffusionDithering();
450                                    ed.setTemplateType(ErrorDiffusionDithering.TYPE_BURKES);
451                                    ed.setGrayscaleOutputBits(numBits);
452                                    op = ed;
453                                    break;
454                            }
455                            case(ReduceGrayscaleDialog.TYPE_SIERRA_ERROR_DIFFUSION):
456                            {
457                                    ErrorDiffusionDithering ed = new ErrorDiffusionDithering();
458                                    ed.setTemplateType(ErrorDiffusionDithering.TYPE_SIERRA);
459                                    ed.setGrayscaleOutputBits(numBits);
460                                    op = ed;
461                                    break;
462                            }
463                            case(ReduceGrayscaleDialog.TYPE_JARVIS_JUDICE_NINKE_ERROR_DIFFUSION):
464                            {
465                                    ErrorDiffusionDithering ed = new ErrorDiffusionDithering();
466                                    ed.setTemplateType(ErrorDiffusionDithering.TYPE_JARVIS_JUDICE_NINKE);
467                                    ed.setGrayscaleOutputBits(numBits);
468                                    op = ed;
469                                    break;
470                            }
471                            case(ReduceGrayscaleDialog.TYPE_STEVENSON_ARCE_ERROR_DIFFUSION):
472                            {
473                                    ErrorDiffusionDithering ed = new ErrorDiffusionDithering();
474                                    ed.setTemplateType(ErrorDiffusionDithering.TYPE_STEVENSON_ARCE);
475                                    ed.setGrayscaleOutputBits(numBits);
476                                    op = ed;
477                                    break;
478                            }
479                            default:
480                            {
481                                    return;
482                            }
483                    }
484                    op.setInputImage(image);
485                    op.addProgressListeners(state.getProgressListeners());
486                    process(op);
487            }
488    
489            public void colorReduceConvertToGrayscale()
490            {
491                    process(new RGBToGrayConversion());
492            }
493    
494            public void colorReduceMedianCut()
495            {
496                    EditorState state = getEditorState();
497                    Strings strings = state.getStrings();
498                    PixelImage image = state.getImage();
499                    MedianCutDialog mcd  = new MedianCutDialog(
500                            frame, 
501                            strings, 
502                            256, 
503                            MedianCutQuantizer.METHOD_REPR_COLOR_WEIGHTED_AVERAGE, 
504                            true, 
505                            MedianCutContourRemoval.DEFAULT_NUM_PASSES, 
506                            MedianCutContourRemoval.DEFAULT_TAU);
507                    mcd.show();
508                    if (!mcd.hasPressedOk())
509                    {
510                            return;
511                    }
512                    int numColors = mcd.getNumColors();
513                    int method = mcd.getReprColorMethod();
514                    boolean palettedOutput = mcd.isOutputTypePaletted();
515                    int numBitsToBeCleared = 0;
516                    ImageToImageOperation op = null;
517    
518                    if (mcd.useContourRemoval())
519                    {
520                            MedianCutQuantizer quantizer = new MedianCutQuantizer();
521                            quantizer.setInputImage(image);
522                            quantizer.setPaletteSize(numColors);
523                            quantizer.setMethodToDetermineRepresentativeColors(method);
524                            MedianCutContourRemoval removal = new MedianCutContourRemoval();
525                            removal.setQuantizer(quantizer);
526                            removal.setTau(mcd.getTau());
527                            removal.setNumPasses(mcd.getNumPasses());
528                            op = removal;
529                    }
530                    else
531                    if (mcd.useErrorDiffusion())
532                    {
533                            MedianCutQuantizer medianCut = new MedianCutQuantizer();
534                            medianCut.setInputImage(image);
535                            medianCut.setPaletteSize(numColors);
536                            medianCut.setMethodToDetermineRepresentativeColors(method);
537                            medianCut.setMapping(false);
538                            try
539                            {
540                                    medianCut.process();
541                            }
542                            catch (OperationFailedException ofe)
543                            {
544                                    frame.showError(ofe.toString());
545                                    return;
546                            }
547                            ErrorDiffusionDithering ed = new ErrorDiffusionDithering();
548                            ed.setTemplateType(mcd.getErrorDiffusion());
549                            ed.setQuantizer(medianCut);
550                            op = ed;
551                    }
552                    else
553                    {
554                            MedianCutQuantizer medianCut = new MedianCutQuantizer();
555                            medianCut.setInputImage(image);
556                            medianCut.setPaletteSize(numColors);
557                            medianCut.setTruecolorOutput(!palettedOutput);
558                            medianCut.setMethodToDetermineRepresentativeColors(method);
559                            op = medianCut;
560                    }
561                    process(op);
562            }
563    
564            public void colorInvert()
565            {
566                    process(new Invert());
567            }
568    
569            public void colorConvertToMinimumColorType()
570            {
571                    EditorState state = getEditorState();
572                    PixelImage image = state.getImage();
573                    AutoDetectColorType adct = new AutoDetectColorType();
574                    adct.setInputImage(image);
575                    adct.addProgressListeners(state.getProgressListeners());
576                    try
577                    {
578                            frame.setWaitCursor();
579                            adct.process();
580                    }
581                    catch (MissingParameterException mpe)
582                    {
583                            frame.setDefaultCursor();
584                            return;
585                    }
586                    catch (WrongParameterException mpe)
587                    {
588                            frame.setDefaultCursor();
589                            return;
590                    }
591                    if (!adct.isReducible())
592                    {
593                            frame.setDefaultCursor();
594                            return;
595                    }
596                    frame.setDefaultCursor();
597                    setImage(adct.getOutputImage(), true);
598                    frame.updateImage();
599            }
600    
601            public void colorReduceOctree()
602            {
603                    EditorState state = getEditorState();
604                    Strings strings = state.getStrings();
605                    PixelImage image = state.getImage();
606                    OctreeDialog od = new OctreeDialog(frame, strings, 256, true);
607                    od.show();
608                    if (!(od.hasPressedOk()))
609                    {
610                            return;
611                    }
612                    OctreeColorQuantizer quantizer = new OctreeColorQuantizer();
613                    quantizer.setPaletteSize(od.getNumColors());
614                    quantizer.setInputImage(image);
615                    if (od.useNoDithering())
616                    {
617                            quantizer.addProgressListeners(state.getProgressListeners());
618                            try
619                            {
620                                    quantizer.process();
621                            }
622                            catch(WrongParameterException wpe)
623                            {
624                            }       
625                            catch(MissingParameterException mpe)
626                            {
627                            }
628                            image = quantizer.getOutputImage();
629                    }
630                    else
631                    if (od.useErrorDiffusion())
632                    {
633                            try
634                            {
635                                    quantizer.init();
636                            }
637                            catch(WrongParameterException wpe)
638                            {
639                            }       
640                            catch(MissingParameterException mpe)
641                            {
642                            }
643                            ErrorDiffusionDithering ed = new ErrorDiffusionDithering();
644                            ed.setTemplateType(od.getErrorDiffusion());
645                            ed.setQuantizer(quantizer);
646                            process(ed);
647                            return;
648                    }
649                    setImage(image, true);
650                    frame.updateImage();
651            }
652    
653            public void colorReduceReduceToBilevelThreshold()
654            {
655                    EditorState state = getEditorState();
656                    Strings strings = state.getStrings();
657                    IntegerImage image = (IntegerImage)state.getImage();
658                    final int MAX = image.getMaxSample(0);
659                    Integer value = Dialogs.getInteger(frame, strings.get(StringIndexConstants.REDUCE_TO_BILEVEL_THRESHOLD), 
660                            strings.get(Strings.ENTER_THRESHOLD_VALUE), 0, MAX / 2, MAX, 
661                            strings.get(Strings.OK),
662                            strings.get(Strings.CANCEL));
663                    if (value == null)
664                    {
665                            return;
666                    }
667                    ReduceToBilevelThreshold red = new ReduceToBilevelThreshold();
668                    red.setThreshold(value.intValue());
669                    process(red);
670            }
671    
672            private int convertUniformToErrorDiffusion(int utype)
673            {
674                    switch(utype)
675                    {
676                            case(UniformPaletteQuantizerDialog.TYPE_FLOYD_STEINBERG_ERROR_DIFFUSION): return ErrorDiffusionDithering.TYPE_FLOYD_STEINBERG;
677                            case(UniformPaletteQuantizerDialog.TYPE_BURKES_ERROR_DIFFUSION): return ErrorDiffusionDithering.TYPE_BURKES;
678                            case(UniformPaletteQuantizerDialog.TYPE_STUCKI_ERROR_DIFFUSION): return ErrorDiffusionDithering.TYPE_STUCKI;
679                            case(UniformPaletteQuantizerDialog.TYPE_SIERRA_ERROR_DIFFUSION): return ErrorDiffusionDithering.TYPE_SIERRA;
680                            case(UniformPaletteQuantizerDialog.TYPE_JARVIS_JUDICE_NINKE_ERROR_DIFFUSION): return ErrorDiffusionDithering.TYPE_JARVIS_JUDICE_NINKE;
681                            case(UniformPaletteQuantizerDialog.TYPE_STEVENSON_ARCE_ERROR_DIFFUSION): return ErrorDiffusionDithering.TYPE_STEVENSON_ARCE;
682                            default: return -1;
683                    }
684            }
685    
686            public void colorReduceUniformPalette()
687            {
688                    EditorState state = getEditorState();
689                    Strings strings = state.getStrings();
690                    PixelImage image = state.getImage();
691                    UniformPaletteQuantizerDialog upqd = new UniformPaletteQuantizerDialog
692                            (frame, strings, 3, 3, 2, UniformPaletteQuantizerDialog.TYPE_FLOYD_STEINBERG_ERROR_DIFFUSION);
693                    upqd.show();
694                    if (!upqd.hasPressedOk())
695                    {
696                            return;
697                    }
698                    int redBits = upqd.getRedBits();
699                    int greenBits = upqd.getGreenBits();
700                    int blueBits = upqd.getBlueBits();
701                    int sum = redBits + greenBits + blueBits;
702                    switch (upqd.getDitheringMethod())
703                    {
704                            case(UniformPaletteQuantizerDialog.TYPE_DITHERING_NONE):
705                            {
706                                    UniformPaletteQuantizer upq = new UniformPaletteQuantizer(redBits, greenBits, blueBits);
707                                    process(upq);
708                                    return;
709                            }
710                            case(UniformPaletteQuantizerDialog.TYPE_ORDERED_DITHERING):
711                            {
712                                    OrderedDither od = new OrderedDither();
713                                    od.setRgbBits(redBits, greenBits, blueBits);
714                                    process(od);
715                                    return;
716                            }
717                            case(UniformPaletteQuantizerDialog.TYPE_FLOYD_STEINBERG_ERROR_DIFFUSION):
718                            case(UniformPaletteQuantizerDialog.TYPE_BURKES_ERROR_DIFFUSION):
719                            case(UniformPaletteQuantizerDialog.TYPE_STUCKI_ERROR_DIFFUSION):
720                            case(UniformPaletteQuantizerDialog.TYPE_SIERRA_ERROR_DIFFUSION):
721                            case(UniformPaletteQuantizerDialog.TYPE_JARVIS_JUDICE_NINKE_ERROR_DIFFUSION):
722                            case(UniformPaletteQuantizerDialog.TYPE_STEVENSON_ARCE_ERROR_DIFFUSION):
723                            {
724                                    ErrorDiffusionDithering ed = new ErrorDiffusionDithering();
725                                    ed.setTemplateType(convertUniformToErrorDiffusion(upqd.getDitheringMethod()));
726                                    UniformPaletteQuantizer upq = new UniformPaletteQuantizer(redBits, greenBits, blueBits);
727                                    ed.setQuantizer(upq);
728                                    ed.setTruecolorOutput(sum > 8);
729                                    process(ed);
730                                    return;
731                            }
732                            default:
733                            {
734                                    return;
735                            }
736                    }
737            }
738    
739            public void colorReduceMapToArbitraryPalette()
740            {
741                    EditorState state = getEditorState();
742                    Strings strings = state.getStrings();
743                    PixelImage image = state.getImage();
744                    MapToArbitraryPaletteDialog d = new MapToArbitraryPaletteDialog(frame, strings);
745                    d.show();
746                    if (!d.hasPressedOk())
747                    {
748                            return;
749                    }
750                    int paletteType = d.getPaletteType();
751                    if (paletteType < 0)
752                    {
753                            return;
754                    }
755                    // load palette from file
756                    Palette palette;
757                    switch(paletteType)
758                    {
759                            case(MapToArbitraryPaletteDialog.PALETTE_FILE):
760                            {
761                                    String name = getUserFileName(null, StringIndexConstants.LOAD_PALETTE, FileDialog.LOAD);
762                                    if (name == null)
763                                    {
764                                            return;
765                                    }
766                                    File file = new File(name);
767                                    palette = PaletteSerialization.load(file);
768                                    break;
769                            }
770                            case(MapToArbitraryPaletteDialog.PALETTE_WEBSAFE):
771                            {
772                                    palette = WebsafePaletteCreator.create();
773                                    break;
774                            }
775                            case(MapToArbitraryPaletteDialog.PALETTE_PALM_256_COLORS):
776                            {
777                                    palette = PalmCodec.createSystem8BitPalette();
778                                    break;
779                            }
780                            case(MapToArbitraryPaletteDialog.PALETTE_PALM_16_COLORS):
781                            {
782                                    palette = PalmCodec.createSystem4BitColorPalette();
783                                    break;
784                            }
785                            case(MapToArbitraryPaletteDialog.PALETTE_PALM_16_GRAY):
786                            {
787                                    palette = PalmCodec.createSystem4BitGrayscalePalette();
788                                    break;
789                            }
790                            case(MapToArbitraryPaletteDialog.PALETTE_PALM_4_GRAY):
791                            {
792                                    palette = PalmCodec.createSystem2BitGrayscalePalette();
793                                    break;
794                            }
795                            default:
796                            {
797                                    return;
798                            }
799                    }
800                    ArbitraryPaletteQuantizer apq = new ArbitraryPaletteQuantizer(palette);
801                    if (palette == null)
802                    {
803                            return;
804                    }
805                    if (d.useErrorDiffusion())
806                    {
807                            // error diffusion dithering
808                            ErrorDiffusionDithering ed = new ErrorDiffusionDithering();
809                            ed.setTemplateType(d.getErrorDiffusionType());
810                            ed.setQuantizer(apq);
811                            process(ed);
812                            return;
813                    }
814                    else
815                    {
816                            // no dithering
817                            apq.setInputImage(image);
818                            apq.addProgressListeners(state.getProgressListeners());
819                            try
820                            {
821                                    apq.process();
822                            }
823                            catch (OperationFailedException ofe)
824                            {
825                                    return;
826                            }
827                            image = apq.getOutputImage();
828                    }
829                    setImage(image, true);
830                    frame.updateImage();
831            }
832    
833            public void editRedo()
834            {
835                    EditorState state = getEditorState();
836                    if (!state.canRedo())
837                    {
838                            return;
839                    }
840                    state.redo();
841                    frame.updateImage();
842            }
843    
844            public void editUndo()
845            {
846                    EditorState state = getEditorState();
847                    if (!state.canUndo())
848                    {
849                            return;
850                    }
851                    state.undo();
852                    frame.updateImage();
853            }
854    
855            public void fileClose()
856            {
857                    EditorState state = getEditorState();
858                    if (state.getModified())
859                    {
860                            YesNoDialog dialog = new YesNoDialog(frame, state.getStrings(), 
861                                    StringIndexConstants.CLOSE_FILE, 
862                                    StringIndexConstants.DO_YOU_REALLY_WANT_TO_CLOSE_WITHOUT_SAVING, 
863                                    false);
864                            dialog.show();
865                            if (dialog.getResult() == YesNoDialog.RESULT_NO)
866                            {
867                                    return;
868                            }
869                    }
870                    setImage(null, false);
871                    state.resetZoomFactors();
872                    state.setFileName("");
873                    state.clearRedo();
874                    state.clearUndo();
875                    frame.updateImage();
876            }
877    
878            public void fileExit()
879            {
880                    EditorState state = getEditorState();
881                    if (state.getModified())
882                    {
883                            YesNoDialog dialog = new YesNoDialog(frame, state.getStrings(), 
884                                    StringIndexConstants.QUIT_PROGRAM, 
885                                    StringIndexConstants.DO_YOU_REALLY_WANT_TO_QUIT_WITHOUT_SAVING, 
886                                    false);
887                            dialog.show();
888                            if (dialog.getResult() == YesNoDialog.RESULT_NO)
889                            {
890                                    return;
891                            }
892                    }
893                    System.exit(0);
894            }
895    
896            public void fileOpen()
897            {
898                    EditorState state = getEditorState();
899                    Strings strings = state.getStrings();
900    
901                    if (state.getModified())
902                    {
903                            YesNoDialog dialog = new YesNoDialog(frame, state.getStrings(), 
904                                    StringIndexConstants.CLOSE_FILE, 
905                                    StringIndexConstants.DO_YOU_REALLY_WANT_TO_CLOSE_WITHOUT_SAVING, 
906                                    false);
907                            dialog.show();
908                            if (dialog.getResult() == YesNoDialog.RESULT_NO)
909                            {
910                                    return;
911                            }
912                    }
913    
914                    File file = null;
915                    if (state.getStartupImageName() != null)
916                    {
917                            file = new File(state.getStartupImageName());
918                            state.setStartupImageName(null);
919                    }
920                    else
921                    {
922                            FileDialog fd = new FileDialog(frame, strings.get(StringIndexConstants.LOAD_IMAGE_FILE), FileDialog.LOAD);
923                            String dir = state.getCurrentDirectory();
924                            if (dir != null)
925                            {
926                                    fd.setDirectory(dir);
927                            }
928                            //fd.setFilenameFilter(ImageLoader.createFilenameFilter());
929                            fd.show();
930                            fd.setMode(FileDialog.LOAD);
931                            String fn = fd.getFile();
932                            String dn = fd.getDirectory();
933                            if (fn == null || dn == null)
934                            {
935                                    return;
936                            }
937                            state.setCurrentDirectory(dn);
938                            file = new File(dn, fn);
939                    }
940    
941                    PixelImage image = null;
942                    try
943                    {
944                            image = ImageLoader.load(file, state.getProgressListeners());
945                    }
946                    catch (Exception e)
947                    {
948                            frame.showInfo("Error loading image", e.toString());
949                            e.printStackTrace();
950                            return;
951                    }
952                    String fullName = file.getAbsolutePath();
953                    if (image == null)
954                    {
955                            image = ToolkitLoader.loadAsRgb24Image(fullName);
956                    }
957                    if (image == null)
958                    {
959                            frame.showInfo(strings.get(StringIndexConstants.ERROR_LOADING_IMAGE), 
960                                    strings.get(StringIndexConstants.FILE_FORMAT_UNKNOWN));
961                            return;
962                    }
963                    setImage(image, false);
964                    state.setFileName(fullName);
965                    frame.updateImage();
966            }
967    
968            public void fileSaveAsBmp()
969            {
970                    EditorState editor = getEditorState();
971                    PixelImage image = editor.getImage();
972                    if (image == null)
973                    {
974                            return;
975                    }
976                    BMPCodec codec = new BMPCodec();
977                    String name = getUserSaveAsFileName(codec.suggestFileExtension(image), StringIndexConstants.SAVE_IMAGE_AS);
978                    if (name == null)
979                    {
980                            return;
981                    }
982                    codec.addProgressListeners(editor.getProgressListeners());
983                    try
984                    {
985                            codec.setOutputStream(new BufferedOutputStream(new FileOutputStream(name)));
986                            codec.setImage(image);
987                            codec.process();
988                    }
989                    catch (Exception e)
990                    {
991                            frame.showError(e.toString());
992                            return;
993                    }
994                    editor.setFileName(name);
995                    setImage(image, false);
996                    frame.updateImage();
997            }
998    
999            public void fileSaveAsGif()
1000            {
1001                    EditorState editor = getEditorState();
1002                    PixelImage image = editor.getImage();
1003                    if (image == null)
1004                    {
1005                            return;
1006                    }
1007                    GIFCodec codec = new GIFCodec();
1008                    String name = getUserSaveAsFileName(codec.suggestFileExtension(image), 
1009                            StringIndexConstants.SAVE_IMAGE_AS);
1010                    if (name == null)
1011                    {
1012                            return;
1013                    }
1014                    codec.addProgressListeners(editor.getProgressListeners());
1015                    try
1016                    {
1017                            codec.setFile(name, CodecMode.SAVE);
1018                            codec.setImage(image);
1019                            codec.process();
1020                    }
1021                    catch (Exception e)
1022                    {
1023                            frame.showError(e.toString());
1024                            return;
1025                    }
1026                    editor.setFileName(name);
1027                    setImage(image, false);
1028                    frame.updateImage();
1029            }
1030    
1031            public void fileSaveAsPalm()
1032            {
1033                    EditorState editor = getEditorState();
1034                    PixelImage image = editor.getImage();
1035                    if (image == null)
1036                    {
1037                            return;
1038                    }
1039                    PalmCodec codec = new PalmCodec();
1040                    String name = getUserSaveAsFileName(codec.suggestFileExtension(image), StringIndexConstants.SAVE_IMAGE_AS);
1041                    if (name == null)
1042                    {
1043                            return;
1044                    }
1045                    codec.setCompression(PalmCodec.COMPRESSION_SCANLINE);
1046                    codec.addProgressListeners(editor.getProgressListeners());
1047                    try
1048                    {
1049                            codec.setFile(name, CodecMode.SAVE);
1050                            codec.setImage(image);
1051                            codec.process();
1052                    }
1053                    catch (Exception e)
1054                    {
1055                            frame.showError(e.toString());
1056                            return;
1057                    }
1058                    editor.setFileName(name);
1059                    setImage(image, false);
1060                    frame.updateImage();
1061            }
1062    
1063            public void fileSaveAsPbm()
1064            {
1065                    fileSaveAsPnm();
1066            }
1067    
1068            public void fileSaveAsPgm()
1069            {
1070                    fileSaveAsPnm();
1071            }
1072    
1073            public void fileSaveAsPng()
1074            {
1075                    EditorState editor = getEditorState();
1076                    PixelImage image = editor.getImage();
1077                    if (image == null)
1078                    {
1079                            return;
1080                    }
1081                    PNGCodec codec = new PNGCodec();
1082                    String name = getUserSaveAsFileName(codec.suggestFileExtension(image), StringIndexConstants.SAVE_IMAGE_AS);
1083                    if (name == null)
1084                    {
1085                            return;
1086                    }
1087                    codec.addProgressListeners(editor.getProgressListeners());
1088                    try
1089                    {
1090                            codec.setFile(name, CodecMode.SAVE);
1091                            codec.setImage(image);
1092                            codec.process();
1093                    }
1094                    catch (Exception e)
1095                    {
1096                            frame.showError(e.toString());
1097                            return;
1098                    }
1099                    editor.setFileName(name);
1100                    setImage(image, false);
1101                    frame.updateImage();
1102            }
1103    
1104            private void fileSaveAsPnm()
1105            {
1106                    EditorState editor = getEditorState();
1107                    PixelImage image = editor.getImage();
1108                    if (image == null)
1109                    {
1110                            return;
1111                    }
1112                    PNMCodec codec = new PNMCodec();
1113                    String name = getUserSaveAsFileName(codec.suggestFileExtension(image), StringIndexConstants.SAVE_IMAGE_AS);
1114                    if (name == null)
1115                    {
1116                            return;
1117                    }
1118                    codec.addProgressListeners(editor.getProgressListeners());
1119                    try
1120                    {
1121                            codec.setOutputStream(new BufferedOutputStream(new FileOutputStream(name)));
1122                            codec.setImage(image);
1123                            codec.process();
1124                    }
1125                    catch (Exception e)
1126                    {
1127                            frame.showError(e.toString());
1128                            return;
1129                    }
1130                    editor.setFileName(name);
1131                    setImage(image, false);
1132                    frame.updateImage();
1133            }
1134    
1135            public void fileSaveAsPpm()
1136            {
1137                    fileSaveAsPnm();
1138            }
1139    
1140            public void fileSaveAsRas()
1141            {
1142                    EditorState editor = getEditorState();
1143                    PixelImage image = editor.getImage();
1144                    if (image == null)
1145                    {
1146                            return;
1147                    }
1148                    RASCodec codec = new RASCodec();
1149                    String name = getUserSaveAsFileName(codec.suggestFileExtension(image), StringIndexConstants.SAVE_IMAGE_AS);
1150                    if (name == null)
1151                    {
1152                            return;
1153                    }
1154                    codec.addProgressListeners(editor.getProgressListeners());
1155                    try
1156                    {
1157                            codec.setOutputStream(new BufferedOutputStream(new FileOutputStream(name)));
1158                            codec.setImage(image);
1159                            codec.process();
1160                    }
1161                    catch (Exception e)
1162                    {
1163                            frame.showError(e.toString());
1164                            return;
1165                    }
1166                    editor.setFileName(name);
1167                    setImage(image, false);
1168                    frame.updateImage();
1169            }
1170    
1171            public void filterConvolutionFilter(int type)
1172            {
1173                    EditorState state = getEditorState();
1174                    ConvolutionKernelFilter ckf = new ConvolutionKernelFilter();
1175                    ckf.setKernel(type);
1176                    process(ckf);
1177            }
1178    
1179            public void filtersBlur()
1180            {
1181                    filterConvolutionFilter(ConvolutionKernelFilter.TYPE_BLUR);
1182            }
1183    
1184            public void filtersSharpen()
1185            {
1186                    filterConvolutionFilter(ConvolutionKernelFilter.TYPE_SHARPEN);
1187            }
1188    
1189            public void filtersEdgeDetection()
1190            {
1191                    filterConvolutionFilter(ConvolutionKernelFilter.TYPE_EDGE_DETECTION);
1192            }
1193    
1194            public void filtersEmboss()
1195            {
1196                    filterConvolutionFilter(ConvolutionKernelFilter.TYPE_EMBOSS);
1197            }
1198    
1199            public void filtersPsychedelicDistillation()
1200            {
1201                    filterConvolutionFilter(ConvolutionKernelFilter.TYPE_PSYCHEDELIC_DISTILLATION);
1202            }
1203    
1204            public void filtersLithograph()
1205            {
1206                    filterConvolutionFilter(ConvolutionKernelFilter.TYPE_LITHOGRAPH);
1207            }
1208    
1209            public void filtersHorizontalSobel()
1210            {
1211                    filterConvolutionFilter(ConvolutionKernelFilter.TYPE_HORIZONTAL_SOBEL);
1212            }
1213    
1214            public void filtersVerticalSobel()
1215            {
1216                    filterConvolutionFilter(ConvolutionKernelFilter.TYPE_VERTICAL_SOBEL);
1217            }
1218    
1219            public void filtersHorizontalPrewitt()
1220            {
1221                    filterConvolutionFilter(ConvolutionKernelFilter.TYPE_HORIZONTAL_PREWITT);
1222            }
1223    
1224            public void filtersVerticalPrewitt()
1225            {
1226                    filterConvolutionFilter(ConvolutionKernelFilter.TYPE_VERTICAL_PREWITT);
1227            }
1228    
1229            public void filtersMaximum()
1230            {
1231                    EditorState state = getEditorState();
1232                    Strings strings = state.getStrings();
1233                    WindowSizeDialog wsd = new WindowSizeDialog(frame, strings, StringIndexConstants.APPLY_MAXIMUM_FILTER, 3, 3);
1234                    wsd.show();
1235                    if (!wsd.hasPressedOk())
1236                    {
1237                            return;
1238                    }
1239                    MaximumFilter mf = new MaximumFilter();
1240                    mf.setArea(wsd.getWidthValue(), wsd.getHeightValue());
1241                    process(mf);
1242            }
1243    
1244            public void filtersMedian()
1245            {
1246                    EditorState state = getEditorState();
1247                    Strings strings = state.getStrings();
1248                    WindowSizeDialog wsd = new WindowSizeDialog(frame, strings, StringIndexConstants.APPLY_MEDIAN_FILTER, 3, 3);
1249                    wsd.show();
1250                    if (!wsd.hasPressedOk())
1251                    {
1252                            return;
1253                    }
1254                    MedianFilter mf = new MedianFilter();
1255                    mf.setArea(wsd.getWidthValue(), wsd.getHeightValue());
1256                    process(mf);
1257            }
1258    
1259            public void filtersMean()
1260            {
1261                    EditorState state = getEditorState();
1262                    Strings strings = state.getStrings();
1263                    WindowSizeDialog wsd = new WindowSizeDialog(frame, strings, StringIndexConstants.APPLY_MEAN_FILTER, 3, 3);
1264                    wsd.show();
1265                    if (!wsd.hasPressedOk())
1266                    {
1267                            return;
1268                    }
1269                    MeanFilter mf = new MeanFilter();
1270                    mf.setArea(wsd.getWidthValue(), wsd.getHeightValue());
1271                    process(mf);
1272            }
1273    
1274    
1275            public void filtersMinimum()
1276            {
1277                    EditorState state = getEditorState();
1278                    Strings strings = state.getStrings();
1279                    WindowSizeDialog wsd = new WindowSizeDialog(frame, strings, StringIndexConstants.APPLY_MINIMUM_FILTER, 3, 3);
1280                    wsd.show();
1281                    if (!wsd.hasPressedOk())
1282                    {
1283                            return;
1284                    }
1285                    MinimumFilter mf = new MinimumFilter();
1286                    mf.setArea(wsd.getWidthValue(), wsd.getHeightValue());
1287                    process(mf);
1288            }
1289    
1290            public void filtersOil()
1291            {
1292                    EditorState state = getEditorState();
1293                    Strings strings = state.getStrings();
1294                    WindowSizeDialog wsd = new WindowSizeDialog(frame, strings, StringIndexConstants.APPLY_OIL_FILTER, 3, 3);
1295                    wsd.show();
1296                    if (!wsd.hasPressedOk())
1297                    {
1298                            return;
1299                    }
1300                    OilFilter of = new OilFilter();
1301                    of.setArea(wsd.getWidthValue(), wsd.getHeightValue());
1302                    process(of);
1303            }
1304    
1305            public String getUserFileName(String extension, int titleIndex, int fileDialogType)
1306            {
1307                    EditorState editor = getEditorState();
1308                    Strings strings = editor.getStrings();
1309                    FileDialog fd = new FileDialog(frame, strings.get(titleIndex), fileDialogType);
1310                    String currentDirectory = editor.getCurrentDirectory();
1311                    if (currentDirectory != null)
1312                    {
1313                            fd.setDirectory(currentDirectory);
1314                    }
1315                    String fileName = editor.getFileName();
1316                    if (fileDialogType == FileDialog.SAVE && 
1317                        fileName != null && 
1318                        extension != null)
1319                    {
1320                            File existingFile = new File(fileName);
1321                            String name = existingFile.getName();
1322                            if (name != null)
1323                            {
1324                                    int dotIndex = name.lastIndexOf(".");
1325                                    if (dotIndex != -1)
1326                                    {
1327                                            name = name.substring(0, dotIndex);
1328                                            name += extension;
1329                                    }
1330                            }
1331                            fd.setFile(name);
1332                    }
1333                    fd.show();
1334                    String fn = fd.getFile();
1335                    String dn = fd.getDirectory();
1336                    if (fn == null || dn == null)
1337                    {
1338                            return null;
1339                    }
1340                    File file = new File(dn, fn);
1341                    return file.getAbsolutePath();
1342            }
1343    
1344            public String getUserSaveAsFileName(String extension, int titleIndex)
1345            {
1346                    return getUserFileName(extension, titleIndex, FileDialog.SAVE);
1347            }
1348    
1349            public void helpAbout()
1350            {
1351                    EditorState state = getEditorState();
1352                    Strings strings = state.getStrings();
1353                    String message = 
1354                            JiuAwtFrame.APP_NAME + "\n" + 
1355                            strings.get(StringIndexConstants.HOMEPAGE) + "=" + JiuInfo.JIU_HOMEPAGE + "\n" +
1356                            strings.get(StringIndexConstants.FEEDBACK) + "=" + JiuInfo.JIU_FEEDBACK_ADDRESS;
1357                    frame.showInfo(strings.get(StringIndexConstants.ABOUT), message);
1358            }
1359    
1360            public void helpSystemInformation()
1361            {
1362                    EditorState state = getEditorState();
1363                    Strings strings = state.getStrings();
1364                    frame.showInfo(strings.get(StringIndexConstants.SYSTEM_INFORMATION), 
1365                            SystemInfo.getSystemInfo(strings) + "\n" + 
1366                            AwtInfo.getAwtInfo(strings) + "\n" + 
1367                            SystemInfo.getMemoryInfo(strings));
1368            }
1369    
1370            /**
1371             * This method can be called for ImageToImageOperation objects.
1372             */
1373            public void process(ImageToImageOperation op)
1374            {
1375                    EditorState state = getEditorState();
1376                    PixelImage image = state.getImage();
1377                    if (image == null)
1378                    {
1379                            return;
1380                    }
1381                    frame.setWaitCursor();
1382                    op.setInputImage(image);
1383                    op.addProgressListeners(state.getProgressListeners());
1384                    try
1385                    {
1386                            op.process();
1387                            frame.setDefaultCursor();
1388                    }
1389                    catch (OperationFailedException ofe)
1390                    {
1391                            frame.setDefaultCursor();
1392                            frame.showError(ofe.toString());
1393                            return;
1394                    }
1395                    setImage(op.getOutputImage(), true);
1396                    frame.updateImage();
1397            }
1398    
1399            public void setImage(PixelImage newImage, boolean newModified)
1400            {
1401                    EditorState state = getEditorState();
1402                    state.setImage(newImage, newModified);
1403            }
1404    
1405            public void transformationsFlip()
1406            {
1407                    process(new Flip());
1408            }
1409    
1410            public void transformationsMirror()
1411            {
1412                    process(new Mirror());
1413            }
1414    
1415            public void transformationsRotate90Left()
1416            {
1417                    process(new Rotate90Left());
1418            }
1419    
1420            public void transformationsRotate90Right()
1421            {
1422                    process(new Rotate90Right());
1423            }
1424    
1425            public void transformationsRotate180()
1426            {
1427                    Rotate180 rot = new Rotate180();
1428                    EditorState state = getEditorState();
1429                    rot.setInputImage(state.getImage());
1430                    process(rot);
1431            }
1432    
1433            public void transformationsCrop()
1434            {
1435                    EditorState state = getEditorState();
1436                    Strings strings = state.getStrings();
1437                    PixelImage image = state.getImage();
1438                    CropDialog cd = new CropDialog(frame, strings, image.getWidth(), image.getHeight());
1439                    cd.show();
1440                    if (!cd.hasPressedOk())
1441                    {
1442                            return;
1443                    }
1444                    int x1 = cd.getX1();
1445                    int x2 = cd.getX2();
1446                    int y1 = cd.getY1();
1447                    int y2 = cd.getY2();
1448                    Crop crop = new Crop();
1449                    crop.setBounds(x1, y1, x2, y2);
1450                    process(crop);
1451            }
1452    
1453            public void transformationsShear()
1454            {
1455                    EditorState state = getEditorState();
1456                    PixelImage image = state.getImage();
1457                    Strings strings = state.getStrings();
1458                    ShearDialog sd = new ShearDialog(frame, strings, 45.0, image.getWidth(), image.getHeight());
1459                    sd.show();
1460                    if (!sd.hasPressedOk())
1461                    {
1462                            return;
1463                    }
1464                    Double angle = sd.getValue();
1465                    if (angle == null || angle.doubleValue() == 0.0)
1466                    {
1467                            return;
1468                    }
1469                    Shear shear = new Shear();
1470                    shear.setAngle(angle.doubleValue());
1471                    process(shear);
1472            }
1473    
1474            public void transformationsScale()
1475            {
1476                    EditorState state = getEditorState();
1477                    PixelImage image = state.getImage();
1478                    Strings strings = state.getStrings();
1479                    // a type can be chosen by the user if rgb or gray image
1480                    boolean pickType = image instanceof RGB24Image || image instanceof Gray8Image;
1481                    int initialType;
1482                    if (pickType)
1483                    {
1484                            initialType = Resample.FILTER_TYPE_B_SPLINE;
1485                    }
1486                    else
1487                    {
1488                            initialType = Resample.FILTER_TYPE_BOX;
1489                    }
1490                    ScaleDialog sd = new ScaleDialog(frame, strings, image.getWidth(), 
1491                            image.getHeight(), pickType, Resample.getFilterNames(), initialType);
1492                    sd.show();
1493                    if (sd.hasPressedOk())
1494                    {
1495                            int newWidth = sd.getWidthValue();
1496                            int newHeight = sd.getHeightValue();
1497                            if (newWidth < 1 || newHeight < 1 ||
1498                                (newWidth == image.getWidth() && newHeight == image.getHeight()))
1499                            {
1500                                    return;
1501                            }
1502                            if (pickType)
1503                            {
1504                                    Resample resample = new Resample();
1505                                    resample.setFilter(sd.getType());
1506                                    ResampleFilter filter = resample.getFilter();
1507                                    filter.setSamplingRadius(filter.getRecommendedSamplingRadius() * 50);
1508                                    resample.setSize(newWidth, newHeight);
1509                                    process(resample);
1510                            }
1511                            else
1512                            {
1513                                    ScaleReplication sc = new ScaleReplication();
1514                                    sc.setSize(newWidth, newHeight);
1515                                    process(sc);
1516                            }
1517                    }
1518            }
1519    
1520            public void updateFrame(PixelImage image)
1521            {
1522                    EditorState state = getEditorState();
1523                    state.setImage(image, true);
1524                    frame.setDefaultCursor();
1525                    frame.updateImage();
1526            }
1527    
1528            public void viewInterpolationTypeBicubic()
1529            {
1530                    EditorState state = getEditorState();
1531                    state.setInterpolation(EditorState.INTERPOLATION_BICUBIC);
1532                    frame.updateCanvas();
1533            }
1534    
1535            public void viewInterpolationTypeBilinear()
1536            {
1537                    EditorState state = getEditorState();
1538                    state.setInterpolation(EditorState.INTERPOLATION_BILINEAR);
1539                    frame.updateCanvas();
1540            }
1541    
1542            public void viewInterpolationTypeNearestNeighbor()
1543            {
1544                    EditorState state = getEditorState();
1545                    state.setInterpolation(EditorState.INTERPOLATION_NEAREST_NEIGHBOR);
1546                    frame.updateCanvas();
1547            }
1548    
1549            public void viewZoomIn()
1550            {
1551                    frame.zoomIn();
1552            }
1553    
1554            public void viewZoomOut()
1555            {
1556                    frame.zoomOut();
1557            }
1558    
1559            public void viewSetOriginalSize()
1560            {
1561                    frame.setOriginalSize();
1562            }
1563    }