From 66cd54f3c6f692fc6882651d10945f26b31ca614 Mon Sep 17 00:00:00 2001 From: tth Date: Sat, 10 Aug 2019 18:37:52 +0200 Subject: [PATCH] grabing floatimb picz from a webcam --- doc/the_floatimg_hack.tex | 67 +++++++++++++++++++++++++++++++++++---- floatimg.h | 2 +- lib/t.c | 9 +++--- tools/Makefile | 2 +- v4l2/Makefile | 7 ++-- v4l2/funcs.h | 11 ++++++- v4l2/grabvidseq.c | 30 +++++++++++++++++- v4l2/rgb2fimg.c | 58 +++++++++++++++++++++++++++++++++ v4l2/t.c | 2 +- v4l2/video-infos.c | 19 +++-------- 10 files changed, 175 insertions(+), 32 deletions(-) create mode 100644 v4l2/rgb2fimg.c diff --git a/doc/the_floatimg_hack.tex b/doc/the_floatimg_hack.tex index 48c7f9d..5a438d2 100644 --- a/doc/the_floatimg_hack.tex +++ b/doc/the_floatimg_hack.tex @@ -132,10 +132,13 @@ est en fait arbitraire. \subsection{Structures, macros\dots} +Les pixels flottants d'une image résidant en mémoire centrale +sont décrits par un ensemble +de données (certains appelent ça des \textsl{metadats}) regroupées +dans une jolie structure que nous allons examiner dès maintenant. + \begin{verbatim} -/* - * in memory descriptor - */ +/* in memory descriptor */ typedef struct { int width; int height; @@ -147,6 +150,26 @@ typedef struct { } FloatImg; \end{verbatim}\index{FloatImg} +Les deux premiers champs sont \textsl{obvious}. +Le troisième est le type d'image : pour le moment, il y en a trois +qui sont définis\footnote{et plus ou moins bien gérés\dots} : +gris, rgb et rgba\index{rgba}. + +\begin{verbatim} +#define FIMG_TYPE_GRAY 1 +#define FIMG_TYPE_RGB 3 +#define FIMG_TYPE_RGBA 4 +\end{verbatim} + +Les deux champs suivants (fval et count) sont à la disposition du yuser +qui peut jouer avec à loisir. + +Et pour finir dans la joie, nous avons les pointeurs vers les +différents \textsl{pixmaps} de l'image. + + + + \subsection{lib/}\index{lib/} @@ -160,10 +183,20 @@ int fimg_destroy(FloatImg *fimg); Les types d'images actuellement gérés sont les trois grands classiques : gray, rgb et rgba. Il y a les constantes adéquates -dans \texttt{floatimg.h}. +dans \texttt{floatimg.h}. Les codes d'erreur sont disparates +et non documenté. +\vspace{1em} + + +Bon, vous avez une image latente, et +vous souhaité dessiner dessus (ou dedans ?) avec vos encres +flottantes ? \subsection{funcs/}\index{funcs/} +Une bonne partie de ces fonctions est indéterministe. Ce qui +veut dire, en langage de tous les soirs, que ça risque de ne +pas être la même chose dans l'avenir. % ------------------------------------------------------------------- \section{Les outils}\label{outils} @@ -173,7 +206,12 @@ in-fine sur des objets que l'on peut considérer comme « physiques », il est important de passer à une utilisation normale\footnote{Il y a une vie en dehors de git.} et construire des trucs qui mettent en action le code primitif. -% \vspace{1em} +\vspace{1em} + +Ces machins ont en commun deux options bien pratiques~: +\texttt{-h} pour avoir un résumé des options disponibles +et \texttt{-v} qui augmente la puissance de bavardage. +Dans un avenir incertain, il existera des pages de man\index{man}. \subsection{mkfimg}\index{mkfimg}\label{mkfimg} @@ -185,12 +223,26 @@ Création d'un fichier contenant une image de teinte constante. Affichage de quelques valeurs calculées à partir d'un fichier \texttt{.fimg}\index{.fimg}. +\subsection{fimg2png et fimg2pnm} + \index{fimg2png}\label{fimg2png} + \index{fimg2pnm}\label{fimg2pnm} + +Deux petits proggies pour exporter notre format\index{.fimg} secret +vers des choses plus directement utilisables. + + % ------------------------------------------------------------------- \section{Video for Linux}\index{v4l2} -Donc, maintenant, nous savons un peu tripoter des images flottantes. +Donc, maintenant, nous savons un peu tripoter ces images flottantes. Et nous devons nous poser une question fondamentale\footnote{primitive ?} sur la provenance de ces données prétendant être des images. +\vspace{1em} + +En fait, notre désir secret est la découverte des choses cachées du +monde qui nous entoure. Nous voulons des images du \textbf{réel} et +pour cela, l'outil le plus commun, le plus répandu, +est la webcam\index{webcam}. L'universelle webcam. % ------------------------------------------------------------------- \section{Et pour la suite ?} @@ -199,7 +251,8 @@ En fait, je fait de la photo par la méthode du « cumul » depuis plusieurs années. Une webcam\index{webcam}, un Linux\index{Linux}, et ça \textsl{juste marche}. Sauf que c'est quand même un peu galère à déplacer, il faut -avoir un shell pour déclencher, c'est pas facile\dots +avoir un shell pour déclencher, c'est pas facile à utiliser +en mode portnawak\dots % ------------------------------------------------------------------- diff --git a/floatimg.h b/floatimg.h index 9dc68b6..3f49941 100644 --- a/floatimg.h +++ b/floatimg.h @@ -2,7 +2,7 @@ * floatimg.h */ -#define FIMG_VERSION 64 +#define FIMG_VERSION 65 /* * in memory descriptor diff --git a/lib/t.c b/lib/t.c index c409aae..a1d5544 100644 --- a/lib/t.c +++ b/lib/t.c @@ -32,7 +32,8 @@ for (y=0; yheight; y++) { return -1; } /* ---------------------------------------------------------------- */ - +#define W 4000 +#define H 3000 int main(int argc, char *argv[]) { int foo; @@ -43,15 +44,15 @@ verbosity = 1; fimg_print_version(1); -foo = fimg_create(&dessin, 640, 480, 3); +foo = fimg_create(&dessin, W, H, 3); petit_dessin(&dessin); fimg_save_as_pnm(&dessin, "dessin.pnm", 0); -foo = fimg_create(&noise, 640, 480, 3); +foo = fimg_create(&noise, W, H, 3); fimg_drand48(&noise, 1.0); fimg_save_as_pnm(&noise, "noise.pnm", 0); -foo = fimg_create(&result, 640, 480, 3); +foo = fimg_create(&result, W, H, 3); foo = fimg_add(&dessin, &noise, &result); fimg_save_as_pnm(&result, "r_add.pnm", 0); diff --git a/tools/Makefile b/tools/Makefile index 6e997dc..8921e1b 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -3,7 +3,7 @@ # use with caution # -COPT = -Wall -fpic -g -DDEBUG_LEVEL=0 +COPT = -Wall -fpic -g -DDEBUG_LEVEL=0 -lm DEPS = ../floatimg.h ../libfloatimg.a Makefile # ---------- diff --git a/v4l2/Makefile b/v4l2/Makefile index 947c765..6ce9dfc 100644 --- a/v4l2/Makefile +++ b/v4l2/Makefile @@ -11,11 +11,14 @@ t: t.c Makefile ${DEPS} funcs.o v4l2_pr_structs.o funcs.o: funcs.c funcs.h Makefile gcc ${COPT} -c $< +rgb2fimg.o: rgb2fimg.c funcs.h Makefile + gcc ${COPT} -c $< + v4l2_pr_structs.o: v4l2_pr_structs.c v4l2_pr_structs.h Makefile gcc ${COPT} -c $< -grabvidseq: grabvidseq.c Makefile - gcc -Wall -g $< ../libfloatimg.a -lv4l2 -o $@ +grabvidseq: grabvidseq.c Makefile rgb2fimg.o + gcc -Wall -g $< rgb2fimg.o ../libfloatimg.a -lv4l2 -o $@ video-infos: video-infos.c Makefile funcs.o v4l2_pr_structs.o gcc -Wall -g $< funcs.o v4l2_pr_structs.o -o $@ diff --git a/v4l2/funcs.h b/v4l2/funcs.h index 90393ab..809f837 100644 --- a/v4l2/funcs.h +++ b/v4l2/funcs.h @@ -4,4 +4,13 @@ int open_device(char *dev_name); -int init_device(int notused); \ No newline at end of file +int init_device(int notused); + +/* --------------------------------------------------------------------- */ + +int x_rgb2fimg(unsigned char *src, int w, int h, FloatImg *d); +int x_rgb2file(unsigned char *src, int w, int h, char *fname); + +/* --------------------------------------------------------------------- */ + + diff --git a/v4l2/grabvidseq.c b/v4l2/grabvidseq.c index ac4c2bb..5cb3092 100644 --- a/v4l2/grabvidseq.c +++ b/v4l2/grabvidseq.c @@ -27,9 +27,23 @@ #include #include "../floatimg.h" +#include "funcs.h" + +/* --------------------------------------------------------------------- */ +/* compilation control */ + +#define SAVE_AS_PNM 0 +#define SAVE_AS_FIMG 1 + +/* --------------------------------------------------------------------- */ + + #define CLEAR(x) memset(&(x), 0, sizeof(x)) + + + struct buffer { void *start; size_t length; @@ -81,6 +95,7 @@ char out_name[256]; FILE *fout; struct buffer *buffers; +int foo, bar; int period = 10; /* delai entre les captures */ int nbre_capt = 1; /* nombre de captures */ int opt; @@ -189,9 +204,12 @@ for (i = 0; i < nbre_capt; i++) { buf.memory = V4L2_MEMORY_MMAP; xioctl(fd, VIDIOC_DQBUF, &buf); +#if SAVE_AS_PNM + + /* at this time,we'v got a picture in-memory, + so we can blast in on storage */ sprintf(out_name, "%s/%05d.ppm", dest_dir, i); if (verbosity > 1) fprintf(stderr, "--> %s\n", out_name); - fout = fopen(out_name, "w"); if (!fout) { perror("Cannot open image"); @@ -202,6 +220,16 @@ for (i = 0; i < nbre_capt; i++) { fwrite(buffers[buf.index].start, buf.bytesused, 1, fout); fclose(fout); +#endif + +#if SAVE_AS_FIMG + sprintf(out_name, "%s/%05d.fimg", dest_dir, i); + if (verbosity > 1) fprintf(stderr, "--> %s\n", out_name); + foo = x_rgb2file(buffers[buf.index].start, + fmt.fmt.pix.width, fmt.fmt.pix.height, + out_name); +#endif + if (nbre_capt > 1 && period) { sleep(period); } diff --git a/v4l2/rgb2fimg.c b/v4l2/rgb2fimg.c new file mode 100644 index 0000000..57154d4 --- /dev/null +++ b/v4l2/rgb2fimg.c @@ -0,0 +1,58 @@ +#include +#include + +#include "../floatimg.h" + +#include "funcs.h" + +/* --------------------------------------------------------------------- */ +int x_rgb2fimg(unsigned char *src, int w, int h, FloatImg *d) +{ +int iter, size; +float *rp, *gp, *bp; + +size = w * h; +rp = d->R, gp = d->G, bp = d->G; + +for (iter=0; iter>> %s ( %p %d %d '%s' )\n", __func__, + src, w, h, fname); +#endif + +foo = fimg_create(&buff, w, h, FIMG_TYPE_RGB); +if (foo) { + fprintf(stderr, "Crash on create in %s %s\n", __FILE__, __func__); + exit(1); + } + +foo = x_rgb2fimg(src, w, h, &buff); +if (foo) { + fprintf(stderr, "Crash on bit massage in %s %s\n", __FILE__, __func__); + exit(1); + } + +foo = fimg_dump_to_file(&buff, fname, 0); +if (foo) { + fprintf(stderr, "Crash on dump in %s %s\n", __FILE__, __func__); + exit(1); + } + +fimg_destroy(&buff); + +return -1; +} +/* --------------------------------------------------------------------- */ diff --git a/v4l2/t.c b/v4l2/t.c index 266a590..b3259e6 100644 --- a/v4l2/t.c +++ b/v4l2/t.c @@ -11,8 +11,8 @@ #include #include -#include "funcs.h" #include "../floatimg.h" +#include "funcs.h" #include "v4l2_pr_structs.h" diff --git a/v4l2/video-infos.c b/v4l2/video-infos.c index 8845556..f1d9e95 100644 --- a/v4l2/video-infos.c +++ b/v4l2/video-infos.c @@ -175,7 +175,7 @@ char ligne[100]; struct v4l2_capability cap; struct v4l2_format fmt; -struct v4l2_input input; +// struct v4l2_input input; // int index; // struct v4l2_requestbuffers reqbuf; @@ -202,26 +202,17 @@ pr_v4l2_capability(devname, &cap); foo = enum_inputs(vfd, "on peut voir quoi ?", 0); -/*** -memset(&input, 0, sizeof(input)); -input.index = 1; -if (-1 == ioctl(vfd, VIDIOC_ENUMINPUT, &input)) { - perror("VIDIOC_ENUMINPUT"); - exit(EXIT_FAILURE); - } -sprintf(ligne, "input %d", input.index); -pr_v4l2_input(ligne, &input); -***/ memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; foo = ioctl(vfd, VIDIOC_G_FMT, &fmt); -fprintf(stderr, "ioctl -> %d\n", foo); if (0 != foo) { perror("ioctl G_FMT"); - exit(1); + // exit(1); + } +else { + pr_v4l2_format("Experimental", &fmt); } -pr_v4l2_format("Experimental", &fmt); foo = enum_image_formats(vfd, "Experimental", 0);