2362N/A * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * The Java Image IO plugin writer for encoding a binary RenderedImage into 0N/A * The encoding process may clip, subsample using the parameters 0N/A * specified in the <code>ImageWriteParam</code>. 0N/A * @see javax.imageio.plugins.bmp.BMPImageWriteParam 0N/A /** The output stream to write into */ 0N/A /** Constructs <code>BMPImageWriter</code> based on the provided 0N/A * <code>ImageWriterSpi</code>. 0N/A // Default is using 24 bits per pixel. 0N/A // cache the data type; 0N/A // Raw data can only handle bytes, everything greater must be ASCII. 0N/A // for images with BandedSampleModel we can not work 0N/A // with raster directly and must use writePixels() 0N/A // we can work with raster directly only in case of 0N/A // BGR component order. 0N/A // In any other case we must use writePixels() 0N/A // BugId 4892214: we can not work with raster directly 0N/A // if image have different color order than RGB. 0N/A // We should use writePixels() for such images. 0N/A // we will use getPixels() to extract pixel data for writePixels() 0N/A // Please note that getPixels() provides rgb bands order. 0N/A // Number of bytes that a scanline for the image written out will have. 0N/A // ImageWriteParam.MODE_DISABLED: 0N/A throw new IOException(
"Image can not be encoded with compression type " 0N/A // we should use 32bpp images in case of BI_BITFIELD 0N/A // compression to avoid color conversion artefacts 0N/A // Setting this flag to false ensures that generic 0N/A // writePixels() will be used to store image data 0N/A /* NB: canEncodeImage() ensures we have image of 0N/A * either USHORT_565_RGB or USHORT_555_RGB type here. 0N/A * Technically, it should work for other direct color 0N/A * model types but it might be non compatible with win98 0N/A // it is unlikely, but if it happens, we should throw 0N/A // an exception related to unsupported image format 0N/A "compression type " +
0N/A // prepare info for writePixels procedure 0N/A }
else {
// handle BI_RGB compression 0N/A // Cannot be written as a Palette image. So write out as 0N/A // Grey scale images 0N/A for (
int i =
0; i <
256; i++) {
0N/A /* NB: the actual pixel size can be smaller than 0N/A * size of used DataBuffer element. 0N/A * For example: in case of TYPE_INT_RGB actual pixel 0N/A * size is 24 bits, but size of DataBuffere element 0N/A // actual writing of image data 0N/A // Calculate padding for each scanline 0N/A // FileHeader is 14 bytes, BitmapHeader is 40 bytes, 0N/A // add palette size and that is where the data will begin 1289N/A /* According to MSDN description, the top-down image layout 1289N/A * is allowed only if compression type is BI_RGB or BI_BITFIELDS. 1289N/A * Images with any other compression type must be wrote in the 0N/A // write masks for red, green and blue components. 0N/A for (
int i=
0; i<
3; i++) {
0N/A int mask = (a[i]&
0xFF) + ((r[i]&
0xFF)*
0x100) + ((g[i]&
0xFF)*
0x10000) + ((b[i]&
0xFF)*
0x1000000);
0N/A // Writing of actual image data 0N/A // Buffer for up to 8 rows of pixels 0N/A // Also create a buffer to hold one line of the data 0N/A // to be written to the file, so we can use array writes. 0N/A // prepare embedded buffer 0N/A for (
int i =
0; i < h; i++) {
0N/A // ((DataBufferByte)src.getDataBuffer()).getData(); 0N/A //System.out.println("bdata.length="+bdata.length); 0N/A //System.arraycopy(bdata, pos, bpixels, 0, scanlineBytes); 0N/A for (
int j =
0, k =
0, n=
0; j < w;
0N/A // pixel data is provided here in RGB order 0N/A // Write the RLE EOF marker and 0N/A // Partially filled last byte, if any 0N/A // Put the last pixel of odd-length lines in the 4 MSBs 0N/A * We expect that pixel data comes in RGB order. 0N/A * We will assemble short pixel taking into account 0N/A * the compression type: 0N/A * BI_RGB - the RGB order should be maintained. 0N/A * BI_BITFIELDS - use bitPos array that was built 0N/A * according to bitfields masks. 0N/A * please note that despite other cases, 0N/A * the 16bpp BI_RGB requires the RGB data order 0N/A // Since BMP needs BGR format 0N/A // Case where IndexColorModel had > 256 colors. 0N/A * We expect that pixel data comes in RGB order. 0N/A * We will assemble int pixel taking into account 0N/A * the compression type. 0N/A * BI_RGB - the BGR order should be used. 0N/A * BI_BITFIELDS - use bitPos array that was built 0N/A * according to bitfields masks. 0N/A // We have two possibilities here: 0N/A // 1. we are writing the indexed image with bitfields 0N/A // compression (this covers also the case of BYTE_BINARY) 0N/A // => use icm to get actual RGB color values. 0N/A // 2. we are writing the gray-scaled image with BI_BITFIELDS 0N/A // => just replicate the level of gray to color components. 0N/A // Write out the padding 0N/A /// Check if there was an existing Absolute Run 0N/A /// Absolute Encoding for less than 3 0N/A /// treated as regular encoding 0N/A /// Do not include the last element since it will 0N/A /// Only 255 values permitted 0N/A /// If there was an existing run 0N/A // padding since 255 elts is not even 0N/A // write the Absolute Run 0N/A //Check if there was an existing Absolute Run 0N/A // we need to exclude last 2 elts, similarity of 0N/A // which caused to enter this part of the code 0N/A // if # of elts is odd - read the last element 0N/A // Padding to word align absolute encoding 0N/A // odd runlength and the run ends here 0N/A // runCount wont be > 254 since 256/255 case will 0N/A // be taken care of in above code. 0N/A // If end of scanline 0N/A // Check for existing run 0N/A }
else if (
absVal <
253){
// only 255 elements 0N/A // Padding for word align 0N/A // since it will fit into 127 bytes 0N/A // Handle the End of scanline for the last 2 4bits 0N/A // reserved1 and reserved2 0N/A // offset to image data 0N/A //param.setDestinationBands(bmpParam.getDestinationBands()); 0N/A * Returns preferred compression type for given image. 0N/A * The default compression type is BI_RGB, but some image types can't be 0N/A * encodeed with using default compression without cahnge color resolution. 0N/A * For example, TYPE_USHORT_565_RGB may be encodeed only by using BI_BITFIELDS 0N/A * NB: we probably need to extend this method if we encounter other image 0N/A * types which can not be encoded with BI_RGB compression type. 0N/A * Check whether we can encode image of given type using compression method in question. 0N/A * For example, TYPE_USHORT_565_RGB can be encodeed with BI_BITFIELDS compression only. 0N/A * NB: method should be extended if other cases when we can not encode 0N/A * with given compression will be discovered. 0N/A // only 4bpp images can be encoded as BI_RLE4 0N/A // only 8bpp images can be encoded as BI_RLE8 0N/A * Technically we expect that we may be able to 0N/A * encode only some of SinglePixelPackedSampleModel 0N/A * In addition we should take into account following: 0N/A * 1. BI_RGB case, according to the MSDN description: 0N/A * The bitmap has a maximum of 2^16 colors. If the 0N/A * biCompression member of the BITMAPINFOHEADER is BI_RGB, 0N/A * the bmiColors member of BITMAPINFO is NULL. Each WORD 0N/A * in the bitmap array represents a single pixel. The 0N/A * relative intensities of red, green, and blue are 0N/A * represented with five bits for each color component. 0N/A * 2. BI_BITFIELDS case, according ot the MSDN description: 0N/A * Windows 95/98/Me: When the biCompression member is 0N/A * BI_BITFIELDS, the system supports only the following 0N/A * 16bpp color masks: A 5-5-5 16-bit image, where the blue 0N/A * mask is 0x001F, the green mask is 0x03E0, and the red mask 0N/A * is 0x7C00; and a 5-6-5 16-bit image, where the blue mask 0N/A * is 0x001F, the green mask is 0x07E0, and the red mask is 0N/A byte[] r,
byte[]g,
byte[] b,
byte[]a) {
0N/A b[i] = (
byte)(
0xff & (
mask >>
24));
0N/A g[i] = (
byte)(
0xff & (
mask >>
16));
0N/A }
else if (x <=
16) {