4337e608f94d73ad77ce2bae6593f2160664affb
[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   int i;
47   
48   receive_size = receive_line( connected_socket, buf);
49
50   if( receive_size == 0){ 
51     fprintf( stderr, "Error to receive the header of client message\n");
52     return MSGERROR;
53   }
54
55   for( i=0; i<NUM_OF_MSGTYPES; i++){
56     if( strncasecmp( magicid[i], buf, strlen(magicid[i])) == 0){
57       fprintf( stderr, "%s\n", magicid[i]);
58       return i;
59     }
60   }
61   
62   fprintf( stderr, "Cannot identify client message type %s\n", buf);
63   return MSGERROR;
64 }
65
66 Byte_t * receive_JPIPstream( SOCKET connected_socket, char **target, char **tid, char **cid, OPJ_SIZE_T *streamlen)
67 {
68   char buf[BUF_LEN];
69   const char versionstring[] = "version 1.2";
70   int idatalen;
71   OPJ_SIZE_T linelen, datalen;
72   Byte_t *jpipstream;
73   
74   *target = *cid = *tid = NULL;
75   
76   if((linelen = receive_line( connected_socket, buf)) == 0)
77     return NULL;
78   if( strncmp( versionstring, buf, strlen(versionstring))!=0){
79     fprintf( stderr, "Wrong format\n");
80     return NULL;
81   }
82   
83   if((linelen = receive_line( connected_socket, buf)) == 0)
84     return NULL;
85
86   if( strstr( buf, "jp2")){ 
87     /* register cid option*/
88     *target = strdup( buf);
89     
90     if((linelen = receive_line( connected_socket, buf)) == 0)
91       return NULL;
92     if( strcmp( buf, "0") != 0)
93       *tid = strdup( buf);
94
95     if((linelen = receive_line( connected_socket, buf)) == 0)
96       return NULL;
97     if( strcmp( buf, "0") != 0)
98       *cid = strdup( buf);
99     
100     if((linelen = receive_line( connected_socket, buf)) == 0)
101       return NULL;
102   }
103
104   idatalen = atoi( buf);
105   if( idatalen < 0 )
106     {
107     fprintf( stderr, "Receive Data: %d Bytes\n", idatalen);
108     return NULL;
109     }
110   datalen = (OPJ_SIZE_T)idatalen;
111   fprintf( stdout, "Receive Data: %lu Bytes\n", datalen);
112
113   jpipstream = receive_stream( connected_socket, datalen);
114
115   /* check EOR*/
116   if( jpipstream[datalen-3] == 0x00 && ( jpipstream[datalen-2] == 0x01 || jpipstream[datalen-2] == 0x02))
117     *streamlen = datalen -3;
118   else
119     *streamlen = datalen;
120   
121   return jpipstream;
122 }
123
124 void send_XMLstream( SOCKET connected_socket, Byte_t *xmlstream, OPJ_SIZE_T length)
125 {
126   Byte_t header[5];
127   
128   header[0] = 'X';
129   header[1] = 'M';
130   header[2] = 'L';
131   header[3] = (Byte_t)((length >> 8) & 0xff);
132   header[4] = (Byte_t)(length & 0xff);
133
134   send_stream( connected_socket, header, 5);
135   send_stream( connected_socket, xmlstream, length);
136 }
137
138 void send_IDstream(  SOCKET connected_socket, const char *id, OPJ_SIZE_T idlen, const char *label);
139
140 void send_CIDstream( SOCKET connected_socket, const char *cid, OPJ_SIZE_T cidlen)
141 {
142   send_IDstream( connected_socket, cid, cidlen, "CID");
143 }
144
145 void send_TIDstream( SOCKET connected_socket, const char *tid, OPJ_SIZE_T tidlen)
146 {
147   send_IDstream( connected_socket, tid, tidlen, "TID");
148 }
149
150 void send_IDstream(  SOCKET connected_socket, const char *id, OPJ_SIZE_T idlen, const char *label)
151 {
152   char header[4];
153
154   header[0] = label[0];
155   header[1] = label[1];
156   header[2] = label[2];
157   header[3] = (char)(idlen & 0xff);
158
159   send_stream( connected_socket, header, 4);
160   send_stream( connected_socket, id, idlen);
161 }
162
163 void send_PNMstream( SOCKET connected_socket, Byte_t *pnmstream, unsigned int width, unsigned int height, unsigned int numofcomp, Byte_t maxval)
164
165   OPJ_SIZE_T pnmlen = 0;
166   Byte_t header[7];
167
168   pnmlen = width*height*numofcomp;
169   
170   header[0] = 'P';
171   header[1] = numofcomp==3 ? 6:5;
172   header[2] = (width >> 8) & 0xff;
173   header[3] = width & 0xff;
174   header[4] = (height >> 8) & 0xff;
175   header[5] = height & 0xff;
176   header[6] = maxval;
177
178   send_stream( connected_socket, header, 7);
179   send_stream( connected_socket, pnmstream, pnmlen);
180 }
181
182 void send_SIZstream( SOCKET connected_socket, unsigned int width, unsigned int height)
183 {
184   Byte_t response[9];
185   
186   response[0] = 'S';
187   response[1] = 'I';
188   response[2] = 'Z';
189   response[3] = (width >> 16) & 0xff;
190   response[4] = (width >> 8) & 0xff;
191   response[5] = width & 0xff;
192   response[6] = (height >> 16) & 0xff;
193   response[7] = (height >> 8) & 0xff;
194   response[8] = height & 0xff;
195
196   send_stream( connected_socket, response, 9);
197 }
198
199 void response_signal( SOCKET connected_socket, OPJ_BOOL succeed)
200 {
201   Byte_t code;
202
203   if( succeed)
204     code = 1;
205   else
206     code = 0;
207
208   send_stream( connected_socket, &code, 1);
209 }