rdex-client colour histogram calculation and upload
[rdex:client.git] / src / upload.c
1 /* =====================================================================
2 rdex -- reaction-diffusion explorer
3 Copyright (C) 2008  Claude Heiland-Allen <claudiusmaximus@goto10.org>
4 ------------------------------------------------------------------------
5 Uploader
6 ===================================================================== */
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include <curl/curl.h>
11 #include "upload.h"
12 #include "histogram.h"
13
14 //======================================================================
15 // initialise uploader
16 struct upload *upload_init(
17   struct upload *upload
18 ) {
19   CURLcode c = curl_global_init(CURL_GLOBAL_ALL);
20   if (c) { return 0; }
21   upload->url = getenv("RDEX_UPLOAD");
22   return upload;
23 }
24
25 //======================================================================
26 // clean up uploader
27 void upload_atexit(
28   struct upload *upload
29 ) {
30   curl_global_cleanup();
31 }
32
33 //======================================================================
34 // prepare an upload
35 struct upload_data *upload_prepare(
36   struct upload *upload,
37   float ru, float rv, float f, float k, const char *behaviour,
38   float coarseness_u, float contrast_u, float directionality_u,
39   float coarseness_v, float contrast_v, float directionality_v,
40   const struct histogram *histogram, const char *ppm, int ppm_bytes
41 ) {
42   if (ppm_bytes > UPLOAD_DATA_PPMLEN) {
43     return NULL;
44   }
45   struct upload_data *data = malloc(sizeof(struct upload_data));
46   if (data) {
47     snprintf(data->ru,               UPLOAD_DATA_STRLEN, "%f", ru);
48     snprintf(data->rv,               UPLOAD_DATA_STRLEN, "%f", rv);
49     snprintf(data->f,                UPLOAD_DATA_STRLEN, "%f", f);
50     snprintf(data->k,                UPLOAD_DATA_STRLEN, "%f", k);
51     snprintf(data->behaviour,        UPLOAD_DATA_STRLEN, "%s", behaviour);
52     snprintf(data->coarseness_u,     UPLOAD_DATA_STRLEN, "%f", coarseness_u);
53     snprintf(data->contrast_u,       UPLOAD_DATA_STRLEN, "%f", contrast_u);
54     snprintf(data->directionality_u, UPLOAD_DATA_STRLEN, "%f", directionality_u);
55     snprintf(data->coarseness_v,     UPLOAD_DATA_STRLEN, "%f", coarseness_v);
56     snprintf(data->contrast_v,       UPLOAD_DATA_STRLEN, "%f", contrast_v);
57     snprintf(data->directionality_v, UPLOAD_DATA_STRLEN, "%f", directionality_v);
58     for (int r = 0; r < HISTOGRAM_BUCKETS; ++r) {
59     for (int g = 0; g < HISTOGRAM_BUCKETS; ++g) {
60     for (int b = 0; b < HISTOGRAM_BUCKETS; ++b) {
61       snprintf(data->histogram[r][g][b], UPLOAD_DATA_STRLEN, "%f", histogram->bucket[r][g][b]);
62     }
63     }
64     }
65     memcpy(data->ppm, ppm, ppm_bytes);
66     data->ppm_bytes = ppm_bytes;
67   }
68   return data;
69 }
70
71 //======================================================================
72 // clean an upload
73 void upload_cleanup(
74   struct upload_data *data
75 ) {
76   if (data) {
77     free(data);
78   }
79 }
80
81
82 //======================================================================
83 // do an upload
84 void upload_upload(
85   struct upload *upload,
86   const struct upload_data *data
87 ) {
88   if (! upload->url) { return; }
89   struct curl_httppost *formpost = NULL;
90   struct curl_httppost *lastptr = NULL;
91   curl_formadd(
92     &formpost, &lastptr,
93     CURLFORM_COPYNAME, "ru",
94     CURLFORM_COPYCONTENTS, data->ru,
95     CURLFORM_END
96   );
97   curl_formadd(
98     &formpost, &lastptr,
99     CURLFORM_COPYNAME, "rv",
100     CURLFORM_COPYCONTENTS, data->rv,
101     CURLFORM_END
102   );
103   curl_formadd(
104     &formpost, &lastptr,
105     CURLFORM_COPYNAME, "f",
106     CURLFORM_COPYCONTENTS, data->f,
107     CURLFORM_END
108   );
109   curl_formadd(
110     &formpost, &lastptr,
111     CURLFORM_COPYNAME, "k",
112     CURLFORM_COPYCONTENTS, data->k,
113     CURLFORM_END
114   );
115   curl_formadd(
116     &formpost, &lastptr,
117     CURLFORM_COPYNAME, "behaviour",
118     CURLFORM_COPYCONTENTS, data->behaviour,
119     CURLFORM_END
120   );
121   curl_formadd(
122     &formpost, &lastptr,
123     CURLFORM_COPYNAME, "coarseness_u",
124     CURLFORM_COPYCONTENTS, data->coarseness_u,
125     CURLFORM_END
126   );
127   curl_formadd(
128     &formpost, &lastptr,
129     CURLFORM_COPYNAME, "contrast_u",
130     CURLFORM_COPYCONTENTS, data->contrast_u,
131     CURLFORM_END
132   );
133   curl_formadd(
134     &formpost, &lastptr,
135     CURLFORM_COPYNAME, "directionality_u",
136     CURLFORM_COPYCONTENTS, data->directionality_u,
137     CURLFORM_END
138   );
139   curl_formadd(
140     &formpost, &lastptr,
141     CURLFORM_COPYNAME, "coarseness_v",
142     CURLFORM_COPYCONTENTS, data->coarseness_u,
143     CURLFORM_END
144   );
145   curl_formadd(
146     &formpost, &lastptr,
147     CURLFORM_COPYNAME, "contrast_v",
148     CURLFORM_COPYCONTENTS, data->contrast_u,
149     CURLFORM_END
150   );
151   curl_formadd(
152     &formpost, &lastptr,
153     CURLFORM_COPYNAME, "directionality_v",
154     CURLFORM_COPYCONTENTS, data->directionality_u,
155     CURLFORM_END
156   );
157   for (int r = 0; r < HISTOGRAM_BUCKETS; ++r) {
158   for (int g = 0; g < HISTOGRAM_BUCKETS; ++g) {
159   for (int b = 0; b < HISTOGRAM_BUCKETS; ++b) {
160     char hist[UPLOAD_DATA_STRLEN];
161     snprintf(hist, UPLOAD_DATA_STRLEN, "hist_%d_%d_%d", r, g, b);
162     curl_formadd(
163       &formpost, &lastptr,
164       CURLFORM_COPYNAME, hist,
165       CURLFORM_COPYCONTENTS, data->histogram[r][g][b],
166       CURLFORM_END
167     );
168   }
169   }
170   }
171   curl_formadd(
172     &formpost, &lastptr,
173     CURLFORM_COPYNAME, "image",
174     CURLFORM_BUFFER, "rdex.ppm",
175     CURLFORM_BUFFERPTR, data->ppm,
176     CURLFORM_BUFFERLENGTH, data->ppm_bytes,
177     CURLFORM_END
178   );
179   curl_formadd(
180     &formpost, &lastptr,
181     CURLFORM_COPYNAME, "submit",
182     CURLFORM_COPYCONTENTS, "submit",
183     CURLFORM_END
184   );
185   CURL *curl = curl_easy_init();
186   if (curl) {
187     curl_easy_setopt(curl, CURLOPT_URL, upload->url);
188     curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
189     curl_easy_perform(curl);
190     curl_easy_cleanup(curl);
191     curl_formfree(formpost);
192   }
193 }
194
195 // EOF