xtiffimage.java
来自「OpenMap是一个基于JavaBeansTM的开发工具包。利用OpenMap你」· Java 代码 · 共 662 行 · 第 1/2 页
JAVA
662 行
image_type = XTIFF.TYPE_BILEVEL_BLACK_IS_ZERO; // Keep pixels packed, use IndexColorModel sampleModel = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, tileWidth, tileHeight, 1); // Set up the palette byte r[] = new byte[] { (byte) 0, (byte) 255 }; byte g[] = new byte[] { (byte) 0, (byte) 255 }; byte b[] = new byte[] { (byte) 0, (byte) 255 }; // 1 Bit pixels packed into a byte, use IndexColorModel colorModel = new IndexColorModel(1, 2, r, g, b); } else { image_type = XTIFF.TYPE_GREYSCALE_BLACK_IS_ZERO; if (bitsPerSample[0] == 4) { sampleModel = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, tileWidth, tileHeight, 4); colorModel = ImageCodec.createGrayIndexColorModel(sampleModel, true); } else if (bitsPerSample[0] == 8) { sampleModel = RasterFactory.createPixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, tileWidth, tileHeight, bands); colorModel = ImageCodec.createComponentColorModel(sampleModel); } else if (bitsPerSample[0] == 16) { sampleModel = RasterFactory.createPixelInterleavedSampleModel(dataType, tileWidth, tileHeight, bands); colorModel = ImageCodec.createComponentColorModel(sampleModel); } else { throw new IllegalArgumentException(JaiI18N.getString("XTIFFImageDecoder14")); } } break; case XTIFF.PHOTOMETRIC_RGB: bands = samplesPerPixel; // RGB full color image if (bitsPerSample[0] == 8) { sampleModel = RasterFactory.createPixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, tileWidth, tileHeight, bands); } else if (bitsPerSample[0] == 16) { sampleModel = RasterFactory.createPixelInterleavedSampleModel(dataType, tileWidth, tileHeight, bands); } else { throw new RuntimeException(JaiI18N.getString("XTIFFImageDecoder15")); } if (samplesPerPixel < 3) { throw new RuntimeException(JaiI18N.getString("XTIFFImageDecoder1")); } else if (samplesPerPixel == 3) { image_type = XTIFF.TYPE_RGB; // No alpha colorModel = ImageCodec.createComponentColorModel(sampleModel); } else if (samplesPerPixel == 4) { if (extraSamples == 0) { image_type = XTIFF.TYPE_ORGB; // Transparency.OPAQUE signifies image data that is // completely opaque, meaning that all pixels have an alpha // value of 1.0. So the extra band gets ignored, which is // what we want. colorModel = createAlphaComponentColorModel(dataType, true, false, Transparency.OPAQUE); } else if (extraSamples == 1) { image_type = XTIFF.TYPE_ARGB_PRE; // Pre multiplied alpha. colorModel = createAlphaComponentColorModel(dataType, true, true, Transparency.TRANSLUCENT); } else if (extraSamples == 2) { image_type = XTIFF.TYPE_ARGB; // The extra sample here is unassociated alpha, usually a // transparency mask, also called soft matte. colorModel = createAlphaComponentColorModel(dataType, true, false, Transparency.BITMASK); } } else { image_type = XTIFF.TYPE_RGB_EXTRA; // For this case we can't display the image, so there is no // point in trying to reformat the data to be BGR followed by // the ExtraSamples, the way Java2D would like it, because // Java2D can't display it anyway. Therefore create a sample // model with increasing bandOffsets, and keep the colorModel // as null, as there is no appropriate ColorModel. int bandOffsets[] = new int[bands]; for (int i = 0; i < bands; i++) { bandOffsets[i] = i; } if (bitsPerSample[0] == 8) { sampleModel = new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, tileWidth, tileHeight, bands, bands * tileWidth, bandOffsets); colorModel = null; } else if (bitsPerSample[0] == 16) { sampleModel = new PixelInterleavedSampleModel(dataType, tileWidth, tileHeight, bands, bands * tileWidth, bandOffsets); colorModel = null; } } break; case XTIFF.PHOTOMETRIC_PALETTE: image_type = XTIFF.TYPE_PALETTE; // Get the colormap XTIFFField cfield = dir.getField(XTIFF.TIFFTAG_COLORMAP); if (cfield == null) { throw new RuntimeException(JaiI18N.getString("XTIFFImageDecoder2")); } else { colormap = cfield.getAsChars(); } // Could be either 1 or 3 bands depending on whether we use // IndexColorModel or not. if (decodePaletteAsShorts) { bands = 3; if (bitsPerSample[0] != 4 && bitsPerSample[0] != 8 && bitsPerSample[0] != 16) { throw new RuntimeException(JaiI18N.getString("XTIFFImageDecoder13")); } // If no SampleFormat tag was specified and if the // bitsPerSample are less than or equal to 8, then the // dataType was initially set to byte, but now we want to // expand the palette as shorts, so the dataType should // be ushort. if (dataType == DataBuffer.TYPE_BYTE) { dataType = DataBuffer.TYPE_USHORT; } // Data will have to be unpacked into a 3 band short image // as we do not have a IndexColorModel that can deal with // a colormodel whose entries are of short data type. sampleModel = RasterFactory.createPixelInterleavedSampleModel(dataType, tileWidth, tileHeight, bands); colorModel = ImageCodec.createComponentColorModel(sampleModel); } else { bands = 1; if (bitsPerSample[0] == 4) { // Pixel data will not be unpacked, will use MPPSM to store // packed data and IndexColorModel to do the unpacking. sampleModel = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, tileWidth, tileHeight, bitsPerSample[0]); } else if (bitsPerSample[0] == 8) { sampleModel = RasterFactory.createPixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, tileWidth, tileHeight, bands); } else if (bitsPerSample[0] == 16) { // Here datatype has to be unsigned since we are storing // indices into the IndexColorModel palette. Ofcourse // the actual palette entries are allowed to be negative. sampleModel = RasterFactory.createPixelInterleavedSampleModel(DataBuffer.TYPE_USHORT, tileWidth, tileHeight, bands); } else { throw new RuntimeException(JaiI18N.getString("XTIFFImageDecoder13")); } int bandLength = colormap.length / 3; byte r[] = new byte[bandLength]; byte g[] = new byte[bandLength]; byte b[] = new byte[bandLength]; int gIndex = bandLength; int bIndex = bandLength * 2; if (dataType == DataBuffer.TYPE_SHORT) { for (int i = 0; i < bandLength; i++) { r[i] = param.decodeSigned16BitsTo8Bits((short) colormap[i]); g[i] = param.decodeSigned16BitsTo8Bits((short) colormap[gIndex + i]); b[i] = param.decodeSigned16BitsTo8Bits((short) colormap[bIndex + i]); } } else { for (int i = 0; i < bandLength; i++) { r[i] = param.decode16BitsTo8Bits(colormap[i] & 0xffff); g[i] = param.decode16BitsTo8Bits(colormap[gIndex + i] & 0xffff); b[i] = param.decode16BitsTo8Bits(colormap[bIndex + i] & 0xffff); } } colorModel = new IndexColorModel(bitsPerSample[0], bandLength, r, g, b); } break; case XTIFF.PHOTOMETRIC_TRANSPARENCY: image_type = XTIFF.TYPE_TRANS; // Transparency Mask throw new RuntimeException(JaiI18N.getString("XTIFFImageDecoder3")); // break; default: throw new RuntimeException(JaiI18N.getString("XTIFFImageDecoder4")); } } /** * Reads a private IFD from a given offset in the stream. This method may be * used to obtain IFDs that are referenced only by private tag values. */ public XTIFFDirectory getPrivateIFD(long offset) throws IOException { return XTIFFDirectory.create(stream, offset); } private WritableRaster tile00 = null; /** * Returns tile (tileX, tileY) as a Raster. */ public synchronized Raster getTile(int tileX, int tileY) { if (tileX == 0 && tileY == 0 && tile00 != null) { return tile00; } if ((tileX < 0) || (tileX >= tilesX) || (tileY < 0) || (tileY >= tilesY)) { throw new IllegalArgumentException(JaiI18N.getString("XTIFFImageDecoder5")); } // file setup1 // Save original file pointer position and seek to tile data location. long save_offset = 0; try { save_offset = stream.getFilePointer(); stream.seek(tileOffsets[tileY * tilesX + tileX]); } catch (IOException ioe) { throw new RuntimeException(JaiI18N.getString("XTIFFImageDecoder8")); } // Number of bytes in this tile (strip) after compression. int byteCount = (int) tileByteCounts[tileY * tilesX + tileX]; // Find out the number of bytes in the current tile Rectangle tileRect = new Rectangle(tileXToX(tileX), tileYToY(tileY), tileWidth, tileHeight); Rectangle newRect = tileRect.intersection(getBounds()); // file setup2 byte data[] = new byte[byteCount]; WritableRaster tile = null; try { stream.readFully(data, 0, byteCount); tile = codec.decode(this, newRect, data); stream.seek(save_offset); } catch (IOException e) { throw new RuntimeException("Failed to read raw tile data:" + e); } if (tileX == 0 && tileY == 0) { tile00 = tile; } return tile; } // Create ComponentColorModel for TYPE_RGB images private ComponentColorModel createAlphaComponentColorModel( int dataType, boolean hasAlpha, boolean isAlphaPremultiplied, int transparency) { ComponentColorModel ccm = null; int RGBBits[][] = new int[3][]; RGBBits[0] = new int[] { 8, 8, 8, 8 }; // Byte RGBBits[1] = new int[] { 16, 16, 16, 16 }; // Short RGBBits[2] = new int[] { 16, 16, 16, 16 }; // UShort RGBBits[2] = new int[] { 32, 32, 32, 32 }; // Int ccm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), RGBBits[dataType], hasAlpha, isAlphaPremultiplied, transparency, dataType); return ccm; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?