1 /*
2 * Copyright (C) 2000-2006 Constantin Kaplinsky. All Rights Reserved.
3 * Copyright (C) 2000 Tridia Corporation. All Rights Reserved.
4 * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
5 *
6 * This is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This software is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this software; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 * USA.
20 */
21
22 /*
23 * rfbproto.c - functions to deal with client side of RFB protocol.
24 */
25
26 #include <unistd.h>
27 #include <errno.h>
28 #include <pwd.h>
29 #include <vncviewer.h>
30 #include <vncauth.h>
31 #include <zlib.h>
32 #include <jpeglib.h>
33
34 static void InitCapabilities(void);
35 static Bool SetupTunneling(void);
36 static int ReadSecurityType(void);
37 static int SelectSecurityType(void);
38 static Bool PerformAuthenticationTight(void);
39 static Bool AuthenticateVNC(void);
40 static Bool AuthenticateNone(void);
41 static Bool ReadAuthenticationResult(void);
42 static Bool ReadInteractionCaps(void);
43 static Bool ReadCapabilityList(CapsContainer *caps, int count);
44
45 static Bool HandleRRE8(int rx, int ry, int rw, int rh);
46 static Bool HandleRRE16(int rx, int ry, int rw, int rh);
47 static Bool HandleRRE32(int rx, int ry, int rw, int rh);
48 static Bool HandleCoRRE8(int rx, int ry, int rw, int rh);
49 static Bool HandleCoRRE16(int rx, int ry, int rw, int rh);
50 static Bool HandleCoRRE32(int rx, int ry, int rw, int rh);
51 static Bool HandleHextile8(int rx, int ry, int rw, int rh);
52 static Bool HandleHextile16(int rx, int ry, int rw, int rh);
53 static Bool HandleHextile32(int rx, int ry, int rw, int rh);
54 static Bool HandleZlib8(int rx, int ry, int rw, int rh);
55 static Bool HandleZlib16(int rx, int ry, int rw, int rh);
56 static Bool HandleZlib32(int rx, int ry, int rw, int rh);
57 static Bool HandleTight8(int rx, int ry, int rw, int rh);
58 static Bool HandleTight16(int rx, int ry, int rw, int rh);
59 static Bool HandleTight32(int rx, int ry, int rw, int rh);
60
61 static void ReadConnFailedReason(void);
62 static long ReadCompactLen (void);
63
64 static void JpegInitSource(j_decompress_ptr cinfo);
65 static boolean JpegFillInputBuffer(j_decompress_ptr cinfo);
66 static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes);
67 static void JpegTermSource(j_decompress_ptr cinfo);
68 static void JpegSetSrcManager(j_decompress_ptr cinfo, CARD8 *compressedData,
69 int compressedLen);
70
71
72 int rfbsock;
73 char *desktopName;
74 rfbPixelFormat myFormat;
75 rfbServerInitMsg si;
76 char *serverCutText = NULL;
77 Bool newServerCutText = False;
78
79 int endianTest = 1;
80
81 static int protocolMinorVersion;
82 static Bool tightVncProtocol = False;
83 static CapsContainer *tunnelCaps; /* known tunneling/encryption methods */
84 static CapsContainer *authCaps; /* known authentication schemes */
85 static CapsContainer *serverMsgCaps; /* known non-standard server messages */
86 static CapsContainer *clientMsgCaps; /* known non-standard client messages */
87 static CapsContainer *encodingCaps; /* known encodings besides Raw */
88
89
90 /* Note that the CoRRE encoding uses this buffer and assumes it is big enough
91 to hold 255 * 255 * 32 bits -> 260100 bytes. 640*480 = 307200 bytes.
92 Hextile also assumes it is big enough to hold 16 * 16 * 32 bits.
93 Tight encoding assumes BUFFER_SIZE is at least 16384 bytes. */
94
95 #define BUFFER_SIZE (640*480)
96 static char buffer[BUFFER_SIZE];
97
98
99 /* The zlib encoding requires expansion/decompression/deflation of the
100 compressed data in the "buffer" above into another, result buffer.
101 However, the size of the result buffer can be determined precisely
102 based on the bitsPerPixel, height and width of the rectangle. We
103 allocate this buffer one time to be the full size of the buffer. */
104
105 static int raw_buffer_size = -1;
106 static char *raw_buffer;
107
108 static z_stream decompStream;
109 static Bool decompStreamInited = False;
110
111
112 /*
113 * Variables for the ``tight'' encoding implementation.
114 */
115
116 /* Separate buffer for compressed data. */
117 #define ZLIB_BUFFER_SIZE 512
118 static char zlib_buffer[ZLIB_BUFFER_SIZE];
119
120 /* Four independent compression streams for zlib library. */
121 static z_stream zlibStream[4];
122 static Bool zlibStreamActive[4] = {
123 False, False, False, False
124 };
125
126 /* Filter stuff. Should be initialized by filter initialization code. */
127 static Bool cutZeros;
128 static int rectWidth, rectColors;
129 static char tightPalette[256*4];
130 static CARD8 tightPrevRow[2048*3*sizeof(CARD16)];
131
132 /* JPEG decoder state. */
133 static Bool jpegError;
134
135
136 /*
137 * InitCapabilities.
138 */
139
140 static void
InitCapabilities(void)141 InitCapabilities(void)
142 {
143 tunnelCaps = CapsNewContainer();
144 authCaps = CapsNewContainer();
145 serverMsgCaps = CapsNewContainer();
146 clientMsgCaps = CapsNewContainer();
147 encodingCaps = CapsNewContainer();
148
149 /* Supported authentication methods */
150 CapsAdd(authCaps, rfbAuthNone, rfbStandardVendor, sig_rfbAuthNone,
151 "No authentication");
152 CapsAdd(authCaps, rfbAuthVNC, rfbStandardVendor, sig_rfbAuthVNC,
153 "Standard VNC password authentication");
154
155 /* Supported encoding types */
156 CapsAdd(encodingCaps, rfbEncodingCopyRect, rfbStandardVendor,
157 sig_rfbEncodingCopyRect, "Standard CopyRect encoding");
158 CapsAdd(encodingCaps, rfbEncodingRRE, rfbStandardVendor,
159 sig_rfbEncodingRRE, "Standard RRE encoding");
160 CapsAdd(encodingCaps, rfbEncodingCoRRE, rfbStandardVendor,
161 sig_rfbEncodingCoRRE, "Standard CoRRE encoding");
162 CapsAdd(encodingCaps, rfbEncodingHextile, rfbStandardVendor,
163 sig_rfbEncodingHextile, "Standard Hextile encoding");
164 CapsAdd(encodingCaps, rfbEncodingZlib, rfbTridiaVncVendor,
165 sig_rfbEncodingZlib, "Zlib encoding from TridiaVNC");
166 CapsAdd(encodingCaps, rfbEncodingTight, rfbTightVncVendor,
167 sig_rfbEncodingTight, "Tight encoding by Constantin Kaplinsky");
168
169 /* Supported "fake" encoding types */
170 CapsAdd(encodingCaps, rfbEncodingCompressLevel0, rfbTightVncVendor,
171 sig_rfbEncodingCompressLevel0, "Compression level");
172 CapsAdd(encodingCaps, rfbEncodingQualityLevel0, rfbTightVncVendor,
173 sig_rfbEncodingQualityLevel0, "JPEG quality level");
174 CapsAdd(encodingCaps, rfbEncodingXCursor, rfbTightVncVendor,
175 sig_rfbEncodingXCursor, "X-style cursor shape update");
176 CapsAdd(encodingCaps, rfbEncodingRichCursor, rfbTightVncVendor,
177 sig_rfbEncodingRichCursor, "Rich-color cursor shape update");
178 CapsAdd(encodingCaps, rfbEncodingPointerPos, rfbTightVncVendor,
179 sig_rfbEncodingPointerPos, "Pointer position update");
180 CapsAdd(encodingCaps, rfbEncodingLastRect, rfbTightVncVendor,
181 sig_rfbEncodingLastRect, "LastRect protocol extension");
182 }
183
184
185 /*
186 * ConnectToRFBServer.
187 */
188
189 Bool
ConnectToRFBServer(const char * hostname,int port)190 ConnectToRFBServer(const char *hostname, int port)
191 {
192 unsigned int host;
193
194 if (!StringToIPAddr(hostname, &host)) {
195 fprintf(stderr,"Couldn't convert '%s' to host address\n", hostname);
196 return False;
197 }
198
199 rfbsock = ConnectToTcpAddr(host, port);
200
201 if (rfbsock < 0) {
202 fprintf(stderr,"Unable to connect to VNC server\n");
203 return False;
204 }
205
206 return SetNonBlocking(rfbsock);
207 }
208
209
210 /*
211 * InitialiseRFBConnection.
212 */
213
214 Bool
InitialiseRFBConnection(void)215 InitialiseRFBConnection(void)
216 {
217 rfbProtocolVersionMsg pv;
218 int server_major, server_minor;
219 rfbClientInitMsg ci;
220 int secType;
221
222 /* if the connection is immediately closed, don't report anything, so
223 that pmw's monitor can make test connections */
224
225 if (listenSpecified)
226 errorMessageOnReadFailure = False;
227
228 if (!ReadFromRFBServer(pv, sz_rfbProtocolVersionMsg))
229 return False;
230
231 errorMessageOnReadFailure = True;
232
233 pv[sz_rfbProtocolVersionMsg] = 0;
234
235 if (sscanf(pv, rfbProtocolVersionFormat,
236 &server_major, &server_minor) != 2) {
237 fprintf(stderr,"Not a valid VNC server\n");
238 return False;
239 }
240
241 if (server_major == 3 && server_minor >= 8) {
242 /* the server supports protocol 3.8 or higher version */
243 protocolMinorVersion = 8;
244 } else if (server_major == 3 && server_minor == 7) {
245 /* the server supports protocol 3.7 */
246 protocolMinorVersion = 7;
247 } else {
248 /* any other server version, request the standard 3.3 */
249 protocolMinorVersion = 3;
250 }
251
252 fprintf(stderr, "Connected to RFB server, using protocol version 3.%d\n",
253 protocolMinorVersion);
254
255 sprintf(pv, rfbProtocolVersionFormat, 3, protocolMinorVersion);
256
257 if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg))
258 return False;
259
260 /* Read or select the security type. */
261 if (protocolMinorVersion >= 7) {
262 secType = SelectSecurityType();
263 } else {
264 secType = ReadSecurityType();
265 }
266 if (secType == rfbSecTypeInvalid)
267 return False;
268
269 switch (secType) {
270 case rfbSecTypeNone:
271 if (!AuthenticateNone())
272 return False;
273 break;
274 case rfbSecTypeVncAuth:
275 if (!AuthenticateVNC())
276 return False;
277 break;
278 case rfbSecTypeTight:
279 tightVncProtocol = True;
280 InitCapabilities();
281 if (!SetupTunneling())
282 return False;
283 if (!PerformAuthenticationTight())
284 return False;
285 break;
286 default: /* should never happen */
287 fprintf(stderr, "Internal error: Invalid security type\n");
288 return False;
289 }
290
291 ci.shared = (appData.shareDesktop ? 1 : 0);
292
293 if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg))
294 return False;
295
296 if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg))
297 return False;
298
299 si.framebufferWidth = Swap16IfLE(si.framebufferWidth);
300 si.framebufferHeight = Swap16IfLE(si.framebufferHeight);
301 si.format.redMax = Swap16IfLE(si.format.redMax);
302 si.format.greenMax = Swap16IfLE(si.format.greenMax);
303 si.format.blueMax = Swap16IfLE(si.format.blueMax);
304 si.nameLength = Swap32IfLE(si.nameLength);
305
306 /* FIXME: Check arguments to malloc() calls. */
307 desktopName = malloc(si.nameLength + 1);
308 if (!desktopName) {
309 fprintf(stderr, "Error allocating memory for desktop name, %lu bytes\n",
310 (unsigned long)si.nameLength);
311 return False;
312 }
313
314 if (!ReadFromRFBServer(desktopName, si.nameLength)) return False;
315
316 desktopName[si.nameLength] = 0;
317
318 fprintf(stderr,"Desktop name \"%s\"\n",desktopName);
319
320 fprintf(stderr,"VNC server default format:\n");
321 PrintPixelFormat(&si.format);
322
323 if (tightVncProtocol) {
324 /* Read interaction capabilities (protocol 3.7t, 3.8t) */
325 if (!ReadInteractionCaps())
326 return False;
327 }
328
329 return True;
330 }
331
332
333 /*
334 * Read security type from the server (protocol 3.3)
335 */
336
337 static int
ReadSecurityType(void)338 ReadSecurityType(void)
339 {
340 CARD32 secType;
341
342 /* Read the security type */
343 if (!ReadFromRFBServer((char *)&secType, sizeof(secType)))
344 return rfbSecTypeInvalid;
345
346 secType = Swap32IfLE(secType);
347
348 if (secType == rfbSecTypeInvalid) {
349 ReadConnFailedReason();
350 return rfbSecTypeInvalid;
351 }
352
353 if (secType != rfbSecTypeNone && secType != rfbSecTypeVncAuth) {
354 fprintf(stderr, "Unknown security type from RFB server: %d\n",
355 (int)secType);
356 return rfbSecTypeInvalid;
357 }
358
359 return (int)secType;
360 }
361
362
363 /*
364 * Select security type from the server's list (protocol 3.7 and above)
365 */
366
367 static int
SelectSecurityType(void)368 SelectSecurityType(void)
369 {
370 CARD8 nSecTypes;
371 char *secTypeNames[] = {"None", "VncAuth"};
372 CARD8 knownSecTypes[] = {rfbSecTypeNone, rfbSecTypeVncAuth};
373 int nKnownSecTypes = sizeof(knownSecTypes);
374 CARD8 *secTypes;
375 CARD8 secType = rfbSecTypeInvalid;
376 int i, j;
377
378 /* Read the list of secutiry types. */
379 if (!ReadFromRFBServer((char *)&nSecTypes, sizeof(nSecTypes)))
380 return rfbSecTypeInvalid;
381
382 if (nSecTypes == 0) {
383 ReadConnFailedReason();
384 return rfbSecTypeInvalid;
385 }
386
387 secTypes = malloc(nSecTypes);
388 if (!ReadFromRFBServer((char *)secTypes, nSecTypes))
389 return rfbSecTypeInvalid;
390
391 /* Find out if the server supports TightVNC protocol extensions */
392 for (j = 0; j < (int)nSecTypes; j++) {
393 if (secTypes[j] == rfbSecTypeTight) {
394 free(secTypes);
395 secType = rfbSecTypeTight;
396 if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType)))
397 return rfbSecTypeInvalid;
398 fprintf(stderr, "Enabling TightVNC protocol extensions\n");
399 return rfbSecTypeTight;
400 }
401 }
402
403 /* Find first supported security type */
404 for (j = 0; j < (int)nSecTypes; j++) {
405 for (i = 0; i < nKnownSecTypes; i++) {
406 if (secTypes[j] == knownSecTypes[i]) {
407 secType = secTypes[j];
408 if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType))) {
409 free(secTypes);
410 return rfbSecTypeInvalid;
411 }
412 break;
413 }
414 }
415 if (secType != rfbSecTypeInvalid) break;
416 }
417
418 free(secTypes);
419
420 if (secType == rfbSecTypeInvalid)
421 fprintf(stderr, "Server did not offer supported security type\n");
422
423 return (int)secType;
424 }
425
426
427 /*
428 * Setup tunneling (protocol 3.7t, 3.8t).
429 */
430
431 static Bool
SetupTunneling(void)432 SetupTunneling(void)
433 {
434 rfbTunnelingCapsMsg caps;
435 CARD32 tunnelType;
436
437 /* In protocols 3.7t/3.8t, the server informs us about
438 supported tunneling methods. Here we read this information. */
439
440 if (!ReadFromRFBServer((char *)&caps, sz_rfbTunnelingCapsMsg))
441 return False;
442
443 caps.nTunnelTypes = Swap32IfLE(caps.nTunnelTypes);
444
445 if (caps.nTunnelTypes) {
446 if (!ReadCapabilityList(tunnelCaps, caps.nTunnelTypes))
447 return False;
448
449 /* We cannot do tunneling anyway yet. */
450 tunnelType = Swap32IfLE(rfbNoTunneling);
451 if (!WriteExact(rfbsock, (char *)&tunnelType, sizeof(tunnelType)))
452 return False;
453 }
454
455 return True;
456 }
457
458
459 /*
460 * Negotiate authentication scheme (protocol 3.7t, 3.8t)
461 */
462
463 static Bool
PerformAuthenticationTight(void)464 PerformAuthenticationTight(void)
465 {
466 rfbAuthenticationCapsMsg caps;
467 CARD32 authScheme;
468 int i;
469
470 /* In protocols 3.7t/3.8t, the server informs us about supported
471 authentication schemes. Here we read this information. */
472
473 if (!ReadFromRFBServer((char *)&caps, sz_rfbAuthenticationCapsMsg))
474 return False;
475
476 caps.nAuthTypes = Swap32IfLE(caps.nAuthTypes);
477
478 /* Special case - empty capability list stands for no authentication. */
479 if (!caps.nAuthTypes)
480 return AuthenticateNone();
481
482 if (!ReadCapabilityList(authCaps, caps.nAuthTypes))
483 return False;
484
485 /* Try server's preferred authentication scheme. */
486 for (i = 0; i < CapsNumEnabled(authCaps); i++) {
487 authScheme = CapsGetByOrder(authCaps, i);
488 if (authScheme != rfbAuthVNC && authScheme != rfbAuthNone)
489 continue; /* unknown scheme - cannot use it */
490 authScheme = Swap32IfLE(authScheme);
491 if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme)))
492 return False;
493 authScheme = Swap32IfLE(authScheme); /* convert it back */
494
495 switch (authScheme) {
496 case rfbAuthNone:
497 return AuthenticateNone();
498 case rfbAuthVNC:
499 return AuthenticateVNC();
500 default: /* should never happen */
501 fprintf(stderr, "Internal error: Invalid authentication type\n");
502 return False;
503 }
504 }
505
506 fprintf(stderr, "No suitable authentication schemes offered by server\n");
507 return False;
508 }
509
510
511 /*
512 * Null authentication.
513 */
514
515 static Bool
AuthenticateNone(void)516 AuthenticateNone(void)
517 {
518 fprintf(stderr, "No authentication needed\n");
519
520 if (protocolMinorVersion >= 8) {
521 if (!ReadAuthenticationResult())
522 return False;
523 }
524
525 return True;
526 }
527
528
529 /*
530 * Standard VNC authentication.
531 */
532
533 static Bool
AuthenticateVNC(void)534 AuthenticateVNC(void)
535 {
536 CARD32 authScheme;
537 CARD8 challenge[CHALLENGESIZE];
538 char *passwd;
539 char buffer[64];
540 char* cstatus;
541 int len;
542
543 fprintf(stderr, "Performing standard VNC authentication\n");
544
545 if (!ReadFromRFBServer((char *)challenge, CHALLENGESIZE))
546 return False;
547
548 if (appData.passwordFile) {
549 passwd = vncDecryptPasswdFromFile(appData.passwordFile);
550 if (!passwd) {
551 fprintf(stderr, "Cannot read valid password from file \"%s\"\n",
552 appData.passwordFile);
553 return False;
554 }
555 } else if (appData.autoPass) {
556 passwd = buffer;
557 cstatus = fgets(buffer, sizeof buffer, stdin);
558 if (cstatus == NULL)
559 buffer[0] = '\0';
560 else
561 {
562 len = strlen(buffer);
563 if (len > 0 && buffer[len - 1] == '\n')
564 buffer[len - 1] = '\0';
565 }
566 } else if (appData.passwordDialog) {
567 passwd = DoPasswordDialog();
568 } else {
569 passwd = getpass("Password: ");
570 }
571
572 if (!passwd) {
573 fprintf(stderr, "Reading password failed\n");
574 return False;
575 }
576 if (strlen(passwd) > 8) {
577 passwd[8] = '\0';
578 }
579
580 vncEncryptBytes(challenge, passwd);
581
582 /* Lose the password from memory */
583 memset(passwd, '\0', strlen(passwd));
584
585 if (!WriteExact(rfbsock, (char *)challenge, CHALLENGESIZE))
586 return False;
587
588 return ReadAuthenticationResult();
589 }
590
591 /*
592 * Read and report the result of authentication.
593 */
594
595 static Bool
ReadAuthenticationResult(void)596 ReadAuthenticationResult(void)
597 {
598 CARD32 authResult;
599
600 if (!ReadFromRFBServer((char *)&authResult, 4))
601 return False;
602
603 authResult = Swap32IfLE(authResult);
604
605 switch (authResult) {
606 case rfbAuthOK:
607 fprintf(stderr, "Authentication successful\n");
608 break;
609 case rfbAuthFailed:
610 if (protocolMinorVersion >= 8) {
611 ReadConnFailedReason();
612 } else {
613 fprintf(stderr, "Authentication failure\n");
614 }
615 return False;
616 case rfbAuthTooMany:
617 fprintf(stderr, "Authentication failure, too many tries\n");
618 return False;
619 default:
620 fprintf(stderr, "Unknown result of authentication (%d)\n",
621 (int)authResult);
622 return False;
623 }
624
625 return True;
626 }
627
628 /*
629 * In protocols 3.7t/3.8t, the server informs us about supported
630 * protocol messages and encodings. Here we read this information.
631 */
632
633 static Bool
ReadInteractionCaps(void)634 ReadInteractionCaps(void)
635 {
636 rfbInteractionCapsMsg intr_caps;
637
638 /* Read the counts of list items following */
639 if (!ReadFromRFBServer((char *)&intr_caps, sz_rfbInteractionCapsMsg))
640 return False;
641 intr_caps.nServerMessageTypes = Swap16IfLE(intr_caps.nServerMessageTypes);
642 intr_caps.nClientMessageTypes = Swap16IfLE(intr_caps.nClientMessageTypes);
643 intr_caps.nEncodingTypes = Swap16IfLE(intr_caps.nEncodingTypes);
644
645 /* Read the lists of server- and client-initiated messages */
646 return (ReadCapabilityList(serverMsgCaps, intr_caps.nServerMessageTypes) &&
647 ReadCapabilityList(clientMsgCaps, intr_caps.nClientMessageTypes) &&
648 ReadCapabilityList(encodingCaps, intr_caps.nEncodingTypes));
649 }
650
651
652 /*
653 * Read the list of rfbCapabilityInfo structures and enable corresponding
654 * capabilities in the specified container. The count argument specifies how
655 * many records to read from the socket.
656 */
657
658 static Bool
ReadCapabilityList(CapsContainer * caps,int count)659 ReadCapabilityList(CapsContainer *caps, int count)
660 {
661 rfbCapabilityInfo msginfo;
662 int i;
663
664 for (i = 0; i < count; i++) {
665 if (!ReadFromRFBServer((char *)&msginfo, sz_rfbCapabilityInfo))
666 return False;
667 msginfo.code = Swap32IfLE(msginfo.code);
668 CapsEnable(caps, &msginfo);
669 }
670
671 return True;
672 }
673
674
675 /*
676 * SetFormatAndEncodings.
677 */
678
679 Bool
SetFormatAndEncodings()680 SetFormatAndEncodings()
681 {
682 rfbSetPixelFormatMsg spf;
683 char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4];
684 rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf;
685 CARD32 *encs = (CARD32 *)(&buf[sz_rfbSetEncodingsMsg]);
686 int len = 0;
687 Bool requestCompressLevel = False;
688 Bool requestQualityLevel = False;
689 Bool requestLastRectEncoding = False;
690
691 spf.type = rfbSetPixelFormat;
692 spf.format = myFormat;
693 spf.format.redMax = Swap16IfLE(spf.format.redMax);
694 spf.format.greenMax = Swap16IfLE(spf.format.greenMax);
695 spf.format.blueMax = Swap16IfLE(spf.format.blueMax);
696
697 if (!WriteExact(rfbsock, (char *)&spf, sz_rfbSetPixelFormatMsg))
698 return False;
699
700 se->type = rfbSetEncodings;
701 se->nEncodings = 0;
702
703 if (appData.encodingsString) {
704 char *encStr = appData.encodingsString;
705 int encStrLen;
706 do {
707 char *nextEncStr = strchr(encStr, ' ');
708 if (nextEncStr) {
709 encStrLen = nextEncStr - encStr;
710 nextEncStr++;
711 } else {
712 encStrLen = strlen(encStr);
713 }
714
715 if (strncasecmp(encStr,"raw",encStrLen) == 0) {
716 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw);
717 } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) {
718 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect);
719 } else if (strncasecmp(encStr,"tight",encStrLen) == 0) {
720 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight);
721 requestLastRectEncoding = True;
722 if (appData.compressLevel >= 0 && appData.compressLevel <= 9)
723 requestCompressLevel = True;
724 if (appData.enableJPEG)
725 requestQualityLevel = True;
726 } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) {
727 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile);
728 } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) {
729 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib);
730 if (appData.compressLevel >= 0 && appData.compressLevel <= 9)
731 requestCompressLevel = True;
732 } else if (strncasecmp(encStr,"corre",encStrLen) == 0) {
733 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE);
734 } else if (strncasecmp(encStr,"rre",encStrLen) == 0) {
735 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRRE);
736 } else {
737 fprintf(stderr,"Unknown encoding '%.*s'\n",encStrLen,encStr);
738 }
739
740 encStr = nextEncStr;
741 } while (encStr && se->nEncodings < MAX_ENCODINGS);
742
743 if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) {
744 encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel +
745 rfbEncodingCompressLevel0);
746 }
747
748 if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) {
749 if (appData.qualityLevel < 0 || appData.qualityLevel > 9)
750 appData.qualityLevel = 5;
751 encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel +
752 rfbEncodingQualityLevel0);
753 }
754
755 if (appData.useRemoteCursor) {
756 if (se->nEncodings < MAX_ENCODINGS)
757 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor);
758 if (se->nEncodings < MAX_ENCODINGS)
759 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor);
760 if (se->nEncodings < MAX_ENCODINGS)
761 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos);
762 }
763
764 if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) {
765 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
766 }
767 }
768 else {
769 if (SameMachine(rfbsock)) {
770 if (!tunnelSpecified) {
771 fprintf(stderr,"Same machine: preferring raw encoding\n");
772 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw);
773 } else {
774 fprintf(stderr,"Tunneling active: preferring tight encoding\n");
775 }
776 }
777
778 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect);
779 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight);
780 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile);
781 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib);
782 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE);
783 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRRE);
784
785 if (appData.compressLevel >= 0 && appData.compressLevel <= 9) {
786 encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel +
787 rfbEncodingCompressLevel0);
788 } else if (!tunnelSpecified) {
789 /* If -tunnel option was provided, we assume that server machine is
790 not in the local network so we use default compression level for
791 tight encoding instead of fast compression. Thus we are
792 requesting level 1 compression only if tunneling is not used. */
793 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCompressLevel1);
794 }
795
796 if (appData.enableJPEG) {
797 if (appData.qualityLevel < 0 || appData.qualityLevel > 9)
798 appData.qualityLevel = 5;
799 encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel +
800 rfbEncodingQualityLevel0);
801 }
802
803 if (appData.useRemoteCursor) {
804 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor);
805 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor);
806 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos);
807 }
808
809 encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
810 }
811
812 len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
813
814 se->nEncodings = Swap16IfLE(se->nEncodings);
815
816 if (!WriteExact(rfbsock, buf, len)) return False;
817
818 return True;
819 }
820
821
822 /*
823 * SendIncrementalFramebufferUpdateRequest.
824 */
825
826 Bool
SendIncrementalFramebufferUpdateRequest()827 SendIncrementalFramebufferUpdateRequest()
828 {
829 return SendFramebufferUpdateRequest(0, 0, si.framebufferWidth,
830 si.framebufferHeight, True);
831 }
832
833
834 /*
835 * SendFramebufferUpdateRequest.
836 */
837
838 Bool
SendFramebufferUpdateRequest(int x,int y,int w,int h,Bool incremental)839 SendFramebufferUpdateRequest(int x, int y, int w, int h, Bool incremental)
840 {
841 rfbFramebufferUpdateRequestMsg fur;
842
843 fur.type = rfbFramebufferUpdateRequest;
844 fur.incremental = incremental ? 1 : 0;
845 fur.x = Swap16IfLE(x);
846 fur.y = Swap16IfLE(y);
847 fur.w = Swap16IfLE(w);
848 fur.h = Swap16IfLE(h);
849
850 if (!WriteExact(rfbsock, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg))
851 return False;
852
853 return True;
854 }
855
856
857 /*
858 * SendPointerEvent.
859 */
860
861 Bool
SendPointerEvent(int x,int y,int buttonMask)862 SendPointerEvent(int x, int y, int buttonMask)
863 {
864 rfbPointerEventMsg pe;
865
866 pe.type = rfbPointerEvent;
867 pe.buttonMask = buttonMask;
868 if (x < 0) x = 0;
869 if (y < 0) y = 0;
870
871 if (!appData.useX11Cursor)
872 SoftCursorMove(x, y);
873
874 pe.x = Swap16IfLE(x);
875 pe.y = Swap16IfLE(y);
876 return WriteExact(rfbsock, (char *)&pe, sz_rfbPointerEventMsg);
877 }
878
879
880 /*
881 * SendKeyEvent.
882 */
883
884 Bool
SendKeyEvent(CARD32 key,Bool down)885 SendKeyEvent(CARD32 key, Bool down)
886 {
887 rfbKeyEventMsg ke;
888
889 ke.type = rfbKeyEvent;
890 ke.down = down ? 1 : 0;
891 ke.key = Swap32IfLE(key);
892 return WriteExact(rfbsock, (char *)&ke, sz_rfbKeyEventMsg);
893 }
894
895
896 /*
897 * SendClientCutText.
898 */
899
900 Bool
SendClientCutText(char * str,int len)901 SendClientCutText(char *str, int len)
902 {
903 rfbClientCutTextMsg cct;
904
905 if (serverCutText)
906 free(serverCutText);
907 serverCutText = NULL;
908
909 cct.type = rfbClientCutText;
910 cct.length = Swap32IfLE(len);
911 return (WriteExact(rfbsock, (char *)&cct, sz_rfbClientCutTextMsg) &&
912 WriteExact(rfbsock, str, len));
913 }
914
915
916 /*
917 * HandleRFBServerMessage.
918 */
919
920 Bool
HandleRFBServerMessage()921 HandleRFBServerMessage()
922 {
923 rfbServerToClientMsg msg;
924
925 if (!ReadFromRFBServer((char *)&msg, 1))
926 return False;
927
928 switch (msg.type) {
929
930 case rfbSetColourMapEntries:
931 {
932 int i;
933 CARD16 rgb[3];
934 XColor xc;
935
936 if (!ReadFromRFBServer(((char *)&msg) + 1,
937 sz_rfbSetColourMapEntriesMsg - 1))
938 return False;
939
940 msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour);
941 msg.scme.nColours = Swap16IfLE(msg.scme.nColours);
942
943 for (i = 0; i < msg.scme.nColours; i++) {
944 if (!ReadFromRFBServer((char *)rgb, 6))
945 return False;
946 xc.pixel = msg.scme.firstColour + i;
947 xc.red = Swap16IfLE(rgb[0]);
948 xc.green = Swap16IfLE(rgb[1]);
949 xc.blue = Swap16IfLE(rgb[2]);
950 xc.flags = DoRed|DoGreen|DoBlue;
951 XStoreColor(dpy, cmap, &xc);
952 }
953
954 break;
955 }
956
957 case rfbFramebufferUpdate:
958 {
959 rfbFramebufferUpdateRectHeader rect;
960 int linesToRead;
961 int bytesPerLine;
962 int i;
963 int usecs;
964
965 if (!ReadFromRFBServer(((char *)&msg.fu) + 1,
966 sz_rfbFramebufferUpdateMsg - 1))
967 return False;
968
969 msg.fu.nRects = Swap16IfLE(msg.fu.nRects);
970
971 for (i = 0; i < msg.fu.nRects; i++) {
972 if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader))
973 return False;
974
975 rect.encoding = Swap32IfLE(rect.encoding);
976 if (rect.encoding == rfbEncodingLastRect)
977 break;
978
979 rect.r.x = Swap16IfLE(rect.r.x);
980 rect.r.y = Swap16IfLE(rect.r.y);
981 rect.r.w = Swap16IfLE(rect.r.w);
982 rect.r.h = Swap16IfLE(rect.r.h);
983
984 if (rect.encoding == rfbEncodingXCursor ||
985 rect.encoding == rfbEncodingRichCursor) {
986 if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h,
987 rect.encoding)) {
988 return False;
989 }
990 continue;
991 }
992
993 if (rect.encoding == rfbEncodingPointerPos) {
994 if (!HandleCursorPos(rect.r.x, rect.r.y)) {
995 return False;
996 }
997 continue;
998 }
999
1000 if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
1001 (rect.r.y + rect.r.h > si.framebufferHeight))
1002 {
1003 fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n",
1004 rect.r.w, rect.r.h, rect.r.x, rect.r.y);
1005 return False;
1006 }
1007
1008 if (rect.r.h * rect.r.w == 0) {
1009 fprintf(stderr,"Zero size rect - ignoring\n");
1010 continue;
1011 }
1012
1013 /* If RichCursor encoding is used, we should prevent collisions
1014 between framebuffer updates and cursor drawing operations. */
1015 SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h);
1016
1017 switch (rect.encoding) {
1018
1019 case rfbEncodingRaw:
1020
1021 bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8;
1022 linesToRead = BUFFER_SIZE / bytesPerLine;
1023
1024 while (rect.r.h > 0) {
1025 if (linesToRead > rect.r.h)
1026 linesToRead = rect.r.h;
1027
1028 if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead))
1029 return False;
1030
1031 CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w,
1032 linesToRead);
1033
1034 rect.r.h -= linesToRead;
1035 rect.r.y += linesToRead;
1036
1037 }
1038 break;
1039
1040 case rfbEncodingCopyRect:
1041 {
1042 rfbCopyRect cr;
1043
1044 if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect))
1045 return False;
1046
1047 cr.srcX = Swap16IfLE(cr.srcX);
1048 cr.srcY = Swap16IfLE(cr.srcY);
1049
1050 /* If RichCursor encoding is used, we should extend our
1051 "cursor lock area" (previously set to destination
1052 rectangle) to the source rectangle as well. */
1053 SoftCursorLockArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h);
1054
1055 if (appData.copyRectDelay != 0) {
1056 XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY,
1057 rect.r.w, rect.r.h);
1058 XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y,
1059 rect.r.w, rect.r.h);
1060 XSync(dpy,False);
1061 usleep(appData.copyRectDelay * 1000);
1062 XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y,
1063 rect.r.w, rect.r.h);
1064 XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY,
1065 rect.r.w, rect.r.h);
1066 }
1067
1068 XCopyArea(dpy, desktopWin, desktopWin, gc, cr.srcX, cr.srcY,
1069 rect.r.w, rect.r.h, rect.r.x, rect.r.y);
1070
1071 break;
1072 }
1073
1074 case rfbEncodingRRE:
1075 {
1076 switch (myFormat.bitsPerPixel) {
1077 case 8:
1078 if (!HandleRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1079 return False;
1080 break;
1081 case 16:
1082 if (!HandleRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1083 return False;
1084 break;
1085 case 32:
1086 if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1087 return False;
1088 break;
1089 }
1090 break;
1091 }
1092
1093 case rfbEncodingCoRRE:
1094 {
1095 switch (myFormat.bitsPerPixel) {
1096 case 8:
1097 if (!HandleCoRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1098 return False;
1099 break;
1100 case 16:
1101 if (!HandleCoRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1102 return False;
1103 break;
1104 case 32:
1105 if (!HandleCoRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1106 return False;
1107 break;
1108 }
1109 break;
1110 }
1111
1112 case rfbEncodingHextile:
1113 {
1114 switch (myFormat.bitsPerPixel) {
1115 case 8:
1116 if (!HandleHextile8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1117 return False;
1118 break;
1119 case 16:
1120 if (!HandleHextile16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1121 return False;
1122 break;
1123 case 32:
1124 if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1125 return False;
1126 break;
1127 }
1128 break;
1129 }
1130
1131 case rfbEncodingZlib:
1132 {
1133 switch (myFormat.bitsPerPixel) {
1134 case 8:
1135 if (!HandleZlib8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1136 return False;
1137 break;
1138 case 16:
1139 if (!HandleZlib16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1140 return False;
1141 break;
1142 case 32:
1143 if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1144 return False;
1145 break;
1146 }
1147 break;
1148 }
1149
1150 case rfbEncodingTight:
1151 {
1152 switch (myFormat.bitsPerPixel) {
1153 case 8:
1154 if (!HandleTight8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1155 return False;
1156 break;
1157 case 16:
1158 if (!HandleTight16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1159 return False;
1160 break;
1161 case 32:
1162 if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1163 return False;
1164 break;
1165 }
1166 break;
1167 }
1168
1169 default:
1170 fprintf(stderr,"Unknown rect encoding %d\n",
1171 (int)rect.encoding);
1172 return False;
1173 }
1174
1175 /* Now we may discard "soft cursor locks". */
1176 SoftCursorUnlockScreen();
1177 }
1178
1179 #ifdef MITSHM
1180 /* if using shared memory PutImage, make sure that the X server has
1181 updated its framebuffer before we reuse the shared memory. This is
1182 mainly to avoid copyrect using invalid screen contents - not sure
1183 if we'd need it otherwise. */
1184
1185 if (appData.useShm)
1186 XSync(dpy, False);
1187 #endif
1188
1189 if (!SendIncrementalFramebufferUpdateRequest())
1190 return False;
1191
1192 break;
1193 }
1194
1195 case rfbBell:
1196 {
1197 Window toplevelWin;
1198
1199 XBell(dpy, 0);
1200
1201 if (appData.raiseOnBeep) {
1202 toplevelWin = XtWindow(toplevel);
1203 XMapRaised(dpy, toplevelWin);
1204 }
1205
1206 break;
1207 }
1208
1209 case rfbServerCutText:
1210 {
1211 if (!ReadFromRFBServer(((char *)&msg) + 1,
1212 sz_rfbServerCutTextMsg - 1))
1213 return False;
1214
1215 msg.sct.length = Swap32IfLE(msg.sct.length);
1216
1217 if (serverCutText)
1218 free(serverCutText);
1219
1220 serverCutText = malloc(msg.sct.length+1);
1221
1222 if (!ReadFromRFBServer(serverCutText, msg.sct.length))
1223 return False;
1224
1225 serverCutText[msg.sct.length] = 0;
1226
1227 newServerCutText = True;
1228
1229 break;
1230 }
1231
1232 default:
1233 fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type);
1234 return False;
1235 }
1236
1237 return True;
1238 }
1239
1240
1241 #define GET_PIXEL8(pix, ptr) ((pix) = *(ptr)++)
1242
1243 #define GET_PIXEL16(pix, ptr) (((CARD8*)&(pix))[0] = *(ptr)++, \
1244 ((CARD8*)&(pix))[1] = *(ptr)++)
1245
1246 #define GET_PIXEL32(pix, ptr) (((CARD8*)&(pix))[0] = *(ptr)++, \
1247 ((CARD8*)&(pix))[1] = *(ptr)++, \
1248 ((CARD8*)&(pix))[2] = *(ptr)++, \
1249 ((CARD8*)&(pix))[3] = *(ptr)++)
1250
1251 /* CONCAT2 concatenates its two arguments. CONCAT2E does the same but also
1252 expands its arguments if they are macros */
1253
1254 #define CONCAT2(a,b) a##b
1255 #define CONCAT2E(a,b) CONCAT2(a,b)
1256
1257 #define BPP 8
1258 #include "rre.c"
1259 #include "corre.c"
1260 #include "hextile.c"
1261 #include "zlib.c"
1262 #include "tight.c"
1263 #undef BPP
1264 #define BPP 16
1265 #include "rre.c"
1266 #include "corre.c"
1267 #include "hextile.c"
1268 #include "zlib.c"
1269 #include "tight.c"
1270 #undef BPP
1271 #define BPP 32
1272 #include "rre.c"
1273 #include "corre.c"
1274 #include "hextile.c"
1275 #include "zlib.c"
1276 #include "tight.c"
1277 #undef BPP
1278
1279 /*
1280 * Read the string describing the reason for a connection failure.
1281 */
1282
1283 static void
ReadConnFailedReason(void)1284 ReadConnFailedReason(void)
1285 {
1286 CARD32 reasonLen;
1287 char *reason = NULL;
1288
1289 if (ReadFromRFBServer((char *)&reasonLen, sizeof(reasonLen))) {
1290 reasonLen = Swap32IfLE(reasonLen);
1291 if ((reason = malloc(reasonLen)) != NULL &&
1292 ReadFromRFBServer(reason, reasonLen)) {
1293 fprintf(stderr,"%.*s\n", (int)reasonLen, reason);
1294 free(reason);
1295 return;
1296 }
1297 }
1298
1299 fprintf(stderr, "VNC connection failed\n");
1300
1301 if (reason != NULL)
1302 free(reason);
1303 }
1304
1305 /*
1306 * PrintPixelFormat.
1307 */
1308
1309 void
PrintPixelFormat(format)1310 PrintPixelFormat(format)
1311 rfbPixelFormat *format;
1312 {
1313 if (format->bitsPerPixel == 1) {
1314 fprintf(stderr," Single bit per pixel.\n");
1315 fprintf(stderr,
1316 " %s significant bit in each byte is leftmost on the screen.\n",
1317 (format->bigEndian ? "Most" : "Least"));
1318 } else {
1319 fprintf(stderr," %d bits per pixel.\n",format->bitsPerPixel);
1320 if (format->bitsPerPixel != 8) {
1321 fprintf(stderr," %s significant byte first in each pixel.\n",
1322 (format->bigEndian ? "Most" : "Least"));
1323 }
1324 if (format->trueColour) {
1325 fprintf(stderr," True colour: max red %d green %d blue %d",
1326 format->redMax, format->greenMax, format->blueMax);
1327 fprintf(stderr,", shift red %d green %d blue %d\n",
1328 format->redShift, format->greenShift, format->blueShift);
1329 } else {
1330 fprintf(stderr," Colour map (not true colour).\n");
1331 }
1332 }
1333 }
1334
1335 /*
1336 * Read an integer value encoded in 1..3 bytes. This function is used
1337 * by the Tight decoder.
1338 */
1339
1340 static long
ReadCompactLen(void)1341 ReadCompactLen (void)
1342 {
1343 long len;
1344 CARD8 b;
1345
1346 if (!ReadFromRFBServer((char *)&b, 1))
1347 return -1;
1348 len = (int)b & 0x7F;
1349 if (b & 0x80) {
1350 if (!ReadFromRFBServer((char *)&b, 1))
1351 return -1;
1352 len |= ((int)b & 0x7F) << 7;
1353 if (b & 0x80) {
1354 if (!ReadFromRFBServer((char *)&b, 1))
1355 return -1;
1356 len |= ((int)b & 0xFF) << 14;
1357 }
1358 }
1359 return len;
1360 }
1361
1362
1363 /*
1364 * JPEG source manager functions for JPEG decompression in Tight decoder.
1365 */
1366
1367 static struct jpeg_source_mgr jpegSrcManager;
1368 static JOCTET *jpegBufferPtr;
1369 static size_t jpegBufferLen;
1370
1371 static void
JpegInitSource(j_decompress_ptr cinfo)1372 JpegInitSource(j_decompress_ptr cinfo)
1373 {
1374 jpegError = False;
1375 }
1376
1377 static boolean
JpegFillInputBuffer(j_decompress_ptr cinfo)1378 JpegFillInputBuffer(j_decompress_ptr cinfo)
1379 {
1380 jpegError = True;
1381 jpegSrcManager.bytes_in_buffer = jpegBufferLen;
1382 jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
1383
1384 return TRUE;
1385 }
1386
1387 static void
JpegSkipInputData(j_decompress_ptr cinfo,long num_bytes)1388 JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes)
1389 {
1390 if (num_bytes < 0 || num_bytes > jpegSrcManager.bytes_in_buffer) {
1391 jpegError = True;
1392 jpegSrcManager.bytes_in_buffer = jpegBufferLen;
1393 jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
1394 } else {
1395 jpegSrcManager.next_input_byte += (size_t) num_bytes;
1396 jpegSrcManager.bytes_in_buffer -= (size_t) num_bytes;
1397 }
1398 }
1399
1400 static void
JpegTermSource(j_decompress_ptr cinfo)1401 JpegTermSource(j_decompress_ptr cinfo)
1402 {
1403 /* No work necessary here. */
1404 }
1405
1406 static void
JpegSetSrcManager(j_decompress_ptr cinfo,CARD8 * compressedData,int compressedLen)1407 JpegSetSrcManager(j_decompress_ptr cinfo, CARD8 *compressedData,
1408 int compressedLen)
1409 {
1410 jpegBufferPtr = (JOCTET *)compressedData;
1411 jpegBufferLen = (size_t)compressedLen;
1412
1413 jpegSrcManager.init_source = JpegInitSource;
1414 jpegSrcManager.fill_input_buffer = JpegFillInputBuffer;
1415 jpegSrcManager.skip_input_data = JpegSkipInputData;
1416 jpegSrcManager.resync_to_restart = jpeg_resync_to_restart;
1417 jpegSrcManager.term_source = JpegTermSource;
1418 jpegSrcManager.next_input_byte = jpegBufferPtr;
1419 jpegSrcManager.bytes_in_buffer = jpegBufferLen;
1420
1421 cinfo->src = &jpegSrcManager;
1422 }
1423
1424