📄 bmpimagereader.java
字号:
new int[]{0}); finished++; } else if ((lineNo - sourceRegion.y) % scaleY == 0) { int currentLine = (lineNo - sourceRegion.y) / scaleY + destinationRegion.y; int pos = currentLine * lineStride; pos += destinationRegion.x; for (int i = sourceRegion.x; i < sourceRegion.x + sourceRegion.width; i += scaleX) bdata[pos++] = val[i]; processImageUpdate(bi, 0, currentLine, destinationRegion.width, 1, 1, 1, new int[]{0}); finished++; } } processImageProgress(100.0F * finished / destinationRegion.height); lineNo += isBottomUp ? -1 : 1; l = 0; if (abortRequested()) { flag = true; } break; case 1: // End-of-RLE marker flag = true; break; case 2: // delta or vector marker int xoff = values[count++] & 0xff; int yoff = values[count] & 0xff; // Move to the position xoff, yoff down l += xoff + yoff*width; break; default: int end = values[count-1] & 0xff; for (int i=0; i<end; i++) { val[l++] = (byte)(values[count++] & 0xff); } // Whenever end pixels can fit into odd number of bytes, // an extra padding byte will be present, so skip that. if ((end & 1) == 1) { count++; } } } else { for (int i=0; i<value; i++) { val[l++] = (byte)(values[count] & 0xff); } count++; } // If End-of-RLE data, then exit the while loop if (flag) { break; } } } private void readRLE4(byte[] bdata) throws IOException { // If imageSize field is not specified, calculate it. int imSize = (int)imageSize; if (imSize == 0) { imSize = (int)(bitmapFileSize - bitmapOffset); } int padding = 0; // If width is not 32 byte aligned, then while uncompressing each // scanline will have padding bytes, calculate the amount of padding int remainder = width % 4; if (remainder != 0) { padding = 4 - remainder; } // Read till we have the whole image byte[] values = new byte[imSize]; iis.readFully(values, 0, imSize); // Decompress the RLE4 compressed data. decodeRLE4(imSize, padding, values, bdata); } private void decodeRLE4(int imSize, int padding, byte[] values, byte[] bdata) throws IOException { byte[] val = new byte[width]; int count = 0, l = 0; int value; boolean flag = false; int lineNo = isBottomUp ? height - 1 : 0; int lineStride = ((MultiPixelPackedSampleModel)sampleModel).getScanlineStride(); int finished = 0; while (count != imSize) { value = values[count++] & 0xFF; if (value == 0) { // Absolute mode switch(values[count++] & 0xFF) { case 0: // End-of-scanline marker // End-of-scanline marker if (lineNo >= sourceRegion.y && lineNo < sourceRegion.y + sourceRegion.height) { if (noTransform) { int pos = lineNo * (width + 1 >> 1); for(int i = 0, j = 0; i < width >> 1; i++) bdata[pos++] = (byte)((val[j++] << 4) | val[j++]); if ((width & 1) == 1) bdata[pos] |= val[width - 1] << 4; processImageUpdate(bi, 0, lineNo, destinationRegion.width, 1, 1, 1, new int[]{0}); finished++; } else if ((lineNo - sourceRegion.y) % scaleY == 0) { int currentLine = (lineNo - sourceRegion.y) / scaleY + destinationRegion.y; int pos = currentLine * lineStride; pos += destinationRegion.x >> 1; int shift = (1 - (destinationRegion.x & 1)) << 2; for (int i = sourceRegion.x; i < sourceRegion.x + sourceRegion.width; i += scaleX) { bdata[pos] |= val[i] << shift; shift += 4; if (shift == 4) { pos++; } shift &= 7; } processImageUpdate(bi, 0, currentLine, destinationRegion.width, 1, 1, 1, new int[]{0}); finished++; } } processImageProgress(100.0F * finished / destinationRegion.height); lineNo += isBottomUp ? -1 : 1; l = 0; if (abortRequested()) { flag = true; } break; case 1: // End-of-RLE marker flag = true; break; case 2: // delta or vector marker int xoff = values[count++] & 0xFF; int yoff = values[count] & 0xFF; // Move to the position xoff, yoff down l += xoff + yoff*width; break; default: int end = values[count-1] & 0xFF; for (int i=0; i<end; i++) { val[l++] = (byte)(((i & 1) == 0) ? (values[count] & 0xf0) >> 4 : (values[count++] & 0x0f)); } // When end is odd, the above for loop does not // increment count, so do it now. if ((end & 1) == 1) { count++; } // Whenever end pixels can fit into odd number of bytes, // an extra padding byte will be present, so skip that. if ((((int)Math.ceil(end/2)) & 1) ==1 ) { count++; } break; } } else { // Encoded mode int alternate[] = { (values[count] & 0xf0) >> 4, values[count] & 0x0f }; for (int i=0; (i < value) && (l < width); i++) { val[l++] = (byte)alternate[i & 1]; } count++; } // If End-of-RLE data, then exit the while loop if (flag) { break; } } } /** Decodes the jpeg/png image embedded in the bitmap using any jpeg * ImageIO-style plugin. * * @param bi The destination <code>BufferedImage</code>. * @param bmpParam The <code>ImageReadParam</code> for decoding this * BMP image. The parameters for subregion, band selection and * subsampling are used in decoding the jpeg image. */ private BufferedImage readEmbedded(int type, BufferedImage bi, ImageReadParam bmpParam) throws IOException { String format; switch(type) { case BI_JPEG: format = "JPEG"; break; case BI_PNG: format = "PNG"; break; default: throw new IOException("Unexpected compression type: " + type); } ImageReader reader = ImageIO.getImageReadersByFormatName(format).next(); if (reader == null) { throw new RuntimeException(I18N.getString("BMPImageReader4") + " " + format); } // prepare input byte[] buff = new byte[(int)imageSize]; iis.read(buff); reader.setInput(ImageIO.createImageInputStream(new ByteArrayInputStream(buff))); if (bi == null) { ImageTypeSpecifier embType = reader.getImageTypes(0).next(); bi = embType.createBufferedImage(destinationRegion.x + destinationRegion.width, destinationRegion.y + destinationRegion.height); } reader.addIIOReadProgressListener(new EmbeddedProgressAdapter() { public void imageProgress(ImageReader source, float percentageDone) { processImageProgress(percentageDone); } }); reader.addIIOReadUpdateListener(new IIOReadUpdateListener() { public void imageUpdate(ImageReader source, BufferedImage theImage, int minX, int minY, int width, int height, int periodX, int periodY, int[] bands) { processImageUpdate(theImage, minX, minY, width, height, periodX, periodY, bands); } public void passComplete(ImageReader source, BufferedImage theImage) { processPassComplete(theImage); } public void passStarted(ImageReader source, BufferedImage theImage, int pass, int minPass, int maxPass, int minX, int minY, int periodX, int periodY, int[] bands) { processPassStarted(theImage, pass, minPass, maxPass, minX, minY, periodX, periodY, bands); } public void thumbnailPassComplete(ImageReader source, BufferedImage thumb) {} public void thumbnailPassStarted(ImageReader source, BufferedImage thumb, int pass, int minPass, int maxPass, int minX, int minY, int periodX, int periodY, int[] bands) {} public void thumbnailUpdate(ImageReader source, BufferedImage theThumbnail, int minX, int minY, int width, int height, int periodX, int periodY, int[] bands) {} }); reader.addIIOReadWarningListener(new IIOReadWarningListener() { public void warningOccurred(ImageReader source, String warning) { processWarningOccurred(warning); } }); ImageReadParam param = reader.getDefaultReadParam(); param.setDestination(bi); param.setDestinationBands(bmpParam.getDestinationBands()); param.setDestinationOffset(bmpParam.getDestinationOffset()); param.setSourceBands(bmpParam.getSourceBands()); param.setSourceRegion(bmpParam.getSourceRegion()); param.setSourceSubsampling(bmpParam.getSourceXSubsampling(), bmpParam.getSourceYSubsampling(), bmpParam.getSubsamplingXOffset(), bmpParam.getSubsamplingYOffset()); reader.read(0, param); return bi; } private class EmbeddedProgressAdapter implements IIOReadProgressListener { public void imageComplete(ImageReader src) {} public void imageProgress(ImageReader src, float percentageDone) {} public void imageStarted(ImageReader src, int imageIndex) {} public void thumbnailComplete(ImageReader src) {} public void thumbnailProgress(ImageReader src, float percentageDone) {} public void thumbnailStarted(ImageReader src, int iIdx, int tIdx) {} public void sequenceComplete(ImageReader src) {} public void sequenceStarted(ImageReader src, int minIndex) {} public void readAborted(ImageReader src) {} }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -