Package javax.imageio.plugins.bmp

Examples of javax.imageio.plugins.bmp.BMPImageWriteParam


  protected boolean exportAsBMP(final File file){
    final BufferedImage rendImage = createRenderedImage();
    boolean success = false;

    try {
      final ImageWriteParam iwparam  = new BMPImageWriteParam();
      final ImageWriter iw      = ImageIO.getImageWritersByFormatName("bmp").next();//$NON-NLS-1$
      try(final ImageOutputStream ios  = ImageIO.createImageOutputStream(file)) {
        iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        iw.setOutput(ios);
        iw.write(null, new IIOImage(rendImage, null, null), iwparam);
        iw.dispose();
        success = true;
      }
View Full Code Here


        clearAbortRequest();
        processImageStarted(0);
        if (param == null)
            param = getDefaultWriteParam();

        BMPImageWriteParam bmpParam = (BMPImageWriteParam)param;

        // Default is using 24 bits per pixel.
        int bitsPerPixel = 24;
        boolean isPalette = false;
        int paletteEntries = 0;
        IndexColorModel icm = null;

        RenderedImage input = null;
        Raster inputRaster = null;
        boolean writeRaster = image.hasRaster();
        Rectangle sourceRegion = param.getSourceRegion();
        SampleModel sampleModel = null;
        ColorModel colorModel = null;

        compImageSize = 0;

        if (writeRaster) {
            inputRaster = image.getRaster();
            sampleModel = inputRaster.getSampleModel();
            colorModel = ImageUtil.createColorModel(null, sampleModel);
            if (sourceRegion == null)
                sourceRegion = inputRaster.getBounds();
            else
                sourceRegion = sourceRegion.intersection(inputRaster.getBounds());
        } else {
            input = image.getRenderedImage();
            sampleModel = input.getSampleModel();
            colorModel = input.getColorModel();
            Rectangle rect = new Rectangle(input.getMinX(), input.getMinY(),
                                           input.getWidth(), input.getHeight());
            if (sourceRegion == null)
                sourceRegion = rect;
            else
                sourceRegion = sourceRegion.intersection(rect);
        }

        IIOMetadata imageMetadata = image.getMetadata();
        BMPMetadata bmpImageMetadata = null;
        if (imageMetadata != null
            && imageMetadata instanceof BMPMetadata)
        {
            bmpImageMetadata = (BMPMetadata)imageMetadata;
        } else {
            ImageTypeSpecifier imageType =
                new ImageTypeSpecifier(colorModel, sampleModel);

            bmpImageMetadata = (BMPMetadata)getDefaultImageMetadata(imageType,
                                                                    param);
        }

        if (sourceRegion.isEmpty())
            throw new RuntimeException(I18N.getString("BMPImageWrite0"));

        int scaleX = param.getSourceXSubsampling();
        int scaleY = param.getSourceYSubsampling();
        int xOffset = param.getSubsamplingXOffset();
        int yOffset = param.getSubsamplingYOffset();

        // cache the data type;
        int dataType = sampleModel.getDataType();

        sourceRegion.translate(xOffset, yOffset);
        sourceRegion.width -= xOffset;
        sourceRegion.height -= yOffset;

        int minX = sourceRegion.x / scaleX;
        int minY = sourceRegion.y / scaleY;
        w = (sourceRegion.width + scaleX - 1) / scaleX;
        h = (sourceRegion.height + scaleY - 1) / scaleY;
        xOffset = sourceRegion.x % scaleX;
        yOffset = sourceRegion.y % scaleY;

        Rectangle destinationRegion = new Rectangle(minX, minY, w, h);
        boolean noTransform = destinationRegion.equals(sourceRegion);

        // Raw data can only handle bytes, everything greater must be ASCII.
        int[] sourceBands = param.getSourceBands();
        boolean noSubband = true;
        int numBands = sampleModel.getNumBands();

        if (sourceBands != null) {
            sampleModel = sampleModel.createSubsetSampleModel(sourceBands);
            colorModel = null;
            noSubband = false;
            numBands = sampleModel.getNumBands();
        } else {
            sourceBands = new int[numBands];
            for (int i = 0; i < numBands; i++)
                sourceBands[i] = i;
        }

        int[] bandOffsets = null;
        boolean bgrOrder = true;

        if (sampleModel instanceof ComponentSampleModel) {
            bandOffsets = ((ComponentSampleModel)sampleModel).getBandOffsets();
            if (sampleModel instanceof BandedSampleModel) {
                // for images with BandedSampleModel we can not work
                //  with raster directly and must use writePixels()
                bgrOrder = false;
            } else {
                // we can work with raster directly only in case of
                // BGR component order.
                // In any other case we must use writePixels()
                for (int i = 0; i < bandOffsets.length; i++) {
                    bgrOrder &= (bandOffsets[i] == (bandOffsets.length - i - 1));
                }
            }
        } else {
            if (sampleModel instanceof SinglePixelPackedSampleModel) {

                // BugId 4892214: we can not work with raster directly
                // if image have different color order than RGB.
                // We should use writePixels() for such images.
                int[] bitOffsets = ((SinglePixelPackedSampleModel)sampleModel).getBitOffsets();
                for (int i=0; i<bitOffsets.length-1; i++) {
                    bgrOrder &= bitOffsets[i] > bitOffsets[i+1];
                }
            }
        }

        if (bandOffsets == null) {
            // we will use getPixels() to extract pixel data for writePixels()
            // Please note that getPixels() provides rgb bands order.
            bandOffsets = new int[numBands];
            for (int i = 0; i < numBands; i++)
                bandOffsets[i] = i;
        }

        noTransform &= bgrOrder;

        int sampleSize[] = sampleModel.getSampleSize();

        //XXX: check more

        // Number of bytes that a scanline for the image written out will have.
        int destScanlineBytes = w * numBands;

        switch(bmpParam.getCompressionMode()) {
        case ImageWriteParam.MODE_EXPLICIT:
            compressionType = BMPCompressionTypes.getType(bmpParam.getCompressionType());
            break;
        case ImageWriteParam.MODE_COPY_FROM_METADATA:
            compressionType = bmpImageMetadata.compression;
            break;
        case ImageWriteParam.MODE_DEFAULT:
            compressionType = getPreferredCompressionType(colorModel, sampleModel);
            break;
        default:
            // ImageWriteParam.MODE_DISABLED:
            compressionType = BI_RGB;
        }

        if (!canEncodeImage(compressionType, colorModel, sampleModel)) {
            throw new IOException("Image can not be encoded with compression type "
                                  + BMPCompressionTypes.getName(compressionType));
        }

        byte r[] = null, g[] = null, b[] = null, a[] = null;

        if (compressionType == BI_BITFIELDS) {
            bitsPerPixel =
                DataBuffer.getDataTypeSize(sampleModel.getDataType());

            if (bitsPerPixel != 16 && bitsPerPixel != 32) {
                // we should use 32bpp images in case of BI_BITFIELD
                // compression to avoid color conversion artefacts
                bitsPerPixel = 32;

                // Setting this flag to false ensures that generic
                // writePixels() will be used to store image data
                noTransform = false;
            }

            destScanlineBytes = w * bitsPerPixel + 7 >> 3;

            isPalette = true;
            paletteEntries = 3;
            r = new byte[paletteEntries];
            g = new byte[paletteEntries];
            b = new byte[paletteEntries];
            a = new byte[paletteEntries];

            int rmask = 0x00ff0000;
            int gmask = 0x0000ff00;
            int bmask = 0x000000ff;

            if (bitsPerPixel == 16) {
                /* NB: canEncodeImage() ensures we have image of
                 * either USHORT_565_RGB or USHORT_555_RGB type here.
                 * Technically, it should work for other direct color
                 * model types but it might be non compatible with win98
                 * and friends.
                 */
                if (colorModel instanceof DirectColorModel) {
                    DirectColorModel dcm = (DirectColorModel)colorModel;
                    rmask = dcm.getRedMask();
                    gmask = dcm.getGreenMask();
                    bmask = dcm.getBlueMask();
                } else {
                    // it is unlikely, but if it happens, we should throw
                    // an exception related to unsupported image format
                    throw new IOException("Image can not be encoded with " +
                                          "compression type " +
                                          BMPCompressionTypes.getName(compressionType));
                }
            }
            writeMaskToPalette(rmask, 0, r, g, b, a);
            writeMaskToPalette(gmask, 1, r, g, b, a);
            writeMaskToPalette(bmask, 2, r, g, b, a);

            if (!noTransform) {
                // prepare info for writePixels procedure
                bitMasks = new int[3];
                bitMasks[0] = rmask;
                bitMasks[1] = gmask;
                bitMasks[2] = bmask;

                bitPos = new int[3];
                bitPos[0] = firstLowBit(rmask);
                bitPos[1] = firstLowBit(gmask);
                bitPos[2] = firstLowBit(bmask);
            }

            if (colorModel instanceof IndexColorModel) {
                icm = (IndexColorModel)colorModel;
            }
        } else { // handle BI_RGB compression
            if (colorModel instanceof IndexColorModel) {
                isPalette = true;
                icm = (IndexColorModel)colorModel;
                paletteEntries = icm.getMapSize();

                if (paletteEntries <= 2) {
                    bitsPerPixel = 1;
                    destScanlineBytes = w + 7 >> 3;
                } else if (paletteEntries <= 16) {
                    bitsPerPixel = 4;
                    destScanlineBytes = w + 1 >> 1;
                } else if (paletteEntries <= 256) {
                    bitsPerPixel = 8;
                } else {
                    // Cannot be written as a Palette image. So write out as
                    // 24 bit image.
                    bitsPerPixel = 24;
                    isPalette = false;
                    paletteEntries = 0;
                    destScanlineBytes = w * 3;
                }

                if (isPalette == true) {
                    r = new byte[paletteEntries];
                    g = new byte[paletteEntries];
                    b = new byte[paletteEntries];
                    a = new byte[paletteEntries];

                    icm.getAlphas(a);
                    icm.getReds(r);
                    icm.getGreens(g);
                    icm.getBlues(b);
                }

            } else {
                // Grey scale images
                if (numBands == 1) {

                    isPalette = true;
                    paletteEntries = 256;
                    bitsPerPixel = sampleSize[0];

                    destScanlineBytes = (w * bitsPerPixel + 7 >> 3);

                    r = new byte[256];
                    g = new byte[256];
                    b = new byte[256];
                    a = new byte[256];

                    for (int i = 0; i < 256; i++) {
                        r[i] = (byte)i;
                        g[i] = (byte)i;
                        b[i] = (byte)i;
                        a[i] = (byte)255;
                    }

                } else {
                    if (sampleModel instanceof SinglePixelPackedSampleModel &&
                        noSubband)
                    {
                        /* NB: the actual pixel size can be smaller than
                         * size of used DataBuffer element.
                         * For example: in case of TYPE_INT_RGB actual pixel
                         * size is 24 bits, but size of DataBuffere element
                         * is 32 bits
                         */
                        int[] sample_sizes = sampleModel.getSampleSize();
                        bitsPerPixel = 0;
                        for (int size : sample_sizes) {
                            bitsPerPixel += size;
                        }
                        bitsPerPixel = roundBpp(bitsPerPixel);
                        if (bitsPerPixel != DataBuffer.getDataTypeSize(sampleModel.getDataType())) {
                            noTransform = false;
                        }
                        destScanlineBytes = w * bitsPerPixel + 7 >> 3;
                    }
                }
            }
        }

        // actual writing of image data
        int fileSize = 0;
        int offset = 0;
        int headerSize = 0;
        int imageSize = 0;
        int xPelsPerMeter = 0;
        int yPelsPerMeter = 0;
        int colorsUsed = 0;
        int colorsImportant = paletteEntries;

        // Calculate padding for each scanline
        int padding = destScanlineBytes % 4;
        if (padding != 0) {
            padding = 4 - padding;
        }


        // FileHeader is 14 bytes, BitmapHeader is 40 bytes,
        // add palette size and that is where the data will begin
        offset = 54 + paletteEntries * 4;

        imageSize = (destScanlineBytes + padding) * h;
        fileSize = imageSize + offset;
        headerSize = 40;

        long headPos = stream.getStreamPosition();

        writeFileHeader(fileSize, offset);

        /* According to MSDN description, the top-down image layout
         * is allowed only if compression type is BI_RGB or BI_BITFIELDS.
         * Images with any other compression type must be wrote in the
         * bottom-up layout.
         */
        if (compressionType == BI_RGB ||
            compressionType == BI_BITFIELDS)
        {
            isTopDown = bmpParam.isTopDown();
        } else {
            isTopDown = false;
        }

        writeInfoHeader(headerSize, bitsPerPixel);
View Full Code Here

        } else
            this.stream = null;
    }

    public ImageWriteParam getDefaultWriteParam() {
        return new BMPImageWriteParam();
    }
