1 #include "config.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <string.h>
7
8 #include "grab-ng.h"
9
10 /*-------------------------------------------------------------------------*/
11 /* color space conversion / compression helper functions */
12
13 struct ng_convert_handle*
ng_convert_alloc(struct ng_video_conv * conv,struct ng_video_fmt * i,struct ng_video_fmt * o)14 ng_convert_alloc(struct ng_video_conv *conv,
15 struct ng_video_fmt *i,
16 struct ng_video_fmt *o)
17 {
18 struct ng_convert_handle *h;
19
20 h = malloc(sizeof(*h));
21 if (NULL == h)
22 return 0;
23 memset(h,0,sizeof(*h));
24
25 /* fixup output image size to match incoming */
26 o->width = i->width;
27 o->height = i->height;
28 if (0 == o->bytesperline)
29 o->bytesperline = o->width * ng_vfmt_to_depth[o->fmtid] / 8;
30
31 h->ifmt = *i;
32 h->ofmt = *o;
33 if (conv)
34 h->conv = conv;
35 return h;
36 }
37
38 void
ng_convert_init(struct ng_convert_handle * h)39 ng_convert_init(struct ng_convert_handle *h)
40 {
41 if (0 == h->ifmt.bytesperline)
42 h->ifmt.bytesperline = h->ifmt.width *
43 ng_vfmt_to_depth[h->ifmt.fmtid] / 8;
44 if (0 == h->ofmt.bytesperline)
45 h->ofmt.bytesperline = h->ofmt.width *
46 ng_vfmt_to_depth[h->ofmt.fmtid] / 8;
47
48 h->isize = h->ifmt.height * h->ifmt.bytesperline;
49 if (0 == h->isize)
50 h->isize = h->ifmt.width * h->ifmt.height * 3;
51 h->osize = h->ofmt.height * h->ofmt.bytesperline;
52 if (0 == h->osize)
53 h->osize = h->ofmt.width * h->ofmt.height * 3;
54
55 if (h->conv)
56 h->chandle = h->conv->init(&h->ofmt,h->conv->priv);
57
58 if (ng_debug) {
59 fprintf(stderr,"convert-in : %dx%d %s (size=%d)\n",
60 h->ifmt.width, h->ifmt.height,
61 ng_vfmt_to_desc[h->ifmt.fmtid], h->isize);
62 fprintf(stderr,"convert-out: %dx%d %s (size=%d)\n",
63 h->ofmt.width, h->ofmt.height,
64 ng_vfmt_to_desc[h->ofmt.fmtid], h->osize);
65 }
66 }
67
68 static void
ng_convert_copyframe(struct ng_video_buf * dest,struct ng_video_buf * src)69 ng_convert_copyframe(struct ng_video_buf *dest,
70 struct ng_video_buf *src)
71 {
72 unsigned int i,sw,dw;
73 unsigned char *sp,*dp;
74
75 dw = dest->fmt.width * ng_vfmt_to_depth[dest->fmt.fmtid] / 8;
76 sw = src->fmt.width * ng_vfmt_to_depth[src->fmt.fmtid] / 8;
77 if (src->fmt.bytesperline == sw && dest->fmt.bytesperline == dw) {
78 /* can copy in one go */
79 memcpy(dest->data, src->data,
80 src->fmt.bytesperline * src->fmt.height);
81 } else {
82 /* copy line by line */
83 dp = dest->data;
84 sp = src->data;
85 for (i = 0; i < src->fmt.height; i++) {
86 memcpy(dp,sp,dw);
87 dp += dest->fmt.bytesperline;
88 sp += src->fmt.bytesperline;
89 }
90 }
91 }
92
93 struct ng_video_buf*
ng_convert_frame(struct ng_convert_handle * h,struct ng_video_buf * dest,struct ng_video_buf * buf)94 ng_convert_frame(struct ng_convert_handle *h,
95 struct ng_video_buf *dest,
96 struct ng_video_buf *buf)
97 {
98 if (NULL == buf)
99 return NULL;
100
101 if (NULL == dest && NULL != h->conv)
102 dest = ng_malloc_video_buf(&h->ofmt,h->osize);
103
104 if (NULL != dest) {
105 dest->fmt = h->ofmt;
106 dest->size = h->osize;
107 if (NULL != h->conv) {
108 h->conv->frame(h->chandle,dest,buf);
109 } else {
110 ng_convert_copyframe(dest,buf);
111 }
112 dest->info = buf->info;
113 ng_release_video_buf(buf);
114 buf = dest;
115 }
116 return buf;
117 }
118
119 void
ng_convert_fini(struct ng_convert_handle * h)120 ng_convert_fini(struct ng_convert_handle *h)
121 {
122 if (h->conv)
123 h->conv->fini(h->chandle);
124 free(h);
125 }
126
127 struct ng_video_buf*
ng_convert_single(struct ng_convert_handle * h,struct ng_video_buf * in)128 ng_convert_single(struct ng_convert_handle *h, struct ng_video_buf *in)
129 {
130 struct ng_video_buf *out;
131
132 ng_convert_init(h);
133 out = ng_convert_frame(h,NULL,in);
134 ng_convert_fini(h);
135 return out;
136 }
137
138