1 /* Aravis - Digital camera library
2 *
3 * Copyright © 2009-2010 Emmanuel Pacaud
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 * Author: Emmanuel Pacaud <emmanuel@gnome.org>
21 */
22
23 #include <arvmisc.h>
24 #include <arvdebug.h>
25 #include <string.h>
26 #include <math.h>
27 #include <stdio.h>
28 #include <zlib.h>
29
30 /**
31 * SECTION: arvstatistic
32 * @short_description: An histogram tool
33 */
34
35 typedef struct _ArvHistogram ArvHistogram;
36
37 struct _ArvHistogram {
38 char * name;
39
40 guint64 and_more;
41 guint64 and_less;
42 guint64 last_seen_worst;
43 int worst;
44 int best;
45
46 guint64 * bins;
47 };
48
49 struct _ArvStatistic {
50 guint n_histograms;
51 guint n_bins;
52 guint bin_step;
53 int offset;
54
55 guint64 counter;
56
57 ArvHistogram *histograms;
58 };
59
60 static void
_arv_statistic_free(ArvStatistic * statistic)61 _arv_statistic_free (ArvStatistic *statistic)
62 {
63 guint j;
64
65 if (statistic == NULL)
66 return;
67
68 if (statistic->histograms != NULL) {
69 for (j = 0; j < statistic->n_histograms && statistic->histograms[j].bins != NULL; j++) {
70 if (statistic->histograms[j].name != NULL)
71 g_free (statistic->histograms[j].name);
72 g_free (statistic->histograms[j].bins);
73 }
74 g_free (statistic->histograms);
75 }
76
77 g_free (statistic);
78 }
79
80 /**
81 * arv_statistic_new: (skip)
82 * @n_histograms: number of histograms
83 * @n_bins: number of bins for each histogram
84 * @bin_step: bin step
85 * @offset: offset of the first bin
86 * Return value: a new #ArvStatistic structure
87 */
88
89 ArvStatistic *
arv_statistic_new(unsigned int n_histograms,unsigned n_bins,unsigned int bin_step,int offset)90 arv_statistic_new (unsigned int n_histograms, unsigned n_bins, unsigned int bin_step, int offset)
91 {
92 ArvStatistic *statistic;
93 unsigned int i;
94
95 g_return_val_if_fail (n_histograms > 0, NULL);
96 g_return_val_if_fail (n_bins > 0, NULL);
97 g_return_val_if_fail (bin_step > 0, NULL);
98
99 statistic = g_new0 (ArvStatistic, 1);
100
101 statistic->n_histograms = n_histograms;
102 statistic->n_bins = n_bins;
103 statistic->bin_step = bin_step;
104 statistic->offset = offset;
105
106 statistic->histograms = g_new (ArvHistogram, n_histograms);
107
108 for (i = 0; i < statistic->n_histograms; i++) {
109 statistic->histograms[i].name = NULL;
110 statistic->histograms[i].bins = g_new (guint64, statistic->n_bins);
111 }
112
113 arv_statistic_reset (statistic);
114
115 return statistic;
116 }
117
118 void
arv_statistic_free(ArvStatistic * statistic)119 arv_statistic_free (ArvStatistic *statistic)
120 {
121 g_return_if_fail (statistic != NULL);
122
123 _arv_statistic_free (statistic);
124 }
125
126 void
arv_statistic_reset(ArvStatistic * statistic)127 arv_statistic_reset (ArvStatistic *statistic)
128 {
129 ArvHistogram *histogram;
130 int i, j;
131
132 g_return_if_fail (statistic != NULL);
133
134 statistic->counter = 0;
135
136 for (j = 0; j < statistic->n_histograms; j++) {
137 histogram = &statistic->histograms[j];
138
139 histogram->last_seen_worst = 0;
140 histogram->best = 0x7fffffff;
141 histogram->worst = 0x80000000;
142 histogram->and_more = histogram->and_less = 0;
143 for (i = 0; i < statistic->n_bins; i++)
144 histogram->bins[i] = 0;
145 }
146 }
147
148 void
arv_statistic_set_name(ArvStatistic * statistic,unsigned int histogram_id,char const * name)149 arv_statistic_set_name (ArvStatistic *statistic, unsigned int histogram_id, char const *name)
150 {
151 ArvHistogram *histogram;
152 size_t length;
153
154 g_return_if_fail (statistic != NULL);
155 g_return_if_fail (histogram_id < statistic->n_histograms);
156
157 histogram = &statistic->histograms[histogram_id];
158
159 if (histogram->name != NULL) {
160 g_free (histogram->name);
161 histogram->name = NULL;
162 }
163
164 if (name == NULL)
165 return;
166
167 length = strlen (name);
168 if (length < 1)
169 return;
170
171 histogram->name = g_malloc (length + 1);
172 if (histogram->name == NULL)
173 return;
174
175 memcpy (histogram->name, name, length + 1);
176 }
177
178 gboolean
arv_statistic_fill(ArvStatistic * statistic,guint histogram_id,int value,guint64 counter)179 arv_statistic_fill (ArvStatistic *statistic, guint histogram_id, int value, guint64 counter)
180 {
181 ArvHistogram *histogram;
182 unsigned int class;
183
184 if (statistic == NULL)
185 return FALSE;
186 if (histogram_id >= statistic->n_histograms)
187 return FALSE;
188
189 statistic->counter = counter;
190
191 histogram = &statistic->histograms[histogram_id];
192
193 if (histogram->best > value)
194 histogram->best = value;
195
196 if (histogram->worst < value) {
197 histogram->worst = value;
198 histogram->last_seen_worst = counter;
199 }
200
201 class = (value - statistic->offset) / statistic->bin_step;
202
203 if (value < statistic->offset)
204 histogram->and_less++;
205 else if (class >= statistic->n_bins)
206 histogram->and_more++;
207 else
208 histogram->bins[class]++;
209
210 return TRUE;
211 }
212
213 char *
arv_statistic_to_string(const ArvStatistic * statistic)214 arv_statistic_to_string (const ArvStatistic *statistic)
215 {
216 int i, j, bin_max;
217 gboolean max_found = FALSE;
218 GString *string;
219 char *str;
220
221 g_return_val_if_fail (statistic != NULL, NULL);
222
223 string = g_string_new ("");
224
225 bin_max = 0;
226 for (i = statistic->n_bins - 1; i > 0 && !max_found; i--) {
227 for (j = 0; j < statistic->n_histograms && !max_found; j++) {
228 if (statistic->histograms[j].bins[i] != 0) {
229 bin_max = i;
230 max_found = TRUE;
231 }
232 }
233 }
234
235 if (bin_max >= statistic->n_bins)
236 bin_max = statistic->n_bins - 1;
237
238 for (j = 0; j < statistic->n_histograms; j++) {
239 if (j == 0)
240 g_string_append (string, " bins ");
241 g_string_append_printf (string, ";%8.8s",
242 statistic->histograms[j].name != NULL ?
243 statistic->histograms[j].name :
244 " ---- ");
245 }
246 g_string_append (string, "\n");
247
248 for (i = 0; i <= bin_max; i++) {
249 for (j = 0; j < statistic->n_histograms; j++) {
250 if (j == 0)
251 g_string_append_printf (string, "%8d", i * statistic->bin_step + statistic->offset);
252 g_string_append_printf (string, ";%8Lu", (unsigned long long) statistic->histograms[j].bins[i]);
253 }
254 g_string_append (string, "\n");
255 }
256
257 g_string_append (string, "-------------\n");
258
259 for (j = 0; j < statistic->n_histograms; j++) {
260 if (j == 0)
261 g_string_append_printf (string, ">=%6d", i * statistic->bin_step + statistic->offset);
262 g_string_append_printf (string, ";%8Lu", (unsigned long long) statistic->histograms[j].and_more);
263 }
264 g_string_append (string, "\n");
265
266 for (j = 0; j < statistic->n_histograms; j++) {
267 if (j == 0)
268 g_string_append_printf (string, "< %6d", statistic->offset);
269 g_string_append_printf (string, ";%8Lu", (unsigned long long) statistic->histograms[j].and_less);
270 }
271 g_string_append (string, "\n");
272
273 for (j = 0; j < statistic->n_histograms; j++) {
274 if (j == 0)
275 g_string_append (string, "min ");
276 if (statistic->histograms[j].best != 0x7fffffff)
277 g_string_append_printf (string, ";%8d", statistic->histograms[j].best);
278 else
279 g_string_append_printf (string, ";%8s", "n/a");
280 }
281 g_string_append (string, "\n");
282
283 for (j = 0; j < statistic->n_histograms; j++) {
284 if (j == 0)
285 g_string_append (string, "max ");
286 if (statistic->histograms[j].worst != 0x80000000)
287 g_string_append_printf (string, ";%8d", statistic->histograms[j].worst);
288 else
289 g_string_append_printf (string, ";%8s", "n/a");
290 }
291 g_string_append (string, "\n");
292
293 for (j = 0; j < statistic->n_histograms; j++) {
294 if (j == 0)
295 g_string_append (string, "last max\nat: ");
296 g_string_append_printf (string, ";%8Lu", (unsigned long long) statistic->histograms[j].last_seen_worst);
297 }
298 g_string_append (string, "\n");
299
300 g_string_append_printf (string, "Counter = %8Lu", (unsigned long long) statistic->counter);
301
302 str = string->str;
303 g_string_free (string, FALSE);
304
305 return str;
306 }
307
308 /**
309 * SECTION: arvvalue
310 * @short_description: An int64/double value storage
311 */
312
313 ArvValue *
arv_value_new_double(double v_double)314 arv_value_new_double (double v_double)
315 {
316 ArvValue *value = g_new (ArvValue, 1);
317 value->type = G_TYPE_DOUBLE;
318 value->data.v_double = v_double;
319
320 return value;
321 }
322
323 ArvValue *
arv_value_new_int64(double v_int64)324 arv_value_new_int64 (double v_int64)
325 {
326 ArvValue *value = g_new (ArvValue, 1);
327 value->type = G_TYPE_INT64;
328 value->data.v_int64 = v_int64;
329
330 return value;
331 }
332
333 void
arv_value_free(ArvValue * value)334 arv_value_free (ArvValue *value)
335 {
336 g_free (value);
337 }
338
339 void
arv_value_copy(ArvValue * to,const ArvValue * from)340 arv_value_copy (ArvValue *to, const ArvValue *from)
341 {
342 *to = *from;
343 }
344
345 ArvValue *
arv_value_duplicate(const ArvValue * from)346 arv_value_duplicate (const ArvValue *from)
347 {
348 ArvValue *value = g_new (ArvValue, 1);
349
350 if (from == NULL)
351 return NULL;
352
353 *value = *from;
354
355 return value;
356 }
357
358 GType
arv_value_get_type(void)359 arv_value_get_type (void)
360 {
361 GType type_id = 0;
362
363 if (type_id == 0)
364 type_id = g_boxed_type_register_static ("ArvValue",
365 (GBoxedCopyFunc) arv_value_duplicate,
366 (GBoxedFreeFunc) arv_value_free);
367
368 return type_id;
369 }
370
371 void
arv_value_set_int64(ArvValue * value,gint64 v_int64)372 arv_value_set_int64 (ArvValue *value, gint64 v_int64)
373 {
374 value->type = G_TYPE_INT64;
375 value->data.v_int64 = v_int64;
376 }
377
378 void
arv_value_set_double(ArvValue * value,double v_double)379 arv_value_set_double (ArvValue *value, double v_double)
380 {
381 value->type = G_TYPE_DOUBLE;
382 value->data.v_double = v_double;
383 }
384
385 gint64
arv_value_get_int64(ArvValue * value)386 arv_value_get_int64 (ArvValue *value)
387 {
388 if (value->type == G_TYPE_INT64)
389 return value->data.v_int64;
390 else
391 return (gint64) value->data.v_double;
392 }
393
394 double
arv_value_get_double(ArvValue * value)395 arv_value_get_double (ArvValue *value)
396 {
397 if (value->type == G_TYPE_INT64)
398 return (double) value->data.v_int64;
399 else
400 return value->data.v_double;
401 }
402
403 gboolean
arv_value_holds_int64(ArvValue * value)404 arv_value_holds_int64 (ArvValue *value)
405 {
406 return value->type == G_TYPE_INT64;
407 }
408
409 double
arv_value_holds_double(ArvValue * value)410 arv_value_holds_double (ArvValue *value)
411 {
412 return value->type == G_TYPE_DOUBLE;
413 }
414
415 void
arv_copy_memory_with_endianess(void * to,size_t to_size,guint to_endianess,void * from,size_t from_size,guint from_endianess)416 arv_copy_memory_with_endianess (void *to, size_t to_size, guint to_endianess,
417 void *from, size_t from_size, guint from_endianess)
418 {
419 char *to_ptr;
420 char *from_ptr;
421 int i;
422
423 g_return_if_fail (to != NULL);
424 g_return_if_fail (from != NULL);
425
426 if (to_endianess == G_LITTLE_ENDIAN &&
427 from_endianess == G_BIG_ENDIAN) {
428 to_ptr = to;
429 from_ptr = ((char *) from) + from_size - 1;
430 if (to_size <= from_size) {
431 for (i = 0; i < to_size; i++, to_ptr++, from_ptr--)
432 *to_ptr = *from_ptr;
433 } else {
434 for (i = 0; i < from_size; i++, to_ptr++, from_ptr--)
435 *to_ptr = *from_ptr;
436 memset (((char *) to) + from_size, 0, to_size - from_size);
437 }
438 } else if (to_endianess == G_BIG_ENDIAN &&
439 from_endianess == G_LITTLE_ENDIAN) {
440 to_ptr = ((char *) to) + to_size - 1;
441 from_ptr = from;
442 if (to_size <= from_size) {
443 for (i = 0; i < to_size; i++, to_ptr--, from_ptr++)
444 *to_ptr = *from_ptr;
445 } else {
446 for (i = 0; i < from_size; i++, to_ptr--, from_ptr++)
447 *to_ptr = *from_ptr;
448 memset (to, 0, to_size - from_size);
449 }
450 } else if (to_endianess == G_LITTLE_ENDIAN &&
451 from_endianess == G_LITTLE_ENDIAN) {
452 if (to_size <= from_size)
453 memcpy (to, from, to_size);
454 else {
455 memcpy (to, from, from_size);
456 memset (((char *) to) + from_size, 0, to_size - from_size);
457 }
458 } else if (to_endianess == G_BIG_ENDIAN &&
459 from_endianess == G_BIG_ENDIAN) {
460 if (to_size <= from_size)
461 memcpy (to, ((char *) from) + from_size - to_size, to_size);
462 else {
463 memcpy (((char *) to) + to_size - from_size, from, from_size);
464 memset (to, 0, to_size - from_size);
465 }
466 } else
467 g_assert_not_reached ();
468 }
469
470 #define ARV_DECOMPRESS_CHUNK 16384
471
472 /**
473 * arv_decompress:
474 * @input_buffer: compressed data
475 * @input_buffer: size of compressed data
476 * @output_size: (out): placeholder for inflated data
477 * Return value: (transfer full): a newly allocated buffer
478 **/
479
480 void *
arv_decompress(void * input_buffer,size_t input_size,size_t * output_size)481 arv_decompress (void *input_buffer, size_t input_size, size_t *output_size)
482 {
483 z_stream stream;
484 GByteArray *output;
485 guchar z_stream_output[ARV_DECOMPRESS_CHUNK];
486 unsigned have;
487 int result;
488
489 g_return_val_if_fail (input_buffer != NULL, NULL);
490 g_return_val_if_fail (input_size > 0, NULL);
491
492 /* allocate inflate state */
493 stream.zalloc = Z_NULL;
494 stream.zfree = Z_NULL;
495 stream.opaque = Z_NULL;
496 stream.avail_in = 0;
497 stream.next_in = Z_NULL;
498 stream.data_type = Z_UNKNOWN;
499
500 g_return_val_if_fail (inflateInit2(&stream, -MAX_WBITS) == Z_OK, NULL);
501
502 output = g_byte_array_new ();
503
504 /* decompress until deflate stream ends or end of file */
505 do {
506 stream.avail_in = MIN (input_size, ARV_DECOMPRESS_CHUNK);
507 stream.next_in = input_buffer;
508
509 arv_debug_misc ("[Decompress] Input ptr = 0x%x - Chunk size = %d - %c",
510 stream.next_in, stream.avail_in, *stream.next_in);
511
512 input_size -= stream.avail_in;
513 input_buffer = ((char *) input_buffer) + stream.avail_in;
514
515 /* run inflate() on input until output buffer not full */
516 do {
517 stream.avail_out = ARV_DECOMPRESS_CHUNK;
518 stream.next_out = z_stream_output;
519 result = inflate(&stream, Z_NO_FLUSH);
520 if (result == Z_STREAM_ERROR) {
521 arv_warning_misc ("[Decompress] Z_STREAM_ERROR");
522 goto CLEANUP;
523 }
524
525 switch (result) {
526 case Z_NEED_DICT:
527 arv_warning_misc ("[Decompress] Z_NEED_DICT");
528 goto CLEANUP;
529 case Z_DATA_ERROR:
530 arv_warning_misc ("[Decompress] Z_DATA_ERROR");
531 goto CLEANUP;
532 case Z_MEM_ERROR:
533 arv_warning_misc ("[Decompress] Z_MEM_ERROR");
534 goto CLEANUP;
535 }
536
537 have = ARV_DECOMPRESS_CHUNK - stream.avail_out;
538 g_byte_array_append (output, z_stream_output, have);
539 } while (stream.avail_out == 0);
540
541 /* done when inflate() says it's done */
542 } while (input_size > 0 && result != Z_STREAM_END);
543
544 /* clean up and return */
545 inflateEnd(&stream);
546
547 if (result != Z_STREAM_END) {
548 arv_warning_misc ("[Decompress] !Z_STREAM_END");
549 g_byte_array_free (output, TRUE);
550 if (output_size != NULL)
551 *output_size = 0;
552 return NULL;
553 }
554
555 if (output_size != NULL)
556 *output_size = output->len;
557
558 return g_byte_array_free (output, FALSE);
559
560 CLEANUP:
561
562 if (output_size != NULL)
563 *output_size = 0;
564
565 g_byte_array_free (output, TRUE);
566 inflateEnd(&stream);
567
568 return NULL;
569 }
570
571 /**
572 * SECTION: arvgst
573 * @short_description: Gstreamer utilities
574 */
575
576 #define ARV_MAKE_FOURCC(a,b,c,d) ((guint32)((a)|(b)<<8|(c)<<16|(d)<<24))
577
578 typedef struct {
579 ArvPixelFormat pixel_format;
580 const char *gst_caps_string;
581 const char *name;
582 const char *format;
583 const char *gst_0_10_caps_string;
584 const char *name_0_10;
585 int bpp;
586 int depth;
587 guint32 fourcc;
588 } ArvGstCapsInfos;
589
590 ArvGstCapsInfos arv_gst_caps_infos[] = {
591 {
592 ARV_PIXEL_FORMAT_MONO_8,
593 "video/x-raw, format=(string)GRAY8",
594 "video/x-raw", "GRAY8",
595 "video/x-raw-gray, bpp=(int)8, depth=(int)8",
596 "video/x-raw-gray", 8, 8, 0
597 },
598 {
599 ARV_PIXEL_FORMAT_MONO_16,
600 "video/x-raw, format=(string)GRAY16_LE",
601 "video/x-raw", "GRAY16_LE",
602 "video/x-raw-gray, bpp=(int)16, depth=(int)16",
603 "video/x-raw-gray", 16, 16, 0
604 },
605 {
606 ARV_PIXEL_FORMAT_MONO_12,
607 "video/x-raw, format=(string)GRAY16_LE",
608 "video/x-raw", "GRAY16_LE",
609 "video/x-raw-gray, bpp=(int)16, depth=(int)12",
610 "video/x-raw-gray", 16, 12, 0
611 },
612 {
613 ARV_PIXEL_FORMAT_MONO_12_PACKED,
614 "video/x-raw, format=(string)GRAY16_LE",
615 "video/x-raw", "GRAY16_LE",
616 "video/x-raw-gray, bpp=(int)12, depth=(int)12",
617 "video/x-raw-gray", 12, 12, 0
618 },
619 {
620 ARV_PIXEL_FORMAT_MONO_10,
621 "video/x-raw, format=(string)GRAY16_LE",
622 "video/x-raw", "GRAY16_LE",
623 "video/x-raw-gray, bpp=(int)16, depth=(int)10",
624 "video/x-raw-gray", 16, 10, 0
625 },
626 {
627 ARV_PIXEL_FORMAT_BAYER_GR_8,
628 "video/x-bayer, format=(string)grbg",
629 "video/x-bayer", "grbg",
630 "video/x-raw-bayer, format=(string)grbg, bpp=(int)8, depth=(int)8",
631 "video/x-raw-bayer", 8, 8, ARV_MAKE_FOURCC ('g','r','b','g')
632 },
633 {
634 ARV_PIXEL_FORMAT_BAYER_RG_8,
635 "video/x-bayer, format=(string)rggb",
636 "video/x-bayer", "rggb",
637 "video/x-raw-bayer, format=(string)rggb, bpp=(int)8, depth=(int)8",
638 "video/x-raw-bayer", 8, 8, ARV_MAKE_FOURCC ('r','g','g','b')
639 },
640 {
641 ARV_PIXEL_FORMAT_BAYER_GB_8,
642 "video/x-bayer, format=(string)gbrg",
643 "video/x-bayer", "gbrg",
644 "video/x-raw-bayer, format=(string)gbrg, bpp=(int)8, depth=(int)8",
645 "video/x-raw-bayer", 8, 8, ARV_MAKE_FOURCC ('g','b','r','g')
646 },
647 {
648 ARV_PIXEL_FORMAT_BAYER_BG_8,
649 "video/x-bayer, format=(string)bggr",
650 "video/x-bayer", "bggr",
651 "video/x-raw-bayer, format=(string)bggr, bpp=(int)8, depth=(int)8",
652 "video/x-raw-bayer", 8, 8, ARV_MAKE_FOURCC ('b','g','g','r')
653 },
654
655 /* Non 8bit bayer formats are not supported by gstreamer bayer plugin.
656 * This feature is discussed in bug https://bugzilla.gnome.org/show_bug.cgi?id=693666 .*/
657
658 {
659 ARV_PIXEL_FORMAT_YUV_422_PACKED,
660 "video/x-raw, format=(string)UYVY",
661 "video/x-raw", "UYVY",
662 "video/x-raw-yuv, format=(fourcc)UYVY",
663 "video/x-raw-yuv", 0, 0, ARV_MAKE_FOURCC ('U','Y','V','Y')
664 },
665 {
666 ARV_PIXEL_FORMAT_YUV_422_YUYV_PACKED,
667 "video/x-raw, format=(string)YUY2",
668 "video/x-raw", "YUY2",
669 "video/x-raw-yuv, format=(fourcc)YUYU2",
670 "video/x-raw-yuv", 0, 0, ARV_MAKE_FOURCC ('Y','U','Y','2')
671 },
672 {
673 ARV_PIXEL_FORMAT_RGB_8_PACKED,
674 "video/x-raw, format=(string)RGB",
675 "video/x-raw", "RGB",
676 "video/x-raw-rgb, format=(string)RGB, bpp=(int)24, depth=(int)24",
677 "video/x-raw-rgb", 24, 24, 0
678 },
679 {
680 ARV_PIXEL_FORMAT_CUSTOM_YUV_422_YUYV_PACKED,
681 "video/x-raw, format=(string)YUY2",
682 "video/x-raw", "YUY2",
683 "video/x-raw-yuv, format=(fourcc)YUYU2",
684 "video/x-raw-yuv", 0, 0, ARV_MAKE_FOURCC ('Y','U','Y','2')
685 }
686 };
687
688 /**
689 * arv_pixel_format_to_gst_caps_string:
690 * @pixel_format: a pixel format
691 * Return value: a gstreamer caps string describing the given @pixel_format.
692 */
693
694 const char *
arv_pixel_format_to_gst_caps_string(ArvPixelFormat pixel_format)695 arv_pixel_format_to_gst_caps_string (ArvPixelFormat pixel_format)
696 {
697 int i;
698
699 for (i = 0; i < G_N_ELEMENTS (arv_gst_caps_infos); i++)
700 if (arv_gst_caps_infos[i].pixel_format == pixel_format)
701 break;
702
703 if (i == G_N_ELEMENTS (arv_gst_caps_infos)) {
704 arv_warning_misc ("[PixelFormat::to_gst_caps_string] 0x%08x not found", pixel_format);
705 return NULL;
706 }
707
708 arv_log_misc ("[PixelFormat::to_gst_caps_string] 0x%08x -> %s",
709 pixel_format, arv_gst_caps_infos[i].gst_caps_string);
710
711 return arv_gst_caps_infos[i].gst_caps_string;
712 }
713
714 ArvPixelFormat
arv_pixel_format_from_gst_caps(const char * name,const char * format,int bpp,int depth)715 arv_pixel_format_from_gst_caps (const char *name, const char *format, int bpp, int depth)
716 {
717 unsigned int i;
718
719 g_return_val_if_fail (name != NULL, 0);
720
721 for (i = 0; i < G_N_ELEMENTS (arv_gst_caps_infos); i++) {
722 if (strcmp (name, arv_gst_caps_infos[i].name) != 0 ||
723 (depth > 0 && depth != arv_gst_caps_infos[i].depth) ||
724 (bpp > 0 && bpp != arv_gst_caps_infos[i].bpp))
725 continue;
726
727 if (strcmp (name, "video/x-raw") == 0 &&
728 strcmp (format, arv_gst_caps_infos[i].format) == 0)
729 return arv_gst_caps_infos[i].pixel_format;
730
731 if (strcmp (name, "video/x-bayer") == 0 &&
732 strcmp (format, arv_gst_caps_infos[i].format) == 0)
733 return arv_gst_caps_infos[i].pixel_format;
734 }
735
736 return 0;
737 }
738
739 const char *
arv_pixel_format_to_gst_0_10_caps_string(ArvPixelFormat pixel_format)740 arv_pixel_format_to_gst_0_10_caps_string (ArvPixelFormat pixel_format)
741 {
742 int i;
743
744 for (i = 0; i < G_N_ELEMENTS (arv_gst_caps_infos); i++)
745 if (arv_gst_caps_infos[i].pixel_format == pixel_format)
746 break;
747
748 if (i == G_N_ELEMENTS (arv_gst_caps_infos)) {
749 arv_warning_misc ("[PixelFormat::to_gst_0_10_caps_string] 0x%08x not found", pixel_format);
750 return NULL;
751 }
752
753 arv_log_misc ("[PixelFormat::to_gst_0_10_caps_string] 0x%08x -> %s",
754 pixel_format, arv_gst_caps_infos[i].gst_0_10_caps_string);
755
756 return arv_gst_caps_infos[i].gst_0_10_caps_string;
757 }
758
759 ArvPixelFormat
arv_pixel_format_from_gst_0_10_caps(const char * name,int bpp,int depth,guint32 fourcc)760 arv_pixel_format_from_gst_0_10_caps (const char *name, int bpp, int depth, guint32 fourcc)
761 {
762 unsigned int i;
763
764 g_return_val_if_fail (name != NULL, 0);
765
766 for (i = 0; i < G_N_ELEMENTS (arv_gst_caps_infos); i++) {
767 if (strcmp (name, arv_gst_caps_infos[i].name_0_10) != 0)
768 continue;
769
770 if (strcmp (name, "video/x-raw-yuv") == 0 &&
771 (fourcc <= 0 || fourcc == arv_gst_caps_infos[i].fourcc))
772 return arv_gst_caps_infos[i].pixel_format;
773
774 if ((depth <= 0 || depth == arv_gst_caps_infos[i].depth) &&
775 (bpp <= 0 || bpp == arv_gst_caps_infos[i].bpp) &&
776 fourcc == arv_gst_caps_infos[i].fourcc)
777 return arv_gst_caps_infos[i].pixel_format;
778 }
779
780 return 0;
781 }
782
783 static struct {
784 const char *vendor;
785 const char *alias;
786 } vendor_aliases[] = {
787 { "The Imaging Source Europe GmbH", "TIS"},
788 { "Point Grey Research", "PointGrey"}
789 };
790
791 /**
792 * arv_vendor_alias_lookup:
793 * @vendor: a vendor string
794 *
795 * Returns: vendor alias string if found, or @vendor if not found.
796 *
797 * Since: 0.6.0
798 */
799
800 const char *
arv_vendor_alias_lookup(const char * vendor)801 arv_vendor_alias_lookup (const char *vendor)
802 {
803 int i;
804
805 if (vendor == NULL)
806 return NULL;
807
808 for (i = 0; i < G_N_ELEMENTS (vendor_aliases); i++)
809 if (g_strcmp0 (vendor_aliases[i].vendor, vendor) == 0)
810 return vendor_aliases[i].alias;
811
812 return vendor;
813 }
814