1 /**************************************************************************/
2 /* */
3 /* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/. */
4 /* */
5 /* NXCOMP, NX protocol compression and NX extensions to this software */
6 /* are copyright of NoMachine. Redistribution and use of the present */
7 /* software is allowed according to terms specified in the file LICENSE */
8 /* which comes in the source distribution. */
9 /* */
10 /* Check http://www.nomachine.com/licensing.html for applicability. */
11 /* */
12 /* NX and NoMachine are trademarks of Medialogic S.p.A. */
13 /* */
14 /* All rights reserved. */
15 /* */
16 /**************************************************************************/
17
18 #include <X11/Xmd.h>
19
20 #ifdef ANDROID
21 #include <strings.h>
22 #endif
23 #include <unistd.h>
24 #include <setjmp.h>
25 #include <zlib.h>
26
27 #ifdef __cplusplus
28
29 extern "C"
30 {
31 #include <stdio.h>
32 #include <jpeglib.h>
33 }
34
35 #else
36
37 #include <stdio.h>
38 #include <jpeglib.h>
39
40 #endif
41
42 #include "Misc.h"
43 #include "Jpeg.h"
44 #include "Unpack.h"
45
46 #define PANIC
47 #define WARNING
48 #undef TEST
49 #undef DEBUG
50
51 #define RGB24_TO_PIXEL(bpp,r,g,b) \
52 ((((CARD##bpp)(r) & 0xff) * srcRedMax + 127) / 255 \
53 << srcRedShift | \
54 (((CARD##bpp)(g) & 0xff) * srcGreenMax + 127) / 255 \
55 << srcGreenShift | \
56 (((CARD##bpp)(b) & 0xff) * srcBlueMax + 127) / 255 \
57 << srcBlueShift)
58
59 #define RGB24_TO_PIXEL32(r,g,b) \
60 (((CARD32)(r) & 0xff) << srcRedShift | \
61 ((CARD32)(g) & 0xff) << srcGreenShift | \
62 ((CARD32)(b) & 0xff) << srcBlueShift)
63
64 //
65 // Functions from Unpack.cpp
66 //
67
68 extern int Unpack32To32(const T_colormask *colormask, const unsigned int *data,
69 unsigned int *out, unsigned int *end);
70
71 extern int Unpack24To24(const T_colormask *colormask, const unsigned char *data,
72 unsigned char *out, unsigned char *end);
73
74 extern int Unpack16To16(const T_colormask *colormask, const unsigned char *data,
75 unsigned char *out, unsigned char *end);
76
77 //
78 // Local functions used for the jpeg decompression.
79 //
80
81 static void JpegSetSrcManager(j_decompress_ptr cinfo, CARD8 *compressedData, int compressedLen);
82 static void JpegInitSource(j_decompress_ptr cinfo);
83 static void JpegTermSource(j_decompress_ptr cinfo);
84 static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes);
85
86 static boolean JpegFillInputBuffer(j_decompress_ptr cinfo);
87
88 static int DecompressJpeg16(unsigned char *compressedData, int compressedLen,
89 unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder);
90
91 static int DecompressJpeg24(unsigned char *compressedData, int compressedLen,
92 unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder);
93
94 static int DecompressJpeg32(unsigned char *compressedData, int compressedLen,
95 unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder);
96
97 void UnpackJpegErrorHandler(j_common_ptr cinfo);
98
99 //
100 // Colormap stuff.
101 //
102
103 CARD16 srcRedMax, srcGreenMax, srcBlueMax;
104 CARD8 srcRedShift, srcGreenShift, srcBlueShift;
105
106 //
107 // Error handler.
108 //
109
110 static bool jpegError;
111
112 jmp_buf UnpackJpegContext;
113
UnpackJpegErrorHandler(j_common_ptr cinfo)114 void UnpackJpegErrorHandler(j_common_ptr cinfo)
115 {
116 #ifdef PANIC
117 *logofs << "UnpackJpegErrorHandler: PANIC! Detected error in JPEG decompression.\n"
118 << logofs_flush;
119
120 *logofs << "UnpackJpegErrorHandler: PANIC! Trying to revert to the previous context.\n"
121 << logofs_flush;
122 #endif
123
124 jpegError = 1;
125
126 longjmp(UnpackJpegContext, 1);
127 }
128
129 //
130 // Attributes used for the jpeg decompression.
131 //
132
133 static struct jpeg_source_mgr jpegSrcManager;
134 static JOCTET *jpegBufferPtr;
135 static size_t jpegBufferLen;
136
137 static char *tmpBuf;
138 static int tmpBufSize = 0;
139
UnpackJpeg(T_geometry * geometry,unsigned char method,unsigned char * srcData,int srcSize,int dstBpp,int dstWidth,int dstHeight,unsigned char * dstData,int dstSize)140 int UnpackJpeg(T_geometry *geometry, unsigned char method, unsigned char *srcData,
141 int srcSize, int dstBpp, int dstWidth, int dstHeight,
142 unsigned char *dstData, int dstSize)
143 {
144 int byteOrder = geometry -> image_byte_order;
145
146 //
147 // Check if data is coming from a failed unsplit.
148 //
149
150 if (srcSize < 2 || (srcData[0] == SPLIT_PATTERN &&
151 srcData[1] == SPLIT_PATTERN))
152 {
153 #ifdef WARNING
154 *logofs << "UnpackJpeg: WARNING! Skipping unpack of dummy data.\n"
155 << logofs_flush;
156 #endif
157
158 return -1;
159 }
160
161 #ifdef DEBUG
162 *logofs << "UnpackJpeg: Decompression. Source size "
163 << srcSize << " bits per plane " << dstBpp
164 << ".\n" << logofs_flush;
165 #endif
166
167 srcRedShift = ffs(geometry -> red_mask) - 1;
168 srcGreenShift = ffs(geometry -> green_mask) - 1;
169 srcBlueShift = ffs(geometry -> blue_mask) - 1;
170
171 #ifdef DEBUG
172 *logofs << "UnpackJpeg: Red shift " << (int) srcRedShift
173 << " green shift " << (int) srcGreenShift << " blue shift "
174 << (int) srcBlueShift << ".\n" << logofs_flush;
175 #endif
176
177 srcRedMax = geometry -> red_mask >> srcRedShift;
178 srcGreenMax = geometry -> green_mask >> srcGreenShift;
179 srcBlueMax = geometry -> blue_mask >> srcBlueShift;
180
181 #ifdef DEBUG
182 *logofs << "UnpackJpeg: Red mask " << (void *) geometry -> red_mask
183 << " green mask " << (void *) geometry -> green_mask
184 << " blue mask " << (void *) geometry -> blue_mask
185 << ".\n" << logofs_flush;
186 #endif
187
188 #ifdef DEBUG
189 *logofs << "UnpackJpeg: Red max " << srcRedMax << " green max "
190 << srcGreenMax << " blue max " << srcBlueMax
191 << ".\n" << logofs_flush;
192 #endif
193
194 //
195 // Make enough space in the temporary
196 // buffer to have one complete row of
197 // the image with 3 bytes for a pixel.
198 //
199
200 tmpBufSize = dstWidth * 3;
201 tmpBuf = new char[tmpBufSize];
202
203 if (tmpBuf == NULL)
204 {
205 #ifdef PANIC
206 *logofs << "UnpackJpeg: PANIC! Cannot allocate "
207 << dstWidth * 3 << " bytes for Jpeg "
208 << "decompressed data.\n" << logofs_flush;
209 #endif
210
211 delete [] tmpBuf;
212
213 return -1;
214 }
215
216 int result = 1;
217
218 switch(dstBpp)
219 {
220 case 8:
221 {
222 //
223 // Simply move the data from srcData to dstData
224 // taking into consideration the correct padding.
225 //
226
227 int row;
228
229 unsigned char * dstBuff = dstData;
230 unsigned char * srcBuff = srcData;
231
232 for (row = 0; row < dstHeight; row++)
233 {
234 memcpy(dstBuff, srcBuff, dstWidth);
235
236 dstBuff += RoundUp4(dstWidth);
237 srcBuff += dstWidth;
238 }
239
240 break;
241 }
242 case 16:
243 {
244 result = DecompressJpeg16(srcData, srcSize, dstWidth,
245 dstHeight, dstData, byteOrder);
246 break;
247 }
248 case 24:
249 {
250 result = DecompressJpeg24(srcData, srcSize, dstWidth,
251 dstHeight, dstData, byteOrder);
252 break;
253 }
254 case 32:
255 {
256 result = DecompressJpeg32(srcData, srcSize, dstWidth,
257 dstHeight, dstData, byteOrder);
258 break;
259 }
260 default:
261 {
262 #ifdef PANIC
263 *logofs << "UnpackJpeg: PANIC! Failed to decode Jpeg image. "
264 << " Unsupported Bpp value " << dstBpp
265 << " for the Jpeg compression"
266 << ".\n" << logofs_flush;
267 #endif
268
269 delete [] tmpBuf;
270
271 result = -1;
272 }
273 }
274
275 #ifdef DEBUG
276 *logofs << "UnpackJpeg: Decompression finished with result "
277 << result << ".\n" << logofs_flush;
278 #endif
279
280 if (result == -1)
281 {
282 delete [] tmpBuf;
283
284 #ifdef PANIC
285 *logofs << "UnpackJpeg: PANIC! Failed to decode Jpeg image using "
286 << dstBpp << " Bpp destination.\n" << logofs_flush;
287 #endif
288
289 return result;
290 }
291
292 //
293 // Apply the correction for the brightness.
294 //
295
296 int maskMethod;
297
298 switch(method)
299 {
300 case PACK_JPEG_8_COLORS:
301 {
302 maskMethod = MASK_8_COLORS;
303
304 break;
305 }
306 case PACK_JPEG_64_COLORS:
307 {
308 maskMethod = MASK_64_COLORS;
309
310 break;
311 }
312 case PACK_JPEG_256_COLORS:
313 {
314 maskMethod = MASK_256_COLORS;
315
316 break;
317 }
318 case PACK_JPEG_512_COLORS:
319 {
320 maskMethod = MASK_512_COLORS;
321
322 break;
323 }
324 case PACK_JPEG_4K_COLORS:
325 {
326 maskMethod = MASK_4K_COLORS;
327
328 break;
329 }
330 case PACK_JPEG_32K_COLORS:
331 {
332 maskMethod = MASK_32K_COLORS;
333
334 break;
335 }
336 case PACK_JPEG_64K_COLORS:
337 {
338 maskMethod = MASK_64K_COLORS;
339
340 break;
341 }
342 case PACK_JPEG_256K_COLORS:
343 {
344 maskMethod = MASK_256K_COLORS;
345
346 break;
347 }
348 case PACK_JPEG_2M_COLORS:
349 {
350 maskMethod = MASK_2M_COLORS;
351
352 break;
353 }
354 case PACK_JPEG_16M_COLORS:
355 {
356 maskMethod = MASK_16M_COLORS;
357
358 break;
359 }
360 default:
361 {
362 delete [] tmpBuf;
363
364 return -1;
365 }
366 }
367
368 const T_colormask *colorMask = MethodColorMask(maskMethod);
369
370 unsigned char *dstBuff = dstData;
371
372 switch (dstBpp)
373 {
374 case 16:
375 {
376 Unpack16To16(colorMask, dstBuff, dstBuff, dstBuff + dstSize);
377
378 break;
379 }
380 case 24:
381 {
382 break;
383 }
384 case 32:
385 {
386 Unpack32To32(colorMask, (unsigned int *) dstBuff, (unsigned int *) dstBuff,
387 (unsigned int *) (dstBuff + dstSize));
388 break;
389 }
390 default:
391 {
392 delete [] tmpBuf;
393
394 return -1;
395 }
396 }
397
398 delete [] tmpBuf;
399
400 return 1;
401 }
402
403 //
404 // Functions that actually do the Jpeg decompression.
405 //
406
DecompressJpeg16(unsigned char * compressedData,int compressedLen,unsigned int w,unsigned int h,unsigned char * dstBuf,int byteOrder)407 int DecompressJpeg16(unsigned char *compressedData, int compressedLen,
408 unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder)
409 {
410 struct jpeg_decompress_struct cinfo;
411 struct jpeg_error_mgr jerr;
412 unsigned char *data;
413 JSAMPROW rowPointer[1];
414
415 unsigned int dx = 0;
416 unsigned int dy = 0;
417
418 #ifdef DEBUG
419 *logofs << "DecompressJpeg16: Decompressing with length "
420 << compressedLen << " width " << w << " height "
421 << h << ".\n" << logofs_flush;
422 #endif
423
424 jpegError = 0;
425
426 cinfo.err = jpeg_std_error(&jerr);
427
428 jerr.error_exit = UnpackJpegErrorHandler;
429
430 if (setjmp(UnpackJpegContext) == 1)
431 {
432 #ifdef TEST
433 *logofs << "DecompressJpeg16: Out of the long jump with error '"
434 << jpegError << "'.\n" << logofs_flush;
435 #endif
436
437 goto AbortDecompressJpeg16;
438 }
439
440 jpeg_create_decompress(&cinfo);
441
442 if (jpegError) goto AbortDecompressJpeg16;
443
444 JpegSetSrcManager(&cinfo, compressedData, compressedLen);
445
446 jpeg_read_header(&cinfo, TRUE);
447
448 if (jpegError) goto AbortDecompressJpeg16;
449
450 cinfo.out_color_space = JCS_RGB;
451
452 jpeg_start_decompress(&cinfo);
453
454 if (jpegError) goto AbortDecompressJpeg16;
455
456 if (cinfo.output_width != w ||
457 cinfo.output_height != h ||
458 cinfo.output_components != 3)
459 {
460 #ifdef PANIC
461 *logofs << "DecompressJpeg16: PANIC! Wrong JPEG data received.\n"
462 << logofs_flush;
463 #endif
464
465 jpeg_destroy_decompress(&cinfo);
466
467 return -1;
468 }
469
470 //
471 // PixelPtr points to dstBuf which is
472 // already padded correctly for the final
473 // image to put
474 //
475
476 data = dstBuf;
477
478 rowPointer[0] = (JSAMPROW) tmpBuf;
479
480 unsigned long pixel;
481
482 while (cinfo.output_scanline < cinfo.output_height)
483 {
484 jpeg_read_scanlines(&cinfo, rowPointer, 1);
485
486 if (jpegError) goto AbortDecompressJpeg16;
487
488 for (dx = 0; dx < w; dx++)
489 {
490 pixel = RGB24_TO_PIXEL(16, tmpBuf[dx * 3], tmpBuf[dx * 3 + 1],
491 tmpBuf[dx * 3 + 2]);
492
493 //
494 // Follow the server byte order when arranging data.
495 //
496
497 if (byteOrder == LSBFirst)
498 {
499 data[0] = (unsigned char) (pixel & 0xff);
500 data[1] = (unsigned char) ((pixel >> 8) & 0xff);
501 }
502 else
503 {
504 data[1] = (unsigned char) (pixel & 0xff);
505 data[0] = (unsigned char) ((pixel >> 8) & 0xff);
506 }
507
508 data += 2;
509 }
510
511 //
512 // Move data at the beginning of the
513 // next line.
514 //
515
516 data = data + (RoundUp4(w * 2) - w * 2);
517
518 dy++;
519 }
520
521 AbortDecompressJpeg16:
522
523 if (jpegError == 0)
524 {
525 jpeg_finish_decompress(&cinfo);
526 }
527
528 jpeg_destroy_decompress(&cinfo);
529
530 if (jpegError == 1)
531 {
532 #ifdef PANIC
533 *logofs << "DecompressJpeg16: Failed to decompress JPEG image.\n"
534 << logofs_flush;
535 #endif
536
537 return -1;
538 }
539
540 #ifdef TEST
541 *logofs << "DecompressJpeg16: Decompression finished with "
542 << dy << " lines handled.\n" << logofs_flush;
543 #endif
544
545 return 1;
546 }
547
DecompressJpeg24(unsigned char * compressedData,int compressedLen,unsigned int w,unsigned int h,unsigned char * dstBuf,int byteOrder)548 int DecompressJpeg24(unsigned char *compressedData, int compressedLen,
549 unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder)
550 {
551 struct jpeg_decompress_struct cinfo;
552 struct jpeg_error_mgr jerr;
553 CARD8 *pixelPtr = NULL;
554 JSAMPROW rowPointer[1];
555
556 unsigned int dx = 0;
557 unsigned int dy = 0;
558
559 #ifdef TEST
560 *logofs << "DecompressJpeg24: Decompressing with length "
561 << compressedLen << " width " << w << " height "
562 << h << ".\n" << logofs_flush;
563 #endif
564
565 jpegError = 0;
566
567 cinfo.err = jpeg_std_error(&jerr);
568
569 jerr.error_exit = UnpackJpegErrorHandler;
570
571 if (setjmp(UnpackJpegContext) == 1)
572 {
573 #ifdef TEST
574 *logofs << "DecompressJpeg24: Out of the long jump with error '"
575 << jpegError << "'.\n" << logofs_flush;
576 #endif
577
578 goto AbortDecompressJpeg24;
579 }
580
581 jpeg_create_decompress(&cinfo);
582
583 if (jpegError) goto AbortDecompressJpeg24;
584
585 JpegSetSrcManager(&cinfo, compressedData, compressedLen);
586
587 jpeg_read_header(&cinfo, TRUE);
588
589 if (jpegError) goto AbortDecompressJpeg24;
590
591 cinfo.out_color_space = JCS_RGB;
592
593 jpeg_start_decompress(&cinfo);
594
595 if (jpegError) goto AbortDecompressJpeg24;
596
597 if (cinfo.output_width != w ||
598 cinfo.output_height != h ||
599 cinfo.output_components != 3)
600 {
601 #ifdef PANIC
602 *logofs << "DecompressJpeg24: PANIC! Wrong JPEG data received.\n"
603 << logofs_flush;
604 #endif
605
606 jpeg_destroy_decompress(&cinfo);
607
608 return -1;
609 }
610
611 //
612 // PixelPtr points to dstBuf which is
613 // already padded correctly for the final
614 // image to put.
615 //
616
617 pixelPtr = (CARD8 *) dstBuf;
618
619 rowPointer[0] = (JSAMPROW) tmpBuf;
620
621 while (cinfo.output_scanline < cinfo.output_height)
622 {
623 jpeg_read_scanlines(&cinfo, rowPointer, 1);
624
625 if (jpegError) goto AbortDecompressJpeg24;
626
627 for (dx = 0; dx < w; dx++)
628 {
629 //
630 // Follow the server byte order when arranging data.
631 //
632
633 if (byteOrder == LSBFirst)
634 {
635 pixelPtr[0] = tmpBuf[dx * 3];
636 pixelPtr[1] = tmpBuf[dx * 3 + 1];
637 pixelPtr[2] = tmpBuf[dx * 3 + 2];
638 }
639 else
640 {
641 pixelPtr[2] = tmpBuf[dx * 3];
642 pixelPtr[1] = tmpBuf[dx * 3 + 1];
643 pixelPtr[0] = tmpBuf[dx * 3 + 2];
644 }
645
646 pixelPtr += 3;
647 }
648
649 //
650 // Go to the next line.
651 //
652
653 pixelPtr = (CARD8 *) (((char *) pixelPtr) + (RoundUp4(w * 3) - w * 3));
654
655 dy++;
656 }
657
658 AbortDecompressJpeg24:
659
660 if (jpegError == 0)
661 {
662 jpeg_finish_decompress(&cinfo);
663 }
664
665 jpeg_destroy_decompress(&cinfo);
666
667 if (jpegError == 1)
668 {
669 #ifdef PANIC
670 *logofs << "DecompressJpeg24: Failed to decompress JPEG image.\n"
671 << logofs_flush;
672 #endif
673
674 return -1;
675 }
676
677 #ifdef TEST
678 *logofs << "DecompressJpeg24: Decompression finished with "
679 << dy << " lines handled.\n" << logofs_flush;
680 #endif
681
682 return 1;
683 }
684
DecompressJpeg32(unsigned char * compressedData,int compressedLen,unsigned int w,unsigned int h,unsigned char * dstBuf,int byteOrder)685 int DecompressJpeg32(unsigned char *compressedData, int compressedLen,
686 unsigned int w, unsigned int h, unsigned char *dstBuf, int byteOrder)
687 {
688 struct jpeg_decompress_struct cinfo;
689 struct jpeg_error_mgr jerr;
690 unsigned char *data;
691 JSAMPROW rowPointer[1];
692
693 unsigned int dx = 0;
694 unsigned int dy = 0;
695
696 #ifdef TEST
697 *logofs << "DecompressJpeg32: Decompressing with length "
698 << compressedLen << " width " << w << " height "
699 << h << ".\n" << logofs_flush;
700 #endif
701
702 jpegError = 0;
703
704 cinfo.err = jpeg_std_error(&jerr);
705
706 jerr.error_exit = UnpackJpegErrorHandler;
707
708 if (setjmp(UnpackJpegContext) == 1)
709 {
710 #ifdef TEST
711 *logofs << "DecompressJpeg32: Out of the long jump with error '"
712 << jpegError << "'.\n" << logofs_flush;
713 #endif
714
715 goto AbortDecompressJpeg32;
716 }
717
718 jpeg_create_decompress(&cinfo);
719
720 if (jpegError) goto AbortDecompressJpeg32;
721
722 JpegSetSrcManager(&cinfo, compressedData, compressedLen);
723
724 jpeg_read_header(&cinfo, TRUE);
725
726 if (jpegError) goto AbortDecompressJpeg32;
727
728 cinfo.out_color_space = JCS_RGB;
729
730 jpeg_start_decompress(&cinfo);
731
732 if (jpegError) goto AbortDecompressJpeg32;
733
734 if (cinfo.output_width != w ||
735 cinfo.output_height != h ||
736 cinfo.output_components != 3)
737 {
738 #ifdef PANIC
739 *logofs << "DecompressJpeg32 : PANIC! Wrong JPEG data received.\n"
740 << logofs_flush;
741 #endif
742
743 jpeg_destroy_decompress(&cinfo);
744
745 return -1;
746 }
747
748 //
749 // PixelPtr points to dstBuf which is
750 // already padded correctly for the final
751 // image to put
752 //
753
754 data = dstBuf;
755
756 rowPointer[0] = (JSAMPROW) tmpBuf;
757
758 unsigned long pixel;
759
760 int i;
761
762 while (cinfo.output_scanline < cinfo.output_height)
763 {
764 jpeg_read_scanlines(&cinfo, rowPointer, 1);
765
766 if (jpegError) goto AbortDecompressJpeg32;
767
768 for (dx = 0; dx < w; dx++)
769 {
770 pixel = RGB24_TO_PIXEL(32, tmpBuf[dx * 3], tmpBuf[dx * 3 + 1],
771 tmpBuf[dx * 3 + 2]);
772
773 //
774 // Follow the server byte order when arranging data.
775 //
776
777 if (byteOrder == LSBFirst)
778 {
779 for (i = 0; i < 4; i++)
780 {
781 data[i] = (unsigned char)(pixel & 0xff);
782 pixel >>= 8;
783 }
784 }
785 else
786 {
787 for (i = 3; i >= 0; i--)
788 {
789 data[i] = (unsigned char) (pixel & 0xff);
790 pixel >>= 8;
791 }
792 }
793
794 data += 4;
795 }
796
797 dy++;
798 }
799
800 AbortDecompressJpeg32:
801
802 if (jpegError == 0)
803 {
804 jpeg_finish_decompress(&cinfo);
805 }
806
807 jpeg_destroy_decompress(&cinfo);
808
809 if (jpegError == 1)
810 {
811 #ifdef PANIC
812 *logofs << "DecompressJpeg32: Failed to decompress JPEG image.\n"
813 << logofs_flush;
814 #endif
815
816 return -1;
817 }
818
819 #ifdef TEST
820 *logofs << "DecompressJpeg32: Decompression finished with "
821 << dy << " lines handled.\n" << logofs_flush;
822 #endif
823
824 return 1;
825 }
826
JpegInitSource(j_decompress_ptr cinfo)827 static void JpegInitSource(j_decompress_ptr cinfo)
828 {
829 jpegError = 0;
830 }
831
JpegFillInputBuffer(j_decompress_ptr cinfo)832 static boolean JpegFillInputBuffer(j_decompress_ptr cinfo)
833 {
834 jpegError = 1;
835
836 jpegSrcManager.bytes_in_buffer = jpegBufferLen;
837 jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
838
839 return TRUE;
840 }
841
JpegSkipInputData(j_decompress_ptr cinfo,long num_bytes)842 static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes)
843 {
844 if (num_bytes < 0 || (unsigned long) num_bytes > jpegSrcManager.bytes_in_buffer)
845 {
846 jpegError = 1;
847
848 jpegSrcManager.bytes_in_buffer = jpegBufferLen;
849 jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
850 }
851 else
852 {
853 jpegSrcManager.next_input_byte += (size_t) num_bytes;
854 jpegSrcManager.bytes_in_buffer -= (size_t) num_bytes;
855 }
856 }
857
JpegTermSource(j_decompress_ptr cinfo)858 static void JpegTermSource(j_decompress_ptr cinfo)
859 {
860 }
861
JpegSetSrcManager(j_decompress_ptr cinfo,CARD8 * compressedData,int compressedLen)862 static void JpegSetSrcManager(j_decompress_ptr cinfo,
863 CARD8 *compressedData,
864 int compressedLen)
865 {
866 jpegBufferPtr = (JOCTET *) compressedData;
867 jpegBufferLen = (size_t) compressedLen;
868
869 jpegSrcManager.init_source = JpegInitSource;
870 jpegSrcManager.fill_input_buffer = JpegFillInputBuffer;
871 jpegSrcManager.skip_input_data = JpegSkipInputData;
872 jpegSrcManager.resync_to_restart = jpeg_resync_to_restart;
873 jpegSrcManager.term_source = JpegTermSource;
874 jpegSrcManager.next_input_byte = jpegBufferPtr;
875 jpegSrcManager.bytes_in_buffer = jpegBufferLen;
876
877 cinfo->src = &jpegSrcManager;
878 }
879