Esempio n. 1
0
  private BufferedImage decodeDxt3Buffer() {
    int numBlocksWide = width / BLOCK_SIZE;
    int numBlocksHigh = height / BLOCK_SIZE;

    // always at least 1x1 tile
    numBlocksWide = numBlocksWide < 1 ? 1 : numBlocksWide;
    numBlocksHigh = numBlocksHigh < 1 ? 1 : numBlocksHigh;

    int blockWidth = Math.min(width, BLOCK_SIZE);
    int blockHeight = Math.min(height, BLOCK_SIZE);

    int[] pixels = new int[blockWidth * blockHeight];

    BufferedImage delegate = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

    // One copy of table to minimises new calls
    Color24[] table = new Color24[4];
    table[0] = new Color24();
    table[1] = new Color24();
    table[2] = new Color24();
    table[3] = new Color24();

    for (int row = 0; row < numBlocksHigh; row++) {
      for (int col = 0; col < numBlocksWide; col++) {
        long alphaData = buffer.getLong();
        short minColor = buffer.getShort();
        short maxColor = buffer.getShort();
        int colorIndexMask = buffer.getInt();

        Color24[] lookupTable = Color24.expandLookupTable(table, minColor, maxColor);

        for (int br = 0; br < blockHeight; br++) {
          for (int bc = 0; bc < blockWidth; bc++) {
            int k = (br * blockWidth) + bc;
            int alpha = (int) (alphaData >>> (k * 4)) & 0xF; // Alphas are just 4 bits per pixel
            alpha <<= 4;

            int colorIndex = (colorIndexMask >>> k * 2) & 0x03;

            Color24 color = lookupTable[colorIndex];
            int pixel8888 = (alpha << 24) | color.pix888;

            // for yUp must flip it , so NOT pixels[br  * blockWidth + bc] = pixel8888;
            pixels[((blockHeight - 1) - br) * blockWidth + bc] = pixel8888;
          }
        }
        // notice vertical flipping there
        delegate.setRGB(
            col * blockWidth,
            (height - blockHeight) - (row * blockHeight),
            blockWidth,
            blockHeight,
            pixels,
            0,
            blockWidth);
      }
    }
    return delegate;
  }
Esempio n. 2
0
  private BufferedImage decompressRGBA_S3TC_DXT5_EXT() {
    int numBlocksWide = width / BLOCK_SIZE;
    int numBlocksHigh = height / BLOCK_SIZE;

    // always at least 1x1 tile
    numBlocksWide = numBlocksWide < 1 ? 1 : numBlocksWide;
    numBlocksHigh = numBlocksHigh < 1 ? 1 : numBlocksHigh;

    int blockWidth = Math.min(width, BLOCK_SIZE);
    int blockHeight = Math.min(height, BLOCK_SIZE);

    int[] pixels = new int[blockWidth * blockHeight];

    BufferedImage delegate = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

    // One copy of table to minimises new calls
    Color24[] table = new Color24[4];
    table[0] = new Color24();
    table[1] = new Color24();
    table[2] = new Color24();
    table[3] = new Color24();

    for (int row = 0; row < numBlocksHigh; row++) {
      for (int col = 0; col < numBlocksWide; col++) {
        int alpha0 = buffer.get() & 0xff; // unsigned byte
        int alpha1 = buffer.get() & 0xff; // unsigned byte

        // next 6 bytes are a look up list (note long casts, important!)
        long alphaBits =
            (buffer.get() & 0xffL) << 0L //
                | (buffer.get() & 0xffL) << 8L //
                | (buffer.get() & 0xffL) << 16L //
                | (buffer.get() & 0xffL) << 24L //
                | (buffer.get() & 0xffL) << 32L //
                | (buffer.get() & 0xffL) << 40L; //

        short minColor = buffer.getShort();
        short maxColor = buffer.getShort();
        int colorIndexMask = buffer.getInt();

        Color24[] lookupTable = Color24.expandLookupTable(table, minColor, maxColor);

        for (int br = 0; br < blockHeight; br++) {
          for (int bc = 0; bc < blockWidth; bc++) {
            int k = (br * blockWidth) + bc;

            int alphaCode = (int) (alphaBits >> (3 * k) & 0x07); // bottom 3 bits

            int alpha = 0;

            if (alphaCode == 0) {
              alpha = alpha0;
            } else if (alphaCode == 1) {
              alpha = alpha1;
            } else if (alpha0 > alpha1) {
              alpha = ((8 - alphaCode) * alpha0 + (alphaCode - 1) * alpha1) / 7;
            } else {
              if (alphaCode == 6) alpha = 0;
              else if (alphaCode == 7) alpha = 255;
              else alpha = ((6 - alphaCode) * alpha0 + (alphaCode - 1) * alpha1) / 5;
            }

            int colorIndex = (colorIndexMask >>> k * 2) & 0x03;

            Color24 color = lookupTable[colorIndex];
            int pixel8888 = (alpha << 24) | color.pix888;
            // for yUp must flip it , so NOT pixels[br  * blockWidth + bc] = pixel8888;
            pixels[((blockHeight - 1) - br) * blockWidth + bc] = pixel8888;
          }
        }
        // notice vertical flipping there
        delegate.setRGB(
            col * blockWidth,
            (height - blockHeight) - (row * blockHeight),
            blockWidth,
            blockHeight,
            pixels,
            0,
            blockWidth);
      }
    }

    return delegate;
  }
