default: assert (false);
}
int stride = frame.stride();
int size = frame.image_bytes();
int numChannels = stride/w*8/depth;
ByteOrder frameEndian = frame.little_endian() != 0 ?
ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN;
boolean alreadySwapped = false;
int color_coding = frame.color_coding();
boolean colorbayer = color_coding == DC1394_COLOR_CODING_RAW8 ||
color_coding == DC1394_COLOR_CODING_RAW16;
boolean colorrgb = color_coding == DC1394_COLOR_CODING_RGB8 ||
color_coding == DC1394_COLOR_CODING_RGB16;
boolean coloryuv = color_coding == DC1394_COLOR_CODING_YUV411 ||
color_coding == DC1394_COLOR_CODING_YUV422 ||
color_coding == DC1394_COLOR_CODING_YUV444;
BytePointer imageData = frame.image();
if ((depth <= 8 || frameEndian.equals(ByteOrder.nativeOrder())) && !coloryuv &&
(colorMode == ColorMode.RAW || (colorMode == ColorMode.BGR && numChannels == 3) ||
(colorMode == ColorMode.GRAY && numChannels == 1 && !colorbayer))) {
if (return_image == null) {
return_image = IplImage.createHeader(w, h, iplDepth, numChannels);
}
return_image.widthStep(stride);
return_image.imageSize(size);
return_image.imageData(imageData);
} else {
// in the padding, there's sometimes timeframe information and stuff
// that libdc1394 will copy for us, so we need to allocate it
int padding_bytes = frame.padding_bytes();
int padding1 = (int)Math.ceil((double)padding_bytes/(w * depth/8));
int padding3 = (int)Math.ceil((double)padding_bytes/(w*3*depth/8));
if (return_image == null) {
int c = colorMode == ColorMode.BGR ? 3 : 1;
int padding = colorMode == ColorMode.BGR ? padding3 : padding1;
return_image = IplImage.create(w, h+padding, iplDepth, c);
return_image.height(return_image.height() - padding);
}
if (temp_image == null) {
if (colorMode == ColorMode.BGR && numChannels != 3 && !colorbayer) {
temp_image = IplImage.create(w, h+padding1, iplDepth, 1);
temp_image.height(temp_image.height() - padding1);
} else if (colorMode == ColorMode.GRAY &&
(coloryuv || colorbayer || (colorrgb && depth > 8))) {
temp_image = IplImage.create(w, h+padding3, iplDepth, 3);
temp_image.height(temp_image.height() - padding3);
} else if (colorMode == ColorMode.GRAY && colorrgb) {
temp_image = IplImage.createHeader(w, h, iplDepth, 3);
temp_image.widthStep(stride);
temp_image.imageSize(size);
temp_image.imageData(imageData);
} else {
temp_image = return_image;
}
}
conv_image.size(0, temp_image.width());
conv_image.size(1, temp_image.height());
if (depth > 8) {
conv_image.color_coding(colorMode == ColorMode.RAW ? DC1394_COLOR_CODING_RAW16 :
temp_image.nChannels() == 1 ? DC1394_COLOR_CODING_MONO16 :
DC1394_COLOR_CODING_RGB16);
conv_image.data_depth(16);
} else {
conv_image.color_coding(colorMode == ColorMode.RAW ? DC1394_COLOR_CODING_RAW8 :
temp_image.nChannels() == 1 ? DC1394_COLOR_CODING_MONO8 :
DC1394_COLOR_CODING_RGB8);
conv_image.data_depth(8);
}
conv_image.stride(temp_image.widthStep());
int temp_size = temp_image.imageSize();
conv_image.allocated_image_bytes(temp_size).
total_bytes(temp_size).image_bytes(temp_size);
conv_image.image(temp_image.imageData());
if (colorbayer) {
// from raw Bayer... invert R and B to get BGR images
// (like OpenCV wants them) instead of RGB
int c = frame.color_filter();
if (c == DC1394_COLOR_FILTER_RGGB) {
frame.color_filter(DC1394_COLOR_FILTER_BGGR);
} else if (c == DC1394_COLOR_FILTER_GBRG) {
frame.color_filter(DC1394_COLOR_FILTER_GRBG);
} else if (c == DC1394_COLOR_FILTER_GRBG) {
frame.color_filter(DC1394_COLOR_FILTER_GBRG);
} else if (c == DC1394_COLOR_FILTER_BGGR) {
frame.color_filter(DC1394_COLOR_FILTER_RGGB);
} else {
assert(false);
}
// other better methods than "simple" give garbage at 16 bits..
err = dc1394_debayer_frames(frame, conv_image, DC1394_BAYER_METHOD_SIMPLE);
frame.color_filter(c);
if (err != DC1394_SUCCESS) {
throw new Exception("dc1394_debayer_frames() Error " + err + ": Could not debayer frame.");
}
} else if (depth > 8 &&
frame.data_depth() == conv_image.data_depth() &&
frame.color_coding() == conv_image.color_coding() &&
frame.stride() == conv_image.stride()) {
// we just need a copy to swap bytes..
ShortBuffer in = frame.getByteBuffer().order(frameEndian).asShortBuffer();
ShortBuffer out = temp_image.getByteBuffer().order(ByteOrder.nativeOrder()).asShortBuffer();
out.put(in);
alreadySwapped = true;
} else if (!colorrgb) {
// from YUV, etc.
err = dc1394_convert_frames(frame, conv_image);
if (err != DC1394_SUCCESS) {
throw new Exception("dc1394_convert_frames() Error " + err + ": Could not convert frame.");
}
}
}
if (!alreadySwapped && depth > 8 && !frameEndian.equals(ByteOrder.nativeOrder())) {
// ack, the camera's endianness doesn't correspond to our machine ...
// swap bytes of 16-bit images
ByteBuffer bb = temp_image.getByteBuffer();
ShortBuffer in = bb.order(frameEndian).asShortBuffer();
ShortBuffer out = bb.order(ByteOrder.nativeOrder()).asShortBuffer();