Ejemplo n.º 1
0
  /**
   * @param width width of the to be converted pixel rectangle
   * @param height height of the to be converted pixel rectangle
   * @param src_bb {@link ByteBuffer} source
   * @param src_fmt source {@link PixelFormat}
   * @param src_glOriented if true, the source memory is laid out in OpenGL's coordinate system,
   *     <i>origin at bottom left</i>, otherwise <i>origin at top left</i>.
   * @param src_lineStride line stride in byte-size for source, i.e. byte count from one line to the
   *     next. Must be >= {@link PixelFormat.Composition#bytesPerPixel()
   *     src_fmt.comp.bytesPerPixel()} * width or {@code zero} for default stride.
   * @param dst_bb {@link ByteBuffer} sink
   * @param dst_fmt destination {@link PixelFormat}
   * @param dst_glOriented if true, the source memory is laid out in OpenGL's coordinate system,
   *     <i>origin at bottom left</i>, otherwise <i>origin at top left</i>.
   * @param dst_lineStride line stride in byte-size for destination, i.e. byte count from one line
   *     to the next. Must be >= {@link PixelFormat.Composition#bytesPerPixel()
   *     dst_fmt.comp.bytesPerPixel()} * width or {@code zero} for default stride.
   * @throws IllegalStateException
   * @throws IllegalArgumentException if {@code src_lineStride} or {@code dst_lineStride} is invalid
   */
  public static void convert(
      final int width,
      final int height,
      final ByteBuffer src_bb,
      final PixelFormat src_fmt,
      final boolean src_glOriented,
      int src_lineStride,
      final ByteBuffer dst_bb,
      final PixelFormat dst_fmt,
      final boolean dst_glOriented,
      int dst_lineStride)
      throws IllegalStateException, IllegalArgumentException {
    final PixelFormat.Composition src_comp = src_fmt.comp;
    final PixelFormat.Composition dst_comp = dst_fmt.comp;
    final int src_bpp = src_comp.bytesPerPixel();
    final int dst_bpp = dst_comp.bytesPerPixel();

    if (0 != src_lineStride) {
      if (src_lineStride < src_bpp * width) {
        throw new IllegalArgumentException(
            String.format(
                "Invalid %s stride %d, must be greater than bytesPerPixel %d * width %d",
                "source", src_lineStride, src_bpp, width));
      }
    } else {
      src_lineStride = src_bpp * width;
    }
    if (0 != dst_lineStride) {
      if (dst_lineStride < dst_bpp * width) {
        throw new IllegalArgumentException(
            String.format(
                "Invalid %s stride %d, must be greater than bytesPerPixel %d * width %d",
                "destination", dst_lineStride, dst_bpp, width));
      }
    } else {
      dst_lineStride = dst_bpp * width;
    }

    // final int src_comp_bitStride = src_comp.bitStride();
    final int dst_comp_bitStride = dst_comp.bitStride();
    final boolean vert_flip = src_glOriented != dst_glOriented;
    final boolean fast_copy = src_comp.equals(dst_comp) && 0 == dst_comp_bitStride % 8;
    if (DEBUG) {
      System.err.println("XXX: size " + width + "x" + height + ", fast_copy " + fast_copy);
      System.err.println(
          "XXX: SRC fmt "
              + src_fmt
              + ", "
              + src_comp
              + ", stride "
              + src_lineStride
              + ", isGLOrient "
              + src_glOriented);
      System.err.println(
          "XXX: DST fmt "
              + dst_fmt
              + ", "
              + dst_comp
              + ", stride "
              + dst_lineStride
              + ", isGLOrient "
              + dst_glOriented);
    }

    if (fast_copy) {
      // Fast copy
      for (int y = 0; y < height; y++) {
        int src_off = vert_flip ? (height - 1 - y) * src_lineStride : y * src_lineStride;
        int dst_off = dst_lineStride * y;
        for (int x = 0; x < width; x++) {
          dst_bb.put(dst_off + 0, src_bb.get(src_off + 0)); // 1
          if (2 <= dst_bpp) {
            dst_bb.put(dst_off + 1, src_bb.get(src_off + 1)); // 2
            if (3 <= dst_bpp) {
              dst_bb.put(dst_off + 2, src_bb.get(src_off + 2)); // 3
              if (4 <= dst_bpp) {
                dst_bb.put(dst_off + 3, src_bb.get(src_off + 3)); // 4
              }
            }
          }
          src_off += src_bpp;
          dst_off += dst_bpp;
        }
      }
    } else {
      // Conversion
      final ComponentMap cmap = new ComponentMap(src_fmt.comp, dst_fmt.comp);

      final Bitstream.ByteBufferStream srcBBS = new Bitstream.ByteBufferStream(src_bb);
      final Bitstream<ByteBuffer> srcBitStream =
          new Bitstream<ByteBuffer>(srcBBS, false /* outputMode */);
      srcBitStream.setThrowIOExceptionOnEOF(true);

      final Bitstream.ByteBufferStream dstBBS = new Bitstream.ByteBufferStream(dst_bb);
      final Bitstream<ByteBuffer> dstBitStream =
          new Bitstream<ByteBuffer>(dstBBS, true /* outputMode */);
      dstBitStream.setThrowIOExceptionOnEOF(true);

      if (DEBUG) {
        System.err.println("XXX: cmap.dst2src " + Arrays.toString(cmap.dst2src));
        System.err.println("XXX: cmap.src2dst " + Arrays.toString(cmap.src2dst));
        System.err.println("XXX: cmap.srcRGBA " + Arrays.toString(cmap.srcRGBA));
        System.err.println("XXX: srcBitStream " + srcBitStream);
        System.err.println("XXX: dstBitStream " + dstBitStream);
      }
      try {
        for (int y = 0; y < height; y++) {
          final int src_off =
              vert_flip ? (height - 1 - y) * src_lineStride * 8 : y * src_lineStride * 8;
          // final int dst_off = dst_lineStride*8*y;
          srcBitStream.position(src_off);
          for (int x = 0; x < width; x++) {
            convert(cmap, dst_comp, dstBitStream, src_comp, srcBitStream);
          }
          // srcBitStream.skip(( src_lineStride * 8 ) - ( src_comp_bitStride * width ));
          dstBitStream.skip((dst_lineStride * 8) - (dst_comp_bitStride * width));
        }
      } catch (final IOException ioe) {
        throw new RuntimeException(ioe);
      }
      if (DEBUG) {
        System.err.println("XXX: srcBitStream " + srcBitStream);
        System.err.println("XXX: dstBitStream " + dstBitStream);
      }
    }
  }