1 /* babl - dynamically extendable universal pixel conversion library.
2  * Copyright (C) 2009 Martin Nordholts
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 3 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General
15  * Public License along with this library; if not, see
16  * <https://www.gnu.org/licenses/>.
17  */
18 
19 
20 #include "config.h"
21 
22 #include <stdlib.h>
23 #include <pthread.h>
24 
25 #include "babl.h"
26 
27 
28 #define N_THREADS 10
29 #define N_PIXELS  1000000 /* (per thread) */
30 
31 
32 /* should be the same as HASH_TABLE_SIZE in babl/babl-palette.c */
33 #define BABL_PALETTE_HASH_TABLE_SIZE 1111
34 
35 
36 typedef struct
37 {
38   const Babl    *fish;
39   unsigned char  src[4 * N_PIXELS];
40   unsigned char  dest[N_PIXELS];
41 } ThreadContext;
42 
43 
44 static void *
thread_proc(void * data)45 thread_proc (void *data)
46 {
47   ThreadContext *ctx = data;
48 
49   babl_process (ctx->fish, ctx->src, ctx->dest, N_PIXELS);
50 
51   return NULL;
52 }
53 
54 int
main(int argc,char ** argv)55 main (int    argc,
56       char **argv)
57 {
58   const Babl    *pal;
59   const Babl    *pal_format;
60   unsigned char  colors[4 * N_THREADS];
61   pthread_t      threads[N_THREADS];
62   ThreadContext *ctx[N_THREADS];
63   int            i, j;
64   int            OK = 1;
65 
66   babl_init ();
67 
68   /* create a palette of N_THREADS different colors, all of which have the same
69    * hash
70    */
71   pal = babl_new_palette (NULL, &pal_format, NULL);
72 
73   for (i = 0; i < N_THREADS; i++)
74     {
75       unsigned char *p = &colors[4 * i];
76       unsigned int   v;
77 
78       v = i * BABL_PALETTE_HASH_TABLE_SIZE;
79 
80       p[0] = (v >>  0) & 0xff;
81       p[1] = (v >>  8) & 0xff;
82       p[2] = (v >> 16) & 0xff;
83       p[3] = 0xff;
84     }
85 
86   babl_palette_set_palette (pal, babl_format ("R'G'B'A u8"), colors, N_THREADS);
87 
88   /* initialize the thread contexts such that each thread processes a buffer
89    * containing a single, distinct color
90    */
91   for (i = 0; i < N_THREADS; i++)
92     {
93       ctx[i] = malloc (sizeof (ThreadContext));
94 
95       ctx[i]->fish = babl_fish (babl_format ("R'G'B'A u8"), pal_format);
96 
97       for (j = 0; j < 4 * N_PIXELS; j++)
98         {
99           ctx[i]->src[j] = colors[4 * i + j % 4];
100         }
101     }
102 
103   /* run all threads at the same time */
104   for (i = 0; i < N_THREADS; i++)
105     {
106       pthread_create (&threads[i],
107                       NULL, /* attr */
108                       thread_proc,
109                       ctx[i]);
110     }
111 
112   /* wait for them to finish */
113   for (i = 0; i < N_THREADS; i++)
114     {
115       pthread_join (threads[i],
116                     NULL /* thread_return */);
117     }
118 
119   /* verify the results */
120   for (i = 0; i < N_THREADS; i++)
121     {
122       for (j = 0; OK && j < N_PIXELS; j++)
123         {
124           OK = (ctx[i]->dest[j] == i);
125         }
126 
127       free (ctx[i]);
128     }
129 
130   babl_exit ();
131 
132   return ! OK;
133 }
134