Statistics
| Branch: | Revision:

root / rgbdslam / external / siftgpu / src / ServerSiftGPU / ServerSiftGPU.cpp @ 9240aaa3

History | View | Annotate | Download (24 KB)

1
////////////////////////////////////////////////////////////////////////////
2
//        File:                ServerSiftGPU.cpp
3
//        Author:                Changchang Wu
4
//        Description :        implementation for the ServerSiftGPU class.
5
//
6
//        Copyright (c) 2007 University of North Carolina at Chapel Hill
7
//        All Rights Reserved
8
//
9
//        Permission to use, copy, modify and distribute this software and its
10
//        documentation for educational, research and non-profit purposes, without
11
//        fee, and without a written agreement is hereby granted, provided that the
12
//        above copyright notice and the following paragraph appear in all copies.
13
//        
14
//        The University of North Carolina at Chapel Hill make no representations
15
//        about the suitability of this software for any purpose. It is provided
16
//        'as is' without express or implied warranty. 
17
//
18
//        Please send BUG REPORTS to ccwu@cs.unc.edu
19
//
20
////////////////////////////////////////////////////////////////////////////
21

    
22
#include <iostream>
23
#include <vector>
24

    
25
using std::cout;
26
using std::vector;
27

    
28

    
29
#if defined(SERVER_SIFTGPU_ENABLED)
30

    
31
#include "GL/glew.h"
32

    
33
#ifdef _WIN32
34
        #include <winsock2.h>
35
        #include <process.h>
36
        #define socklen_t int
37
    #pragma comment(lib,  "ws2_32.lib")
38
#else
39
    #include <string.h>
40
    #include <stdio.h>
41
    #include <stdlib.h>
42
        #include <sys/types.h>
43
        #include <sys/socket.h>
44
        #include <unistd.h>
45
        #include <pthread.h>
46
        #include <spawn.h>
47
        #include <netdb.h>
48
        #include <netinet/in.h>
49
        //conversion from Win32
50
        typedef int SOCKET;
51
        #define INVALID_SOCKET -1
52
        #define closesocket close
