JavaCPP Presets for libdc1394 - Java bindings for controlling IEEE 1394 (FireWire) digital cameras following IIDC/DCAM specifications
—
Built-in image format conversion including Bayer pattern demosaicing, color space conversion, and stereo processing for libdc1394.
Converts raw Bayer pattern images to RGB color images using various interpolation algorithms.
/**
* Demosaics 8-bit Bayer pattern data to RGB
* @param bayer Input Bayer pattern data
* @param rgb Output RGB data buffer (3x size of input)
* @param sx Image width in pixels
* @param sy Image height in pixels
* @param tile Bayer tile pattern (DC1394_COLOR_FILTER_*)
* @param method Demosaicing method (DC1394_BAYER_METHOD_*)
* @return DC1394_SUCCESS on success, error code on failure
*/
int dc1394_bayer_decoding_8bit(BytePointer bayer, BytePointer rgb, int sx, int sy,
int tile, int method);
/**
* Demosaics 16-bit Bayer pattern data to RGB
* @param bayer Input 16-bit Bayer pattern data
* @param rgb Output 16-bit RGB data buffer (3x size of input)
* @param sx Image width in pixels
* @param sy Image height in pixels
* @param tile Bayer tile pattern (DC1394_COLOR_FILTER_*)
* @param method Demosaicing method (DC1394_BAYER_METHOD_*)
* @param bits Actual bit depth of input data (8-16)
* @return DC1394_SUCCESS on success, error code on failure
*/
int dc1394_bayer_decoding_16bit(ShortPointer bayer, ShortPointer rgb, int sx, int sy,
int tile, int method, int bits);Usage Example:
import org.bytedeco.libdc1394.*;
import static org.bytedeco.libdc1394.global.dc1394.*;
import org.bytedeco.javacpp.*;
// Capture RAW frame and convert to RGB
dc1394video_frame_t frame = new dc1394video_frame_t(null);
dc1394_capture_dequeue(camera, DC1394_CAPTURE_POLICY_WAIT, frame);
if (frame.color_coding() == DC1394_COLOR_CODING_RAW8) {
int width = frame.size(0);
int height = frame.size(1);
// Allocate RGB output buffer (3x larger than input)
BytePointer rgbData = new BytePointer(width * height * 3);
// Perform Bayer demosaicing
int err = dc1394_bayer_decoding_8bit(
frame.image(), // Input Bayer data
rgbData, // Output RGB buffer
width, height, // Image dimensions
frame.color_filter(), // Bayer tile pattern
DC1394_BAYER_METHOD_BILINEAR // Demosaicing algorithm
);
if (err == DC1394_SUCCESS) {
System.out.println("Bayer demosaicing successful");
System.out.println("RGB data size: " + (width * height * 3) + " bytes");
// Use RGB data...
processRGBImage(rgbData, width, height);
}
rgbData.deallocate();
}
dc1394_capture_enqueue(camera, frame);High-level conversion functions that operate on complete frame structures.
/**
* Demosaics a complete video frame from Bayer to RGB
* @param in Input frame with Bayer data
* @param out Output frame for RGB data (must be pre-allocated)
* @param method Demosaicing method (DC1394_BAYER_METHOD_*)
* @return DC1394_SUCCESS on success, error code on failure
*/
int dc1394_debayer_frames(dc1394video_frame_t in, dc1394video_frame_t out, int method);
/**
* Converts between different color formats
* @param in Input frame
* @param out Output frame (must be pre-allocated with correct format)
* @return DC1394_SUCCESS on success, error code on failure
*/
int dc1394_convert_frames(dc1394video_frame_t in, dc1394video_frame_t out);Usage Example:
// High-level frame conversion
dc1394video_frame_t inputFrame = new dc1394video_frame_t(null);
dc1394video_frame_t outputFrame = new dc1394video_frame_t(null);
dc1394_capture_dequeue(camera, DC1394_CAPTURE_POLICY_WAIT, inputFrame);
if (inputFrame.color_coding() == DC1394_COLOR_CODING_RAW8) {
// Allocate output frame for RGB data
int width = inputFrame.size(0);
int height = inputFrame.size(1);
long rgbBytes = width * height * 3;
BytePointer rgbBuffer = new BytePointer(rgbBytes);
// Setup output frame structure
outputFrame.image(rgbBuffer);
outputFrame.total_bytes(rgbBytes);
outputFrame.image_bytes(rgbBytes);
outputFrame.size(0, width);
outputFrame.size(1, height);
outputFrame.color_coding(DC1394_COLOR_CODING_RGB8);
// Perform frame-based debayering
int err = dc1394_debayer_frames(inputFrame, outputFrame, DC1394_BAYER_METHOD_VNG);
if (err == DC1394_SUCCESS) {
System.out.println("Frame debayering completed");
}
rgbBuffer.deallocate();
}
dc1394_capture_enqueue(camera, inputFrame);Converts between different color formats (YUV, RGB, Monochrome).
/**
* Converts image data to YUV422 format
* @param src Source image data
* @param dest Destination buffer
* @param width Image width
* @param height Image height
* @param byte_order Byte order (DC1394_BYTE_ORDER_*)
* @param source_coding Source color coding
* @param bits Bit depth
* @return DC1394_SUCCESS on success, error code on failure
*/
int dc1394_convert_to_YUV422(BytePointer src, BytePointer dest, int width, int height,
int byte_order, int source_coding, int bits);
/**
* Converts image data to RGB8 format
* @param src Source image data
* @param dest Destination buffer
* @param width Image width
* @param height Image height
* @param byte_order Byte order
* @param source_coding Source color coding
* @param bits Bit depth
* @return DC1394_SUCCESS on success, error code on failure
*/
int dc1394_convert_to_RGB8(BytePointer src, BytePointer dest, int width, int height,
int byte_order, int source_coding, int bits);
/**
* Converts image data to MONO8 format
* @param src Source image data
* @param dest Destination buffer
* @param width Image width
* @param height Image height
* @param byte_order Byte order
* @param source_coding Source color coding
* @param bits Bit depth
* @return DC1394_SUCCESS on success, error code on failure
*/
int dc1394_convert_to_MONO8(BytePointer src, BytePointer dest, int width, int height,
int byte_order, int source_coding, int bits);Usage Example:
// Convert YUV422 to RGB8
dc1394video_frame_t frame = new dc1394video_frame_t(null);
dc1394_capture_dequeue(camera, DC1394_CAPTURE_POLICY_WAIT, frame);
if (frame.color_coding() == DC1394_COLOR_CODING_YUV422) {
int width = frame.size(0);
int height = frame.size(1);
// YUV422 uses 2 bytes per pixel, RGB8 uses 3
BytePointer rgbBuffer = new BytePointer(width * height * 3);
int err = dc1394_convert_to_RGB8(
frame.image(), // Source YUV422 data
rgbBuffer, // Destination RGB buffer
width, height, // Dimensions
DC1394_BYTE_ORDER_UYVY, // YUV byte order
DC1394_COLOR_CODING_YUV422, // Source format
8 // Bit depth
);
if (err == DC1394_SUCCESS) {
System.out.println("YUV422 to RGB8 conversion successful");
// Use RGB data...
}
rgbBuffer.deallocate();
}
dc1394_capture_enqueue(camera, frame);Processes stereo image pairs and deinterlaced stereo data.
/**
* Deinterlaces stereo image data (line-interleaved)
* @param src Source interleaved stereo data
* @param dest Destination buffers for left and right images
* @param width Image width
* @param height Total height (both images)
* @param bpp Bytes per pixel
* @return DC1394_SUCCESS on success, error code on failure
*/
int dc1394_deinterlace_stereo(BytePointer src, BytePointer dest, int width, int height, int bpp);
/**
* Deinterlaces stereo frame data
* @param in Input stereo frame
* @param out1 Output frame for first camera
* @param out2 Output frame for second camera
* @return DC1394_SUCCESS on success, error code on failure
*/
int dc1394_deinterlace_stereo_frames(dc1394video_frame_t in, dc1394video_frame_t out1,
dc1394video_frame_t out2);Direct color space conversion functions for custom processing.
/**
* Converts YUV to RGB (inline function)
* @param y Y component
* @param u U component
* @param v V component
* @param r Output R component
* @param g Output G component
* @param b Output B component
*/
void YUV2RGB(int y, int u, int v, IntPointer r, IntPointer g, IntPointer b);
/**
* Converts RGB to YUV (inline function)
* @param r R component
* @param g G component
* @param b B component
* @param y Output Y component
* @param u Output U component
* @param v Output V component
*/
void RGB2YUV(int r, int g, int b, IntPointer y, IntPointer u, IntPointer v);// Quality vs speed tradeoff methods
static final int DC1394_BAYER_METHOD_NEAREST = 0; // Fastest, lowest quality
static final int DC1394_BAYER_METHOD_SIMPLE = 1; // Simple interpolation
static final int DC1394_BAYER_METHOD_BILINEAR = 2; // Good quality/speed balance
static final int DC1394_BAYER_METHOD_HQLINEAR = 3; // High-quality linear
static final int DC1394_BAYER_METHOD_DOWNSAMPLE = 4; // Downsample for speed
static final int DC1394_BAYER_METHOD_EDGESENSE = 5; // Edge-aware interpolation
static final int DC1394_BAYER_METHOD_VNG = 6; // Variable Number of Gradients (high quality)
static final int DC1394_BAYER_METHOD_AHD = 7; // Adaptive Homogeneity-Directed (best quality)
// Method range
static final int DC1394_BAYER_METHOD_MIN = DC1394_BAYER_METHOD_NEAREST;
static final int DC1394_BAYER_METHOD_MAX = DC1394_BAYER_METHOD_AHD;
static final int DC1394_BAYER_METHOD_NUM = (DC1394_BAYER_METHOD_MAX - DC1394_BAYER_METHOD_MIN + 1);// Bayer color filter arrangements
static final int DC1394_COLOR_FILTER_RGGB = 512; // Red-Green-Green-Blue
static final int DC1394_COLOR_FILTER_GBRG = 513; // Green-Blue-Red-Green
static final int DC1394_COLOR_FILTER_GRBG = 514; // Green-Red-Blue-Green
static final int DC1394_COLOR_FILTER_BGGR = 515; // Blue-Green-Green-Red
// Color filter range
static final int DC1394_COLOR_FILTER_MIN = DC1394_COLOR_FILTER_RGGB;
static final int DC1394_COLOR_FILTER_MAX = DC1394_COLOR_FILTER_BGGR;
static final int DC1394_COLOR_FILTER_NUM = (DC1394_COLOR_FILTER_MAX - DC1394_COLOR_FILTER_MIN + 1);// YUV byte ordering
static final int DC1394_BYTE_ORDER_UYVY = 800; // U-Y-V-Y ordering
static final int DC1394_BYTE_ORDER_YUYV = 801; // Y-U-Y-V ordering
// General byte order
static final int DC1394_LITTLE_ENDIAN = 802; // Little endian byte order
static final int DC1394_BIG_ENDIAN = 803; // Big endian byte order// Algorithm selection based on application needs
int selectBayerMethod(String application) {
switch (application) {
case "realtime":
return DC1394_BAYER_METHOD_BILINEAR; // Good speed/quality balance
case "preview":
return DC1394_BAYER_METHOD_SIMPLE; // Fast preview
case "scientific":
return DC1394_BAYER_METHOD_AHD; // Best quality
case "mobile":
return DC1394_BAYER_METHOD_NEAREST; // Fastest for mobile
case "photography":
return DC1394_BAYER_METHOD_VNG; // High quality
default:
return DC1394_BAYER_METHOD_BILINEAR; // Default choice
}
}// Complete RAW image processing workflow
void processRAWImage(dc1394video_frame_t rawFrame) {
if (rawFrame.color_coding() != DC1394_COLOR_CODING_RAW8) {
System.err.println("Frame is not RAW format");
return;
}
int width = rawFrame.size(0);
int height = rawFrame.size(1);
// Step 1: Demosaic Bayer pattern to RGB
BytePointer rgbData = new BytePointer(width * height * 3);
int err = dc1394_bayer_decoding_8bit(
rawFrame.image(),
rgbData,
width, height,
rawFrame.color_filter(),
DC1394_BAYER_METHOD_VNG // High quality
);
if (err != DC1394_SUCCESS) {
System.err.println("Bayer demosaicing failed: " + err);
rgbData.deallocate();
return;
}
System.out.println("RAW processing completed:");
System.out.println(" Input: " + width + "x" + height + " RAW8");
System.out.println(" Output: " + width + "x" + height + " RGB8");
System.out.println(" Algorithm: VNG");
System.out.println(" Bayer pattern: " + getBayerPatternName(rawFrame.color_filter()));
// Step 2: Additional processing (optional)
// - White balance correction
// - Gamma correction
// - Color space conversion
// - Noise reduction
// Step 3: Save or display result
saveRGBImage(rgbData, width, height, "output.ppm");
rgbData.deallocate();
}
String getBayerPatternName(int pattern) {
switch (pattern) {
case DC1394_COLOR_FILTER_RGGB: return "RGGB";
case DC1394_COLOR_FILTER_GBRG: return "GBRG";
case DC1394_COLOR_FILTER_GRBG: return "GRBG";
case DC1394_COLOR_FILTER_BGGR: return "BGGR";
default: return "Unknown";
}
}// Convert any supported format to RGB8
BytePointer convertToRGB8(dc1394video_frame_t frame) {
int width = frame.size(0);
int height = frame.size(1);
int colorCoding = frame.color_coding();
BytePointer rgbBuffer = new BytePointer(width * height * 3);
switch (colorCoding) {
case DC1394_COLOR_CODING_RGB8:
// Already RGB8, direct copy
frame.image().get(rgbBuffer.asBuffer());
break;
case DC1394_COLOR_CODING_RAW8:
// Demosaic Bayer pattern
dc1394_bayer_decoding_8bit(frame.image(), rgbBuffer,
width, height,
frame.color_filter(),
DC1394_BAYER_METHOD_BILINEAR);
break;
case DC1394_COLOR_CODING_YUV422:
// Convert YUV to RGB
dc1394_convert_to_RGB8(frame.image(), rgbBuffer,
width, height,
DC1394_BYTE_ORDER_UYVY,
colorCoding, 8);
break;
case DC1394_COLOR_CODING_MONO8:
// Convert monochrome to RGB (replicate channels)
convertMono8ToRGB8(frame.image(), rgbBuffer, width, height);
break;
default:
System.err.println("Unsupported color format: " + colorCoding);
rgbBuffer.deallocate();
return null;
}
return rgbBuffer;
}
void convertMono8ToRGB8(BytePointer mono, BytePointer rgb, int width, int height) {
int pixels = width * height;
for (int i = 0; i < pixels; i++) {
byte value = mono.get(i);
rgb.put(i * 3, value); // R
rgb.put(i * 3 + 1, value); // G
rgb.put(i * 3 + 2, value); // B
}
}// Optimized conversion with memory reuse
class ImageConverter {
private BytePointer rgbBuffer;
private BytePointer tempBuffer;
private int bufferWidth = 0;
private int bufferHeight = 0;
public BytePointer convertFrame(dc1394video_frame_t frame) {
int width = frame.size(0);
int height = frame.size(1);
// Reallocate buffers only if size changed
if (width != bufferWidth || height != bufferHeight) {
deallocateBuffers();
allocateBuffers(width, height);
}
// Perform conversion using pre-allocated buffers
switch (frame.color_coding()) {
case DC1394_COLOR_CODING_RAW8:
dc1394_bayer_decoding_8bit(frame.image(), rgbBuffer,
width, height,
frame.color_filter(),
DC1394_BAYER_METHOD_BILINEAR);
break;
case DC1394_COLOR_CODING_YUV422:
dc1394_convert_to_RGB8(frame.image(), rgbBuffer,
width, height,
DC1394_BYTE_ORDER_UYVY,
frame.color_coding(), 8);
break;
// ... other formats
}
return rgbBuffer;
}
private void allocateBuffers(int width, int height) {
rgbBuffer = new BytePointer(width * height * 3);
tempBuffer = new BytePointer(width * height * 4); // For intermediate conversions
bufferWidth = width;
bufferHeight = height;
}
private void deallocateBuffers() {
if (rgbBuffer != null) {
rgbBuffer.deallocate();
rgbBuffer = null;
}
if (tempBuffer != null) {
tempBuffer.deallocate();
tempBuffer = null;
}
}
public void cleanup() {
deallocateBuffers();
}
}// Validate conversion parameters
boolean validateConversionParams(dc1394video_frame_t frame, int method) {
// Check frame validity
if (frame.image() == null || frame.total_bytes() == 0) {
System.err.println("Invalid frame data");
return false;
}
// Check color coding support
int coding = frame.color_coding();
if (coding != DC1394_COLOR_CODING_RAW8 &&
coding != DC1394_COLOR_CODING_RAW16 &&
coding != DC1394_COLOR_CODING_YUV422 &&
coding != DC1394_COLOR_CODING_RGB8) {
System.err.println("Unsupported color coding: " + coding);
return false;
}
// Check method validity
if (method < DC1394_BAYER_METHOD_MIN || method > DC1394_BAYER_METHOD_MAX) {
System.err.println("Invalid Bayer method: " + method);
return false;
}
// Check dimensions
if (frame.size(0) <= 0 || frame.size(1) <= 0) {
System.err.println("Invalid frame dimensions");
return false;
}
return true;
}Install with Tessl CLI
npx tessl i tessl/maven-org-bytedeco--libdc1394