Package fcagnin.jglsdk.glimg

Source Code of fcagnin.jglsdk.glimg.ImageCreator$FaceIndexOutOfBoundsException

package fcagnin.jglsdk.glimg;

import java.util.ArrayList;
import java.util.Arrays;

import fcagnin.jglsdk.glimg.ImageFormat.PixelDataType;
import fcagnin.jglsdk.glimg.ImageSet.Dimensions;
import fcagnin.jglsdk.glimg.Util.CompressedBlockData;


/**
* Visit https://github.com/integeruser/jglsdk for project info, updates and license terms.
*
* @author integeruser
*/
class ImageCreator {
 
  ImageCreator(ImageFormat ddsFormat, Dimensions ddsDimensions, int mipmapCount, int arrayCount, int faceCount) {
    m_imageFormat = ddsFormat;
    m_imageDimensions = new Dimensions(ddsDimensions);
   
    m_mipmapCount = mipmapCount;
    m_arrayCount = arrayCount;
    m_faceCount = faceCount;

    if (faceCount != 6 && faceCount != 1) {
      throw new BadFaceCountException();
    }

    if (faceCount == 6 && ddsDimensions.numDimensions != 2) {
      throw new CubemapsMustBe2DException();
    }

    if (ddsDimensions.numDimensions == 3 && arrayCount != 1) {
      throw new No3DTextureArrayException();
    }

    if (mipmapCount <= 0 || arrayCount <= 0) {
      throw new NoImagesSpecifiedException();
    }
   
    m_imageData = new ArrayList<>(mipmapCount);
    m_imageSizes = new int[mipmapCount];
   
    // Allocate the memory for our data.
    for (int mipmapLevel = 0; mipmapLevel < mipmapCount; mipmapLevel++) {
      Dimensions mipmapLevelDimensions = Util.calcMipmapLevelDimensions(ddsDimensions, mipmapLevel);
     
      int mipmapLevelSize = Util.calcMipmapLevelSize(ddsFormat, mipmapLevelDimensions);
      m_imageSizes[mipmapLevel] = mipmapLevelSize;

      byte[] mipmapLevelData = new byte[mipmapLevelSize * faceCount * arrayCount];   
      m_imageData.add(mipmapLevelData);     
    }
  } 
 

 
  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