53
#endif
54

    
55
#include "../SiftGPU/SiftGPU.h"
56
#include "ServerSiftGPU.h"
57

    
58

    
59

    
60

    
61

    
62

    
63
class SocketUtil
64
{
65
public:
66
        static int readline(SOCKET s, char *buf, int nread)
67
        {
68
                char c;
69
                int  num,n=0;
70
                for(n=1; n<nread; n++)
71
                {
72
                        if((num=recv(s,&c,1,0))==1)
73
                        {
74
                                if(c== '\n')        break;        
75
                                if(c==0) *buf++=' ';
76
                                else *buf++=c;
77
                        }else if( num==0)
78
                        {
79
                                if(n==1)        return 0;
80
                                else                break;
81
                        }else 
82
                        {
83
                                return -1;
84
                        }                
85
                }
86
                *buf=0;        
87
                return n;
88
        }
89
        static int readint(SOCKET s, int* data, int count = 1)
90
        {
91
                int size = (sizeof(int) * count);
92
                data[0] = 0;
93
                return recv(s, (char*)data, size, 0) == size;
94
        }
95
        static int writeint(SOCKET s, int data)
96
        {
97
                int size = sizeof(int);
98
                return send(s, (char*) (&data), size, 0) == size;
99
        }
100
        static int writeint(SOCKET s, unsigned int data)
101
        {
102
                int size = sizeof(unsigned int);
103
                return send(s, (char*) (&data), size, 0) == size;
104
        }
105
        static int writedata(SOCKET s, const void* data, int count)
106
        {
107
                return send(s, (const char*)data, count, 0) == count;
108
        }
109
        static int readdata(SOCKET s, void* data, int count)
110
        {
111
                int count_read_sum = 0, count_read;
112
                char * p = (char*) data;
113
                do
114
                {
115
                        count_read =  recv(s, p, count - count_read_sum, 0);
116
                        p+= count_read;
117
                        count_read_sum += count_read;
118
                }while(count_read > 0 && count_read_sum < count);
119
                return  count_read_sum == count;
120
        }
121
        static int init()
122
        {
123
 
124
#ifdef _WIN32
125
                WSADATA                        WsaData; 
126
                if(WSAStartup(0x0202, &WsaData))
127
                {
128
                        std::cout << "server: can't startup socket\n";
129
                        return 0;
130
                }else
131
        {
132
            return 1;
133
        }
134
#else
135
                return 1;
136
#endif
137

    
138
        }
139
};
140

    
141

    
142
ServerSiftGPU::ServerSiftGPU(int port, char* remote_server)
143
{
144
        _port = port;
145
        _socketfd = INVALID_SOCKET;
146
    _connected = 0;
147
        strcpy(_server_name, remote_server? remote_server : "\0");
148
}
149

    
150
int ServerSiftGPU::InitSocket()
151
{
152
    return SocketUtil::init();
153
}
154

    
155

    
156
int ServerSiftGPU::StartServerProcess(int argc, char** argv)
157
{
158
        vector<char*> args(argc + 4);   char ports[16];
159

    
160
    args[0] = "server_siftgpu";           
161
    args[1] = "-server";
162
        sprintf(ports, "%d", _port);    
163
    args[2] = ports;
164
    ///////////////////////////////////////////////
165
        for(int i = 0; i < argc; ++i)         args[i + 3] = argv[i];
166
        args[argc + 3] = 0;
167
        ///////////////////////////////////////////////////////
168
        //make a new process
169
#ifdef _WIN32
170
    int result = (int) _spawnv(_P_NOWAIT, "server_siftgpu.exe", &args[0]);
171
    if(result == -1) std::cerr<< "spawn returns -1 with error = " << errno << "\n";
172
        return  result != -1;
173
#else
174
        #ifdef __APPLE__
175
        #define LIBPATH_NAME "DYLD_LIBRARY_PATH"
176
        #else
177
        #define LIBPATH_NAME "LD_LIBRARY_PATH"
178
        #endif
179
        int result;         pid_t pid; 
180
    char* oldpath = getenv(LIBPATH_NAME);
181
    if(oldpath == NULL)
182
    {
183
            result =  posix_spawn(&pid, "server_siftgpu", NULL, NULL, &args[0], NULL);
184
    }else
185
    {
186
        char newpath[1024]= LIBPATH_NAME "=";
187
        strcat(newpath, oldpath);
188
        char* envp [] = {newpath, 0};
189
        result = posix_spawn(&pid, "server_siftgpu", NULL, NULL, &args[0], envp);
190
    }
191
        if(result) std::cerr << "failed to use poxis_spawn to create the server.\n";
192
        return  result == 0;
193
#endif
194
}
195

    
196
int ServerSiftGPU::ConnectServer(const char* server_name, int port)
197
{
198
        struct hostent* hh;
199

    
200
        if((hh = gethostbyname(server_name)) == NULL)return 0;
201
        
202
        ////////////////////////////////////////
203
        struct sockaddr_in servaddr;        
204
        memset(&servaddr, 0, sizeof(servaddr));
205
        servaddr.sin_family = AF_INET;
206
        servaddr.sin_port = htons(port);
207
        servaddr.sin_addr.s_addr=((struct in_addr*)(hh->h_addr))->s_addr;
208

    
209
        ((SOCKET&)_socketfd) = socket(AF_INET, SOCK_STREAM, 0);
210
        if(_socketfd==INVALID_SOCKET) return 0;
211

    
212
        //if can not connect to server, start again
213
        if(connect(_socketfd, (struct sockaddr *)&servaddr, sizeof(servaddr)))
214
        {
215
                closesocket(_socketfd);
216
                _socketfd = INVALID_SOCKET;
217
                return 0;
218
        }else
219
        {
220
                std::cout<<"Connected to server " << server_name << "\n";
221
                return 1;
222
        }
223
}
224

    
225
void ServerSiftGPU::Disconnect()
226
{
227
        SocketUtil::writeint(_socketfd, _server_name[0]? COMMAND_DISCONNECT : COMMAND_EXIT);
228
        closesocket(_socketfd);
229
        _socketfd = INVALID_SOCKET;
230
        _connected = 0;
231
}
232

    
233
ServerSiftGPU::~ServerSiftGPU()
234
{
235
        if(_connected) Disconnect();
236
}
237

    
238

    
239
inline void ServerSiftGPU::ServerLoop(int port, int argc, char** argv)
240
{
241
        SOCKET sockfd, newsockfd;        
242
        struct        sockaddr_in        serv_addr, cli_addr;
243
        socklen_t addr_len = sizeof(sockaddr_in);
244
        //////////////////////////////////////////////////
245
        memset((char*)&serv_addr, 0, sizeof(serv_addr));
246
        serv_addr.sin_family        = AF_INET;
247
        serv_addr.sin_port        = htons(port);
248
        serv_addr.sin_addr.s_addr = INADDR_ANY;
249
        /////////////////////////////////////////////
250

    
251
    if(ServerSiftGPU::InitSocket() == 0)
252
        {
253
                return;
254
        }
255
        //////////////////////////////////////////////////////////////
256
        sockfd=socket(AF_INET,SOCK_STREAM,0);
257
        if(sockfd==INVALID_SOCKET) 
258
        {
259
                std::cout << "server: can't open stream socket\n";
260
                return;
261
        }else if(bind(sockfd,(struct sockaddr*)&serv_addr, sizeof(serv_addr)))
262
    {
263
            std::cout << "server: can't bind to port " <<  port <<"\n";
264
            return;
265
    }else if(listen(sockfd, 1))
266
        {
267
                std::cout << "server: failed to listen\n";
268
                return;
269
        }else
270
        {
271
                std::cout << "server: listent to port "<< port << "\n";
272
        }
273
                
274
        newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr, &addr_len);
