blockdxt3compressor.java
来自「world wind java sdk 源码」· Java 代码 · 共 149 行
JAVA
149 行
/* Copyright (C) 2001, 2008 United States Government as represented bythe Administrator of the National Aeronautics and Space Administration.All Rights Reserved.*/package gov.nasa.worldwind.formats.dds;import gov.nasa.worldwind.util.Logging;/** * Compressor for DXT2/DXT3 alpha and color blocks. This class is not thread safe. Unsynchronized access will result in * unpredictable behavior. Acces to methods of this class must be synchronized by the caller. * <p> * Documentation on the DXT2/DXT3 format is available at http://msdn.microsoft.com/en-us/library/bb694531.aspx under * the name "BC2". * * @author dcollins * @version $Id: BlockDXT3Compressor.java 8991 2009-02-25 01:20:20Z dcollins $ */public class BlockDXT3Compressor{ // Implementation based on the NVidia Texture Tools // http://code.google.com/p/nvidia-texture-tools/ protected BlockDXT1Compressor dxt1Compressor; /** * Creates a new DXT2/DXT3 block compressor. */ public BlockDXT3Compressor() { this.dxt1Compressor = new BlockDXT1Compressor(); } /** * Compress the 4x4 color block into a DXT2/DXT3 block using 16 4 bit alpha values, and four colors. This method * compresses the color block exactly as a DXT1 compressor, except that it guarantees that the DXT1 block will use * four colors. * <p> * Access to this method must be synchronized by the caller. This method is frequenty invoked by the DXT * compressor, so in order to reduce garbage each instance of this class has unsynchronized properties that are * reused during each call. * * @param colorBlock the 4x4 color block to compress. * @param attributes attributes that will control the compression. * @param dxtBlock the DXT2/DXT3 block that will receive the compressed data. * * @throws IllegalArgumentException if either <code>colorBlock</code> or <code>dxtBlock</code> are null. */ public void compressBlockDXT3(ColorBlock4x4 colorBlock, DXTCompressionAttributes attributes, BlockDXT3 dxtBlock) { if (colorBlock == null) { String message = Logging.getMessage("nullValue.ColorBlockIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (attributes == null) { String message = Logging.getMessage("nullValue.AttributesIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (dxtBlock == null) { String message = Logging.getMessage("nullValue.DXTBlockIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } // The DXT3 color block is compressed exactly like the DXT1 color block, except that the four color palette is // always used, no matter the ordering of color0 and color1. At this stage we only consider color values, // not alpha. this.dxt1Compressor.compressBlockDXT1(colorBlock, attributes, dxtBlock.colorBlock); // The DXT3 alpha block can be compressed separately. this.compressBlockDXT3a(colorBlock, dxtBlock.alphaBlock); } protected void compressBlockDXT3a(ColorBlock4x4 colorBlock, AlphaBlockDXT3 dxtBlock) { dxtBlock.alphaValueMask = computeAlphaValueMask(colorBlock); } //**************************************************************// //******************** Alpha Block Assembly ******************// //**************************************************************// protected static long computeAlphaValueMask(ColorBlock4x4 colorBlock) { // Alpha is encoded as 4 bit values. Each pair of values will be packed into one byte. The first value goes // in bits 0-4, and the second value goes in bits 5-8. The resultant 64 bit value is structured so that when // converted to little endian ordering, the alpha values will be in the correct order. Here's what the // structure looks like packed into Java's long, where the value aN represents the Nth alpha value in // hexadecimal notation. // // | 63-56 | 55-48 | 47-40 | 39-32 | 31-24 | 23-16 | 15-8 | 7-0 | // | aFaE | aDaC | aBaA | a9a8 | a7a6 | a5a4 | a3a2 | a1a0 | long bitmask = 0L; for (int i = 0; i < 8; i++) { int a0 = 0xF & alpha4FromAlpha8(colorBlock.color[2 * i].a); int a1 = 0xF & alpha4FromAlpha8(colorBlock.color[2 * i + 1].a); long mask10 = (a1 << 4) | a0; bitmask |= (mask10 << (8 * i)); } return bitmask; } //**************************************************************// //******************** Alpha Arithmetic **********************// //**************************************************************// protected static int alpha4FromAlpha8(int alpha8) { // Quantizes an 8 bit alpha value into 4 bits. To reduce rounding error, this will compare the three nearest // 4 bit values and choose the closest one. int q0 = Math.max((alpha8 >> 4) - 1, 0); int q1 = (alpha8 >> 4); int q2 = Math.min((alpha8 >> 4) + 1, 0xF); q0 = (q0 << 4) | q0; q1 = (q1 << 4) | q1; q2 = (q2 << 4) | q2; int d0 = alphaDistanceSquared(q0, alpha8); int d1 = alphaDistanceSquared(q1, alpha8); int d2 = alphaDistanceSquared(q2, alpha8); if (d0 < d1 && d0 < d2) { return q0 >> 4; } if (d1 < d2) { return q1 >> 4; } return q2 >> 4; } protected static int alphaDistanceSquared(int a0, int a1) { return (a0 - a1) * (a0 - a1); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?