  void setImageData(byte sourceData[], boolean isTopLeft, int mipmapLevel, int arrayIx, int faceIx) {
     if (m_imageData.isEmpty()) {
      throw new ImageSetAlreadyCreatedException();
     }
     
    // Check inputs.
    if ((arrayIx < 0) || (m_arrayCount <= arrayIx)) {
      throw new ArrayIndexOutOfBoundsException();
    }
 
    if ((faceIx < 0) || (m_faceCount <= faceIx)) {
      throw new FaceIndexOutOfBoundsException();
    }

    if ((mipmapLevel < 0) || (m_mipmapCount <= mipmapLevel)) {
      throw new MipmapLayerOutOfBoundsException();
    }
   
    // Get the image relative to mipmapLevel
    byte[] imageData = m_imageData.get(mipmapLevel);
       
    if (!isTopLeft) {
      Util.throwNotYetPortedException();
    } else
      int imageDataOffset = ((arrayIx * m_faceCount) + faceIx) * m_imageSizes[mipmapLevel];
      copyImageFlipped(sourceData, imageData, imageDataOffset, mipmapLevel);
    }
  }


  ImageSet createImage() {
    if (m_imageData.isEmpty()) {
      throw new ImageSetAlreadyCreatedException();
    }
   
    return new ImageSet(m_imageFormat, m_imageDimensions,
        m_mipmapCount, m_arrayCount, m_faceCount,
        m_imageData, m_imageSizes);
 
 
 
 
  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */   
  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 
 
  private ImageFormat m_imageFormat;
  private Dimensions m_imageDimensions;
 
  private int m_mipmapCount;
  private int m_arrayCount;
  private int m_faceCount;
 
  private ArrayList<byte[]> m_imageData;
  private int[] m_imageSizes;
 
 
  private static class BadFaceCountException extends RuntimeException {
    private static final long serialVersionUID = -4120563516856357626L;
  }

  private static class CubemapsMustBe2DException extends RuntimeException {
    private static final long serialVersionUID = 4034128602806705190L;
  }

  private static class No3DTextureArrayException extends RuntimeException {
    private static final long serialVersionUID = -9001483779340494905L;
  }

  private static class NoImagesSpecifiedException extends RuntimeException {
    private static final long serialVersionUID = 3390815114957601365L;
  }

  private static class ImageSetAlreadyCreatedException extends RuntimeException {
    private static final long serialVersionUID = -7707381545866051896L;
  }

  private static class MipmapLayerOutOfBoundsException extends RuntimeException {
    private static final long serialVersionUID = 5160364349781356398L;
  }

  private static class FaceIndexOutOfBoundsException extends RuntimeException {
    private static final long serialVersionUID = 5885166000035279615L;
  }

 
 
  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

  private void copyImageFlipped(byte[] sourceData, byte[] imageData, int imageDataOffset, int mipmapLevel) {   
    assert (sourceData.length * m_faceCount * m_arrayCount) == imageData.length;
   
    Dimensions mipmapImageDimensions = Util.calcMipmapLevelDimensions(new Dimensions(m_imageDimensions), mipmapLevel);
   
    if (m_imageFormat.getPixelDataType().ordinal() < PixelDataType.NUM_UNCOMPRESSED_TYPES.ordinal()) {
      copyPixelsFlipped(m_imageFormat,
          sourceData, imageData, imageDataOffset,
          m_imageSizes[mipmapLevel], mipmapImageDimensions);
    } else {
      // Have to decode the pixel data and flip it manually.
      switch (m_imageFormat.getPixelDataType()) {
      case COMPRESSED_BC1:       
      case COMPRESSED_BC2:
      case COMPRESSED_BC3:
      case COMPRESSED_UNSIGNED_BC4:
      case COMPRESSED_SIGNED_BC4:
      case COMPRESSED_UNSIGNED_BC5:
      case COMPRESSED_SIGNED_BC5:
        copyBCFlipped(m_imageFormat,
            sourceData, imageData,imageDataOffset,
            m_imageSizes[mipmapLevel], mipmapImageDimensions, mipmapLevel);
        break;
       
      default:
        Util.throwNotYetPortedException();
      }
    }
  }
 
 
  private void copyPixelsFlipped(ImageFormat imageFormat,
      byte[] sourceData, byte[] imageData, int imageDataOffset,
      int imageSize, Dimensions imageDimensions) {
    // Flip the data. Copy line by line.
    final int numLines = imageDimensions.calcNumLines();
    final int lineSize = imageFormat.alignByteCount(Util.calcBytesPerPixel(imageFormat) * imageDimensions.width);

    // Flipped: start from last line of source, going backward
    int sourceLineOffset = imageSize - lineSize;      // start from last line
    int imageDataLineOffset = imageDataOffset;        // start from imageDataOffset
   
    for (int line = 0; line < numLines; line++) {   
      byte[] sourceLine = Arrays.copyOfRange(sourceData, sourceLineOffset, sourceLineOffset + lineSize);

      // Copy the source line into imageData
      System.arraycopy(sourceLine, 0, imageData, imageDataLineOffset, lineSize);
     
      // Update indices
      sourceLineOffset -= lineSize;
      imageDataLineOffset += lineSize;
    }
  }
 
 
  private void copyBCFlipped(ImageFormat imageFormat,
      byte[] sourceData, byte[] imageData, int imageDataOffset,
      int imageSize, Dimensions imageDimensions, int mipmapLevel) {
    // No support for 3D compressed formats.
    assert imageDimensions.numDimensions != 3 : "No support for 3D compressed formats.";

    CompressedBlockData blockData = Util.getBlockCompressionData(imageFormat.getPixelDataType());
    final int blocksPerLine = (imageDimensions.width + (blockData.dimensions.width - 1)) / blockData.dimensions.width;

    final int blockLineSize = blocksPerLine * blockData.byteCount;
    final int numTotalBlocks = imageSize / blockData.byteCount;
    final int numLines = numTotalBlocks / blocksPerLine;
   
    // Copy each block.
    int sourceBlockOffset = imageSize - blockLineSize;    // start from last block
    int imageDataBlockOffset = imageDataOffset;        // start from imageDataOffset
   
    for (int line = 0; line < numLines; ++line) {   
      for (int block = 0; block < blocksPerLine; ++block) {
        byte[] sourceBlock = Arrays.copyOfRange(sourceData, sourceBlockOffset, sourceBlockOffset + blockData.byteCount);
       
        flippingFunc(imageFormat, sourceBlock, imageData, imageDataBlockOffset);
       
        sourceBlockOffset += blockData.byteCount;
        imageDataBlockOffset += blockData.byteCount;
      }
           
      // First goes back to beginning, second goes back one row.
      sourceBlockOffset -= blockLineSize;
      sourceBlockOffset -= blockLineSize;
   
  }

  private void flippingFunc(ImageFormat imageFormat, byte[] sourceData, byte[] imageData, int imageDataOffset) {
    switch (m_imageFormat.getPixelDataType()) {
    case COMPRESSED_BC1:
      copyBlockBC1Flipped(sourceData, imageData, imageDataOffset);
      break;

    default:
      Util.throwNotYetPortedException();
   
  }

  private void copyBlockBC1Flipped(byte[] sourceData, byte[] imageData, int imageDataOffset) { 
    assert sourceData.length == 8;
   
    // First 4 bytes are 2 16-bit colors. Keep them the same.
    for (int i = 0; i < 4; i++) {
      imageData[imageDataOffset + i] = sourceData[i];
    }

    // Next four bytes are 16 2-bit values, in row-major, top-to-bottom order,
    // representing the 4x4 pixel data for the block. So copy the bytes in reverse order.
    imageData[imageDataOffset + 4] = sourceData[7];
    imageData[imageDataOffset + 5] = sourceData[6];
    imageData[imageDataOffset + 6] = sourceData[5];
    imageData[imageDataOffset + 7] = sourceData[4];
 
}
TOP

Related Classes of fcagnin.jglsdk.glimg.ImageCreator$FaceIndexOutOfBoundsException

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.