Esempio n. 3
0
  private BufferedImage decodeDxt1Buffer() {
    int numBlocksWide = width / BLOCK_SIZE;
    int numBlocksHigh = height / BLOCK_SIZE;

    // always at least 1x1 tile
    numBlocksWide = numBlocksWide < 1 ? 1 : numBlocksWide;
    numBlocksHigh = numBlocksHigh < 1 ? 1 : numBlocksHigh;

    int blockWidth = Math.min(width, BLOCK_SIZE);
    int blockHeight = Math.min(height, BLOCK_SIZE);

    int[] pixels = new int[blockWidth * blockHeight];

    BufferedImage delegate = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

    // One copy of table to minimises new calls
    Color24[] table = new Color24[4];
    table[0] = new Color24();
    table[1] = new Color24();
    table[2] = new Color24();
    table[3] = new Color24();

    for (int row = 0; row < numBlocksHigh; row++) {
      for (int col = 0; col < numBlocksWide; col++) {
        short c0 = buffer.getShort();
        short c1 = buffer.getShort();
        int colorIndexMask = buffer.getInt();

        // http://en.wikipedia.org/wiki/S3_Texture_Compression
        if (ignoreAlpha || !Color24.hasAlphaBit(c0, c1)) {
          Color24[] lookupTable = Color24.expandLookupTable(table, c0, c1);
          for (int br = 0; br < blockHeight; br++) {
            for (int bc = 0; bc < blockWidth; bc++) {
              int k = (br * blockWidth) + bc;
              int colorIndex = (colorIndexMask >>> k * 2) & 0x03;
              // for yUp must flip it so NOT pixels[br  * blockWidth + bc] = (0xFF << 24) |
              // lookupTable[colorIndex].pix888;
              pixels[((blockHeight - 1) - br) * blockWidth + bc] =
                  (0xFF << 24) | lookupTable[colorIndex].pix888;
            }
          }
        } else {
          Color24[] lookupTable = Color24.expandLookupTableAlphable(table, c0, c1);
          for (int br = 0; br < blockHeight; br++) {
            for (int bc = 0; bc < blockWidth; bc++) {
              int k = (br * blockWidth) + bc;
              int colorIndex = (colorIndexMask >>> k * 2) & 0x03;
              int alpha = (colorIndex == 3) ? 0x00 : 0xFF;
              // for yUp must flip it , so NOT pixels[br  * blockWidth + bc] = (alpha << 24) |
              // lookupTable[colorIndex].pix888;
              pixels[((blockHeight - 1) - br) * blockWidth + bc] =
                  (alpha << 24) | lookupTable[colorIndex].pix888;
            }
          }
        }

        delegate.setRGB(
            col * blockWidth,
            (height - blockHeight) - (row * blockHeight),
            blockWidth,
            blockHeight,
            pixels,
            0,
            blockWidth);
      }
    }
    return delegate;
  }