source: 3thparty/jupload/src/main/java/wjhk/jupload2/filedata/helper/ImageHelper.java @ 3951

Revision 3951, 30.3 KB checked in by alexandrecorreia, 13 years ago (diff)

Ticket #1709 - Adicao de codigo fonte java do componente jupload

Line 
1//
2// $Id$
3//
4// jupload - A file upload applet.
5//
6// Copyright 2008 The JUpload Team
7//
8// Created: 12 fevr. 08
9// Creator: etienne_sf
10// Last modified: $Date$
11//
12// This program is free software; you can redistribute it and/or modify
13// it under the terms of the GNU General Public License as published by
14// the Free Software Foundation; either version 2 of the License, or
15// (at your option) any later version.
16//
17// This program is distributed in the hope that it will be useful,
18// but WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20// GNU General Public License for more details.
21//
22// You should have received a copy of the GNU General Public License
23// along with this program; if not, write to the Free Software
24// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26package wjhk.jupload2.filedata.helper;
27
28import java.awt.Image;
29import java.awt.geom.AffineTransform;
30import java.awt.image.AffineTransformOp;
31import java.awt.image.BufferedImage;
32import java.awt.image.ImageObserver;
33
34import wjhk.jupload2.exception.JUploadException;
35import wjhk.jupload2.exception.JUploadIOException;
36import wjhk.jupload2.filedata.DefaultFileData;
37import wjhk.jupload2.filedata.PictureFileData;
38import wjhk.jupload2.policies.PictureUploadPolicy;
39
40/**
41 * Class that contains various utilities about picture, mainly about picture
42 * transformation.
43 *
44 * @author etienne_sf
45 *
46 */
47public class ImageHelper implements ImageObserver {
48
49    /**
50     * hasToTransformPicture indicates whether the picture should be
51     * transformed. Null if unknown. This can happen (for instance) if no calcul
52     * where done (during initialization), or after rotating the picture back to
53     * the original orientation. <BR>
54     * <B>Note:</B> this attribute is from the class Boolean (and not a simple
55     * boolean), to allow null value, meaning <I>unknown</I>.
56     */
57    private Boolean hasToTransformPicture = null;
58
59    /**
60     * The {@link PictureFileData} that this helper will have to help.
61     */
62    private PictureFileData pictureFileData;
63
64    /**
65     * Current rotation of the picture: 0 to 3.
66     *
67     * @see PictureFileData
68     */
69    private int quarterRotation;
70
71    /**
72     * Maximum width for the current transformation
73     */
74    private int maxWidth;
75
76    /**
77     * Maximum height for the current transformation
78     */
79    private int maxHeight;
80
81    /**
82     * Defines the number of pixel for the current picture. Used to update the
83     * progress bar.
84     *
85     * @see #getBufferedImage(boolean, BufferedImage)
86     * @see #imageUpdate(Image, int, int, int, int, int)
87     */
88    private int nbPixelsTotal = -1;
89
90    /**
91     * Indicates the number of pixels that have been read.
92     *
93     * @see #nbPixelsTotal
94     * @see #imageUpdate(Image, int, int, int, int, int)
95     */
96    private int nbPixelsRead = 0;
97
98    /**
99     * Width of picture, after rescaling but without rotation. It should be
100     * scale*originalWidth, but, due to rounding number, it can be transformed
101     * to scale*originalWidth-1.
102     *
103     * @see #initScale()
104     */
105    private int scaledNonRotatedWidth = -1;
106
107    /**
108     * Same as {@link #scaledNonRotatedWidth}
109     */
110    private int scaledNonRotatedHeight = -1;
111
112    /**
113     * The value that has the progress bar when starting to load the picture.
114     * The {@link #imageUpdate(Image, int, int, int, int, int)} method will add
115     * from 0 to 100, to indicate progress with a percentage value of picture
116     * loading.
117     */
118    private int progressBarBaseValue = 0;
119
120    /**
121     * Current scaling factor. If less than 1, means a picture reduction.
122     *
123     * @see #initScale()
124     */
125    private double scale = 1;
126
127    /**
128     * Width of picture, after re-scaling and rotation. It should be
129     * scale*originalWidth or scale*originalHeight (depending on the rotation).
130     * But, due to rounding number, it can be transformed to
131     * scale*originalWidth-1 or scale*originalHeight-1.
132     *
133     * @see #initScale()
134     */
135    private int scaledRotatedWidth = -1;
136
137    /**
138     * Same as {@link #scaledRotatedWidth}, for the height.
139     */
140    private int scaledRotatedHeight = -1;
141
142    /**
143     * The current upload policy must be a {@link PictureUploadPolicy}
144     */
145    PictureUploadPolicy uploadPolicy;
146
147    /**
148     * Standard constructor.
149     *
150     * @param uploadPolicy The current upload policy
151     * @param pictureFileData The picture file data to help
152     * @param targetMaxWidth
153     * @param targetMaxHeight
154     * @param quarterRotation Current quarter rotation (from 0 to 3)
155     * @throws JUploadIOException
156     */
157    public ImageHelper(PictureUploadPolicy uploadPolicy,
158            PictureFileData pictureFileData, int targetMaxWidth,
159            int targetMaxHeight, int quarterRotation) throws JUploadIOException {
160        this.uploadPolicy = uploadPolicy;
161        this.pictureFileData = pictureFileData;
162        this.maxWidth = targetMaxWidth;
163        this.maxHeight = targetMaxHeight;
164        this.quarterRotation = quarterRotation;
165
166        // Pre-calculation: should the current picture be rescaled, to match the
167        // given target size ?
168        initScale();
169    }
170
171    /**
172     * Intialization of scale factor, for the current picture state. The scale
173     * is based on the maximum width and height, the current rotation, and the
174     * picture size.
175     */
176    private void initScale() throws JUploadIOException {
177        double theta = Math.toRadians(90 * this.quarterRotation);
178
179        // The width and height depend on the current rotation :
180        // calculation of the width and height of picture after
181        // rotation.
182        int nonScaledRotatedWidth = this.pictureFileData.getOriginalWidth();
183        int nonScaledRotatedHeight = this.pictureFileData.getOriginalHeight();
184        if (this.quarterRotation % 2 != 0) {
185            // 90 degrees or 270 degrees rotation: width and height are
186            // switched.
187            nonScaledRotatedWidth = this.pictureFileData.getOriginalHeight();
188            nonScaledRotatedHeight = this.pictureFileData.getOriginalWidth();
189        }
190        // Now, we can compare these width and height to the maximum
191        // width and height
192        double scaleWidth = ((this.maxWidth < 0) ? 1 : ((double) this.maxWidth)
193                / nonScaledRotatedWidth);
194        double scaleHeight = ((this.maxHeight < 0) ? 1
195                : ((double) this.maxHeight) / nonScaledRotatedHeight);
196        this.scale = Math.min(scaleWidth, scaleHeight);
197        if (this.scale < 1) {
198            // With number rounding, it can happen that width or size
199            // became one pixel too big. Let's correct it.
200            if ((this.maxWidth > 0 && this.maxWidth < (int) (this.scale
201                    * Math.cos(theta) * nonScaledRotatedWidth))
202                    || (this.maxHeight > 0 && this.maxHeight < (int) (this.scale
203                            * Math.cos(theta) * nonScaledRotatedHeight))) {
204                scaleWidth = ((this.maxWidth < 0) ? 1
205                        : ((double) this.maxWidth - 1)
206                                / (nonScaledRotatedWidth));
207                scaleHeight = ((this.maxHeight < 0) ? 1
208                        : ((double) this.maxHeight - 1)
209                                / (nonScaledRotatedHeight));
210                this.scale = Math.min(scaleWidth, scaleHeight);
211            }
212        }
213
214        // These variables contain the actual width and height after
215        // rescaling, and before rotation.
216        this.scaledRotatedWidth = nonScaledRotatedWidth;
217        this.scaledRotatedHeight = nonScaledRotatedHeight;
218        // Is there any rescaling to do ?
219        // Patch for the first bug, tracked in the sourceforge bug
220        // tracker ! ;-)
221        if (this.scale < 1) {
222            this.scaledRotatedWidth *= this.scale;
223            this.scaledRotatedHeight *= this.scale;
224            this.uploadPolicy.displayDebug("Resizing factor (scale): "
225                    + this.scale, 30);
226        } else {
227            this.uploadPolicy.displayDebug(
228                    "Resizing factor (scale): no resizing (calculated scale was "
229                            + this.scale + ")", 30);
230        }
231        // Due to rounded numbers, the resulting targetWidth or
232        // targetHeight
233        // may be one pixel too big. Let's check that.
234        if (this.scaledRotatedWidth > this.maxWidth) {
235            this.uploadPolicy.displayDebug("Correcting rounded width: "
236                    + this.scaledRotatedWidth + " to " + this.maxWidth, 50);
237            this.scaledRotatedWidth = this.maxWidth;
238        }
239        if (this.scaledRotatedHeight > this.maxHeight) {
240            this.uploadPolicy.displayDebug("Correcting rounded height: "
241                    + this.scaledRotatedHeight + " to " + this.maxHeight, 50);
242            this.scaledRotatedHeight = this.maxHeight;
243        }
244
245        // getBufferedImage will need the two following value:
246        if (this.quarterRotation % 2 == 0) {
247            this.scaledNonRotatedWidth = this.scaledRotatedWidth;
248            this.scaledNonRotatedHeight = this.scaledRotatedHeight;
249        } else {
250            this.scaledNonRotatedWidth = this.scaledRotatedHeight;
251            this.scaledNonRotatedHeight = this.scaledRotatedWidth;
252        }
253    }
254
255    /**
256     * This function indicate if the picture has to be modified. For instance :
257     * a maximum width, height, a target format...
258     *
259     * @return true if the picture must be transformed. false if the file can be
260     *         directly transmitted.
261     * @throws JUploadException Contains any exception that could be thrown in
262     *             this method
263     */
264    public boolean hasToTransformPicture() throws JUploadException {
265        // Animated gif must be transmit as is, as I can't find a way to
266        // recreate them.
267        if (DefaultFileData.getExtension(this.pictureFileData.getFile())
268                .equalsIgnoreCase("gif")) {
269            // If this is an animated gif, no transformation... I can't succeed
270            // to create a transformed picture file for them.
271            ImageReaderWriterHelper irwh = new ImageReaderWriterHelper(
272                    this.uploadPolicy, this.pictureFileData);
273            int nbImages = irwh.getNumImages(true);
274            irwh.dispose();
275            irwh = null;
276            if (nbImages > 1) {
277                // Too bad. We can not transform it.
278                this.hasToTransformPicture = Boolean.FALSE;
279                this.uploadPolicy
280                        .displayWarn("No transformation for gif picture file, that contain several pictures. (see JUpload documentation for details)");
281            }
282        }
283
284        // Did we already estimate if transformation is needed ?
285        if (this.hasToTransformPicture == null) {
286
287            // First : the easiest test. Should we block metadata ?
288            if (this.hasToTransformPicture == null
289                    && !(this.uploadPolicy).getPictureTransmitMetadata()) {
290                this.hasToTransformPicture = Boolean.TRUE;
291                this.uploadPolicy
292                        .displayDebug(
293                                this.pictureFileData.getFileName()
294                                        + " : hasToTransformPicture=true (pictureTransmitMetadata is false)",
295                                80);
296            }
297            // Second : another easy test. A rotation is needed ?
298            if (this.hasToTransformPicture == null && this.quarterRotation != 0) {
299                this.uploadPolicy
300                        .displayDebug(
301                                this.pictureFileData.getFileName()
302                                        + " : hasToTransformPicture = true (quarterRotation != 0)",
303                                10);
304                this.hasToTransformPicture = Boolean.TRUE;
305            }
306
307            // Third : the picture format is the same ?
308            String targetFormat = this.uploadPolicy
309                    .getImageFileConversionInfo().getTargetFormatOrNull(
310                            this.pictureFileData.getFileExtension());
311            if (this.hasToTransformPicture == null && targetFormat != null) {
312                this.uploadPolicy
313                        .displayDebug(
314                                this.pictureFileData.getFileName()
315                                        + " : hasToTransformPicture = true (targetPictureFormat)",
316                                10);
317                this.hasToTransformPicture = Boolean.TRUE;
318            }
319
320            // Fourth : should we resize the picture ?
321            if (this.hasToTransformPicture == null && this.scale < 1) {
322                this.uploadPolicy.displayDebug(this.pictureFileData
323                        .getFileName()
324                        + " : hasToTransformPicture = true (scale < 1)", 10);
325                this.hasToTransformPicture = Boolean.TRUE;
326            }
327
328            // If we find no reason to transform the picture, then let's let the
329            // picture unmodified.
330            if (this.hasToTransformPicture == null) {
331                this.uploadPolicy.displayDebug(this.pictureFileData
332                        .getFileName()
333                        + " : hasToTransformPicture = false", 10);
334                this.hasToTransformPicture = Boolean.FALSE;
335                this.uploadPolicy.displayDebug(this.pictureFileData
336                        .getFileName()
337                        + " : hasToTransformPicture = false", 10);
338            }
339        }
340
341        return this.hasToTransformPicture.booleanValue();
342    }// end of hasToTransformPicture
343
344    /**
345     * This function resizes the picture, if necessary, according to the
346     * maxWidth and maxHeight, given to the ImageHelper constructor. <BR>
347     * This function should only be called if isPicture is true. Otherwise, an
348     * exception is raised. <BR>
349     * Note (Update given by David Gnedt): the highquality will condition the
350     * call of getScaledInstance, instead of a basic scale Transformation. The
351     * generated picture is of better quality, but this is longer, especially on
352     * 'small' CPU. Time samples, with one picture from my canon EOS20D, on a
353     * PII 500M: <BR>
354     * ~3s for the full screen preview with highquality to false, and a quarter
355     * rotation. 12s to 20s with highquality to true. <BR>
356     * ~5s for the first (small) preview of the picture, with both highquality
357     * to false or true.
358     *
359     * @param highquality (added by David Gnedt): if set to true, the
360     *            BufferedImage.getScaledInstance() is called. This generates
361     *            better image, but consumes more CPU.
362     * @param sourceBufferedImage The image to resize or rotate or both or no
363     *            tranformation...
364     * @return A BufferedImage which contains the picture according to current
365     *         parameters (resizing, rotation...), or null if this is not a
366     *         picture.
367     * @throws JUploadException Contains any exception thrown from within this
368     *             method.
369     */
370    public BufferedImage getBufferedImage(boolean highquality,
371            BufferedImage sourceBufferedImage) throws JUploadException {
372        long msGetBufferedImage = System.currentTimeMillis();
373        double theta = Math.toRadians(90 * this.quarterRotation);
374
375        BufferedImage returnedBufferedImage = null;
376
377        this.uploadPolicy.displayDebug("getBufferedImage: start", 10);
378
379        try {
380            AffineTransform transform = new AffineTransform();
381
382            if (this.quarterRotation != 0) {
383                double translationX = 0, translationY = 0;
384                this.uploadPolicy.displayDebug("getBufferedImage: quarter: "
385                        + this.quarterRotation, 50);
386
387                // quarterRotation is one of 0, 1, 2, 3 : see addRotation.
388                // If we're here : it's not 0, so it's one of 1, 2 or 3.
389                switch (this.quarterRotation) {
390                    case 1:
391                        translationX = 0;
392                        translationY = -this.scaledRotatedWidth;
393                        break;
394                    case 2:
395                        translationX = -this.scaledRotatedWidth;
396                        translationY = -this.scaledRotatedHeight;
397                        break;
398                    case 3:
399                        translationX = -this.scaledRotatedHeight;
400                        translationY = 0;
401                        break;
402                    default:
403                        this.uploadPolicy
404                                .displayWarn("Invalid quarterRotation : "
405                                        + this.quarterRotation);
406                        this.quarterRotation = 0;
407                        theta = 0;
408                }
409                transform.rotate(theta);
410                transform.translate(translationX, translationY);
411            }
412
413            // If we have to rescale the picture, we first do it:
414            if (this.scale < 1) {
415                if (highquality) {
416                    this.uploadPolicy
417                            .displayDebug(
418                                    "getBufferedImage: Resizing picture(using high quality picture)",
419                                    30);
420
421                    // SCALE_AREA_AVERAGING forces the picture calculation
422                    // algorithm.
423                    // Other parameters give bad picture quality.
424                    Image img = sourceBufferedImage.getScaledInstance(
425                            this.scaledNonRotatedWidth,
426                            this.scaledNonRotatedHeight,
427                            Image.SCALE_AREA_AVERAGING);
428
429                    // the localBufferedImage may be 'unknown'.
430                    int localImageType = sourceBufferedImage.getType();
431                    if (localImageType == BufferedImage.TYPE_CUSTOM) {
432                        localImageType = BufferedImage.TYPE_INT_BGR;
433                    }
434
435                    BufferedImage tempBufferedImage = new BufferedImage(
436                            this.scaledNonRotatedWidth,
437                            this.scaledNonRotatedHeight, localImageType);
438
439                    // drawImage can be long. Let's follow its progress,
440                    // with the applet progress bar.
441                    this.nbPixelsTotal = this.scaledNonRotatedWidth
442                            * this.scaledNonRotatedHeight;
443                    this.nbPixelsRead = 0;
444
445                    // Let's draw the picture: this code do the rescaling.
446                    this.uploadPolicy.displayDebug(
447                            "getBufferedImage: Before drawImage", 50);
448                    tempBufferedImage.getGraphics().drawImage(img, 0, 0, this);
449                    this.uploadPolicy.displayDebug(
450                            "getBufferedImage: After drawImage", 50);
451
452                    tempBufferedImage.flush();
453
454                    img.flush();
455                    img = null;
456                    PictureFileData
457                            .freeMemory("ImageHelper.getBufferedImage()",
458                                    this.uploadPolicy);
459
460                    // tempBufferedImage contains the rescaled picture. It's
461                    // the source image for the next step (rotation).
462                    sourceBufferedImage = tempBufferedImage;
463                    tempBufferedImage = null;
464                } else {
465                    // 'low' quality
466                    //
467                    // The scale method adds scaling before current
468                    // transformation.
469                    this.uploadPolicy
470                            .displayDebug(
471                                    "getBufferedImage: Resizing picture(using standard quality picture)",
472                                    50);
473                    transform.scale(this.scale, this.scale);
474                }
475            }
476
477            if (transform.isIdentity()) {
478                returnedBufferedImage = sourceBufferedImage;
479            } else {
480                AffineTransformOp affineTransformOp = null;
481                // Pictures are Ok.
482                affineTransformOp = new AffineTransformOp(transform,
483                        AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
484                returnedBufferedImage = affineTransformOp
485                        .createCompatibleDestImage(sourceBufferedImage, null);
486                // Checks, after the fact the pictures produces by the Canon
487                // EOS 30D are not properly resized: colors are 'strange'
488                // after resizing.
489                this.uploadPolicy.displayDebug(
490                        "getBufferedImage: returnedBufferedImage.getColorModel(): "
491                                + sourceBufferedImage.getColorModel()
492                                        .toString(), 50);
493                this.uploadPolicy.displayDebug(
494                        "getBufferedImage: returnedBufferedImage.getColorModel(): "
495                                + sourceBufferedImage.getColorModel()
496                                        .toString(), 50);
497                affineTransformOp.filter(sourceBufferedImage,
498                        returnedBufferedImage);
499                affineTransformOp = null;
500
501                returnedBufferedImage.flush();
502            }
503        } catch (Exception e) {
504            throw new JUploadException(e.getClass().getName() + " ("
505                    + this.getClass().getName() + ".getBufferedImage()) : "
506                    + e.getMessage());
507        }
508
509        if (returnedBufferedImage != null
510                && this.uploadPolicy.getDebugLevel() >= 50) {
511            this.uploadPolicy.displayDebug("getBufferedImage: "
512                    + returnedBufferedImage, 50);
513            this.uploadPolicy.displayDebug("getBufferedImage: MinX="
514                    + returnedBufferedImage.getMinX(), 50);
515            this.uploadPolicy.displayDebug("getBufferedImage: MinY="
516                    + returnedBufferedImage.getMinY(), 50);
517        }
518
519        this.uploadPolicy.displayDebug("getBufferedImage: was "
520                + (System.currentTimeMillis() - msGetBufferedImage)
521                + " ms long", 50);
522        PictureFileData.freeMemory("ImageHelper.getBufferedImage()",
523                this.uploadPolicy);
524        return returnedBufferedImage;
525    }
526
527    /**
528     * This method is a work in progress
529     *
530     * @param highquality
531     * @param sourceBufferedImage
532     * @return The calculated BufferedImage, resized and rotated according to
533     *         the current configuration.
534     * @throws JUploadException
535     */
536    BufferedImage getBufferedImage2(boolean highquality,
537            BufferedImage sourceBufferedImage) throws JUploadException {
538        long msGetBufferedImage = System.currentTimeMillis();
539        BufferedImage dest = null;
540
541        // Scale factor calculation
542        this.uploadPolicy.displayDebug("getBufferedImage: quarter: "
543                + this.quarterRotation, 50);
544
545        // quarterRotation is one of 0, 1, 2, 3 : see addRotation.
546        @SuppressWarnings("unused")
547        int maxWidthBeforeRotation, maxHeigthBeforeRotation, widthBeforeRotation, heigthBeforeRotation, widthAfterRotation, heigthAfterRotation;
548        @SuppressWarnings("unused")
549        double theta = Math.toRadians(90 * this.quarterRotation);
550        switch (this.quarterRotation) {
551            case 0:
552            case 2:
553                maxWidthBeforeRotation = this.uploadPolicy.getMaxWidth();
554                maxHeigthBeforeRotation = this.uploadPolicy.getMaxHeight();
555                widthBeforeRotation = sourceBufferedImage.getWidth();
556                heigthBeforeRotation = sourceBufferedImage.getHeight();
557                widthAfterRotation = sourceBufferedImage.getWidth();
558                heigthAfterRotation = sourceBufferedImage.getHeight();
559                break;
560            case 1:
561            case 3:
562                maxWidthBeforeRotation = this.uploadPolicy.getMaxHeight();
563                maxHeigthBeforeRotation = this.uploadPolicy.getMaxWidth();
564                widthBeforeRotation = sourceBufferedImage.getHeight();
565                heigthBeforeRotation = sourceBufferedImage.getWidth();
566                widthAfterRotation = sourceBufferedImage.getHeight();
567                heigthAfterRotation = sourceBufferedImage.getWidth();
568                break;
569            default:
570                throw new JUploadException("Invalid quarter rotation: <"
571                        + this.quarterRotation + ">");
572        }
573        double scaleWidthBeforeRotation = widthBeforeRotation
574                / maxWidthBeforeRotation;
575        double scaleHeigthBeforeRotation = heigthBeforeRotation
576                / maxHeigthBeforeRotation;
577        double scale = Math.min(scaleWidthBeforeRotation,
578                scaleHeigthBeforeRotation);
579
580        // First: we scale the picture... if necessary.
581        @SuppressWarnings("unused")
582        Image scaledPicture = sourceBufferedImage;
583        if (scale < 1) {
584            int targetWidthBeforeRotation, targetHeigthBeforeRotation;
585            if (scaleWidthBeforeRotation < scaleHeigthBeforeRotation) {
586                // The constraint is on the width.
587                targetWidthBeforeRotation = maxWidthBeforeRotation;
588                targetHeigthBeforeRotation = (int) (heigthBeforeRotation * scale);
589            } else {
590                // The constraint is on the heigth
591                targetHeigthBeforeRotation = maxHeigthBeforeRotation;
592                targetWidthBeforeRotation = (int) (widthBeforeRotation * scale);
593            }
594            int scale_xxx = highquality ? Image.SCALE_SMOOTH : Image.SCALE_FAST;
595            scaledPicture = sourceBufferedImage.getScaledInstance(
596                    targetWidthBeforeRotation, targetHeigthBeforeRotation,
597                    scale_xxx);
598        }// if (scale < 1)
599
600        // Then, rotation of the scaled picture.
601        if (this.quarterRotation != 0) {
602            @SuppressWarnings("unused")
603            AffineTransform rotationTransform;
604            switch (this.quarterRotation) {
605                case 0:
606                case 2:
607                    maxWidthBeforeRotation = this.uploadPolicy.getMaxWidth();
608                    maxHeigthBeforeRotation = this.uploadPolicy.getMaxHeight();
609                    widthBeforeRotation = sourceBufferedImage.getWidth();
610                    heigthBeforeRotation = sourceBufferedImage.getHeight();
611                    widthAfterRotation = sourceBufferedImage.getWidth();
612                    heigthAfterRotation = sourceBufferedImage.getHeight();
613                    break;
614                case 1:
615                case 3:
616                    maxWidthBeforeRotation = this.uploadPolicy.getMaxHeight();
617                    maxHeigthBeforeRotation = this.uploadPolicy.getMaxWidth();
618                    widthBeforeRotation = sourceBufferedImage.getHeight();
619                    heigthBeforeRotation = sourceBufferedImage.getWidth();
620                    widthAfterRotation = sourceBufferedImage.getHeight();
621                    heigthAfterRotation = sourceBufferedImage.getWidth();
622                    break;
623                default:
624                    throw new JUploadException("Invalid quarter rotation: <"
625                            + this.quarterRotation + ">");
626            }
627            // TODO finish this new version
628            // dest = new BufferedImage(widthAfterRotation, heigthAfterRotation,
629            // BufferedImage.TYPE_BYTE_INDEXED,sourceBufferedImage.getColorModel())
630
631            // It's finished !
632            this.uploadPolicy.displayDebug("getBufferedImage: was "
633                    + (System.currentTimeMillis() - msGetBufferedImage)
634                    + " ms long", 50);
635        }
636        return dest;
637    }
638
639    /**
640     * Implementation of the ImageObserver interface. Used to follow the
641     * drawImage progression, and update the applet progress bar.
642     *
643     * @param img
644     * @param infoflags
645     * @param x
646     * @param y
647     * @param width
648     * @param height
649     * @return Whether or not the work must go on.
650     *
651     */
652    public boolean imageUpdate(Image img, int infoflags, int x, int y,
653            int width, int height) {
654        if ((infoflags & ImageObserver.WIDTH) == ImageObserver.WIDTH) {
655            this.progressBarBaseValue = this.uploadPolicy.getContext()
656                    .getUploadPanel().getPreparationProgressBar().getValue();
657            this.uploadPolicy.displayDebug(
658                    "  imageUpdate (start of), progressBar geValue: "
659                            + this.progressBarBaseValue, 50);
660            int max = this.uploadPolicy.getContext().getUploadPanel()
661                    .getPreparationProgressBar().getMaximum();
662            this.uploadPolicy
663                    .displayDebug(
664                            "  imageUpdate (start of), progressBar maximum: "
665                                    + max, 50);
666        } else if ((infoflags & ImageObserver.SOMEBITS) == ImageObserver.SOMEBITS) {
667            this.nbPixelsRead += width * height;
668            int percentage = (int) ((long) this.nbPixelsRead * 100 / this.nbPixelsTotal);
669            this.uploadPolicy.getContext().getUploadPanel()
670                    .getPreparationProgressBar().setValue(
671                            this.progressBarBaseValue + percentage);
672            // TODO: drawImage in another thread, to allow repaint of the
673            // progress bar ?
674            // Current status: the progress bar is only updated ... when
675            // draImage returns, that is: when everything is finished. NO
676            // interest.
677            this.uploadPolicy.getContext().getUploadPanel()
678                    .getPreparationProgressBar().repaint();
679        } else if ((infoflags & ImageObserver.ALLBITS) == ImageObserver.ALLBITS) {
680            this.uploadPolicy.displayDebug(
681                    "  imageUpdate, total number of pixels: "
682                            + this.nbPixelsRead + " read", 50);
683        }
684
685        // We want to go on, after these bits
686        return true;
687    }
688}
Note: See TracBrowser for help on using the repository browser.