jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java
author jdv
Thu, 29 Sep 2016 10:57:34 +0530
changeset 41403 be56daafbeaa
parent 35667 ed476aba94de
permissions -rw-r--r--
8164931: Verify if writer.abort() works properly for all writers in IIOWriteProgressListener. Reviewed-by: prr, bpb, serb, psadhukhan
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
41403
be56daafbeaa 8164931: Verify if writer.abort() works properly for all writers in IIOWriteProgressListener.
jdv
parents: 35667
diff changeset
     2
 * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3011
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3011
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3011
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3011
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3011
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package com.sun.imageio.plugins.bmp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.Rectangle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.awt.image.ColorModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.awt.image.ComponentSampleModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.awt.image.DataBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.awt.image.DataBufferByte;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.awt.image.DataBufferInt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.awt.image.DataBufferShort;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.awt.image.DataBufferUShort;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.awt.image.DirectColorModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.awt.image.IndexColorModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.awt.image.MultiPixelPackedSampleModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.awt.image.BandedSampleModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.awt.image.Raster;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import java.awt.image.RenderedImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import java.awt.image.SampleModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import java.awt.image.SinglePixelPackedSampleModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import java.awt.image.BufferedImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
import java.io.ByteArrayOutputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
import java.nio.ByteOrder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
import java.util.Iterator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
import javax.imageio.IIOImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
import javax.imageio.ImageIO;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
import javax.imageio.ImageTypeSpecifier;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
import javax.imageio.ImageWriteParam;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
import javax.imageio.ImageWriter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
import javax.imageio.metadata.IIOMetadata;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
import javax.imageio.spi.ImageWriterSpi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
import javax.imageio.stream.ImageOutputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
import javax.imageio.event.IIOWriteProgressListener;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
import javax.imageio.event.IIOWriteWarningListener;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
import javax.imageio.plugins.bmp.BMPImageWriteParam;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
import com.sun.imageio.plugins.common.ImageUtil;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
import com.sun.imageio.plugins.common.I18N;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * The Java Image IO plugin writer for encoding a binary RenderedImage into
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * a BMP format.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * The encoding process may clip, subsample using the parameters
35667
ed476aba94de 8138838: docs cleanup for java.desktop
avstepan
parents: 25859
diff changeset
    72
 * specified in the {@code ImageWriteParam}.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * @see javax.imageio.plugins.bmp.BMPImageWriteParam
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
public class BMPImageWriter extends ImageWriter implements BMPConstants {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    /** The output stream to write into */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    private ImageOutputStream stream = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    private ByteArrayOutputStream embedded_stream = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    private int version;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    private int compressionType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    private boolean isTopDown;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    private int w, h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    private int compImageSize = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    private int[] bitMasks;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    private int[] bitPos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    private byte[] bpixels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    private short[] spixels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    private int[] ipixels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
35667
ed476aba94de 8138838: docs cleanup for java.desktop
avstepan
parents: 25859
diff changeset
    91
    /** Constructs {@code BMPImageWriter} based on the provided
ed476aba94de 8138838: docs cleanup for java.desktop
avstepan
parents: 25859
diff changeset
    92
     *  {@code ImageWriterSpi}.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    public BMPImageWriter(ImageWriterSpi originator) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        super(originator);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    public void setOutput(Object output) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
        super.setOutput(output); // validates output
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        if (output != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
            if (!(output instanceof ImageOutputStream))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
                throw new IllegalArgumentException(I18N.getString("BMPImageWriter0"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
            this.stream = (ImageOutputStream)output;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
            stream.setByteOrder(ByteOrder.LITTLE_ENDIAN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
        } else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
            this.stream = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    public ImageWriteParam getDefaultWriteParam() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        return new BMPImageWriteParam();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    public IIOMetadata getDefaultStreamMetadata(ImageWriteParam param) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
                                               ImageWriteParam param) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        BMPMetadata meta = new BMPMetadata();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        meta.bmpVersion = VERSION_3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
        meta.compression = getPreferredCompressionType(imageType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        if (param != null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
            && param.getCompressionMode() == ImageWriteParam.MODE_EXPLICIT) {
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   124
            meta.compression = BMPCompressionTypes.getType(param.getCompressionType());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        meta.bitsPerPixel = (short)imageType.getColorModel().getPixelSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
        return meta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    public IIOMetadata convertStreamMetadata(IIOMetadata inData,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
                                             ImageWriteParam param) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    public IIOMetadata convertImageMetadata(IIOMetadata metadata,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
                                            ImageTypeSpecifier type,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
                                            ImageWriteParam param) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    public boolean canWriteRasters() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    public void write(IIOMetadata streamMetadata,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
                      IIOImage image,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
                      ImageWriteParam param) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        if (stream == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
            throw new IllegalStateException(I18N.getString("BMPImageWriter7"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        if (image == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
            throw new IllegalArgumentException(I18N.getString("BMPImageWriter8"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        clearAbortRequest();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        processImageStarted(0);
41403
be56daafbeaa 8164931: Verify if writer.abort() works properly for all writers in IIOWriteProgressListener.
jdv
parents: 35667
diff changeset
   159
        if (abortRequested()) {
be56daafbeaa 8164931: Verify if writer.abort() works properly for all writers in IIOWriteProgressListener.
jdv
parents: 35667
diff changeset
   160
            processWriteAborted();
be56daafbeaa 8164931: Verify if writer.abort() works properly for all writers in IIOWriteProgressListener.
jdv
parents: 35667
diff changeset
   161
            return;
be56daafbeaa 8164931: Verify if writer.abort() works properly for all writers in IIOWriteProgressListener.
jdv
parents: 35667
diff changeset
   162
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        if (param == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
            param = getDefaultWriteParam();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        BMPImageWriteParam bmpParam = (BMPImageWriteParam)param;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        // Default is using 24 bits per pixel.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        int bitsPerPixel = 24;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        boolean isPalette = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        int paletteEntries = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        IndexColorModel icm = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        RenderedImage input = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        Raster inputRaster = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        boolean writeRaster = image.hasRaster();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        Rectangle sourceRegion = param.getSourceRegion();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        SampleModel sampleModel = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        ColorModel colorModel = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        compImageSize = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        if (writeRaster) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
            inputRaster = image.getRaster();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
            sampleModel = inputRaster.getSampleModel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
            colorModel = ImageUtil.createColorModel(null, sampleModel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
            if (sourceRegion == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
                sourceRegion = inputRaster.getBounds();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
                sourceRegion = sourceRegion.intersection(inputRaster.getBounds());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            input = image.getRenderedImage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            sampleModel = input.getSampleModel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
            colorModel = input.getColorModel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
            Rectangle rect = new Rectangle(input.getMinX(), input.getMinY(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
                                           input.getWidth(), input.getHeight());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            if (sourceRegion == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                sourceRegion = rect;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
                sourceRegion = sourceRegion.intersection(rect);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        IIOMetadata imageMetadata = image.getMetadata();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        BMPMetadata bmpImageMetadata = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        if (imageMetadata != null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            && imageMetadata instanceof BMPMetadata)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            bmpImageMetadata = (BMPMetadata)imageMetadata;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            ImageTypeSpecifier imageType =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                new ImageTypeSpecifier(colorModel, sampleModel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            bmpImageMetadata = (BMPMetadata)getDefaultImageMetadata(imageType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                                                                    param);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        if (sourceRegion.isEmpty())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            throw new RuntimeException(I18N.getString("BMPImageWrite0"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        int scaleX = param.getSourceXSubsampling();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        int scaleY = param.getSourceYSubsampling();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        int xOffset = param.getSubsamplingXOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        int yOffset = param.getSubsamplingYOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        // cache the data type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        int dataType = sampleModel.getDataType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        sourceRegion.translate(xOffset, yOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        sourceRegion.width -= xOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        sourceRegion.height -= yOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        int minX = sourceRegion.x / scaleX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        int minY = sourceRegion.y / scaleY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        w = (sourceRegion.width + scaleX - 1) / scaleX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        h = (sourceRegion.height + scaleY - 1) / scaleY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        xOffset = sourceRegion.x % scaleX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
        yOffset = sourceRegion.y % scaleY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        Rectangle destinationRegion = new Rectangle(minX, minY, w, h);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        boolean noTransform = destinationRegion.equals(sourceRegion);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        // Raw data can only handle bytes, everything greater must be ASCII.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        int[] sourceBands = param.getSourceBands();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        boolean noSubband = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        int numBands = sampleModel.getNumBands();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        if (sourceBands != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
            sampleModel = sampleModel.createSubsetSampleModel(sourceBands);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
            colorModel = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
            noSubband = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
            numBands = sampleModel.getNumBands();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
            sourceBands = new int[numBands];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
            for (int i = 0; i < numBands; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
                sourceBands[i] = i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        int[] bandOffsets = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        boolean bgrOrder = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        if (sampleModel instanceof ComponentSampleModel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
            bandOffsets = ((ComponentSampleModel)sampleModel).getBandOffsets();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            if (sampleModel instanceof BandedSampleModel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                // for images with BandedSampleModel we can not work
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                //  with raster directly and must use writePixels()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
                bgrOrder = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
                // we can work with raster directly only in case of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                // BGR component order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                // In any other case we must use writePixels()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
                for (int i = 0; i < bandOffsets.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
                    bgrOrder &= (bandOffsets[i] == (bandOffsets.length - i - 1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
            if (sampleModel instanceof SinglePixelPackedSampleModel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
                // BugId 4892214: we can not work with raster directly
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                // if image have different color order than RGB.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                // We should use writePixels() for such images.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                int[] bitOffsets = ((SinglePixelPackedSampleModel)sampleModel).getBitOffsets();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                for (int i=0; i<bitOffsets.length-1; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                    bgrOrder &= bitOffsets[i] > bitOffsets[i+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        if (bandOffsets == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            // we will use getPixels() to extract pixel data for writePixels()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            // Please note that getPixels() provides rgb bands order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
            bandOffsets = new int[numBands];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            for (int i = 0; i < numBands; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                bandOffsets[i] = i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        noTransform &= bgrOrder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        int sampleSize[] = sampleModel.getSampleSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        //XXX: check more
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        // Number of bytes that a scanline for the image written out will have.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        int destScanlineBytes = w * numBands;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        switch(bmpParam.getCompressionMode()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        case ImageWriteParam.MODE_EXPLICIT:
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   307
            compressionType = BMPCompressionTypes.getType(bmpParam.getCompressionType());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        case ImageWriteParam.MODE_COPY_FROM_METADATA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            compressionType = bmpImageMetadata.compression;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
        case ImageWriteParam.MODE_DEFAULT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            compressionType = getPreferredCompressionType(colorModel, sampleModel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            // ImageWriteParam.MODE_DISABLED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            compressionType = BI_RGB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        if (!canEncodeImage(compressionType, colorModel, sampleModel)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            throw new IOException("Image can not be encoded with compression type "
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   322
                                  + BMPCompressionTypes.getName(compressionType));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        byte r[] = null, g[] = null, b[] = null, a[] = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   327
        if (compressionType == BI_BITFIELDS) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
            bitsPerPixel =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
                DataBuffer.getDataTypeSize(sampleModel.getDataType());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
            if (bitsPerPixel != 16 && bitsPerPixel != 32) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                // we should use 32bpp images in case of BI_BITFIELD
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                // compression to avoid color conversion artefacts
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                bitsPerPixel = 32;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                // Setting this flag to false ensures that generic
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                // writePixels() will be used to store image data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
                noTransform = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            destScanlineBytes = w * bitsPerPixel + 7 >> 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            isPalette = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            paletteEntries = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
            r = new byte[paletteEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
            g = new byte[paletteEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
            b = new byte[paletteEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
            a = new byte[paletteEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
            int rmask = 0x00ff0000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
            int gmask = 0x0000ff00;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            int bmask = 0x000000ff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            if (bitsPerPixel == 16) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
                /* NB: canEncodeImage() ensures we have image of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
                 * either USHORT_565_RGB or USHORT_555_RGB type here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
                 * Technically, it should work for other direct color
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
                 * model types but it might be non compatible with win98
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
                 * and friends.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
                if (colorModel instanceof DirectColorModel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
                    DirectColorModel dcm = (DirectColorModel)colorModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                    rmask = dcm.getRedMask();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                    gmask = dcm.getGreenMask();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                    bmask = dcm.getBlueMask();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                    // it is unlikely, but if it happens, we should throw
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                    // an exception related to unsupported image format
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
                    throw new IOException("Image can not be encoded with " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
                                          "compression type " +
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   371
                                          BMPCompressionTypes.getName(compressionType));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
            writeMaskToPalette(rmask, 0, r, g, b, a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
            writeMaskToPalette(gmask, 1, r, g, b, a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
            writeMaskToPalette(bmask, 2, r, g, b, a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            if (!noTransform) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
                // prepare info for writePixels procedure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                bitMasks = new int[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
                bitMasks[0] = rmask;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                bitMasks[1] = gmask;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                bitMasks[2] = bmask;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
                bitPos = new int[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                bitPos[0] = firstLowBit(rmask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
                bitPos[1] = firstLowBit(gmask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
                bitPos[2] = firstLowBit(bmask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
            if (colorModel instanceof IndexColorModel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
                icm = (IndexColorModel)colorModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        } else { // handle BI_RGB compression
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
            if (colorModel instanceof IndexColorModel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
                isPalette = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                icm = (IndexColorModel)colorModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                paletteEntries = icm.getMapSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                if (paletteEntries <= 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                    bitsPerPixel = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
                    destScanlineBytes = w + 7 >> 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
                } else if (paletteEntries <= 16) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                    bitsPerPixel = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
                    destScanlineBytes = w + 1 >> 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                } else if (paletteEntries <= 256) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                    bitsPerPixel = 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
                    // Cannot be written as a Palette image. So write out as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
                    // 24 bit image.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                    bitsPerPixel = 24;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                    isPalette = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
                    paletteEntries = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                    destScanlineBytes = w * 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                if (isPalette == true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                    r = new byte[paletteEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                    g = new byte[paletteEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                    b = new byte[paletteEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
                    a = new byte[paletteEntries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
                    icm.getAlphas(a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                    icm.getReds(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
                    icm.getGreens(g);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
                    icm.getBlues(b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
                // Grey scale images
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
                if (numBands == 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
                    isPalette = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                    paletteEntries = 256;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                    bitsPerPixel = sampleSize[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
                    destScanlineBytes = (w * bitsPerPixel + 7 >> 3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
                    r = new byte[256];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
                    g = new byte[256];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                    b = new byte[256];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                    a = new byte[256];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                    for (int i = 0; i < 256; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                        r[i] = (byte)i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                        g[i] = (byte)i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                        b[i] = (byte)i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                        a[i] = (byte)255;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                    if (sampleModel instanceof SinglePixelPackedSampleModel &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
                        noSubband)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
                    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                        /* NB: the actual pixel size can be smaller than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
                         * size of used DataBuffer element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                         * For example: in case of TYPE_INT_RGB actual pixel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                         * size is 24 bits, but size of DataBuffere element
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
                         * is 32 bits
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
                        int[] sample_sizes = sampleModel.getSampleSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
                        bitsPerPixel = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
                        for (int size : sample_sizes) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
                            bitsPerPixel += size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                        bitsPerPixel = roundBpp(bitsPerPixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
                        if (bitsPerPixel != DataBuffer.getDataTypeSize(sampleModel.getDataType())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                            noTransform = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
                        destScanlineBytes = w * bitsPerPixel + 7 >> 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
        // actual writing of image data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        int fileSize = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        int offset = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
        int headerSize = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        int imageSize = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
        int xPelsPerMeter = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        int yPelsPerMeter = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
        int colorsUsed = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
        int colorsImportant = paletteEntries;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        // Calculate padding for each scanline
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        int padding = destScanlineBytes % 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
        if (padding != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
            padding = 4 - padding;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        // FileHeader is 14 bytes, BitmapHeader is 40 bytes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
        // add palette size and that is where the data will begin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        offset = 54 + paletteEntries * 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        imageSize = (destScanlineBytes + padding) * h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        fileSize = imageSize + offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        headerSize = 40;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        long headPos = stream.getStreamPosition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        writeFileHeader(fileSize, offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
3011
1ee026ded54c 6296893: BMP Writer handles TopDown property incorrectly for some of the compression types
bae
parents: 2
diff changeset
   505
        /* According to MSDN description, the top-down image layout
1ee026ded54c 6296893: BMP Writer handles TopDown property incorrectly for some of the compression types
bae
parents: 2
diff changeset
   506
         * is allowed only if compression type is BI_RGB or BI_BITFIELDS.
1ee026ded54c 6296893: BMP Writer handles TopDown property incorrectly for some of the compression types
bae
parents: 2
diff changeset
   507
         * Images with any other compression type must be wrote in the
1ee026ded54c 6296893: BMP Writer handles TopDown property incorrectly for some of the compression types
bae
parents: 2
diff changeset
   508
         * bottom-up layout.
1ee026ded54c 6296893: BMP Writer handles TopDown property incorrectly for some of the compression types
bae
parents: 2
diff changeset
   509
         */
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   510
        if (compressionType == BI_RGB ||
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   511
            compressionType == BI_BITFIELDS)
3011
1ee026ded54c 6296893: BMP Writer handles TopDown property incorrectly for some of the compression types
bae
parents: 2
diff changeset
   512
        {
1ee026ded54c 6296893: BMP Writer handles TopDown property incorrectly for some of the compression types
bae
parents: 2
diff changeset
   513
            isTopDown = bmpParam.isTopDown();
1ee026ded54c 6296893: BMP Writer handles TopDown property incorrectly for some of the compression types
bae
parents: 2
diff changeset
   514
        } else {
1ee026ded54c 6296893: BMP Writer handles TopDown property incorrectly for some of the compression types
bae
parents: 2
diff changeset
   515
            isTopDown = false;
1ee026ded54c 6296893: BMP Writer handles TopDown property incorrectly for some of the compression types
bae
parents: 2
diff changeset
   516
        }
1ee026ded54c 6296893: BMP Writer handles TopDown property incorrectly for some of the compression types
bae
parents: 2
diff changeset
   517
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
        writeInfoHeader(headerSize, bitsPerPixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        // compression
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        stream.writeInt(compressionType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        // imageSize
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        stream.writeInt(imageSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        // xPelsPerMeter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        stream.writeInt(xPelsPerMeter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        // yPelsPerMeter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        stream.writeInt(yPelsPerMeter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        // Colors Used
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        stream.writeInt(colorsUsed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
        // Colors Important
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
        stream.writeInt(colorsImportant);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
        // palette
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        if (isPalette == true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
            // write palette
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   542
            if (compressionType == BI_BITFIELDS) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                // write masks for red, green and blue components.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                for (int i=0; i<3; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                    int mask = (a[i]&0xFF) + ((r[i]&0xFF)*0x100) + ((g[i]&0xFF)*0x10000) + ((b[i]&0xFF)*0x1000000);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                    stream.writeInt(mask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
                for (int i=0; i<paletteEntries; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                    stream.writeByte(b[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                    stream.writeByte(g[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                    stream.writeByte(r[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
                    stream.writeByte(a[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
        // Writing of actual image data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
        int scanlineBytes = w * numBands;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
        // Buffer for up to 8 rows of pixels
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
        int[] pixels = new int[scanlineBytes * scaleX];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
        // Also create a buffer to hold one line of the data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
        // to be written to the file, so we can use array writes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
        bpixels = new byte[destScanlineBytes];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
        int l;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   570
        if (compressionType == BI_JPEG ||
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   571
            compressionType == BI_PNG) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
            // prepare embedded buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
            embedded_stream = new ByteArrayOutputStream();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
            writeEmbedded(image, bmpParam);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
            // update the file/image Size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
            embedded_stream.flush();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
            imageSize = embedded_stream.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
            long endPos = stream.getStreamPosition();
22584
eed64ee05369 8032733: Fix cast lint warnings in client libraries
darcy
parents: 20415
diff changeset
   581
            fileSize = offset + imageSize;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
            stream.seek(headPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
            writeSize(fileSize, 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            stream.seek(headPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
            writeSize(imageSize, 34);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
            stream.seek(endPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
            stream.write(embedded_stream.toByteArray());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            embedded_stream = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
41403
be56daafbeaa 8164931: Verify if writer.abort() works properly for all writers in IIOWriteProgressListener.
jdv
parents: 35667
diff changeset
   590
            processImageComplete();
be56daafbeaa 8164931: Verify if writer.abort() works properly for all writers in IIOWriteProgressListener.
jdv
parents: 35667
diff changeset
   591
            stream.flushBefore(stream.getStreamPosition());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        int maxBandOffset = bandOffsets[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
        for (int i = 1; i < bandOffsets.length; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
            if (bandOffsets[i] > maxBandOffset)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
                maxBandOffset = bandOffsets[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        int[] pixel = new int[maxBandOffset + 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
        int destScanlineLength = destScanlineBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        if (noTransform && noSubband) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
            destScanlineLength = destScanlineBytes / (DataBuffer.getDataTypeSize(dataType)>>3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
        for (int i = 0; i < h; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
            int row = minY + i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
            if (!isTopDown)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
                row = minY + h - i -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
            // Get the pixels
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
            Raster src = inputRaster;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
            Rectangle srcRect =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
                new Rectangle(minX * scaleX + xOffset,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                              row * scaleY + yOffset,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                              (w - 1)* scaleX + 1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
                              1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
            if (!writeRaster)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
                src = input.getData(srcRect);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
            if (noTransform && noSubband) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
                SampleModel sm = src.getSampleModel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
                int pos = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
                int startX = srcRect.x - src.getSampleModelTranslateX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
                int startY = srcRect.y - src.getSampleModelTranslateY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
                if (sm instanceof ComponentSampleModel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
                    ComponentSampleModel csm = (ComponentSampleModel)sm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
                    pos = csm.getOffset(startX, startY, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
                    for(int nb=1; nb < csm.getNumBands(); nb++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
                        if (pos > csm.getOffset(startX, startY, nb)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
                            pos = csm.getOffset(startX, startY, nb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
                } else if (sm instanceof MultiPixelPackedSampleModel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
                    MultiPixelPackedSampleModel mppsm =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
                        (MultiPixelPackedSampleModel)sm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
                    pos = mppsm.getOffset(startX, startY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
                } else if (sm instanceof SinglePixelPackedSampleModel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
                    SinglePixelPackedSampleModel sppsm =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
                        (SinglePixelPackedSampleModel)sm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
                    pos = sppsm.getOffset(startX, startY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   649
                if (compressionType == BI_RGB || compressionType == BI_BITFIELDS){
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
                    switch(dataType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
                    case DataBuffer.TYPE_BYTE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
                        byte[] bdata =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
                            ((DataBufferByte)src.getDataBuffer()).getData();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
                        stream.write(bdata, pos, destScanlineLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
                    case DataBuffer.TYPE_SHORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
                        short[] sdata =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
                            ((DataBufferShort)src.getDataBuffer()).getData();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
                        stream.writeShorts(sdata, pos, destScanlineLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
                    case DataBuffer.TYPE_USHORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
                        short[] usdata =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
                            ((DataBufferUShort)src.getDataBuffer()).getData();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
                        stream.writeShorts(usdata, pos, destScanlineLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
                    case DataBuffer.TYPE_INT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
                        int[] idata =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
                            ((DataBufferInt)src.getDataBuffer()).getData();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
                        stream.writeInts(idata, pos, destScanlineLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
                    for(int k=0; k<padding; k++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
                        stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
                    }
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   679
                } else if (compressionType == BI_RLE4) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
                    if (bpixels == null || bpixels.length < scanlineBytes)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
                        bpixels = new byte[scanlineBytes];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
                    src.getPixels(srcRect.x, srcRect.y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
                                  srcRect.width, srcRect.height, pixels);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
                    for (int h=0; h<scanlineBytes; h++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
                        bpixels[h] = (byte)pixels[h];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
                    encodeRLE4(bpixels, scanlineBytes);
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   688
                } else if (compressionType == BI_RLE8) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
                    //byte[] bdata =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
                    //    ((DataBufferByte)src.getDataBuffer()).getData();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
                    //System.out.println("bdata.length="+bdata.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
                    //System.arraycopy(bdata, pos, bpixels, 0, scanlineBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
                    if (bpixels == null || bpixels.length < scanlineBytes)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
                        bpixels = new byte[scanlineBytes];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
                    src.getPixels(srcRect.x, srcRect.y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
                                  srcRect.width, srcRect.height, pixels);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
                    for (int h=0; h<scanlineBytes; h++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
                        bpixels[h] = (byte)pixels[h];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
                    encodeRLE8(bpixels, scanlineBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
                src.getPixels(srcRect.x, srcRect.y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
                              srcRect.width, srcRect.height, pixels);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
                if (scaleX != 1 || maxBandOffset != numBands - 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
                    for (int j = 0, k = 0, n=0; j < w;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
                         j++, k += scaleX * numBands, n += numBands)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
                    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
                        System.arraycopy(pixels, k, pixel, 0, pixel.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
                        for (int m = 0; m < numBands; m++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
                            // pixel data is provided here in RGB order
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
                            pixels[n + m] = pixel[sourceBands[m]];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
                writePixels(0, scanlineBytes, bitsPerPixel, pixels,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                            padding, numBands, icm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
            processImageProgress(100.0f * (((float)i) / ((float)h)));
41403
be56daafbeaa 8164931: Verify if writer.abort() works properly for all writers in IIOWriteProgressListener.
jdv
parents: 35667
diff changeset
   724
            if (abortRequested()) {
be56daafbeaa 8164931: Verify if writer.abort() works properly for all writers in IIOWriteProgressListener.
jdv
parents: 35667
diff changeset
   725
                break;
be56daafbeaa 8164931: Verify if writer.abort() works properly for all writers in IIOWriteProgressListener.
jdv
parents: 35667
diff changeset
   726
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   729
        if (compressionType == BI_RLE4 ||
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   730
            compressionType == BI_RLE8) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
            // Write the RLE EOF marker and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
            stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
            stream.writeByte(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
            incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
            // update the file/image Size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
            imageSize = compImageSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
            fileSize = compImageSize + offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
            long endPos = stream.getStreamPosition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
            stream.seek(headPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
            writeSize(fileSize, 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
            stream.seek(headPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
            writeSize(imageSize, 34);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
            stream.seek(endPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
        if (abortRequested()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
            processWriteAborted();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
            processImageComplete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
            stream.flushBefore(stream.getStreamPosition());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
    private void writePixels(int l, int scanlineBytes, int bitsPerPixel,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
                             int pixels[],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
                             int padding, int numBands,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
                             IndexColorModel icm) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
        int pixel = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
        int k = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        switch (bitsPerPixel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
        case 1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
            for (int j=0; j<scanlineBytes/8; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
                bpixels[k++] = (byte)((pixels[l++]  << 7) |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
                                      (pixels[l++]  << 6) |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
                                      (pixels[l++]  << 5) |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
                                      (pixels[l++]  << 4) |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
                                      (pixels[l++]  << 3) |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
                                      (pixels[l++]  << 2) |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
                                      (pixels[l++]  << 1) |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
                                      pixels[l++]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
            // Partially filled last byte, if any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
            if (scanlineBytes%8 > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
                pixel = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
                for (int j=0; j<scanlineBytes%8; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
                    pixel |= (pixels[l++] << (7 - j));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
                bpixels[k++] = (byte)pixel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
            stream.write(bpixels, 0, (scanlineBytes+7)/8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
        case 4:
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   788
            if (compressionType == BI_RLE4){
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
                byte[] bipixels = new byte[scanlineBytes];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
                for (int h=0; h<scanlineBytes; h++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
                    bipixels[h] = (byte)pixels[l++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
                encodeRLE4(bipixels, scanlineBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
            }else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
                for (int j=0; j<scanlineBytes/2; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
                    pixel = (pixels[l++] << 4) | pixels[l++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
                    bpixels[k++] = (byte)pixel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
                // Put the last pixel of odd-length lines in the 4 MSBs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
                if ((scanlineBytes%2) == 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
                    pixel = pixels[l] << 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
                    bpixels[k++] = (byte)pixel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
                stream.write(bpixels, 0, (scanlineBytes+1)/2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
        case 8:
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   809
            if(compressionType == BI_RLE8) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
                for (int h=0; h<scanlineBytes; h++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
                    bpixels[h] = (byte)pixels[l++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
                encodeRLE8(bpixels, scanlineBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
            }else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
                for (int j=0; j<scanlineBytes; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
                    bpixels[j] = (byte)pixels[l++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
                stream.write(bpixels, 0, scanlineBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
        case 16:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
            if (spixels == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
                spixels = new short[scanlineBytes / numBands];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
             * We expect that pixel data comes in RGB order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
             * We will assemble short pixel taking into account
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
             * the compression type:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
             * BI_RGB        - the RGB order should be maintained.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
             * BI_BITFIELDS  - use bitPos array that was built
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
             *                 according to bitfields masks.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
            for (int j = 0, m = 0; j < scanlineBytes; m++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
                spixels[m] = 0;
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   836
                if (compressionType == BI_RGB) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
                    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
                     * please note that despite other cases,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
                     * the 16bpp BI_RGB requires the RGB data order
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
                    spixels[m] = (short)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
                        (((0x1f & pixels[j    ]) << 10) |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
                         ((0x1f & pixels[j + 1]) <<  5) |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
                         ((0x1f & pixels[j + 2])      ));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
                     j += 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
                    for(int i = 0 ; i < numBands; i++, j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
                        spixels[m] |=
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
                            (((pixels[j]) << bitPos[i]) & bitMasks[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
            stream.writeShorts(spixels, 0, spixels.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
        case 24:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
            if (numBands == 3) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
                for (int j=0; j<scanlineBytes; j+=3) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                    // Since BMP needs BGR format
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                    bpixels[k++] = (byte)(pixels[l+2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
                    bpixels[k++] = (byte)(pixels[l+1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                    bpixels[k++] = (byte)(pixels[l]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                    l+=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
                stream.write(bpixels, 0, scanlineBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
                // Case where IndexColorModel had > 256 colors.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
                int entries = icm.getMapSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
                byte r[] = new byte[entries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
                byte g[] = new byte[entries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
                byte b[] = new byte[entries];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
                icm.getReds(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
                icm.getGreens(g);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
                icm.getBlues(b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
                int index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
                for (int j=0; j<scanlineBytes; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
                    index = pixels[l];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
                    bpixels[k++] = b[index];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
                    bpixels[k++] = g[index];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
                    bpixels[k++] = b[index];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
                    l++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
                stream.write(bpixels, 0, scanlineBytes*3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
        case 32:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
            if (ipixels == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
                ipixels = new int[scanlineBytes / numBands];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
            if (numBands == 3) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
                /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
                 * We expect that pixel data comes in RGB order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
                 * We will assemble int pixel taking into account
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
                 * the compression type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
                 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
                 * BI_RGB        - the BGR order should be used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
                 * BI_BITFIELDS  - use bitPos array that was built
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
                 *                 according to bitfields masks.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
                for (int j = 0, m = 0; j < scanlineBytes; m++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
                    ipixels[m] = 0;
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   905
                    if (compressionType == BI_RGB) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
                        ipixels[m] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
                            ((0xff & pixels[j + 2]) << 16) |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
                            ((0xff & pixels[j + 1]) <<  8) |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
                            ((0xff & pixels[j    ])      );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
                        j += 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
                        for(int i = 0 ; i < numBands; i++, j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
                            ipixels[m] |=
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
                                (((pixels[j]) << bitPos[i]) & bitMasks[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
                // We have two possibilities here:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
                // 1. we are writing the indexed image with bitfields
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
                //    compression (this covers also the case of BYTE_BINARY)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
                //    => use icm to get actual RGB color values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
                // 2. we are writing the gray-scaled image with BI_BITFIELDS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
                //    compression
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
                //    => just replicate the level of gray to color components.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
                for (int j = 0; j < scanlineBytes; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
                    if (icm != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
                        ipixels[j] = icm.getRGB(pixels[j]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
                        ipixels[j] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
                            pixels[j] << 16 | pixels[j] << 8 | pixels[j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
            stream.writeInts(ipixels, 0, ipixels.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
        // Write out the padding
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   940
        if (compressionType == BI_RGB ||
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
   941
            compressionType == BI_BITFIELDS)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
            for(k=0; k<padding; k++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
                stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
    private void encodeRLE8(byte[] bpixels, int scanlineBytes)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
      throws IOException{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
        int runCount = 1, absVal = -1, j = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
        byte runVal = 0, nextVal =0 ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
        runVal = bpixels[++j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
        byte[] absBuf = new byte[256];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
        while (j < scanlineBytes-1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
            nextVal = bpixels[++j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
            if (nextVal == runVal ){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
                if(absVal >= 3 ){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
                    /// Check if there was an existing Absolute Run
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
                    stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
                    stream.writeByte(absVal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
                    incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
                    for(int a=0; a<absVal;a++){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
                        stream.writeByte(absBuf[a]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
                        incCompImageSize(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
                    if (!isEven(absVal)){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
                        //Padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
                        stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
                        incCompImageSize(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
                else if(absVal > -1){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
                    /// Absolute Encoding for less than 3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
                    /// treated as regular encoding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
                    /// Do not include the last element since it will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
                    /// be inclued in the next encoding/run
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
                    for (int b=0;b<absVal;b++){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
                        stream.writeByte(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
                        stream.writeByte(absBuf[b]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
                        incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
                absVal = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
                runCount++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
                if (runCount == 256){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
                    /// Only 255 values permitted
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
                    stream.writeByte(runCount-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
                    stream.writeByte(runVal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
                    incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
                    runCount = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
                if (runCount > 1){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
                    /// If there was an existing run
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
                    stream.writeByte(runCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
                    stream.writeByte(runVal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
                    incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
                } else if (absVal < 0){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
                    // First time..
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
                    absBuf[++absVal] = runVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
                    absBuf[++absVal] = nextVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
                } else if (absVal < 254){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
                    //  0-254 only
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
                    absBuf[++absVal] = nextVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
                    stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
                    stream.writeByte(absVal+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
                    incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
                    for(int a=0; a<=absVal;a++){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
                        stream.writeByte(absBuf[a]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
                        incCompImageSize(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
                    // padding since 255 elts is not even
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
                    stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
                    incCompImageSize(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
                    absVal = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
                runVal = nextVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
                runCount = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
            if (j == scanlineBytes-1){ // EOF scanline
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
                // Write the run
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
                if (absVal == -1){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
                    stream.writeByte(runCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
                    stream.writeByte(runVal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
                    incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
                    runCount = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
                    // write the Absolute Run
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
                    if(absVal >= 2){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
                        stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
                        stream.writeByte(absVal+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
                        incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
                        for(int a=0; a<=absVal;a++){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
                            stream.writeByte(absBuf[a]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
                            incCompImageSize(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
                        if (!isEven(absVal+1)){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
                            //Padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
                            stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
                            incCompImageSize(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
                    else if(absVal > -1){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
                        for (int b=0;b<=absVal;b++){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
                            stream.writeByte(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
                            stream.writeByte(absBuf[b]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
                            incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
                /// EOF scanline
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
                stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
                stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
                incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
    private void encodeRLE4(byte[] bipixels, int scanlineBytes)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
      throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
        int runCount=2, absVal=-1, j=-1, pixel=0, q=0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
        byte runVal1=0, runVal2=0, nextVal1=0, nextVal2=0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
        byte[] absBuf = new byte[256];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
        runVal1 = bipixels[++j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
        runVal2 = bipixels[++j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
        while (j < scanlineBytes-2){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
            nextVal1 = bipixels[++j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
            nextVal2 = bipixels[++j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
            if (nextVal1 == runVal1 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
                //Check if there was an existing Absolute Run
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
                if(absVal >= 4){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
                    stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
                    stream.writeByte(absVal - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
                    incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
                    // we need to exclude  last 2 elts, similarity of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
                    // which caused to enter this part of the code
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
                    for(int a=0; a<absVal-2;a+=2){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
                        pixel = (absBuf[a] << 4) | absBuf[a+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
                        stream.writeByte((byte)pixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
                        incCompImageSize(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
                    // if # of elts is odd - read the last element
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
                    if(!(isEven(absVal-1))){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
                        q = absBuf[absVal-2] << 4| 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
                        stream.writeByte(q);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
                        incCompImageSize(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
                    // Padding to word align absolute encoding
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
                    if ( !isEven((int)Math.ceil((absVal-1)/2)) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
                        stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
                        incCompImageSize(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
                } else if (absVal > -1){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
                    stream.writeByte(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
                    pixel = (absBuf[0] << 4) | absBuf[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
                    stream.writeByte(pixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
                    incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
                absVal = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
                if (nextVal2 == runVal2){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
                    // Even runlength
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
                    runCount+=2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
                    if(runCount == 256){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
                        stream.writeByte(runCount-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
                        pixel = ( runVal1 << 4) | runVal2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
                        stream.writeByte(pixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
                        incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
                        runCount =2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
                        if(j< scanlineBytes - 1){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
                            runVal1 = runVal2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
                            runVal2 = bipixels[++j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
                        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
                            stream.writeByte(01);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
                            int r = runVal2 << 4 | 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
                            stream.writeByte(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
                            incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
                            runCount = -1;/// Only EOF required now
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
                    // odd runlength and the run ends here
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
                    // runCount wont be > 254 since 256/255 case will
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
                    // be taken care of in above code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
                    runCount++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
                    pixel = ( runVal1 << 4) | runVal2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
                    stream.writeByte(runCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
                    stream.writeByte(pixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
                    incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
                    runCount = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
                    runVal1 = nextVal2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
                    // If end of scanline
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
                    if (j < scanlineBytes -1){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
                        runVal2 = bipixels[++j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
                    }else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
                        stream.writeByte(01);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
                        int r = nextVal2 << 4 | 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
                        stream.writeByte(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
                        incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
                        runCount = -1;/// Only EOF required now
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
            } else{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
                // Check for existing run
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
                if (runCount > 2){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
                    pixel = ( runVal1 << 4) | runVal2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
                    stream.writeByte(runCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
                    stream.writeByte(pixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
                    incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
                } else if (absVal < 0){ // first time
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
                    absBuf[++absVal] = runVal1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
                    absBuf[++absVal] = runVal2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
                    absBuf[++absVal] = nextVal1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
                    absBuf[++absVal] = nextVal2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
                } else if (absVal < 253){ // only 255 elements
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
                    absBuf[++absVal] = nextVal1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
                    absBuf[++absVal] = nextVal2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
                    stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
                    stream.writeByte(absVal+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
                    incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
                    for(int a=0; a<absVal;a+=2){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
                        pixel = (absBuf[a] << 4) | absBuf[a+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
                        stream.writeByte((byte)pixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
                        incCompImageSize(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
                    // Padding for word align
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
                    // since it will fit into 127 bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
                    stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
                    incCompImageSize(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
                    absVal = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
                runVal1 = nextVal1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
                runVal2 = nextVal2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
                runCount = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
            // Handle the End of scanline for the last 2 4bits
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
            if (j >= scanlineBytes-2 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
                if (absVal == -1 && runCount >= 2){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
                    if (j == scanlineBytes-2){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
                        if(bipixels[++j] == runVal1){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
                            runCount++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
                            pixel = ( runVal1 << 4) | runVal2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
                            stream.writeByte(runCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
                            stream.writeByte(pixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
                            incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
                        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
                            pixel = ( runVal1 << 4) | runVal2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
                            stream.writeByte(runCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
                            stream.writeByte(pixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
                            stream.writeByte(01);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
                            pixel =  bipixels[j]<<4 |0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
                            stream.writeByte(pixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
                            int n = bipixels[j]<<4|0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
                            incCompImageSize(4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
                        stream.writeByte(runCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
                        pixel =( runVal1 << 4) | runVal2 ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
                        stream.writeByte(pixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
                        incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
                } else if(absVal > -1){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
                    if (j == scanlineBytes-2){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
                        absBuf[++absVal] = bipixels[++j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
                    if (absVal >=2){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
                        stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
                        stream.writeByte(absVal+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
                        incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
                        for(int a=0; a<absVal;a+=2){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
                            pixel = (absBuf[a] << 4) | absBuf[a+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
                            stream.writeByte((byte)pixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
                            incCompImageSize(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
                        if(!(isEven(absVal+1))){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
                            q = absBuf[absVal] << 4|0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
                            stream.writeByte(q);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
                            incCompImageSize(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
                        // Padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
                        if ( !isEven((int)Math.ceil((absVal+1)/2)) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
                            stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
                            incCompImageSize(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
                        switch (absVal){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
                        case 0:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
                            stream.writeByte(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
                            int n = absBuf[0]<<4 | 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
                            stream.writeByte(n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
                            incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
                        case 1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
                            stream.writeByte(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
                            pixel = (absBuf[0] << 4) | absBuf[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
                            stream.writeByte(pixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
                            incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
                stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
                stream.writeByte(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
                incCompImageSize(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
    private synchronized void incCompImageSize(int value){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
        compImageSize = compImageSize + value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
    private boolean isEven(int number) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
        return (number%2 == 0 ? true : false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
    private void writeFileHeader(int fileSize, int offset) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
        // magic value
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
        stream.writeByte('B');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
        stream.writeByte('M');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
        // File size
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
        stream.writeInt(fileSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
        // reserved1 and reserved2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
        stream.writeInt(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
        // offset to image data
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
        stream.writeInt(offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1295
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
    private void writeInfoHeader(int headerSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
                                 int bitsPerPixel) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
        // size of header
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
        stream.writeInt(headerSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
        // width
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
        stream.writeInt(w);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
        // height
3011
1ee026ded54c 6296893: BMP Writer handles TopDown property incorrectly for some of the compression types
bae
parents: 2
diff changeset
  1305
        stream.writeInt(isTopDown ? -h : h);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
        // number of planes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
        stream.writeShort(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
        // Bits Per Pixel
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
        stream.writeShort(bitsPerPixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
    private void writeSize(int dword, int offset) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
        stream.skipBytes(offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
        stream.writeInt(dword);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
    public void reset() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
        super.reset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
        stream = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
    private void writeEmbedded(IIOImage image,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
                               ImageWriteParam bmpParam) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
        String format =
20415
a88fd521ef00 8001119: [fingbugs] Evaluate necessity to make some arrays package protected
vadim
parents: 5506
diff changeset
  1327
            compressionType == BI_JPEG ? "jpeg" : "png";
23312
4711f66e7d5c 8033716: Fix raw and unchecked lint warnings in com.sun.imageio
henryjen
parents: 22584
diff changeset
  1328
        Iterator<ImageWriter> iterator =
4711f66e7d5c 8033716: Fix raw and unchecked lint warnings in com.sun.imageio
henryjen
parents: 22584
diff changeset
  1329
               ImageIO.getImageWritersByFormatName(format);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
        ImageWriter writer = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
        if (iterator.hasNext())
23312
4711f66e7d5c 8033716: Fix raw and unchecked lint warnings in com.sun.imageio
henryjen
parents: 22584
diff changeset
  1332
            writer = iterator.next();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
        if (writer != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
            if (embedded_stream == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
                throw new RuntimeException("No stream for writing embedded image!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
            writer.addIIOWriteProgressListener(new IIOWriteProgressAdapter() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
                    public void imageProgress(ImageWriter source, float percentageDone) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
                        processImageProgress(percentageDone);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
                });
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
            writer.addIIOWriteWarningListener(new IIOWriteWarningListener() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
                    public void warningOccurred(ImageWriter source, int imageIndex, String warning) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
                        processWarningOccurred(imageIndex, warning);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
                });
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
            writer.setOutput(ImageIO.createImageOutputStream(embedded_stream));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
            ImageWriteParam param = writer.getDefaultWriteParam();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
            //param.setDestinationBands(bmpParam.getDestinationBands());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
            param.setDestinationOffset(bmpParam.getDestinationOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
            param.setSourceBands(bmpParam.getSourceBands());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
            param.setSourceRegion(bmpParam.getSourceRegion());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
            param.setSourceSubsampling(bmpParam.getSourceXSubsampling(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
                                       bmpParam.getSourceYSubsampling(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
                                       bmpParam.getSubsamplingXOffset(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
                                       bmpParam.getSubsamplingYOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
            writer.write(null, image, param);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
        } else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
            throw new RuntimeException(I18N.getString("BMPImageWrite5") + " " + format);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
    private int firstLowBit(int num) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
        int count = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
        while ((num & 1) == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
            count++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
            num >>>= 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
        return count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
    private class IIOWriteProgressAdapter implements IIOWriteProgressListener {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
        public void imageComplete(ImageWriter source) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
        public void imageProgress(ImageWriter source, float percentageDone) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
        public void imageStarted(ImageWriter source, int imageIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
        public void thumbnailComplete(ImageWriter source) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
        public void thumbnailProgress(ImageWriter source, float percentageDone) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
        public void thumbnailStarted(ImageWriter source, int imageIndex, int thumbnailIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
        public void writeAborted(ImageWriter source) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
     * Returns preferred compression type for given image.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
     * The default compression type is BI_RGB, but some image types can't be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
     * encodeed with using default compression without cahnge color resolution.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
     * For example, TYPE_USHORT_565_RGB may be encodeed only by using BI_BITFIELDS
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
     * compression type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
     * NB: we probably need to extend this method if we encounter other image
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
     * types which can not be encoded with BI_RGB compression type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
    protected int getPreferredCompressionType(ColorModel cm, SampleModel sm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
        ImageTypeSpecifier imageType = new ImageTypeSpecifier(cm, sm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
        return getPreferredCompressionType(imageType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
    protected int getPreferredCompressionType(ImageTypeSpecifier imageType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
        if (imageType.getBufferedImageType() == BufferedImage.TYPE_USHORT_565_RGB) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
            return  BI_BITFIELDS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
        return BI_RGB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
     * Check whether we can encode image of given type using compression method in question.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
     * For example, TYPE_USHORT_565_RGB can be encodeed with BI_BITFIELDS compression only.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
     * NB: method should be extended if other cases when we can not encode
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
     *     with given compression will be discovered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
    protected boolean canEncodeImage(int compression, ColorModel cm, SampleModel sm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
        ImageTypeSpecifier imgType = new ImageTypeSpecifier(cm, sm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
        return canEncodeImage(compression, imgType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
    protected boolean canEncodeImage(int compression, ImageTypeSpecifier imgType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
        ImageWriterSpi spi = this.getOriginatingProvider();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
        if (!spi.canEncodeImage(imgType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
        int biType = imgType.getBufferedImageType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
        int bpp = imgType.getColorModel().getPixelSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
        if (compressionType == BI_RLE4 && bpp != 4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
            // only 4bpp images can be encoded as BI_RLE4
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
        if (compressionType == BI_RLE8 && bpp != 8) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
            // only 8bpp images can be encoded as BI_RLE8
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
        if (bpp == 16) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
             * Technically we expect that we may be able to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
             * encode only some of SinglePixelPackedSampleModel
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
             * images here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
             * In addition we should take into account following:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
             * 1. BI_RGB case, according to the MSDN description:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
             *     The bitmap has a maximum of 2^16 colors. If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
             *     biCompression member of the BITMAPINFOHEADER is BI_RGB,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
             *     the bmiColors member of BITMAPINFO is NULL. Each WORD
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
             *     in the bitmap array represents a single pixel. The
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
             *     relative intensities of red, green, and blue are
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
             *     represented with five bits for each color component.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
             * 2. BI_BITFIELDS case, according ot the MSDN description:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
             *     Windows 95/98/Me: When the biCompression member is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
             *     BI_BITFIELDS, the system supports only the following
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
             *     16bpp color masks: A 5-5-5 16-bit image, where the blue
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
             *     mask is 0x001F, the green mask is 0x03E0, and the red mask
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
             *     is 0x7C00; and a 5-6-5 16-bit image, where the blue mask
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
             *     is 0x001F, the green mask is 0x07E0, and the red mask is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
             *     0xF800.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
            boolean canUseRGB = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
            boolean canUseBITFIELDS = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
            SampleModel sm = imgType.getSampleModel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
            if (sm instanceof SinglePixelPackedSampleModel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
                int[] sizes =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
                    ((SinglePixelPackedSampleModel)sm).getSampleSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
                canUseRGB = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
                canUseBITFIELDS = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
                for (int i = 0; i < sizes.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
                    canUseRGB       &=  (sizes[i] == 5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
                    canUseBITFIELDS &= ((sizes[i] == 5) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
                                        (i == 1 && sizes[i] == 6));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
            return (((compressionType == BI_RGB) && canUseRGB) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
                    ((compressionType == BI_BITFIELDS) && canUseBITFIELDS));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
    protected void writeMaskToPalette(int mask, int i,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
                                      byte[] r, byte[]g, byte[] b, byte[]a) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
        b[i] = (byte)(0xff & (mask >> 24));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
        g[i] = (byte)(0xff & (mask >> 16));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1503
        r[i] = (byte)(0xff & (mask >> 8));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1504
        a[i] = (byte)(0xff & mask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
    private int roundBpp(int x) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
        if (x <= 8) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
            return 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
        } else if (x <= 16) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
            return 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
        } if (x <= 24) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
            return 24;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1515
            return 32;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1516
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1517
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
}