#include #include #include "video.h" #include "config.h" #include "gui.h" #include "error.h" #include "convert.h" #include "videodev.h" VideoFrameRaw::VideoFrameRaw() { size = 0; data = NULL; w = 0; h = 0; pixfmt = 0x0; } VideoFrameRaw::~VideoFrameRaw() { if (data != NULL) { free (data); data = NULL; } } int VideoFrameRaw::CopyFrom(int spixfmt, int sw, int sh, int ssize, unsigned char *sdata) { if (size != ssize) { if (ReAlloc(ssize) != 0) { errorexit((char*) "%s:%d %s could not reallocate memory. Error:%s\n", __FILE__, __LINE__, __FUNCTION__, strerror(errno)); } } if (data == NULL) { errorexit((char*) "%s:%d %s invalid pointer of data. Error:%s\n", __FILE__, __LINE__, __FUNCTION__, strerror(errno)); } w = sw; h = sh; pixfmt = spixfmt; memcpy (data, sdata, size); return 1; } int VideoFrameRaw::CopyFrom(VideoFrameRaw *src) { if (src == NULL) return 0; return CopyFrom(src->pixfmt, src->w, src->h, src->size, src->data); } int VideoFrameRaw::CopyFrom(VideoFrame *src) { if (src == NULL) return 0; return CopyFrom(V4L2_PIX_FMT_RGB32, src->w, src->h, src->size, src->data); } int VideoFrameRaw::ReAlloc(int newsize) { unsigned char *newdata = NULL; if (newsize == 0) { free (data); data = NULL; size = newsize; return 0; } if (data == NULL) { if ((data = (unsigned char*) malloc (newsize)) == NULL) return -1; } else if (size < newsize || size > newsize) { if ((newdata = (unsigned char*) realloc (data, newsize)) == NULL) { free (data); size = 0; return -1; } data = newdata; } size = newsize; return 0; } int VideoFrameRaw::RectCopyFrom(VideoFrameRaw *src, int rectx, int recty, int rectw, int recth) { return PixCopy (src->data, src->pixfmt, src->w, src->h, &data, &size, &w, &h, rectx, recty, rectw, recth); } #define VIDEOFRAME_DEPTH_BYTES 3 VideoFrame::VideoFrame() { data = NULL; w = 0; h = 0; size = 0; }; VideoFrame::~VideoFrame() { if (data) { free (data); data = NULL; } w = 0; h = 0; size = 0; }; // // we will only allocate a new image if the needed size increases void VideoFrame::SetSize(int nw, int nh) { uint32_t newsize = VIDEOFRAME_DEPTH_BYTES * nh * nw; if (newsize > size || data == NULL) { unsigned char *newdata = (unsigned char *) malloc (newsize); if (data != NULL) free (data); data = newdata; size = newsize; } w = nw; h = nh; }; VideoFrame VideoFrame::operator=(VideoFrame rightside) { w = rightside.w; h = rightside.h; size = rightside.size; if (size > 0) data = (unsigned char *) malloc (rightside.size); if (rightside.data != NULL && size > 0) { memcpy (data, rightside.data, size); } return *this; } void VideoFrame::CopyFrom(VideoFrame *source) { SetSize (source->w, source->h); memcpy(data, source->data, VIDEOFRAME_DEPTH_BYTES * w * h); } void VideoFrame::CopyFrom(FloatImage *source) { float min, max, f; int x, y, i, idx; unsigned char v; SetSize (source->w, source->h); // find min max; min = source->data[0]; max = source->data[0]; for (y = 0; y < h; y++) for (x = 0; x < w; x++) for (i = 0; i < 3; i++) { idx = 3 * (y * w + x); if (min > source->data[idx+i]) min = source->data[idx+i]; if (max < source->data[idx+i]) max = source->data[idx+i]; } for (y = 0; y < h; y++) for (x = 0; x < w; x++) for (i = 0; i < 3; i++) { idx = 3 * (y * w + x); f = (float)(255.0 * (source->data[idx+i]-min) / (max-min)); if (f < 0.0) v = 0; else if (f > 255.0) v = 255; else v = f; data[idx+i] = v; } } void VideoFrame::CopyTo(FloatImage *dest) { int x, y, i, idx; if (dest == NULL) return; dest->SetSize (w, h); for (y = 0; y < h; y++) for (x = 0; x < w; x++) for (i = 0; i < 3; i++) { idx = 3 * (y * w + x); dest->data[idx+i] = data[idx+i]; } } void VideoFrame::ToPixbuf(GdkPixbuf* dest) { int destw, desth; unsigned char *destpixel; if (dest == NULL) return; desth = gdk_pixbuf_get_height(dest); destw = gdk_pixbuf_get_width(dest); destpixel = gdk_pixbuf_get_pixels(dest); if (destw * desth < h * w) { destw = w; desth = h; } memcpy (destpixel, data, 3*destw*desth); } FloatImage::FloatImage() { data = NULL; w = 0; h = 0; size = 0; }; FloatImage::~FloatImage() { if (data) { free (data); data = NULL; } w = 0; h = 0; size = 0; }; // // we will only allocate a new image if the needed size increases void FloatImage::SetSize(int nw, int nh) { uint32_t newsize = 3 * nh * nw * sizeof(float); if (newsize > size || data == NULL) { float *newdata = (float *) malloc (newsize); if (data != NULL) free (data); data = newdata; size = newsize; } w = nw; h = nh; }; FloatImage FloatImage::operator=(FloatImage rightside) { w = rightside.w; h = rightside.h; size = rightside.size; if (size > 0) data = (float *) malloc (rightside.size); if (rightside.data != NULL && size > 0) { memcpy (data, rightside.data, size); } return *this; } void FloatImage::CopyFrom(FloatImage *source) { SetSize (source->w, source->h); memcpy(data, source->data, 3 * w * h); }