275
        if(newsockfd == INVALID_SOCKET)
276
        {
277
                std::cout << "error: accept failed\n";
278
        closesocket(sockfd);
279
                return;
280
        }
281
        ////////////////////////////////////////////////////////////////
282
        char buf[1024];
283
        int command, result;
284
        int sift_feature_count = 0;;
285
        vector<SiftGPU::SiftKeypoint> keys;
286
        vector<float> descriptors;
287
        vector<char> databuf;
288

    
289
        /////////////////////////////////////////////////////////////////
290
        SiftGPU siftgpu;
291
        SiftMatchGPU matcher;
292

    
293
        if(argc > 0) siftgpu.ParseParam(argc, argv);
294
    
295
        /////////////////////
296
        siftgpu.SetVerbose(0);
297
        /////////////////////////////////////////////////////////////////
298

    
299
    do
300
    {
301
            while(SocketUtil::readint(newsockfd, &command) && command != COMMAND_DISCONNECT)
302
            {
303
                    switch(command)
304
                    {
305
                        case COMMAND_INITIALIZE:
306
                                {
307
                                    result = (siftgpu.CreateContextGL() == SiftGPU::SIFTGPU_FULL_SUPPORTED);
308
                                    SocketUtil::writeint(newsockfd, result);
309
                                    if(result)        break;
310
                                }
311
            case COMMAND_EXIT:
312
                closesocket(newsockfd);
313
                closesocket(sockfd);
314
                return;
315
                    case COMMAND_ALLOCATE_PYRAMID:
316
                            {
317
                                    int size[2];
318
                                    SocketUtil::readint(newsockfd, size, 2);
319
                                    if(size[0] > 0 && size[1] > 0) siftgpu.AllocatePyramid(size[0], size[1]);
320
                                    break;
321
                            }
322
                    case COMMAND_GET_KEY_VECTOR:
323
                            {
324
                                    int size = sift_feature_count * sizeof(SiftGPU::SiftKeypoint);
325
                                    SocketUtil::writedata(newsockfd, &keys[0], size);
326
                                    break;
327
                            }
328
                    case COMMAND_GET_DES_VECTOR:
329
                            {
330
                                    int size = sift_feature_count * sizeof(float) * 128;
331
                                    SocketUtil::writedata(newsockfd, &descriptors[0], size);
332
                                    break;
333
                            }
334
                    case COMMAND_RUNSIFT:
335
                            {
336
                                    result = siftgpu.RunSIFT();
337
                                    if((sift_feature_count = siftgpu.GetFeatureNum()) > 0)
338
                                    {
339
                                            keys.resize(sift_feature_count);
340
                                            descriptors.resize(sift_feature_count * 128);
341
                                            siftgpu.GetFeatureVector(&keys[0], &descriptors[0]);
342
                                                std::cout << "RunSIFT: [-] [" << sift_feature_count << "]\n";
343
                                    }
344
                                    SocketUtil::writeint(newsockfd, result);
345
                                    break;
346
                            }
347
                    case COMMAND_RUNSIFT_FILE:
348
                            {
349
                                    SocketUtil::readline(newsockfd, buf, 1024);
350

    
351
                                    result = siftgpu.RunSIFT(buf);
352
                                    if((sift_feature_count = siftgpu.GetFeatureNum()) > 0)
353
                                    {
354
                                            keys.resize(sift_feature_count);
355
                                            descriptors.resize(sift_feature_count * 128);
356
                                            siftgpu.GetFeatureVector(&keys[0], &descriptors[0]);
357
                                    }
358
                                        std::cout << "RunSIFT: "<< buf <<" " << sift_feature_count << "\n" ;
359
                                    SocketUtil::writeint(newsockfd, result);
360
                                    break;
361
                            }
362
                    case COMMAND_SET_KEYPOINT:
363
                            {
364
                                    int keys_have_orientation;
365
                                    SocketUtil::readint(newsockfd, &sift_feature_count);
366
                                    SocketUtil::readint(newsockfd, &keys_have_orientation);
367
                                    if(sift_feature_count > 0)
368
                                    {
369
                                            keys.resize(sift_feature_count);
370
                                            descriptors.resize(sift_feature_count * 128);
371
                                                SocketUtil::readdata(newsockfd, &keys[0], int(keys.size() * sizeof(SiftGPU::SiftKeypoint)));
372
                                            siftgpu.SetKeypointList(sift_feature_count, &keys[0], keys_have_orientation);
373
                                    }
374
                                    break;
375
                            }
376
                    case COMMAND_RUNSIFT_KEY:
377
                            {
378
                                    int keys_have_orientation;
379
                                    SocketUtil::readint(newsockfd, &sift_feature_count);
380
                                    SocketUtil::readint(newsockfd, &keys_have_orientation);
381
                                    if(sift_feature_count > 0)
382
                                    {
383
                                                std::cout << "RunSIFT: "<< sift_feature_count << " KEYPOINTS\n" ;
384
                                            int key_data_size = sift_feature_count * sizeof(SiftGPU::SiftKeypoint);
385
                                            keys.resize(sift_feature_count);
386
                                            descriptors.resize(sift_feature_count * 128);
387
                                            SocketUtil::readdata(newsockfd, &keys[0], key_data_size);
388
                                            result = siftgpu.RunSIFT(sift_feature_count, &keys[0], keys_have_orientation);
389
                                            siftgpu.GetFeatureVector(NULL, &descriptors[0]);
390
                                    }else
391
                                    {
392
                                            result = 0;
393
                                    }
394
                                    SocketUtil::writeint(newsockfd, result);
395
                                    break;
396
                            }
397
                    case COMMAND_RUNSIFT_DATA:
398
                            {
399
                                    int data_des[4], size = 0;        
400
                                    SocketUtil::readint(newsockfd, data_des, 4);
401
                                        SocketUtil::readint(newsockfd, &size, 1);
402
                                        std::cout << "RunSIFT: [" << data_des[0] << "x" << data_des[1] << "]";
403

    
404
                                        databuf.resize(size);
405
                                        void* data_ptr = &databuf[0];
406
                                        SocketUtil::readdata(newsockfd, data_ptr, size);
407

    
408

    
409
                                    result = siftgpu.RunSIFT(data_des[0], data_des[1], data_ptr, data_des[2], data_des[3]);
410
                                    if((sift_feature_count = siftgpu.GetFeatureNum()) > 0)
411
                                    {
412
                                            keys.resize(sift_feature_count);
413
                                            descriptors.resize(sift_feature_count * 128);
414
                                            siftgpu.GetFeatureVector(&keys[0], &descriptors[0]);
415
                                    }
416
                                        std::cout << "[" << sift_feature_count << "]\n";
417
                                    SocketUtil::writeint(newsockfd, result);
418
                                    break;
419
                            }
420
                    case COMMAND_SAVE_SIFT:
421
                            {
422
                                    SocketUtil::readline(newsockfd, buf, 1024);
423
                                    siftgpu.SaveSIFT(buf);
424
                                    break;
425
                            }
426
                    case COMMAND_SET_MAX_DIMENSION:
427
                            {
428
                                    int maxd;
429
                                    if(SocketUtil::readint(newsockfd, &maxd) && maxd > 0) siftgpu.SetMaxDimension(maxd);
430
                                    break;
431
                            }
432
                    case COMMAND_SET_TIGHTPYRAMID:
433
                            {
434
                                    int tight;
435
                                    if(SocketUtil::readint(newsockfd, &tight))  siftgpu.SetTightPyramid(tight);
436
                                    break;
437
                            }
438
                    case COMMAND_GET_FEATURE_COUNT:
439
                            {
440
                                    SocketUtil::writeint(newsockfd, sift_feature_count);
441
                                    break;
442
                            }
443
                        case COMMAND_PARSE_PARAM:
444
                                {
445
                                    SocketUtil::readline(newsockfd, buf, 1024);
446
                                        std::cout << "ParseParam [" << buf << "]\n";
447
                                        vector<char*> params;
448
                                        char* p = buf;
449
                                        while(*p)
450
                                        {
451
                                                while(*p == ' ' || *p == '\t')*p++ = 0;
452
                                                params.push_back(p);
453
                                                while(*p && *p != ' ' && *p != '\t') p++;
454
                                        }
455
                                        siftgpu.ParseParam(params.size(), &params[0]);
456
                                        break;
457
                                }
458
                        case COMMAND_MATCH_INITIALIZE:
459
                                {
460
                                        result = matcher.CreateContextGL();
461
                                        SocketUtil::writeint(newsockfd, result);
462
                                        break;
463
                                }
464
                        case COMMAND_MATCH_SET_LANGUAGE:
465
                                {
466
                                        int language;
467
                                        if(SocketUtil::readint(newsockfd, &language)) matcher.SetLanguage(language);
468
                                        break;
469
                                }
470
                        case COMMAND_MATCH_SET_DES_FLOAT:
471
                                {
472
                                        int command[3] = {0, 0, 0};
473
                                        if(SocketUtil::readdata(newsockfd, command, sizeof(command)))
474
                                        {
475
                                                databuf.resize(sizeof(float) * 128 * command[1]);
476
                                                if(SocketUtil::readdata(newsockfd, &databuf[0], databuf.size()))
477
                                                {
478
                                                        matcher.SetDescriptors(command[0], command[1], (float*) (&databuf[0]), command[2]);        
479
                                                }
480
                                        }
481
                                        break;
482
                                }
483
                        case COMMAND_MATCH_SET_DES_BYTE:
484
                                {
485
                                        int command[3] = {0, 0, 0};
486
                                        if(SocketUtil::readdata(newsockfd, command, sizeof(command)))
487
                                        {
488
                                                databuf.resize(sizeof(unsigned char) * 128 * command[1]);
489
                                                if(SocketUtil::readdata(newsockfd, &databuf[0], databuf.size()))
490
                                                {
491
                                                        matcher.SetDescriptors(command[0], command[1], (unsigned char*) (&databuf[0]), command[2]);        
492
                                                }
493
                                        }
494
                                        break;
495
                                }
496
                        case COMMAND_MATCH_GET_MATCH:
497
                                {
498
                                        int command[2]; float fcommand[2];
499
                                        result = 0;
500
                                        if( SocketUtil::readdata(newsockfd, command, sizeof(command)) &&
501
                                                SocketUtil::readdata(newsockfd, fcommand, sizeof(fcommand)))
502
                                        {
503
                                                int max_match  = command[0], mbm = command[1];
504
                                                float distmax = fcommand[0], ratiomax = fcommand[1];
505
                                                databuf.resize(max_match * 2 * sizeof(int));
506
                                                result = matcher.GetSiftMatch(max_match, ( int(*)[2]) (&databuf[0]), distmax, ratiomax, mbm);
507

    
508
                                        }
509
                                        SocketUtil::writeint(newsockfd, result);
510
                                        if(result > 0) SocketUtil::writedata(newsockfd, &databuf[0], sizeof(int) * 2 * result);
511
                                        std::cout << "SiftMatch: " <<  result << "\n"; 
512
                                        break;
513
                                }
514
                        case COMMAND_MATCH_SET_MAXSIFT:
515
                                {
516
                                        int max_sift;
517
                                        if(SocketUtil::readint(newsockfd, &max_sift)) matcher.SetMaxSift(max_sift);
518
                                        break;
519
                                }
520
                                break;
521
                    default:
522
                            std::cout << "unrecognized command: " << command << "\n";
523
                                break;
524
                    }
525
            }
526

    
527
        //client disconneted
528
        closesocket(newsockfd);
529
        //wait for the next client.
530
        std::cout << "wait for new client...";
531
            newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr, &addr_len);
