/******************************************************************************
*
* Copyright (c) 2017 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer.
*
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* OpenCVImage.h
*
*****************************************************************************/
#pragma once
#include <oz++/opencv/OpenCVObject.h>
#include <oz++/motif/DC.h>
#include <oz++/motif/Color.h>
using namespace cv;
using namespace std;
namespace OZ {
/*
Based on cxtypes.h
typedef struct _IplImage
{
int nSize; // sizeof(IplImage)
int ID; // version (=0)
int nChannels; // Most of OpenCV functions support 1,2,3 or 4 channels
int alphaChannel; // ignored by OpenCV
int depth; // pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
// IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported
char colorModel[4]; // ignored by OpenCV
char channelSeq[4]; // ditto
int dataOrder; // 0 - interleaved color channels,
// 1 - separate color channels.
// cvCreateImage can only create interleaved images
int origin; // 0 - top-left origin,
// 1 - bottom-left origin (Windows bitmaps style)
int align; // Alignment of image rows (4 or 8).
// OpenCV ignores it and uses widthStep instead
int width; // image width in pixels
int height; // image height in pixels
struct _IplROI *roi; // image ROI. if NULL, the whole image is selected
struct _IplImage *maskROI; // must be NULL
void *imageId; // ditto
struct _IplTileInfo *tileInfo; // ditto
int imageSize; // image data size in bytes
// (==image->height*image->widthStep
// in case of interleaved data
char *imageData; // pointer to aligned image data
int widthStep; // size of aligned image row in bytes
int BorderMode[4]; // ignored by OpenCV
int BorderConst[4]; // ditto
char *imageDataOrigin; // pointer to very origin of image data
// (not necessarily aligned) -
// needed for correct deallocation
}
IplImage;
*/
/*
typedef struct _XImage {
int width, height; // size of image
int xoffset; // number of pixels offset in X direction
int format; // XYBitmap, XYPixmap, ZPixmap
char *data; // pointer to image data
int byte_order; // data byte order, LSBFirst, MSBFirst
int bitmap_unit; // quant. of scanline 8, 16, 32
int bitmap_bit_order; // LSBFirst, MSBFirst
int bitmap_pad; // 8, 16, 32 either XY or ZPixmap
int depth; // depth of image
int bytes_per_line; // accelerator to next scanline
int bits_per_pixel; // bits per pixel (ZPixmap)
unsigned long red_mask; // bits in z arrangement
unsigned long green_mask;
unsigned long blue_mask;
XPointer obdata; // hook for the object routines to hang on
struct funcs { // image manipulation routines
struct _XImage *(*create_image)();
int (*destroy_image)();
unsigned long (*get_pixel)();
int (*put_pixel)();
struct _XImage *(*sub_image)();
int (*add_pixel)();
} f;
} XImage;
*/
class OpenCVImage :public OpenCVObject {
private:
cv::Mat image;
cv::Mat resizedImage;
XImage ximage;
static const int MAX_IMAGE_WIDTH = 640;
static const int MAX_IMAGE_HEIGHT = 480;
public:
OpenCVImage(Display* display,const char* filename, int loadflag=1)
{
memset(&ximage, 0, sizeof(ximage));
image = cv::imread(filename, loadflag);
if (image.empty()) {
throw IException("Failed to load file %s", filename);
}
int width = image.rows;
int height = image.cols;
float ratio = 1.0f;
//Width ratio
float wr = (float)MAX_IMAGE_WIDTH/(float)width;
//Height ratio
float hr = (float)MAX_IMAGE_HEIGHT/(float)height;
if (wr <1.0f || hr < 1.0f) {
if (wr < hr) {
ratio = wr;
} else {
ratio = hr;
}
}
//ratio = 0.8f;
cv::resize(image, resizedImage, cv::Size(), ratio, ratio);
IplImage iplimage = resizedImage;
convertToXImage(display, &iplimage);
}
int getByteOrder ()
{
union {
char c[sizeof(short)];
short s;
} order;
order.s = 1;
if ((1 == order.c[0])) {
return LSBFirst;
} else {
return MSBFirst;
}
}
void convertToXImage(Display* display, const IplImage* image)
{
//Check Iplimage depth field.
//Is the depth value 8?
assert(image->depth ==IPL_DEPTH_8U);
//XImage depth
unsigned int depth = image->depth*image->nChannels;
//The data field of XImage points the imageData
//field of IplImage structure.
//
int byte_order = getByteOrder();
ximage.width = image -> width;
ximage.height = image -> height;
ximage.xoffset = 0;
ximage.format = ZPixmap;
ximage.data = image->imageData;
//XImage data is a shallow copy of Iplimage data.
ximage.byte_order = byte_order;
ximage.bitmap_unit = 0; //24;
ximage.bitmap_bit_order = byte_order;
ximage.bitmap_pad = 8; //32;
ximage.depth = depth; //24;
ximage.bytes_per_line = image->widthStep;
ximage.bits_per_pixel = 24;
/*
ximage.red_mask = 0xffff; // bits in z arrangement
ximage.green_mask = 0xff00;
ximage.blue_mask = 0x0000;
*/
Status status = XInitImage(&ximage);
if (status == 0) {
throw IException("Failed to XInitImage");
}
}
void draw(DC& dc, int srcx, int srcy, int destx, int desty,
int width, int height)
{
//printf("%d %d %d %d %d %d\n", srcx, srcy, destx, desty,
// width, height);
if (ximage.data) {
Display* disp = dc.getDisplay();
GC gc = dc.getGC();
Drawable drawable = dc.getDrawable();
XPutImage(disp, drawable, gc, &ximage, srcx, srcy, destx, desty,
width, height);
}
}
};
}