001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.util; 006 007import java.nio.ByteBuffer; 008 009/** 010 * Class for storing raw frame data between image read call. 011 * 012 * <p>Data is reused for each frame read, rather then reallocating every frame. 013 */ 014public class RawFrame implements AutoCloseable { 015 private long m_nativeObj; 016 private ByteBuffer m_data; 017 private int m_width; 018 private int m_height; 019 private int m_stride; 020 private PixelFormat m_pixelFormat = PixelFormat.kUnknown; 021 022 /** Construct a new empty RawFrame. */ 023 public RawFrame() { 024 m_nativeObj = WPIUtilJNI.allocateRawFrame(); 025 } 026 027 /** 028 * Close the RawFrame, releasing native resources. Any images currently using the data will be 029 * invalidated. 030 */ 031 @Override 032 public void close() { 033 WPIUtilJNI.freeRawFrame(m_nativeObj); 034 m_nativeObj = 0; 035 } 036 037 /** 038 * Called from JNI to set data in class. 039 * 040 * @param data A native ByteBuffer pointing to the frame data. 041 * @param width The width of the frame, in pixels 042 * @param height The height of the frame, in pixels 043 * @param stride The number of bytes in each row of image data 044 * @param pixelFormat The PixelFormat of the frame 045 */ 046 void setDataJNI(ByteBuffer data, int width, int height, int stride, int pixelFormat) { 047 m_data = data; 048 m_width = width; 049 m_height = height; 050 m_stride = stride; 051 m_pixelFormat = PixelFormat.getFromInt(pixelFormat); 052 } 053 054 /** 055 * Called from JNI to set info in class. 056 * 057 * @param width The width of the frame, in pixels 058 * @param height The height of the frame, in pixels 059 * @param stride The number of bytes in each row of image data 060 * @param pixelFormat The PixelFormat of the frame 061 */ 062 void setInfoJNI(int width, int height, int stride, int pixelFormat) { 063 m_width = width; 064 m_height = height; 065 m_stride = stride; 066 m_pixelFormat = PixelFormat.getFromInt(pixelFormat); 067 } 068 069 /** 070 * Set frame data. 071 * 072 * @param data A native ByteBuffer pointing to the frame data. 073 * @param width The width of the frame, in pixels 074 * @param height The height of the frame, in pixels 075 * @param stride The number of bytes in each row of image data 076 * @param pixelFormat The PixelFormat of the frame 077 */ 078 public void setData(ByteBuffer data, int width, int height, int stride, PixelFormat pixelFormat) { 079 if (!data.isDirect()) { 080 throw new UnsupportedOperationException("ByteBuffer must be direct"); 081 } 082 m_data = data; 083 m_width = width; 084 m_height = height; 085 m_stride = stride; 086 m_pixelFormat = pixelFormat; 087 WPIUtilJNI.setRawFrameData( 088 m_nativeObj, data, data.limit(), width, height, stride, pixelFormat.getValue()); 089 } 090 091 /** 092 * Call to set frame information. 093 * 094 * @param width The width of the frame, in pixels 095 * @param height The height of the frame, in pixels 096 * @param stride The number of bytes in each row of image data 097 * @param pixelFormat The PixelFormat of the frame 098 */ 099 public void setInfo(int width, int height, int stride, PixelFormat pixelFormat) { 100 m_width = width; 101 m_height = height; 102 m_stride = stride; 103 m_pixelFormat = pixelFormat; 104 WPIUtilJNI.setRawFrameInfo( 105 m_nativeObj, 106 m_data != null ? m_data.limit() : 0, 107 width, 108 height, 109 stride, 110 pixelFormat.getValue()); 111 } 112 113 /** 114 * Get the pointer to native representation of this frame. 115 * 116 * @return The pointer to native representation of this frame. 117 */ 118 public long getNativeObj() { 119 return m_nativeObj; 120 } 121 122 /** 123 * Get a ByteBuffer pointing to the frame data. This ByteBuffer is backed by the frame directly. 124 * Its lifetime is controlled by the frame. If a new frame gets read, it will overwrite the 125 * current one. 126 * 127 * @return A ByteBuffer pointing to the frame data. 128 */ 129 public ByteBuffer getData() { 130 return m_data; 131 } 132 133 /** 134 * Get a long (is a uint8_t* in native code) pointing to the frame data. This pointer is backed by 135 * the frame directly. Its lifetime is controlled by the frame. If a new frame gets read, it will 136 * overwrite the current one. 137 * 138 * @return A long pointing to the frame data. 139 */ 140 public long getDataPtr() { 141 return WPIUtilJNI.getRawFrameDataPtr(m_nativeObj); 142 } 143 144 /** 145 * Get the total size of the data stored in the frame, in bytes. 146 * 147 * @return The total size of the data stored in the frame. 148 */ 149 public int getSize() { 150 return m_data != null ? m_data.limit() : 0; 151 } 152 153 /** 154 * Get the width of the image. 155 * 156 * @return The width of the image, in pixels. 157 */ 158 public int getWidth() { 159 return m_width; 160 } 161 162 /** 163 * Get the height of the image. 164 * 165 * @return The height of the image, in pixels. 166 */ 167 public int getHeight() { 168 return m_height; 169 } 170 171 /** 172 * Get the number of bytes in each row of image data. 173 * 174 * @return The image data stride, in bytes. 175 */ 176 public int getStride() { 177 return m_stride; 178 } 179 180 /** 181 * Get the PixelFormat of the frame. 182 * 183 * @return The PixelFormat of the frame. 184 */ 185 public PixelFormat getPixelFormat() { 186 return m_pixelFormat; 187 } 188}