532
            if(newsockfd == INVALID_SOCKET)
533
            {
534
                    std::cout << "error: accept failed";
535
            closesocket(sockfd);
536
                    return;
537
            }else
538
        {
539
            std::cout << "connected\n\n";
540
        }
541
   }while(1);
542
}
543

    
544
void ServerSiftGPU::SetParamSiftGPU(int argc, char** argv)
545
{
546
        if(!_connected || argc <= 0) return;
547

    
548
        char buf[1025], *p = buf, cret = '\n';
549
        for(int i = 0; i < argc; ++i)
550
        {
551
                if(argv[i])        
552
                {
553
                        strcpy(p, argv[i]);
554
                        p += strlen(argv[i]);
555
                }
556
                *p++= ((i +1 < argc)? ' ' : '\0');
557
        }
558
        SocketUtil::writeint(_socketfd, COMMAND_PARSE_PARAM);
559
        SocketUtil::writedata(_socketfd, buf, (p - buf));
560
        SocketUtil::writedata(_socketfd, &cret, 1);
561

    
562
}
563

    
564
int ServerSiftGPU:: InitializeConnection(int argc, char** argv)
565
{
566
        char server_name[1024]; 
567
        if(!InitSocket()) return 0 ;
568
    if(_server_name[0] == 0)
569
    {
570
            if(StartServerProcess(argc, argv) == 0) 
571
            {
572
                    std::cout<<"Unable to start local siftgpu server\n";
573
            return 0 ;
574
            }
575
        strcpy(server_name, "127.0.0.1");
576
    }else
577
    {
578
        strcpy(server_name, _server_name);
579
    }
580
        
581
    /////////////////////////////////////////////// 
582
        if(ConnectServer(server_name, _port) == 0)
583
        {
584
        //wait for one second
585
#ifdef _WIN32
586
            Sleep(1000);
587
#else
588
            sleep(1);
589
#endif
590
                if(ConnectServer(server_name, _port) == 0)
591
                {
592
                        std::cout<<"Unable to connect siftgpu sever\n";
593
                        return 0 ;
594
                }
595
        }
596
        return 1;
597
}
598

    
599
void ServerSiftGPU::ParseParam(int argc, char **argv)
600
{
601
    if(_connected == 1) 
602
        {
603
                SetParamSiftGPU(argc, argv); 
604
        }else        
605
        {
606
                _connected = InitializeConnection(argc, argv);
607
                if(_server_name[0] && argc > 0) SetParamSiftGPU(argc, argv);
608
        }
609
}
610

    
611
int ServerSiftGPU::VerifyContextGL()
612
{
613
                ////////////////////////////////////////////////////
614
        if(!_connected) return 0;
615

    
616
        int result = 0;
617

    
618
        if(SocketUtil::writeint(_socketfd, COMMAND_INITIALIZE) && 
619
                SocketUtil::readint(_socketfd, &result) && result)
620
        {
621
                return SiftGPU::SIFTGPU_FULL_SUPPORTED;
622
        }else
623
        {
624
                std::cout<<"SifGPU failed to initialize\n";
625
                Disconnect();
626
                return 0;
627
        }
628
}
629

    
630
int        ServerSiftGPU::GetFeatureNum()
631
{
632
        if(!_connected) return 0;
633
        int result = 0;
634
        SocketUtil::writeint(_socketfd, COMMAND_GET_FEATURE_COUNT);
635
        SocketUtil::readint(_socketfd, &result);
636
        return result;
637
}
638

    
639
int ServerSiftGPU::AllocatePyramid(int width, int height)
640
{
641
        if(!_connected) return 0;
642
        int command[3] = {COMMAND_ALLOCATE_PYRAMID, width, height};
643
        return SocketUtil::writedata(_socketfd, command, sizeof(int) * 3);
644
}
645

    
646
////////////////////////////////////////////////////////////
647
void ServerSiftGPU::SaveSIFT(const char * szFileName)
648
{
649
        if(!_connected) return;
650

    
651
        char cret = '\n';
652
        SocketUtil::writeint(_socketfd, COMMAND_SAVE_SIFT);
653
        SocketUtil::writedata(_socketfd, szFileName, (int)strlen(szFileName));
654
        SocketUtil::writedata(_socketfd, &cret, 1);
655

    
656
}
657

    
658
void ServerSiftGPU::GetFeatureVector(SiftGPU::SiftKeypoint * keys, float * descriptors)
659
{
660
        if(!_connected) return;
661

    
662
        int num = GetFeatureNum(), result = 1;
663
        if(keys && num > 0)
664
        {
665
                result&= SocketUtil::writeint(_socketfd, COMMAND_GET_KEY_VECTOR);
666
                result &= SocketUtil::readdata(_socketfd, keys, num * sizeof(SiftGPU::SiftKeypoint));
667
        }
668
        if(descriptors && num > 0)
669
        {
670
                result&= SocketUtil::writeint(_socketfd, COMMAND_GET_DES_VECTOR);
671
                result&= SocketUtil::readdata(_socketfd, descriptors, num * 128 * sizeof(float));
672
        }
673
}
674

    
675
void ServerSiftGPU::SetKeypointList(int num, const SiftGPU::SiftKeypoint * keys, int keys_have_orientation)
676
{
677
        if(!_connected) return;
678

    
679
        SocketUtil::writeint(_socketfd, COMMAND_SET_KEYPOINT);
680
        SocketUtil::writeint(_socketfd, num);
681
        SocketUtil::writeint(_socketfd, keys_have_orientation);
682
        SocketUtil::writedata(_socketfd, keys, sizeof(SiftGPU::SiftKeypoint) * num);        
683

    
684
}
685

    
686
void ServerSiftGPU::SetTightPyramid(int tight)
687
{
688
        if(!_connected) return ;
689
        SocketUtil::writeint(_socketfd, COMMAND_SET_TIGHTPYRAMID);
690
        SocketUtil::writeint(_socketfd, tight);
691

    
692
}
693

    
694
void ServerSiftGPU::SetMaxDimension(int sz)
695
{
696
        if(!_connected) return ;
697
        SocketUtil::writeint(_socketfd, COMMAND_SET_MAX_DIMENSION);
698
        SocketUtil::writeint(_socketfd, sz);
699

    
700
}
701

    
702
int ServerSiftGPU::GetPixelSizeGL(unsigned int gl_format, unsigned int gl_type)
703
{
704
    int num_channel_byte = 0;
705
    int num_channels  = 0;
706
    switch(gl_type)
707
    {
708
    case GL_BITMAP:
709
    case GL_UNSIGNED_BYTE:
710
    case GL_BYTE:
711
        num_channel_byte = 1;
712
        break;
713
    case GL_UNSIGNED_SHORT:
714
    case GL_SHORT:
715
        num_channel_byte = 2;
716
        break;
717
    case GL_UNSIGNED_INT:
718
    case GL_INT: 
719
    case GL_FLOAT:
720
        num_channel_byte = 4;
721
        break;
722
    default:
723
        num_channel_byte = 0;
724
        break;
725
    }
726

    
727
    switch(gl_format)
728
    {
729
    case GL_RED:
730
    case GL_GREEN:
731
    case GL_BLUE:
732
    case GL_ALPHA:
733
    case GL_LUMINANCE:
734
        num_channels = 1;
735
        break;
736
    case GL_RGB:
737
    case GL_BGR_EXT:
738
        num_channels = 3;
739
        break;
740
    case GL_RGBA:
741
    case GL_BGRA_EXT:
742
#ifdef GL_ARGB_I3D
743
    case GL_ARGB_I3D:
744
#endif
745
        num_channels = 4;
746
        break;
747
    case GL_LUMINANCE_ALPHA:
748
#ifdef GL_422_EXT
749
    case GL_422_EXT:
750
    case GL_422_REV_EXT: 
751
    case GL_422_AVERAGE_EXT:
752
    case GL_422_REV_AVERAGE_EXT:
753
#endif
754
        num_channels = 2;
755
    default:
756
        num_channels = 0;
757
        break;
758
    }
759
    return num_channels * num_channel_byte;
760
}
761

    
762
int ServerSiftGPU::RunSIFT(int width, int height, const void * data, unsigned int gl_format, unsigned int gl_type)
763
{
764
        if(width <=0 || height <= 0 || data == NULL || !_connected) return 0;
765
    int num_bytes = GetPixelSizeGL(gl_format , gl_type) * width * height;
766
    if(num_bytes == 0) return 0;
767
        SocketUtil::writeint(_socketfd, COMMAND_RUNSIFT_DATA);
768
        unsigned int data_des[5] = {width, height, gl_format, gl_type, num_bytes};
769
        SocketUtil::writedata(_socketfd, data_des, 5 * sizeof(unsigned int));
770
        SocketUtil::writedata(_socketfd, data, num_bytes);
771
        int result = 0;        
772
        return SocketUtil::readint(_socketfd, &result) && result;
773
}
774

    
775
int ServerSiftGPU::RunSIFT(int num, const SiftGPU::SiftKeypoint * keys, int keys_have_orientation)
776
{
777
        if(num <= 0 || keys == NULL) return 0;
778
        if(!_connected) return 0;
779
        SocketUtil::writeint(_socketfd, COMMAND_RUNSIFT_KEY);
780
        SocketUtil::writeint(_socketfd, num);
781
        SocketUtil::writeint(_socketfd, keys_have_orientation);
782
        SocketUtil::writedata(_socketfd, keys, sizeof(SiftGPU::SiftKeypoint) * num);
783
        int result = 0;        
784
        return SocketUtil::readint(_socketfd, &result) && result;
785
}
786

    
787
int ServerSiftGPU::RunSIFT()
788
{
789
        if(!_connected) return 0;
790
    int result = 0;
791
    SocketUtil::writeint(_socketfd, COMMAND_RUNSIFT);
792
        return SocketUtil::readint(_socketfd, &result) && result;
793
}
794

    
795
int ServerSiftGPU::RunSIFT(const char *imgpath)
796
{
797
        if(!_connected) return 0;
798
        int result = 0;        char cret = '\n';
799
        SocketUtil::writeint(_socketfd, COMMAND_RUNSIFT_FILE);
800
        SocketUtil::writedata(_socketfd, imgpath, (int)strlen(imgpath));
801
        SocketUtil::writedata(_socketfd, &cret, 1);
802
        return SocketUtil::readint(_socketfd, &result) && result;
803
}
804

    
805

    
806
////////////////////////////////////////////////
807
int ServerSiftGPU::_VerifyContextGL()
808
{
809
        if(!_connected) return 0;
810
        int result;
811
        if( SocketUtil::writeint(_socketfd, COMMAND_MATCH_INITIALIZE) &&
812
                SocketUtil::readint(_socketfd, &result) && result)
813
        {
814
                return 1;
815
        }else
816
        {
817
                Disconnect();
818
                return 0;
819
        }
820
}
821

    
822
void ServerSiftGPU::SetLanguage(int gpu_language)
823
{
824
        if(!_connected) return ;
825
        SocketUtil::writeint(_socketfd, COMMAND_MATCH_SET_LANGUAGE);
826
        SocketUtil::writeint(_socketfd, gpu_language);
827
}
828

    
829
void ServerSiftGPU::SetDeviceParam(int argc, char**argv)
830
{
831
    ServerSiftGPU::ParseParam(argc, argv);
832
}
833

    
834

    
835
void ServerSiftGPU::SetMaxSift(int max_sift)
836
{
837
        if(!_connected) return;
838
        SocketUtil::writeint(_socketfd,        COMMAND_MATCH_SET_MAXSIFT);
839
        SocketUtil::writeint(_socketfd, max_sift);
840
}
841

    
842
void ServerSiftGPU::SetDescriptors(int index, int num, const float* descriptors, int id)
843
{
844
        if(!_connected) return ;
845
        int command[4] = {COMMAND_MATCH_SET_DES_FLOAT, index, num, id};
846
        SocketUtil::writedata(_socketfd, command, sizeof(command));
847
        SocketUtil::writedata(_socketfd, descriptors, sizeof(float) * 128 * num);
848
}
849

    
850

    
851
void ServerSiftGPU::SetDescriptors(int index, int num, const unsigned char * descriptors, int id)
852
{
853
        if(!_connected) return ;
854
        int command[4] = {COMMAND_MATCH_SET_DES_BYTE, index, num, id};
855
        SocketUtil::writedata(_socketfd, command, sizeof(command));
856
        SocketUtil::writedata(_socketfd, descriptors, sizeof(unsigned char) * 128 * num);
857
}
858

    
859
int  ServerSiftGPU::GetSiftMatch(int max_match,        int match_buffer[][2], 
860
        float distmax, float ratiomax,        int mutual_best_match)
