Reformat whole codebase with astyle.options (#128)
[openjpeg.git] / src / lib / openjpip / imgsock_manager.c
1 /*
2  * $Id$
3  *
4  * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
5  * Copyright (c) 2002-2014, Professor Benoit Macq
6  * Copyright (c) 2010-2011, Kaori Hagihara
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include "imgsock_manager.h"
35 #if _WIN32
36 #define strncasecmp _strnicmp
37 #endif
38
39 msgtype_t identify_clientmsg(SOCKET connected_socket)
40 {
41     OPJ_SIZE_T receive_size;
42     char buf[BUF_LEN];
43     static const char *magicid[] = { "JPIP-stream", "PNM request", "XML request",
44                                      "TID request", "CID request", "CID destroy", "SIZ request", "JP2 save",
45                                      "QUIT"
46                                    };
47     int i;
48
49     receive_size = receive_line(connected_socket, buf);
50
51     if (receive_size == 0) {
52         fprintf(stderr, "Error to receive the header of client message\n");
53         return MSGERROR;
54     }
55
56     for (i = 0; i < NUM_OF_MSGTYPES; i++) {
57         if (strncasecmp(magicid[i], buf, strlen(magicid[i])) == 0) {
58             fprintf(stderr, "%s\n", magicid[i]);
59             return i;
60         }
61     }
62
63     fprintf(stderr, "Cannot identify client message type %s\n", buf);
64     return MSGERROR;
65 }
66
67 Byte_t * receive_JPIPstream(SOCKET connected_socket, char **target, char **tid,
68                             char **cid, OPJ_SIZE_T *streamlen)
69 {
70     char buf[BUF_LEN];
71     const char versionstring[] = "version 1.2";
72     int idatalen;
73     OPJ_SIZE_T linelen, datalen;
74     Byte_t *jpipstream;
75
76     *target = *cid = *tid = NULL;
77
78     if ((linelen = receive_line(connected_socket, buf)) == 0) {
79         return NULL;
80     }
81     if (strncmp(versionstring, buf, strlen(versionstring)) != 0) {
82         fprintf(stderr, "Wrong format\n");
83         return NULL;
84     }
85
86     if ((linelen = receive_line(connected_socket, buf)) == 0) {
87         return NULL;
88     }
89
90     if (strstr(buf, "jp2")) {
91         /* register cid option*/
92         *target = strdup(buf);
93
94         if ((linelen = receive_line(connected_socket, buf)) == 0) {
95             return NULL;
96         }
97         if (strcmp(buf, "0") != 0) {
98             *tid = strdup(buf);
99         }
100
101         if ((linelen = receive_line(connected_socket, buf)) == 0) {
102             return NULL;
103         }
104         if (strcmp(buf, "0") != 0) {
105             *cid = strdup(buf);
106         }
107
108         if ((linelen = receive_line(connected_socket, buf)) == 0) {
109             return NULL;
110         }
111     }
112
113     idatalen = atoi(buf);
114     if (idatalen < 0) {
115         fprintf(stderr, "Receive Data: %d Bytes\n", idatalen);
116         return NULL;
117     }
118     datalen = (OPJ_SIZE_T)idatalen;
119     fprintf(stdout, "Receive Data: %lu Bytes\n", datalen);
120
121     jpipstream = receive_stream(connected_socket, datalen);
122
123     /* check EOR*/
124     if (jpipstream[datalen - 3] == 0x00 && (jpipstream[datalen - 2] == 0x01 ||
125                                             jpipstream[datalen - 2] == 0x02)) {
126         *streamlen = datalen - 3;
127     } else {
128         *streamlen = datalen;
129     }
130
131     return jpipstream;
132 }
133
134 void send_XMLstream(SOCKET connected_socket, Byte_t *xmlstream,
135                     OPJ_SIZE_T length)
136 {
137     Byte_t header[5];
138
139     header[0] = 'X';
140     header[1] = 'M';
141     header[2] = 'L';
142     header[3] = (Byte_t)((length >> 8) & 0xff);
143     header[4] = (Byte_t)(length & 0xff);
144
145     send_stream(connected_socket, header, 5);
146     send_stream(connected_socket, xmlstream, length);
147 }
148
149 void send_IDstream(SOCKET connected_socket, const char *id, OPJ_SIZE_T idlen,
150                    const char *label);
151
152 void send_CIDstream(SOCKET connected_socket, const char *cid, OPJ_SIZE_T cidlen)
153 {
154     send_IDstream(connected_socket, cid, cidlen, "CID");
155 }
156
157 void send_TIDstream(SOCKET connected_socket, const char *tid, OPJ_SIZE_T tidlen)
158 {
159     send_IDstream(connected_socket, tid, tidlen, "TID");
160 }
161
162 void send_IDstream(SOCKET connected_socket, const char *id, OPJ_SIZE_T idlen,
163                    const char *label)
164 {
165     char header[4];
166
167     header[0] = label[0];
168     header[1] = label[1];
169     header[2] = label[2];
170     header[3] = (char)(idlen & 0xff);
171
172     send_stream(connected_socket, header, 4);
173     send_stream(connected_socket, id, idlen);
174 }
175
176 void send_PNMstream(SOCKET connected_socket, Byte_t *pnmstream,
177                     unsigned int width, unsigned int height, unsigned int numofcomp, Byte_t maxval)
178 {
179     OPJ_SIZE_T pnmlen = 0;
180     Byte_t header[7];
181
182     pnmlen = width * height * numofcomp;
183
184     header[0] = 'P';
185     header[1] = numofcomp == 3 ? 6 : 5;
186     header[2] = (width >> 8) & 0xff;
187     header[3] = width & 0xff;
188     header[4] = (height >> 8) & 0xff;
189     header[5] = height & 0xff;
190     header[6] = maxval;
191
192     send_stream(connected_socket, header, 7);
193     send_stream(connected_socket, pnmstream, pnmlen);
194 }
195
196 void send_SIZstream(SOCKET connected_socket, unsigned int width,
197                     unsigned int height)
198 {
199     Byte_t response[9];
200
201     response[0] = 'S';
202     response[1] = 'I';
203     response[2] = 'Z';
204     response[3] = (width >> 16) & 0xff;
205     response[4] = (width >> 8) & 0xff;
206     response[5] = width & 0xff;
207     response[6] = (height >> 16) & 0xff;
208     response[7] = (height >> 8) & 0xff;
209     response[8] = height & 0xff;
210
211     send_stream(connected_socket, response, 9);
212 }
213
214 void response_signal(SOCKET connected_socket, OPJ_BOOL succeed)
215 {
216     Byte_t code;
217
218     if (succeed) {
219         code = 1;
220     } else {
221         code = 0;
222     }
223
224     send_stream(connected_socket, &code, 1);
225 }