View Full Code Here

        clearAbortRequest();
        processImageStarted(0);
        if (param == null)
            param = getDefaultWriteParam();

        BMPImageWriteParam bmpParam = (BMPImageWriteParam)param;

        // Default is using 24 bits per pixel.
        int bitsPerPixel = 24;
        boolean isPalette = false;
        int paletteEntries = 0;
        IndexColorModel icm = null;

        RenderedImage input = null;
        Raster inputRaster = null;
        boolean writeRaster = image.hasRaster();
        Rectangle sourceRegion = param.getSourceRegion();
        SampleModel sampleModel = null;
        ColorModel colorModel = null;

  compImageSize = 0;

        if (writeRaster) {
            inputRaster = image.getRaster();
            sampleModel = inputRaster.getSampleModel();
            colorModel = ImageUtil.createColorModel(null, sampleModel);
            if (sourceRegion == null)
                sourceRegion = inputRaster.getBounds();
            else
                sourceRegion = sourceRegion.intersection(inputRaster.getBounds());
        } else {
            input = image.getRenderedImage();
            sampleModel = input.getSampleModel();
            colorModel = input.getColorModel();
            Rectangle rect = new Rectangle(input.getMinX(), input.getMinY(),
                                           input.getWidth(), input.getHeight());
            if (sourceRegion == null)
                sourceRegion = rect;
            else
                sourceRegion = sourceRegion.intersection(rect);
        }

        IIOMetadata imageMetadata = image.getMetadata();
        BMPMetadata bmpImageMetadata = null;
        if (imageMetadata != null
            && imageMetadata instanceof BMPMetadata)
        {
            bmpImageMetadata = (BMPMetadata)imageMetadata;
        } else {
            ImageTypeSpecifier imageType =
                new ImageTypeSpecifier(colorModel, sampleModel);
           
            bmpImageMetadata = (BMPMetadata)getDefaultImageMetadata(imageType,
                                                                    param);
        }   

        if (sourceRegion.isEmpty())
            throw new RuntimeException(I18N.getString("BMPImageWrite0"));

        int scaleX = param.getSourceXSubsampling();
        int scaleY = param.getSourceYSubsampling();
        int xOffset = param.getSubsamplingXOffset();
        int yOffset = param.getSubsamplingYOffset();

        // cache the data type;
        int dataType = sampleModel.getDataType();

        sourceRegion.translate(xOffset, yOffset);
        sourceRegion.width -= xOffset;
        sourceRegion.height -= yOffset;

        int minX = sourceRegion.x / scaleX;
        int minY = sourceRegion.y / scaleY;
        w = (sourceRegion.width + scaleX - 1) / scaleX;
        h = (sourceRegion.height + scaleY - 1) / scaleY;
        xOffset = sourceRegion.x % scaleX;
        yOffset = sourceRegion.y % scaleY;

        Rectangle destinationRegion = new Rectangle(minX, minY, w, h);
        boolean noTransform = destinationRegion.equals(sourceRegion);

        // Raw data can only handle bytes, everything greater must be ASCII.
        int[] sourceBands = param.getSourceBands();
        boolean noSubband = true;
        int numBands = sampleModel.getNumBands();

        if (sourceBands != null) {
            sampleModel = sampleModel.createSubsetSampleModel(sourceBands);
            colorModel = null;
            noSubband = false;
            numBands = sampleModel.getNumBands();
        } else {
            sourceBands = new int[numBands];
            for (int i = 0; i < numBands; i++)
                sourceBands[i] = i;
        }

        int[] bandOffsets = null;
        boolean bgrOrder = true;

        if (sampleModel instanceof ComponentSampleModel) {
            bandOffsets = ((ComponentSampleModel)sampleModel).getBandOffsets();
            if (sampleModel instanceof BandedSampleModel) {
                // for images with BandedSampleModel we can not work
                //  with raster directly and must use writePixels()
                bgrOrder = false;
            } else {
                // we can work with raster directly only in case of
                // BGR component order.
                // In any other case we must use writePixels()
                for (int i = 0; i < bandOffsets.length; i++) {
                    bgrOrder &= (bandOffsets[i] == (bandOffsets.length - i - 1));
                }
            }
        } else {
            if (sampleModel instanceof SinglePixelPackedSampleModel) {
               
                // BugId 4892214: we can not work with raster directly
                // if image have different color order than RGB.
                // We should use writePixels() for such images.
                int[] bitOffsets = ((SinglePixelPackedSampleModel)sampleModel).getBitOffsets();
                for (int i=0; i<bitOffsets.length-1; i++) {
                    bgrOrder &= bitOffsets[i] > bitOffsets[i+1];
                }
            }
        }
        
        if (bandOffsets == null) {
            // we will use getPixels() to extract pixel data for writePixels()
            // Please note that getPixels() provides rgb bands order.           
            bandOffsets = new int[numBands];
            for (int i = 0; i < numBands; i++)
                bandOffsets[i] = i;
        }
       
        noTransform &= bgrOrder;

        int sampleSize[] = sampleModel.getSampleSize();

        //XXX: check more

        // Number of bytes that a scanline for the image written out will have.
        int destScanlineBytes = w * numBands;

        switch(bmpParam.getCompressionMode()) {
        case ImageWriteParam.MODE_EXPLICIT:
            compressionType = getCompressionType(bmpParam.getCompressionType());
            break;
        case ImageWriteParam.MODE_COPY_FROM_METADATA:
            compressionType = bmpImageMetadata.compression;
            break;
        case ImageWriteParam.MODE_DEFAULT:
            compressionType = getPreferredCompressionType(colorModel, sampleModel);
            break;
        default:
            // ImageWriteParam.MODE_DISABLED:
            compressionType = BI_RGB;
        }
       
        if (!canEncodeImage(compressionType, colorModel, sampleModel)) {
            throw new IOException("Image can not be encoded with compression type "
                                  + compressionTypeNames[compressionType]);
        }
        byte r[] = null, g[] = null, b[] = null, a[] = null;

        if (compressionType == BMPConstants.BI_BITFIELDS) {
            bitsPerPixel =
                DataBuffer.getDataTypeSize(sampleModel.getDataType());

            if (bitsPerPixel != 16 && bitsPerPixel != 32) {
                // we should use 32bpp images in case of BI_BITFIELD
                // compression to avoid color conversion artefacts
                bitsPerPixel = 32;

                // Setting this flag to false ensures that generic
                // writePixels() will be used to store image data
                noTransform = false;
            }
           
            destScanlineBytes = w * bitsPerPixel + 7 >> 3;
           
            isPalette = true;
            paletteEntries = 3;
            r = new byte[paletteEntries];
            g = new byte[paletteEntries];
            b = new byte[paletteEntries];
            a = new byte[paletteEntries];
           
            int rmask = 0x00ff0000;
            int gmask = 0x0000ff00;
            int bmask = 0x000000ff;
           
            if (bitsPerPixel == 16) {
                /* NB: canEncodeImage() ensures we have image of 
                 * either USHORT_565_RGB or USHORT_555_RGB type here.
                 * Technically, it should work for other direct color
                 * model types but it might be non compatible with win98
                 * and friends.
                 */
                if (colorModel instanceof DirectColorModel) {
                    DirectColorModel dcm = (DirectColorModel)colorModel;
                    rmask = dcm.getRedMask();
                    gmask = dcm.getGreenMask();
                    bmask = dcm.getBlueMask();
                } else {
                    // it is unlikely, but if it happens, we should throw
                    // an exception related to unsupported image format
                    throw new IOException("Image can not be encoded with " +
                                          "compression type " +
                                          compressionTypeNames[compressionType]);
                }
            }
            writeMaskToPalette(rmask, 0, r, g, b, a);
            writeMaskToPalette(gmask, 1, r, g, b, a);
            writeMaskToPalette(bmask, 2, r, g, b, a);
           
            if (!noTransform) {
                // prepare info for writePixels procedure
                bitMasks = new int[3];
                bitMasks[0] = rmask;
                bitMasks[1] = gmask;
                bitMasks[2] = bmask;

                bitPos = new int[3];
                bitPos[0] = firstLowBit(rmask);
                bitPos[1] = firstLowBit(gmask);
                bitPos[2] = firstLowBit(bmask);
            }

            if (colorModel instanceof IndexColorModel) {
                icm = (IndexColorModel)colorModel;
            }
        } else { // handle BI_RGB compression
            if (colorModel instanceof IndexColorModel) {
                isPalette = true;
                icm = (IndexColorModel)colorModel;
                paletteEntries = icm.getMapSize();
               
                if (paletteEntries <= 2) {
                    bitsPerPixel = 1;
                    destScanlineBytes = w + 7 >> 3;
                } else if (paletteEntries <= 16) {
                    bitsPerPixel = 4;
                    destScanlineBytes = w + 1 >> 1;
                } else if (paletteEntries <= 256) {
                    bitsPerPixel = 8;
                } else {
                    // Cannot be written as a Palette image. So write out as
                    // 24 bit image.
                    bitsPerPixel = 24;
                    isPalette = false;
                    paletteEntries = 0;
                    destScanlineBytes = w * 3;
                }
               
                if (isPalette == true) {
                    r = new byte[paletteEntries];
                    g = new byte[paletteEntries];
                    b = new byte[paletteEntries];
                    a = new byte[paletteEntries];
                   
                    icm.getAlphas(a);
                    icm.getReds(r);
                    icm.getGreens(g);
                    icm.getBlues(b);
                }
               
            } else {
                // Grey scale images
                if (numBands == 1) {
                   
                    isPalette = true;
                    paletteEntries = 256;
                    bitsPerPixel = sampleSize[0];
                   
                    destScanlineBytes = (w * bitsPerPixel + 7 >> 3);
                   
                    r = new byte[256];
                    g = new byte[256];
                    b = new byte[256];
                    a = new byte[256];
                   
                    for (int i = 0; i < 256; i++) {
                        r[i] = (byte)i;
                        g[i] = (byte)i;
                        b[i] = (byte)i;
                        a[i] = (byte)255;
                    }
                   
                } else {
                    if (sampleModel instanceof SinglePixelPackedSampleModel &&
                        noSubband)
        {
      /* NB: the actual pixel size can be smaller than
       * size of used DataBuffer element.
       * For example: in case of TYPE_INT_RGB actual pixel
       * size is 24 bits, but size of DataBuffere element
       * is 32 bits
       */
                        int[] sample_sizes = sampleModel.getSampleSize();
                        bitsPerPixel = 0;
                        for (int size : sample_sizes) {
                            bitsPerPixel += size;
                        }
                        bitsPerPixel = roundBpp(bitsPerPixel);
                        if (bitsPerPixel != DataBuffer.getDataTypeSize(sampleModel.getDataType())) {
                            noTransform = false;
                        }
                        destScanlineBytes = w * bitsPerPixel + 7 >> 3;
                    }
                }
            }
        }

        // actual writing of image data
        int fileSize = 0;
        int offset = 0;
        int headerSize = 0;
        int imageSize = 0;
        int xPelsPerMeter = 0;
        int yPelsPerMeter = 0;
        int colorsUsed = 0;
        int colorsImportant = paletteEntries;

        // Calculate padding for each scanline
        int padding = destScanlineBytes % 4;
        if (padding != 0) {
            padding = 4 - padding;
        }
       

  // FileHeader is 14 bytes, BitmapHeader is 40 bytes,
  // add palette size and that is where the data will begin
  offset = 54 + paletteEntries * 4;
 
  imageSize = (destScanlineBytes + padding) * h;
  fileSize = imageSize + offset;
  headerSize = 40;

        long headPos = stream.getStreamPosition();

        writeFileHeader(fileSize, offset);

        writeInfoHeader(headerSize, bitsPerPixel);

        // compression
        stream.writeInt(compressionType);

        // imageSize
        stream.writeInt(imageSize);

        // xPelsPerMeter
        stream.writeInt(xPelsPerMeter);

        // yPelsPerMeter
        stream.writeInt(yPelsPerMeter);

        // Colors Used
        stream.writeInt(colorsUsed);

        // Colors Important
        stream.writeInt(colorsImportant);

        // palette
        if (isPalette == true) {

            // write palette
      if (compressionType == BMPConstants.BI_BITFIELDS) {
    // write masks for red, green and blue components.
    for (int i=0; i<3; i++) {
        int mask = (a[i]&0xFF) + ((r[i]&0xFF)*0x100) + ((g[i]&0xFF)*0x10000) + ((b[i]&0xFF)*0x1000000);
        stream.writeInt(mask);
    }
      } else {
    for (int i=0; i<paletteEntries; i++) {
        stream.writeByte(b[i]);
        stream.writeByte(g[i]);
        stream.writeByte(r[i]);
        stream.writeByte(a[i]);
    }
      }
  }
       
        // Writing of actual image data
        int scanlineBytes = w * numBands;

        // Buffer for up to 8 rows of pixels
        int[] pixels = new int[scanlineBytes * scaleX];

        // Also create a buffer to hold one line of the data
        // to be written to the file, so we can use array writes.
        bpixels = new byte[destScanlineBytes];

        int l;
 
        if (compressionType == BMPConstants.BI_JPEG ||
            compressionType == BMPConstants.BI_PNG) {
           
            // prepare embedded buffer
            embedded_stream = new ByteArrayOutputStream();      
            writeEmbedded(image, bmpParam);
            // update the file/image Size
            embedded_stream.flush();
            imageSize = embedded_stream.size();
           
            long endPos = stream.getStreamPosition();
            fileSize = (int)(offset + imageSize);
            stream.seek(headPos);
            writeSize(fileSize, 2);
            stream.seek(headPos);
            writeSize(imageSize, 34);
            stream.seek(endPos);
            stream.write(embedded_stream.toByteArray());
            embedded_stream = null;

            if (abortRequested()) {
                processWriteAborted();
            } else {
                processImageComplete();
                stream.flushBefore(stream.getStreamPosition());
            }

            return;
        }

        isTopDown = bmpParam.isTopDown();
       
        int maxBandOffset = bandOffsets[0];
        for (int i = 1; i < bandOffsets.length; i++)
            if (bandOffsets[i] > maxBandOffset)
                maxBandOffset = bandOffsets[i];
