diff --git a/configuration.cc b/configuration.cc index 8618ffc..9d28ab2 100644 --- a/configuration.cc +++ b/configuration.cc @@ -361,6 +361,13 @@ void Configuration::LoadConfig(std::string filename) { } } } + + printf ("%s:%d show debug window\n", __FILE__, __LINE__); + GtkWidget *wnd = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "window-debug")); + if (wnd) { + gtk_widget_show (wnd); + } + setlocale (LC_ALL, s.c_str()); // we need to update the gui so floating numbers will displayed with the correct diff --git a/convert.cc b/convert.cc index e2334e2..27c722b 100644 --- a/convert.cc +++ b/convert.cc @@ -494,15 +494,93 @@ uint32_t convert_to_pixelformat(std::string s) { * copy part of an raw image * destination must be pointer in case we need to align the size of the destination image. * this function will also realloc needed memory if needed. (only if: givin size < needed size) + * + * crop image to event set of dimensions */ int PixCopy(unsigned char *srcdata, uint32_t srcpixfmt, int srcw, int srch, unsigned char **dstdataptr, int *dstsize, int *dstw, int *dsth, int regionx, int regiony, int regionw, int regionh) { if (srcpixfmt == 0 || srcpixfmt == V4L2_PIX_FMT_MJPEG) return 0; - if (srcdata == NULL) return 0; + if (srcdata == NULL || dstdataptr == NULL) return 0; - return 0; + // crop size to an even number + (*dsth) = regionw & ~1; + (*dstw) = regionh & ~1; + + int bytesperpixel = 3; + int dsize = 0; + + switch (srcpixfmt) { + case (V4L2_PIX_FMT_SGRBG8): + bytesperpixel = 2; + break; + case (V4L2_PIX_FMT_BGR32): + case (V4L2_PIX_FMT_RGB32): + case (V4L2_PIX_FMT_SGRBG16): + bytesperpixel = 4; + break; + case (V4L2_PIX_FMT_BGR24): + case (V4L2_PIX_FMT_RGB24): + bytesperpixel = 3; + break; + default: + return 0; + } + + debug_drawraw(srcdata, srcpixfmt, srcw, srch); + + // + // calculate image size and allocate memory if needed + dsize = (*dsth) * (*dstw) * bytesperpixel; + if ((*dstsize) < dsize || (*dstdataptr) == NULL) { + *dstdataptr = (unsigned char*) realloc (*dstdataptr, dsize); + *dstsize = dsize; + printf ("%s:%d reallocate memory for destination raw image\n", __FILE__, __LINE__); + } + + unsigned char *dptr, *sptr; + int y, dy, x, dx, i, d; + + for (y = regiony & (~1), dy = 0; dy < *dsth && y < srch; y++, dy++) { + for (x = regionx & (~1), dx = 0; dx < *dstw && x < srcw; x++, dx++) { + dptr = (*dstdataptr) + bytesperpixel * ( dy * *dstw + dx); + sptr = (srcdata) + bytesperpixel * ( y * srcw + x); + for (d = 0, i = 0; i < bytesperpixel; i++) { + dptr[i] = sptr[i]; + d += sptr[i]; + } +// printf (" %-3d",d); + } +// printf ("\n"); + } +// printf ("%s:%d\n", __FILE__, __LINE__); + +/* int dy, y = regiony & (~1); + int dx, x; + + for (dptr = *dstdataptr, dy = 0; dy < *dsth; dy++, y++) { + x = regionx & (~1); + sptr = (srcdata + bytesperpixel * (y * srcw + x)); +// printf ("\n"); + for (dx = 0; dx < (*dstw * bytesperpixel); dx++, dptr++, sptr++) { + *dptr = *sptr; + + // printf ("%x[%x] ", *dptr, *sptr); + int x1, x2, y1, y2; + + y1 = (sptr - srcdata) / (bytesperpixel * srcw); + x1 = ((sptr - srcdata) % (bytesperpixel * srcw)) / bytesperpixel; + + y2 = (dptr - *dstdataptr) / (bytesperpixel * (*dstw)); + x2 = ((dptr - *dstdataptr) % (bytesperpixel * (*dstw))) / bytesperpixel; + + printf ("copy [%d , %d] ---> [ %d , %d] (%d , %d) Value: %d -> %d\n", x1,y1, x2, y2, dx, dy, *sptr, *dptr); + } + } +*/ + + return 1; } diff --git a/debug.cc b/debug.cc index 5f03dc6..d0d3b42 100644 --- a/debug.cc +++ b/debug.cc @@ -8,7 +8,17 @@ #include #include "debug.h" +#include "convert.h" +#include "gui.h" +#include "video.h" +#include "configuration.h" +#include "debayer.h" + +extern GtkBuilder *_builder_; // work around for threads +GtkWidget *debug_da = NULL; +GdkPixbuf *debug_pixbuf = NULL; +VideoFrame debug_frame; int debug_uninit = 1; GMutex debug_mutex; time_t debug_time; @@ -28,7 +38,7 @@ void debug_tofile(char *fname, int isheader, char *fmt, ...) { std::string fn; if (debug_uninit) debug_init(); - g_mutex_lock(&debug_mutex); + debug_lock_mutex(); // locale set to C, floating points decimals are . std::string s = setlocale(LC_ALL, NULL); @@ -62,5 +72,73 @@ void debug_tofile(char *fname, int isheader, char *fmt, ...) { // reset locale to user setting setlocale (LC_ALL, s.c_str()); - g_mutex_unlock(&debug_mutex); + debug_unlock_mutex(); } + + +gboolean debug_thread_cb (gpointer data) { + debug_lock_mutex(); + + // + // create video drawarea if needed + if (debug_da == NULL) + debug_da = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "debug-da")); + + if (debug_pixbuf == NULL) { + debug_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, false, 8, 100, 100); + memset (gdk_pixbuf_get_pixels(debug_pixbuf), 0, 3 * gdk_pixbuf_get_height(debug_pixbuf) * gdk_pixbuf_get_width(debug_pixbuf)); + } + + debug_frame.ToPixbuf(&debug_pixbuf); // convert Frame to pixeldata + + // redraw drawarea on screen. + gdk_window_invalidate_rect(gtk_widget_get_window(debug_da), NULL, true); + + debug_unlock_mutex(); + return false; +} + + +inline void debug_lock_mutex() { + g_mutex_lock(&debug_mutex); +}; + + +inline void debug_unlock_mutex() { + g_mutex_unlock(&debug_mutex); +}; + + +void debug_drawraw(unsigned char *data, int pixfmt, int w, int h) { + ConvertData cd; + int size, bytesperpixel = 0; + + switch (pixfmt) { + case (V4L2_PIX_FMT_SGRBG8): + bytesperpixel = 2; + break; + case (V4L2_PIX_FMT_BGR32): + case (V4L2_PIX_FMT_RGB32): + case (V4L2_PIX_FMT_SGRBG16): + bytesperpixel = 4; + break; + case (V4L2_PIX_FMT_BGR24): + case (V4L2_PIX_FMT_RGB24): + bytesperpixel = 3; + break; + default: + return; + } + + size = bytesperpixel * w * h; + debug_lock_mutex(); + + ConvertStart(&cd, pixfmt); + Convert(&cd, &debug_frame, data, size, pixfmt, w, h); + ConvertStop(&cd, pixfmt); + + gdk_threads_add_idle(debug_thread_cb, NULL); + + debug_unlock_mutex(); +}; + diff --git a/debug.h b/debug.h index 88ecfbd..9e52f20 100644 --- a/debug.h +++ b/debug.h @@ -10,6 +10,12 @@ #include "config.h" #include "simpleskycam.h" #include "gui.h" +#include "videoframe.h" + +struct Debug_ThreadData { + VideoFrameRaw raw; +}; + #ifdef DEBUG_ANGLES extern void debug_angles_draw(cairo_t *cr); @@ -19,5 +25,9 @@ extern void debug_angles_btnpress(GdkEvent *event); extern void debug_init(); extern void debug_tofile(char *fname, int isheader, char *fmt, ...); +extern inline void debug_lock_mutex(); +extern inline void debug_unlock_mutex(); +void debug_drawraw(unsigned char *data, int pixfmt, int w, int h); + #endif diff --git a/gui.cc b/gui.cc index 54feec1..0ada65d 100644 --- a/gui.cc +++ b/gui.cc @@ -33,6 +33,11 @@ GdkPixbuf *detect_pixbuf = NULL; GtkWidget *image_da = NULL; GdkPixbuf *image_pixbuf = NULL; + +extern GtkWidget *debug_da; +extern GdkPixbuf *debug_pixbuf; + + std::string filename = ""; extern Configuration config; @@ -169,7 +174,7 @@ gboolean cb_thread_detect (gpointer data) { pix_w = dout->image->w; pix_h = dout->image->h; } - dout->image->ToPixbuf(detect_pixbuf); + dout->image->ToPixbuf(&detect_pixbuf); gdk_window_invalidate_rect(gtk_widget_get_window(detect_da), NULL, true); output.NewFrame(dout->rawimage); @@ -217,6 +222,7 @@ void cb_imagetempda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer da if (area == image_da) src = image_pixbuf; else if (area == detect_da) src = detect_pixbuf; + else if (area == debug_da && debug_pixbuf != NULL) src = debug_pixbuf; else return; clienth = gtk_widget_get_allocated_height(area); diff --git a/gui.h b/gui.h index 88dec85..135f9a9 100644 --- a/gui.h +++ b/gui.h @@ -216,15 +216,12 @@ G_MODULE_EXPORT void cb_menu_set_displaycalibdata(GtkCheckMenuItem *checkmenuite // error handling and thread handling G_MODULE_EXPORT gboolean errormessage_thread (gpointer data); G_MODULE_EXPORT void errormessage_cb_btnok (GtkWidget *widget, gpointer data); +G_MODULE_EXPORT gboolean debug_thread_cb (gpointer data); -// G_MODULE_EXPORT gboolean cb_thread_filter (gpointer data); G_MODULE_EXPORT gboolean cb_thread_detect (gpointer data); G_MODULE_EXPORT gboolean cb_thread_posctl (gpointer data); G_MODULE_EXPORT gboolean cb_thread_output (gpointer data); - - - #ifdef __cplusplus } #endif diff --git a/ser.cc b/ser.cc index 4d7125f..e16caeb 100644 --- a/ser.cc +++ b/ser.cc @@ -31,6 +31,14 @@ int ser_convert_type_to_ser (int v4l2_fmt, int *pixeldepth, int *serformat) { *serformat = SER_COLORID_BGR; *pixeldepth = 8; break; + case (V4L2_PIX_FMT_SGRBG8): + *serformat = SER_COLORID_BAYER_GRBG; + *pixeldepth = 8; + break; + case (V4L2_PIX_FMT_SGRBG16): + *serformat = SER_COLORID_BAYER_GRBG; + *pixeldepth = 16; + break; default: return 0; } diff --git a/simpleskycam.ui b/simpleskycam.ui index 0861635..b2d9402 100644 --- a/simpleskycam.ui +++ b/simpleskycam.ui @@ -2639,6 +2639,17 @@ + + False + + + + True + False + + + + False Histogram diff --git a/video.cc b/video.cc index a65c6b8..4473d27 100644 --- a/video.cc +++ b/video.cc @@ -590,7 +590,7 @@ gboolean cb_thread_video (gpointer data) { pix_h = vf->h; } - vf->ToPixbuf(video_pixbuf); // convert Frame to pixeldata + vf->ToPixbuf(&video_pixbuf); // convert Frame to pixeldata histogram_update(vf); // update histogram detect.CopyNewFrame(vf, vfr); // push new data to detect object diff --git a/videoframe.cc b/videoframe.cc index 5167c37..d2a6a29 100644 --- a/videoframe.cc +++ b/videoframe.cc @@ -40,8 +40,16 @@ int VideoFrameRaw::CopyFrom(int spixfmt, int sw, int sh, int ssize, unsigned cha w = sw; h = sh; pixfmt = spixfmt; - memcpy (data, sdata, size); + memcpy (data, sdata, ssize); +/* int i, x, y, d; + for (y = 0; y < w; y++) for (x = 0; x < w; x++) { + for (i = 0, d = 0; i < 4; i++) { + d += data[4* (y*w+x)]; + } + if (d > 1000) printf ("%d,%d -> %d\n", x, y, d); + } +*/ return 1; } @@ -83,9 +91,45 @@ int VideoFrameRaw::ReAlloc(int newsize) { 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); + int res = 0; + pixfmt = src->pixfmt; + + res = PixCopy (src->data, src->pixfmt, src->w, src->h, + &data, &size, &w, &h, + rectx, recty, rectw, recth); + +/* + for (int i = 0; i < size; i++) if (data[i] > 0) { + printf ("%s:%d found data in destination.\n", __FILE__, __LINE__); + break; + } + + for (int i = 0; i < src->size; i++) if (src->data[i] > 0) { + printf ("%s:%d found data in source.\n", __FILE__, __LINE__); + break; + } + + int bytesperpixel = 3; + int dsize = 0; + + switch (src->pixfmt) { + case (V4L2_PIX_FMT_SGRBG8): + bytesperpixel = 2; + break; + case (V4L2_PIX_FMT_BGR32): + case (V4L2_PIX_FMT_RGB32): + case (V4L2_PIX_FMT_SGRBG16): + bytesperpixel = 4; + break; + case (V4L2_PIX_FMT_BGR24): + case (V4L2_PIX_FMT_RGB24): + bytesperpixel = 3; + break; + default: + return 0; + } + */ + return res; } @@ -190,25 +234,32 @@ void VideoFrame::CopyTo(FloatImage *dest) { - - - -void VideoFrame::ToPixbuf(GdkPixbuf* dest) { - int destw, desth; +void VideoFrame::ToPixbuf(GdkPixbuf** dest) { + int destw, desth, bytelen; 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); + desth = gdk_pixbuf_get_height(*dest); + destw = gdk_pixbuf_get_width(*dest); + + // check if the memory allocation way ok. + if (destw != w || desth != h) { + g_object_unref (*dest); + *dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, false, 8, w, h); + } - if (destw * desth < h * w) { - destw = w; - desth = h; + // copy data + destpixel = gdk_pixbuf_get_pixels(*dest); + bytelen = gdk_pixbuf_get_byte_length(*dest); + if (bytelen < h * w * 3) { + printf ("******* Error: %s:%d bytelen (set to:%d) is not %d\n", __FILE__, __LINE__, bytelen, (h * w * 3)); + printf ("******* please inform the maintainer of this project.\n"); + printf ("******* this should not have happened at all.\n"); + exit (-1); } - memcpy (destpixel, data, 3*destw*desth); + memcpy (destpixel, data, 3*w*h); } diff --git a/videoframe.h b/videoframe.h index 55e6677..f3c23a3 100644 --- a/videoframe.h +++ b/videoframe.h @@ -47,7 +47,7 @@ public: void CopyFrom(VideoFrame *source); void CopyFrom(FloatImage *source); void CopyTo(FloatImage *dest); - void ToPixbuf(GdkPixbuf* dest); + void ToPixbuf(GdkPixbuf** dest); void Delete() { w = 0; h = 0; }; };