861
{
862
        if(!_connected) return 0;
863
        int command[3] = {COMMAND_MATCH_GET_MATCH, max_match, mutual_best_match};
864
        float fcommand[2] = {distmax, ratiomax};
865
        SocketUtil::writedata(_socketfd, command, sizeof(command));
866
        SocketUtil::writedata(_socketfd, fcommand, sizeof(fcommand));
867
        int nm;        SocketUtil::readint(_socketfd, &nm);
868
        if(nm > 0) SocketUtil::readint(_socketfd, match_buffer[0], 2 * nm);
869
        return nm;
870
}
871

    
872
void RunServerLoop(int port, int argc, char** argv)
873
{
874
    ServerSiftGPU::ServerLoop(port, argc, argv);
875
}
876

    
877

    
878
ComboSiftGPU* CreateRemoteSiftGPU(int port, char* remote_server)
879
{
880
        return new ServerSiftGPU(port, remote_server);
881
}
882

    
883

    
884
#else
885

    
886
#include "../SiftGPU/LiteWindow.h"
887
#include "../SiftGPU/SiftGPU.h"
888

    
889
ComboSiftGPU* CreateRemoteSiftGPU(int port, char* remote_server)
890
{
891
    std::cout << "ServerSiftGPU need marcro SERVER_SIFTGPU_EANBLED.\n"
892
              << "Use local SiftGPU/SiftMatchGPU instead. \n";
893
        return new ComboSiftGPU;
894
}
895

    
896
void RunServerLoop(int port, int argc, char** argv)
897
{
898
    std::cout << "ServerSiftGPU need marcro SERVER_SIFTGPU_EANBLED.\n"
899
 }
900

    
901
#endif
902