View Full Code Here

        } else
            this.stream = null;
    }

    public ImageWriteParam getDefaultWriteParam() {
        return new BMPImageWriteParam();
    }
View Full Code Here

        clearAbortRequest();
        processImageStarted(0);
        if (param == null)
            param = getDefaultWriteParam();

        BMPImageWriteParam bmpParam = (BMPImageWriteParam)param;

        // Default is using 24 bits per pixel.
        int bitsPerPixel = 24;
        boolean isPalette = false;
        int paletteEntries = 0;
        IndexColorModel icm = null;

        RenderedImage input = null;
        Raster inputRaster = null;
        boolean writeRaster = image.hasRaster();
        Rectangle sourceRegion = param.getSourceRegion();
        SampleModel sampleModel = null;
        ColorModel colorModel = null;

        compImageSize = 0;

        if (writeRaster) {
            inputRaster = image.getRaster();
            sampleModel = inputRaster.getSampleModel();
            colorModel = ImageUtil.createColorModel(null, sampleModel);
            if (sourceRegion == null)
                sourceRegion = inputRaster.getBounds();
            else
                sourceRegion = sourceRegion.intersection(inputRaster.getBounds());
        } else {
            input = image.getRenderedImage();
            sampleModel = input.getSampleModel();
            colorModel = input.getColorModel();
            Rectangle rect = new Rectangle(input.getMinX(), input.getMinY(),
                                           input.getWidth(), input.getHeight());
            if (sourceRegion == null)
                sourceRegion = rect;
            else
                sourceRegion = sourceRegion.intersection(rect);
        }

        IIOMetadata imageMetadata = image.getMetadata();
        BMPMetadata bmpImageMetadata = null;
        if (imageMetadata != null
            && imageMetadata instanceof BMPMetadata)
        {
            bmpImageMetadata = (BMPMetadata)imageMetadata;
        } else {
            ImageTypeSpecifier imageType =
                new ImageTypeSpecifier(colorModel, sampleModel);

            bmpImageMetadata = (BMPMetadata)getDefaultImageMetadata(imageType,
                                                                    param);
        }

        if (sourceRegion.isEmpty())
            throw new RuntimeException(I18N.getString("BMPImageWrite0"));

        int scaleX = param.getSourceXSubsampling();
        int scaleY = param.getSourceYSubsampling();
        int xOffset = param.getSubsamplingXOffset();
        int yOffset = param.getSubsamplingYOffset();

        // cache the data type;
        int dataType = sampleModel.getDataType();

        sourceRegion.translate(xOffset, yOffset);
        sourceRegion.width -= xOffset;
        sourceRegion.height -= yOffset;

        int minX = sourceRegion.x / scaleX;
        int minY = sourceRegion.y / scaleY;
        w = (sourceRegion.width + scaleX - 1) / scaleX;
        h = (sourceRegion.height + scaleY - 1) / scaleY;
        xOffset = sourceRegion.x % scaleX;
        yOffset = sourceRegion.y % scaleY;

        Rectangle destinationRegion = new Rectangle(minX, minY, w, h);
        boolean noTransform = destinationRegion.equals(sourceRegion);

        // Raw data can only handle bytes, everything greater must be ASCII.
        int[] sourceBands = param.getSourceBands();
        boolean noSubband = true;
        int numBands = sampleModel.getNumBands();

        if (sourceBands != null) {
            sampleModel = sampleModel.createSubsetSampleModel(sourceBands);
            colorModel = null;
            noSubband = false;
            numBands = sampleModel.getNumBands();
        } else {
            sourceBands = new int[numBands];
            for (int i = 0; i < numBands; i++)
                sourceBands[i] = i;
        }

        int[] bandOffsets = null;
        boolean bgrOrder = true;

        if (sampleModel instanceof ComponentSampleModel) {
            bandOffsets = ((ComponentSampleModel)sampleModel).getBandOffsets();
            if (sampleModel instanceof BandedSampleModel) {
                // for images with BandedSampleModel we can not work
                //  with raster directly and must use writePixels()
                bgrOrder = false;
            } else {
                // we can work with raster directly only in case of
                // BGR component order.
                // In any other case we must use writePixels()
                for (int i = 0; i < bandOffsets.length; i++) {
                    bgrOrder &= (bandOffsets[i] == (bandOffsets.length - i - 1));
                }
            }
        } else {
            if (sampleModel instanceof SinglePixelPackedSampleModel) {

                // BugId 4892214: we can not work with raster directly
                // if image have different color order than RGB.
                // We should use writePixels() for such images.
                int[] bitOffsets = ((SinglePixelPackedSampleModel)sampleModel).getBitOffsets();
                for (int i=0; i<bitOffsets.length-1; i++) {
                    bgrOrder &= bitOffsets[i] > bitOffsets[i+1];
                }
            }
        }

        if (bandOffsets == null) {
            // we will use getPixels() to extract pixel data for writePixels()
            // Please note that getPixels() provides rgb bands order.
            bandOffsets = new int[numBands];
            for (int i = 0; i < numBands; i++)
                bandOffsets[i] = i;
        }

        noTransform &= bgrOrder;

        int sampleSize[] = sampleModel.getSampleSize();

        //XXX: check more

        // Number of bytes that a scanline for the image written out will have.
        int destScanlineBytes = w * numBands;

        switch(bmpParam.getCompressionMode()) {
        case ImageWriteParam.MODE_EXPLICIT:
            compressionType = getCompressionType(bmpParam.getCompressionType());
            break;
        case ImageWriteParam.MODE_COPY_FROM_METADATA:
            compressionType = bmpImageMetadata.compression;
            break;
        case ImageWriteParam.MODE_DEFAULT:
            compressionType = getPreferredCompressionType(colorModel, sampleModel);
            break;
        default:
            // ImageWriteParam.MODE_DISABLED:
            compressionType = BI_RGB;
        }

        if (!canEncodeImage(compressionType, colorModel, sampleModel)) {
            throw new IOException("Image can not be encoded with compression type "
                                  + compressionTypeNames[compressionType]);
        }

        byte r[] = null, g[] = null, b[] = null, a[] = null;

        if (compressionType == BMPConstants.BI_BITFIELDS) {
            bitsPerPixel =
                DataBuffer.getDataTypeSize(sampleModel.getDataType());

            if (bitsPerPixel != 16 && bitsPerPixel != 32) {
                // we should use 32bpp images in case of BI_BITFIELD
                // compression to avoid color conversion artefacts
                bitsPerPixel = 32;

                // Setting this flag to false ensures that generic
                // writePixels() will be used to store image data
                noTransform = false;
            }

            destScanlineBytes = w * bitsPerPixel + 7 >> 3;

            isPalette = true;
            paletteEntries = 3;
            r = new byte[paletteEntries];
            g = new byte[paletteEntries];
            b = new byte[paletteEntries];
            a = new byte[paletteEntries];

            int rmask = 0x00ff0000;
            int gmask = 0x0000ff00;
            int bmask = 0x000000ff;

            if (bitsPerPixel == 16) {
                /* NB: canEncodeImage() ensures we have image of
                 * either USHORT_565_RGB or USHORT_555_RGB type here.
                 * Technically, it should work for other direct color
                 * model types but it might be non compatible with win98
                 * and friends.
                 */
                if (colorModel instanceof DirectColorModel) {
                    DirectColorModel dcm = (DirectColorModel)colorModel;
                    rmask = dcm.getRedMask();
                    gmask = dcm.getGreenMask();
                    bmask = dcm.getBlueMask();
                } else {
                    // it is unlikely, but if it happens, we should throw
                    // an exception related to unsupported image format
                    throw new IOException("Image can not be encoded with " +
                                          "compression type " +
                                          compressionTypeNames[compressionType]);
                }
            }
            writeMaskToPalette(rmask, 0, r, g, b, a);
            writeMaskToPalette(gmask, 1, r, g, b, a);
            writeMaskToPalette(bmask, 2, r, g, b, a);

            if (!noTransform) {
                // prepare info for writePixels procedure
                bitMasks = new int[3];
                bitMasks[0] = rmask;
                bitMasks[1] = gmask;
                bitMasks[2] = bmask;

                bitPos = new int[3];
                bitPos[0] = firstLowBit(rmask);
                bitPos[1] = firstLowBit(gmask);
                bitPos[2] = firstLowBit(bmask);
            }

            if (colorModel instanceof IndexColorModel) {
                icm = (IndexColorModel)colorModel;
            }
        } else { // handle BI_RGB compression
            if (colorModel instanceof IndexColorModel) {
                isPalette = true;
                icm = (IndexColorModel)colorModel;
                paletteEntries = icm.getMapSize();

                if (paletteEntries <= 2) {
                    bitsPerPixel = 1;
                    destScanlineBytes = w + 7 >> 3;
                } else if (paletteEntries <= 16) {
                    bitsPerPixel = 4;
                    destScanlineBytes = w + 1 >> 1;
                } else if (paletteEntries <= 256) {
                    bitsPerPixel = 8;
                } else {
                    // Cannot be written as a Palette image. So write out as
                    // 24 bit image.
                    bitsPerPixel = 24;
                    isPalette = false;
                    paletteEntries = 0;
                    destScanlineBytes = w * 3;
                }

                if (isPalette == true) {
                    r = new byte[paletteEntries];
                    g = new byte[paletteEntries];
                    b = new byte[paletteEntries];
                    a = new byte[paletteEntries];

                    icm.getAlphas(a);
                    icm.getReds(r);
                    icm.getGreens(g);
                    icm.getBlues(b);
                }

            } else {
                // Grey scale images
                if (numBands == 1) {

                    isPalette = true;
                    paletteEntries = 256;
                    bitsPerPixel = sampleSize[0];

                    destScanlineBytes = (w * bitsPerPixel + 7 >> 3);

                    r = new byte[256];
                    g = new byte[256];
                    b = new byte[256];
                    a = new byte[256];

                    for (int i = 0; i < 256; i++) {
                        r[i] = (byte)i;
                        g[i] = (byte)i;
                        b[i] = (byte)i;
                        a[i] = (byte)255;
                    }

                } else {
                    if (sampleModel instanceof SinglePixelPackedSampleModel &&
                        noSubband)
                    {
                        /* NB: the actual pixel size can be smaller than
                         * size of used DataBuffer element.
                         * For example: in case of TYPE_INT_RGB actual pixel
                         * size is 24 bits, but size of DataBuffere element
                         * is 32 bits
                         */
                        int[] sample_sizes = sampleModel.getSampleSize();
                        bitsPerPixel = 0;
                        for (int size : sample_sizes) {
                            bitsPerPixel += size;
                        }
                        bitsPerPixel = roundBpp(bitsPerPixel);
                        if (bitsPerPixel != DataBuffer.getDataTypeSize(sampleModel.getDataType())) {
                            noTransform = false;
                        }
                        destScanlineBytes = w * bitsPerPixel + 7 >> 3;
                    }
                }
            }
        }

        // actual writing of image data
        int fileSize = 0;
        int offset = 0;
        int headerSize = 0;
        int imageSize = 0;
        int xPelsPerMeter = 0;
        int yPelsPerMeter = 0;
        int colorsUsed = 0;
        int colorsImportant = paletteEntries;

        // Calculate padding for each scanline
        int padding = destScanlineBytes % 4;
        if (padding != 0) {
            padding = 4 - padding;
        }


        // FileHeader is 14 bytes, BitmapHeader is 40 bytes,
        // add palette size and that is where the data will begin
        offset = 54 + paletteEntries * 4;

        imageSize = (destScanlineBytes + padding) * h;
        fileSize = imageSize + offset;
        headerSize = 40;

        long headPos = stream.getStreamPosition();

        writeFileHeader(fileSize, offset);

        /* According to MSDN description, the top-down image layout
         * is allowed only if compression type is BI_RGB or BI_BITFIELDS.
         * Images with any other compression type must be wrote in the
         * bottom-up layout.
         */
        if (compressionType == BMPConstants.BI_RGB ||
            compressionType == BMPConstants.BI_BITFIELDS)
        {
            isTopDown = bmpParam.isTopDown();
        } else {
            isTopDown = false;
        }

        writeInfoHeader(headerSize, bitsPerPixel);
