Пример #1
0
  public static void convert(
      final ComponentMap cmap,
      final PixelFormat.Composition dstComp,
      final Bitstream<ByteBuffer> dstBitStream,
      final PixelFormat.Composition srcComp,
      final Bitstream<ByteBuffer> srcBitStream)
      throws IllegalStateException, IOException {
    final int sCompCount = srcComp.componentCount();
    final int dCompCount = dstComp.componentCount();
    final int[] sc = new int[sCompCount];
    final int[] dcDef = new int[dCompCount];
    final int[] srcCompBitCount = srcComp.componentBitCount();
    final int[] srcCompBitMask = srcComp.componentBitMask();
    final int[] dstCompBitCount = dstComp.componentBitCount();

    // Fill w/ source values
    for (int sIdx = 0; sIdx < sCompCount; sIdx++) {
      sc[sIdx] = srcBitStream.readBits31(srcCompBitCount[sIdx]) & srcCompBitMask[sIdx];
    }
    srcBitStream.skip(srcComp.bitStride() - srcComp.bitsPerPixel());

    // Cache missing defaults
    for (int i = 0; i < dCompCount; i++) {
      dcDef[i] = dstComp.defaultValue(i, false);
    }

    if (1 == dCompCount && PixelFormat.CType.Y == dstComp.componentOrder()[0] && cmap.hasSrcRGB) {
      // RGB[A] -> Y conversion
      final int r = sc[cmap.srcRGBA[0]];
      final int g = sc[cmap.srcRGBA[1]];
      final int b = sc[cmap.srcRGBA[2]];
      final float rF = srcComp.toFloat(r, cmap.srcRGBA[0], false);
      final float gF = srcComp.toFloat(g, cmap.srcRGBA[1], false);
      final float bF = srcComp.toFloat(b, cmap.srcRGBA[2], false);
      final int a;
      final float aF;
      /**
       * if( 0 <= cmap.srcRGBA[3] ) { // disable premultiplied-alpha a = sc[cmap.srcRGBA[3]]; aF =
       * srcComp.toFloat(a, false, cmap.srcRGBA[3]); } else
       */
      {
        a = 1;
        aF = 1f;
      }
      final float lF = (rF + gF + bF) * aF / 3f;
      final int v = dstComp.fromFloat(lF, 0, false);

      dstBitStream.writeBits31(dstCompBitCount[0], v);
      dstBitStream.skip(dstComp.bitStride() - dstComp.bitsPerPixel());
      if (DEBUG) {
        if (srcBitStream.position() <= 8 * 4) {
          System.err.printf(
              "convert: rgb[a] -> Y: rgb 0x%02X 0x%02X 0x%02X 0x%02X -> %f %f %f %f"
                  + " -> %f -> dstC 0 0x%08X (%d bits: %s)%n",
              r,
              g,
              b,
              a,
              rF,
              gF,
              bF,
              aF,
              lF,
              v,
              dstCompBitCount[0],
              Bitstream.toBinString(true, v, dstCompBitCount[0]));
        }
      }
      return;
    }

    for (int dIdx = 0; dIdx < dCompCount; dIdx++) {
      int sIdx;
      if (0 <= (sIdx = cmap.dst2src[dIdx])) {
        final float f = srcComp.toFloat(sc[sIdx], sIdx, false);
        final int v = dstComp.fromFloat(f, dIdx, false);
        dstBitStream.writeBits31(dstCompBitCount[dIdx], v);
        if (DEBUG) {
          if (srcBitStream.position() <= 8 * 4) {
            System.err.printf(
                "convert: srcC %d: 0x%08X -> %f -> dstC %d 0x%08X (%d bits: %s)%n",
                sIdx,
                sc[sIdx],
                f,
                dIdx,
                v,
                dstCompBitCount[dIdx],
                Bitstream.toBinString(true, v, dstCompBitCount[dIdx]));
          }
        }
      } else {
        dstBitStream.writeBits31(dstCompBitCount[dIdx], dcDef[dIdx]);
        if (DEBUG) {
          if (srcBitStream.position() <= 8 * 4) {
            System.err.printf(
                "convert: srcC %d: undef -> dstC %d 0x%08X (%d bits: %s)%n",
                sIdx,
                dIdx,
                dcDef[dIdx],
                dstCompBitCount[dIdx],
                Bitstream.toBinString(true, dcDef[dIdx], dstCompBitCount[dIdx]));
          }
        }
      }
    }
    dstBitStream.skip(dstComp.bitStride() - dstComp.bitsPerPixel());
    return;
  }
Пример #2
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);
      }
    }
  }