You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
SimpleSkyCam/videoframe.cc

243 lines
4.8 KiB

#include <string.h>
#include "video.h"
#include "config.h"
#include "gui.h"
#include "simpleskycam.h"
VideoFrame::VideoFrame() {
data = NULL;
w = 0;
h = 0;
size = 0;
pixelsize = 3;
};
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::SetMemorySize(int nw, int nh, int nps) {
uint32_t newsize = nps * 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;
pixelsize = nps;
};
VideoFrame VideoFrame::operator=(VideoFrame rightside) {
w = rightside.w;
h = rightside.h;
pixelsize = rightside.pixelsize;
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) {
SetPixelSize(source->pixelsize);
SetSize (source->w, source->h);
memcpy(data, source->data, pixelsize * w * h);
}
/*
* will copy the FloatImage to VideoFrame
* with respect of the bits per pixel (3 or 6).
*/
void VideoFrame::CopyFrom(FloatImage *source) {
float min, max, f;
int x, y, i, idx;
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];
}
//
// 3 bytes per pixel (each channel ^ 1 byte)
if (pixelsize == 3) {
unsigned char v;
for (y = 0; y < h; y++) for (x = 0; x < w; x++)
for (i = 0; i < 3; i++) {
idx = pixelsize * (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;
}
}
//
// 6 bytes per pixel (each channel ^ 2 byte)
else if (pixelsize == 6) {
uint16_t v;
int max = (2^16)-1;
for (y = 0; y < h; y++) for (x = 0; x < w; x++)
for (i = 0; i < 3; i++) {
idx = pixelsize * (y * w + x);
f = (float)(double(max) * (source->data[idx+i]-min) / (max-min));
if (f < 0.0) v = 0;
else if (f > double(max)) v = max;
else v = f;
memcpy(data+(idx+2*i), &v, 2);
}
}
else {
errorexit((char*)"Pixelsize not known or implemented. pixelsize should be 3 or 6, current value is:%d\n", pixelsize);
}
}
void VideoFrame::CopyTo(FloatImage *dest) {
int x, y, i, idx;
if (dest == NULL) return;
dest->SetSize (w, h);
if (pixelsize == 3) {
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];
}
}
else if (pixelsize == 6) {
uint16_t *sdata = (uint16_t*)data;
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] = sdata[idx+i];
}
}
else {
errorexit ((char*) "pixelsize not supported.\n");
}
}
void VideoFrame::ToPixbuf(GdkPixbuf* dest) {
int destw, desth;
unsigned char *destpixel;
if (dest == NULL) return;
if (pixelsize == 3) {
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);
}
else if (pixelsize == 6) {
desth = gdk_pixbuf_get_height(dest);
destw = gdk_pixbuf_get_width(dest);
destpixel = gdk_pixbuf_get_pixels(dest);
uint16_t *sdata = (uint16_t*)data;
int x, y, idx, i;
for (y = 0; y < desth; y++) for (x = 0; x < destw; x++)
for (i = 0; i < 3; i++) {
idx = 3 * (y * w + x);
destpixel[idx+i] = sdata[idx+i];
}
}
else {
errorexit ((char*) "pixelsize (%d) not supported.\n", pixelsize);
}
}
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);
}