View Full Code Here

        } else
            this.stream = null;
    }

    public ImageWriteParam getDefaultWriteParam() {
        return new BMPImageWriteParam();
    }
View Full Code Here

        clearAbortRequest();
        processImageStarted(0);
        if (param == null)
            param = getDefaultWriteParam();

        BMPImageWriteParam bmpParam = (BMPImageWriteParam)param;

        // Default is using 24 bits per pixel.
        int bitsPerPixel = 24;
        boolean isPalette = false;
        int paletteEntries = 0;
        IndexColorModel icm = null;

        RenderedImage input = null;
        Raster inputRaster = null;
        boolean writeRaster = image.hasRaster();
        Rectangle sourceRegion = param.getSourceRegion();
        SampleModel sampleModel = null;
        ColorModel colorModel = null;

        compImageSize = 0;

        if (writeRaster) {
            inputRaster = image.getRaster();
            sampleModel = inputRaster.getSampleModel();
            colorModel = ImageUtil.createColorModel(null, sampleModel);
            if (sourceRegion == null)
                sourceRegion = inputRaster.getBounds();
            else
                sourceRegion = sourceRegion.intersection(inputRaster.getBounds());
        } else {
            input = image.getRenderedImage();
            sampleModel = input.getSampleModel();
            colorModel = input.getColorModel();
            Rectangle rect = new Rectangle(input.getMinX(), input.getMinY(),
                                           input.getWidth(), input.getHeight());
            if (sourceRegion == null)
                sourceRegion = rect;
            else
                sourceRegion = sourceRegion.intersection(rect);
        }

        IIOMetadata imageMetadata = image.getMetadata();
        BMPMetadata bmpImageMetadata = null;
        if (imageMetadata != null
            && imageMetadata instanceof BMPMetadata)
        {
            bmpImageMetadata = (BMPMetadata)imageMetadata;
        } else {
            ImageTypeSpecifier imageType =
                new ImageTypeSpecifier(colorModel, sampleModel);

            bmpImageMetadata = (BMPMetadata)getDefaultImageMetadata(imageType,
                                                                    param);
        }

        if (sourceRegion.isEmpty())
            throw new RuntimeException(I18N.getString("BMPImageWrite0"));

        int scaleX = param.getSourceXSubsampling();
        int scaleY = param.getSourceYSubsampling();
        int xOffset = param.getSubsamplingXOffset();
        int yOffset = param.getSubsamplingYOffset();

        // cache the data type;
        int dataType = sampleModel.getDataType();

        sourceRegion.translate(xOffset, yOffset);
        sourceRegion.width -= xOffset;
        sourceRegion.height -= yOffset;

        int minX = sourceRegion.x / scaleX;
        int minY = sourceRegion.y / scaleY;
        w = (sourceRegion.width + scaleX - 1) / scaleX;
        h = (sourceRegion.height + scaleY - 1) / scaleY;
        xOffset = sourceRegion.x % scaleX;
        yOffset = sourceRegion.y % scaleY;

        Rectangle destinationRegion = new Rectangle(minX, minY, w, h);
        boolean noTransform = destinationRegion.equals(sourceRegion);

        // Raw data can only handle bytes, everything greater must be ASCII.
        int[] sourceBands = param.getSourceBands();
        boolean noSubband = true;
        int numBands = sampleModel.getNumBands();

        if (sourceBands != null) {
            sampleModel = sampleModel.createSubsetSampleModel(sourceBands);
            colorModel = null;
            noSubband = false;
            numBands = sampleModel.getNumBands();
        } else {
            sourceBands = new int[numBands];
            for (int i = 0; i < numBands; i++)
                sourceBands[i] = i;
        }

        int[] bandOffsets = null;
        boolean bgrOrder = true;

        if (sampleModel instanceof ComponentSampleModel) {
            bandOffsets = ((ComponentSampleModel)sampleModel).getBandOffsets();
            if (sampleModel instanceof BandedSampleModel) {
                // for images with BandedSampleModel we can not work
                //  with raster directly and must use writePixels()
                bgrOrder = false;
            } else {
                // we can work with raster directly only in case of
                // BGR component order.
                // In any other case we must use writePixels()
                for (int i = 0; i < bandOffsets.length; i++) {
                    bgrOrder &= (bandOffsets[i] == (bandOffsets.length - i - 1));
                }
            }
        } else {
            if (sampleModel instanceof SinglePixelPackedSampleModel) {

                // BugId 4892214: we can not work with raster directly
                // if image have different color order than RGB.
                // We should use writePixels() for such images.
                int[] bitOffsets = ((SinglePixelPackedSampleModel)sampleModel).getBitOffsets();
                for (int i=0; i<bitOffsets.length-1; i++) {
                    bgrOrder &= bitOffsets[i] > bitOffsets[i+1];
                }
            }
        }

        if (bandOffsets == null) {
            // we will use getPixels() to extract pixel data for writePixels()
            // Please note that getPixels() provides rgb bands order.
            bandOffsets = new int[numBands];
            for (int i = 0; i < numBands; i++)
                bandOffsets[i] = i;
        }

        noTransform &= bgrOrder;

        int sampleSize[] = sampleModel.getSampleSize();

        //XXX: check more

        // Number of bytes that a scanline for the image written out will have.
        int destScanlineBytes = w * numBands;

        switch(bmpParam.getCompressionMode()) {
        case ImageWriteParam.MODE_EXPLICIT:
            compressionType = getCompressionType(bmpParam.getCompressionType());
            break;
        case ImageWriteParam.MODE_COPY_FROM_METADATA:
            compressionType = bmpImageMetadata.compression;
            break;
        case ImageWriteParam.MODE_DEFAULT:
            compressionType = getPreferredCompressionType(colorModel, sampleModel);
            break;
        default:
            // ImageWriteParam.MODE_DISABLED:
            compressionType = BI_RGB;
        }

        if (!canEncodeImage(compressionType, colorModel, sampleModel)) {
            throw new IOException("Image can not be encoded with compression type "
                                  + compressionTypeNames[compressionType]);
        }

        byte r[] = null, g[] = null, b[] = null, a[] = null;

        if (compressionType == BMPConstants.BI_BITFIELDS) {
            bitsPerPixel =
                DataBuffer.getDataTypeSize(sampleModel.getDataType());

            if (bitsPerPixel != 16 && bitsPerPixel != 32) {
                // we should use 32bpp images in case of BI_BITFIELD
                // compression to avoid color conversion artefacts
                bitsPerPixel = 32;

                // Setting this flag to false ensures that generic
                // writePixels() will be used to store image data
                noTransform = false;
            }

            destScanlineBytes = w * bitsPerPixel + 7 >> 3;

            isPalette = true;
            paletteEntries = 3;
            r = new byte[paletteEntries];
            g = new byte[paletteEntries];
            b = new byte[paletteEntries];
            a = new byte[paletteEntries];

            int rmask = 0x00ff0000;
            int gmask = 0x0000ff00;
            int bmask = 0x000000ff;

            if (bitsPerPixel == 16) {
                /* NB: canEncodeImage() ensures we have image of
                 * either USHORT_565_RGB or USHORT_555_RGB type here.
                 * Technically, it should work for other direct color
                 * model types but it might be non compatible with win98
                 * and friends.
                 */
                if (colorModel instanceof DirectColorModel) {
                    DirectColorModel dcm = (DirectColorModel)colorModel;
                    rmask = dcm.getRedMask();
                    gmask = dcm.getGreenMask();
                    bmask = dcm.getBlueMask();
                } else {
                    // it is unlikely, but if it happens, we should throw
                    // an exception related to unsupported image format
                    throw new IOException("Image can not be encoded with " +
                                          "compression type " +
                                          compressionTypeNames[compressionType]);
                }
            }
            writeMaskToPalette(rmask, 0, r, g, b, a);
            writeMaskToPalette(gmask, 1, r, g, b, a);
            writeMaskToPalette(bmask, 2, r, g, b, a);

            if (!noTransform) {
                // prepare info for writePixels procedure
                bitMasks = new int[3];
                bitMasks[0] = rmask;
                bitMasks[1] = gmask;
                bitMasks[2] = bmask;

                bitPos = new int[3];
                bitPos[0] = firstLowBit(rmask);
                bitPos[1] = firstLowBit(gmask);
                bitPos[2] = firstLowBit(bmask);
            }

            if (colorModel instanceof IndexColorModel) {
                icm = (IndexColorModel)colorModel;
            }
        } else { // handle BI_RGB compression
            if (colorModel instanceof IndexColorModel) {
                isPalette = true;
                icm = (IndexColorModel)colorModel;
                paletteEntries = icm.getMapSize();

                if (paletteEntries <= 2) {
                    bitsPerPixel = 1;
                    destScanlineBytes = w + 7 >> 3;
                } else if (paletteEntries <= 16) {
                    bitsPerPixel = 4;
                    destScanlineBytes = w + 1 >> 1;
                } else if (paletteEntries <= 256) {
                    bitsPerPixel = 8;
                } else {
                    // Cannot be written as a Palette image. So write out as
                    // 24 bit image.
                    bitsPerPixel = 24;
                    isPalette = false;
                    paletteEntries = 0;
                    destScanlineBytes = w * 3;
                }

                if (isPalette == true) {
                    r = new byte[paletteEntries];
                    g = new byte[paletteEntries];
                    b = new byte[paletteEntries];
                    a = new byte[paletteEntries];

                    icm.getAlphas(a);
                    icm.getReds(r);
                    icm.getGreens(g);
                    icm.getBlues(b);
                }

            } else {
                // Grey scale images
                if (numBands == 1) {

                    isPalette = true;
                    paletteEntries = 256;
                    bitsPerPixel = sampleSize[0];

                    destScanlineBytes = (w * bitsPerPixel + 7 >> 3);

                    r = new byte[256];
                    g = new byte[256];
                    b = new byte[256];
                    a = new byte[256];

                    for (int i = 0; i < 256; i++) {
                        r[i] = (byte)i;
                        g[i] = (byte)i;
                        b[i] = (byte)i;
                        a[i] = (byte)255;
                    }

                } else {
                    if (sampleModel instanceof SinglePixelPackedSampleModel &&
                        noSubband)
                    {
                        /* NB: the actual pixel size can be smaller than
                         * size of used DataBuffer element.
                         * For example: in case of TYPE_INT_RGB actual pixel
                         * size is 24 bits, but size of DataBuffere element
                         * is 32 bits
                         */
                        int[] sample_sizes = sampleModel.getSampleSize();
                        bitsPerPixel = 0;
                        for (int size : sample_sizes) {
                            bitsPerPixel += size;
                        }
                        bitsPerPixel = roundBpp(bitsPerPixel);
                        if (bitsPerPixel != DataBuffer.getDataTypeSize(sampleModel.getDataType())) {
                            noTransform = false;
                        }
                        destScanlineBytes = w * bitsPerPixel + 7 >> 3;
                    }
                }
            }
        }

        // actual writing of image data
        int fileSize = 0;
        int offset = 0;
        int headerSize = 0;
        int imageSize = 0;
        int xPelsPerMeter = 0;
        int yPelsPerMeter = 0;
        int colorsUsed = 0;
        int colorsImportant = paletteEntries;

        // Calculate padding for each scanline
        int padding = destScanlineBytes % 4;
        if (padding != 0) {
            padding = 4 - padding;
        }


        // FileHeader is 14 bytes, BitmapHeader is 40 bytes,
        // add palette size and that is where the data will begin
        offset = 54 + paletteEntries * 4;

        imageSize = (destScanlineBytes + padding) * h;
        fileSize = imageSize + offset;
        headerSize = 40;

        long headPos = stream.getStreamPosition();

        writeFileHeader(fileSize, offset);

        writeInfoHeader(headerSize, bitsPerPixel);

        // compression
        stream.writeInt(compressionType);

        // imageSize
        stream.writeInt(imageSize);

        // xPelsPerMeter
        stream.writeInt(xPelsPerMeter);

        // yPelsPerMeter
        stream.writeInt(yPelsPerMeter);

        // Colors Used
        stream.writeInt(colorsUsed);

        // Colors Important
        stream.writeInt(colorsImportant);

        // palette
        if (isPalette == true) {

            // write palette
            if (compressionType == BMPConstants.BI_BITFIELDS) {
                // write masks for red, green and blue components.
                for (int i=0; i<3; i++) {
                    int mask = (a[i]&0xFF) + ((r[i]&0xFF)*0x100) + ((g[i]&0xFF)*0x10000) + ((b[i]&0xFF)*0x1000000);
                    stream.writeInt(mask);
                }
            } else {
                for (int i=0; i<paletteEntries; i++) {
                    stream.writeByte(b[i]);
                    stream.writeByte(g[i]);
                    stream.writeByte(r[i]);
                    stream.writeByte(a[i]);
                }
            }
        }

        // Writing of actual image data
        int scanlineBytes = w * numBands;

        // Buffer for up to 8 rows of pixels
        int[] pixels = new int[scanlineBytes * scaleX];

        // Also create a buffer to hold one line of the data
        // to be written to the file, so we can use array writes.
        bpixels = new byte[destScanlineBytes];

        int l;

        if (compressionType == BMPConstants.BI_JPEG ||
            compressionType == BMPConstants.BI_PNG) {

            // prepare embedded buffer
            embedded_stream = new ByteArrayOutputStream();
            writeEmbedded(image, bmpParam);
            // update the file/image Size
            embedded_stream.flush();
            imageSize = embedded_stream.size();

            long endPos = stream.getStreamPosition();
            fileSize = (int)(offset + imageSize);
            stream.seek(headPos);
            writeSize(fileSize, 2);
            stream.seek(headPos);
            writeSize(imageSize, 34);
            stream.seek(endPos);
            stream.write(embedded_stream.toByteArray());
            embedded_stream = null;

            if (abortRequested()) {
                processWriteAborted();
            } else {
                processImageComplete();
                stream.flushBefore(stream.getStreamPosition());
            }

            return;
        }

        isTopDown = bmpParam.isTopDown();

        int maxBandOffset = bandOffsets[0];
        for (int i = 1; i < bandOffsets.length; i++)
            if (bandOffsets[i] > maxBandOffset)
                maxBandOffset = bandOffsets[i];
View Full Code Here

TOP

Related Classes of javax.imageio.plugins.bmp.BMPImageWriteParam

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