📄 bmpimage.java
字号:
} } else { count = -padding; for (int i=0; i<height; i++) { count += padding; for (int j=0; j<width; j++) { bdata[l + 2] = values[count++]; bdata[l + 1] = values[count++]; bdata[l] = values[count++]; l += 3; } } } } private int findMask(int mask) { int k = 0; for (; k < 32; ++k) { if ((mask & 1) == 1) break; mask >>>= 1; } return mask; } private int findShift(int mask) { int k = 0; for (; k < 32; ++k) { if ((mask & 1) == 1) break; mask >>>= 1; } return k; } private Image read1632Bit(boolean is32) throws IOException, BadElementException { int red_mask = findMask(redMask); int red_shift = findShift(redMask); int red_factor = red_mask + 1; int green_mask = findMask(greenMask); int green_shift = findShift(greenMask); int green_factor = green_mask + 1; int blue_mask = findMask(blueMask); int blue_shift = findShift(blueMask); int blue_factor = blue_mask + 1; byte bdata[] = new byte[width * height * 3]; // Padding bytes at the end of each scanline int padding = 0; if (!is32) { // width * bitsPerPixel should be divisible by 32 int bitsPerScanline = width * 16; if ( bitsPerScanline%32 != 0) { padding = (bitsPerScanline/32 + 1)*32 - bitsPerScanline; padding = (int)Math.ceil(padding/8.0); } } int imSize = (int)imageSize; if (imSize == 0) { imSize = (int)(bitmapFileSize - bitmapOffset); } int l=0; int v; if (isBottomUp) { for (int i=height - 1; i >= 0; --i) { l = width * 3 * i; for (int j=0; j<width; j++) { if (is32) v = (int)readDWord(inputStream); else v = readWord(inputStream); bdata[l++] = (byte)(((v >>> red_shift) & red_mask) * 256 / red_factor); bdata[l++] = (byte)(((v >>> green_shift) & green_mask) * 256 / green_factor); bdata[l++] = (byte)(((v >>> blue_shift) & blue_mask) * 256 / blue_factor); } for (int m=0; m<padding; m++) { inputStream.read(); } } } else { for (int i=0; i<height; i++) { for (int j=0; j<width; j++) { if (is32) v = (int)readDWord(inputStream); else v = readWord(inputStream); bdata[l++] = (byte)(((v >>> red_shift) & red_mask) * 256 / red_factor); bdata[l++] = (byte)(((v >>> green_shift) & green_mask) * 256 / green_factor); bdata[l++] = (byte)(((v >>> blue_shift) & blue_mask) * 256 / blue_factor); } for (int m=0; m<padding; m++) { inputStream.read(); } } } return new ImgRaw(width, height, 3, 8, bdata); } private Image readRLE8() throws IOException, BadElementException { // If imageSize field is not provided, calculate it. int imSize = (int)imageSize; if (imSize == 0) { imSize = (int)(bitmapFileSize - bitmapOffset); } // Read till we have the whole image byte values[] = new byte[imSize]; int bytesRead = 0; while (bytesRead < imSize) { bytesRead += inputStream.read(values, bytesRead, imSize - bytesRead); } // Since data is compressed, decompress it byte val[] = decodeRLE(true, values); // Uncompressed data does not have any padding imSize = width * height; if (isBottomUp) { // Convert the bottom up image to a top down format by copying // one scanline from the bottom to the top at a time. // int bytesPerScanline = (int)Math.ceil((double)width/8.0); byte temp[] = new byte[val.length]; int bytesPerScanline = width; for (int i=0; i<height; i++) { System.arraycopy(val, imSize - (i+1)*(bytesPerScanline), temp, i*bytesPerScanline, bytesPerScanline); } val = temp; } return indexedModel(val, 8, 4); } private Image readRLE4() throws IOException, BadElementException { // If imageSize field is not specified, calculate it. int imSize = (int)imageSize; if (imSize == 0) { imSize = (int)(bitmapFileSize - bitmapOffset); } // Read till we have the whole image byte values[] = new byte[imSize]; int bytesRead = 0; while (bytesRead < imSize) { bytesRead += inputStream.read(values, bytesRead, imSize - bytesRead); } // Decompress the RLE4 compressed data. byte val[] = decodeRLE(false, values); // Invert it as it is bottom up format. if (isBottomUp) { byte inverted[] = val; val = new byte[width * height]; int l = 0, index, lineEnd; for (int i = height-1; i >= 0; i--) { index = i * width; lineEnd = l + width; while(l != lineEnd) { val[l++] = inverted[index++]; } } } int stride = ((width + 1) / 2); byte bdata[] = new byte[stride * height]; int ptr = 0; int sh = 0; for (int h = 0; h < height; ++h) { for (int w = 0; w < width; ++w) { if ((w & 1) == 0) bdata[sh + w / 2] = (byte)(val[ptr++] << 4); else bdata[sh + w / 2] |= (byte)(val[ptr++] & 0x0f); } sh += stride; } return indexedModel(bdata, 4, 4); } private byte[] decodeRLE(boolean is8, byte values[]) { byte val[] = new byte[width * height]; try { int ptr = 0; int x = 0; int q = 0; for (int y = 0; y < height && ptr < values.length;) { int count = values[ptr++] & 0xff; if (count != 0) { // encoded mode int bt = values[ptr++] & 0xff; if (is8) { for (int i = count; i != 0; --i) { val[q++] = (byte)bt; } } else { for (int i = 0; i < count; ++i) { val[q++] = (byte)((i & 1) == 1 ? (bt & 0x0f) : ((bt >>> 4) & 0x0f)); } } x += count; } else { // escape mode count = values[ptr++] & 0xff; if (count == 1) break; switch (count) { case 0: x = 0; ++y; q = y * width; break; case 2: // delta mode x += values[ptr++] & 0xff; y += values[ptr++] & 0xff; q = y * width + x; break; default: // absolute mode if (is8) { for (int i = count; i != 0; --i) val[q++] = (byte)(values[ptr++] & 0xff); } else { int bt = 0; for (int i = 0; i < count; ++i) { if ((i & 1) == 0) bt = values[ptr++] & 0xff; val[q++] = (byte)((i & 1) == 1 ? (bt & 0x0f) : ((bt >>> 4) & 0x0f)); } } x += count; // read pad byte if (is8) { if ((count & 1) == 1) ++ptr; } else { if ((count & 3) == 1 || (count & 3) == 2) ++ptr; } break; } } } } catch (RuntimeException e) { //empty on purpose } return val; } // Windows defined data type reading methods - everything is little endian // Unsigned 8 bits private int readUnsignedByte(InputStream stream) throws IOException { return (stream.read() & 0xff); } // Unsigned 2 bytes private int readUnsignedShort(InputStream stream) throws IOException { int b1 = readUnsignedByte(stream); int b2 = readUnsignedByte(stream); return ((b2 << 8) | b1) & 0xffff; } // Signed 16 bits private int readShort(InputStream stream) throws IOException { int b1 = readUnsignedByte(stream); int b2 = readUnsignedByte(stream); return (b2 << 8) | b1; } // Unsigned 16 bits private int readWord(InputStream stream) throws IOException { return readUnsignedShort(stream); } // Unsigned 4 bytes private long readUnsignedInt(InputStream stream) throws IOException { int b1 = readUnsignedByte(stream); int b2 = readUnsignedByte(stream); int b3 = readUnsignedByte(stream); int b4 = readUnsignedByte(stream); long l = (b4 << 24) | (b3 << 16) | (b2 << 8) | b1; return l & 0xffffffff; } // Signed 4 bytes private int readInt(InputStream stream) throws IOException { int b1 = readUnsignedByte(stream); int b2 = readUnsignedByte(stream); int b3 = readUnsignedByte(stream); int b4 = readUnsignedByte(stream); return (b4 << 24) | (b3 << 16) | (b2 << 8) | b1; } // Unsigned 4 bytes private long readDWord(InputStream stream) throws IOException { return readUnsignedInt(stream); } // 32 bit signed value private int readLong(InputStream stream) throws IOException { return readInt(stream); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -