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 "Misc.h"
19 #include "Unpack.h"
20 #include "Alpha.h"
21 
22 #define PANIC
23 #define WARNING
24 #undef  TEST
25 #undef  DEBUG
26 
UnpackAlpha(unsigned char method,unsigned char * src_data,int src_size,unsigned char * dst_data,int dst_size)27 int UnpackAlpha(unsigned char method, unsigned char *src_data, int src_size,
28                     unsigned char *dst_data, int dst_size)
29 {
30   if (*src_data == 0)
31   {
32     if (dst_size != src_size - 1)
33     {
34       #ifdef TEST
35       *logofs << "UnpackAlpha: PANIC! Invalid destination size "
36               << dst_size << " with source " << src_size
37               << ".\n" << logofs_flush;
38       #endif
39 
40       return -1;
41     }
42 
43     #ifdef TEST
44     *logofs << "UnpackAlpha: Expanding " << src_size - 1
45             << " bytes of plain alpha data.\n" << logofs_flush;
46     #endif
47 
48     memcpy(dst_data, src_data + 1, src_size - 1);
49 
50     return 1;
51   }
52 
53   unsigned int check_size = dst_size;
54 
55   int result = ZDecompress(&unpackStream, dst_data, &check_size,
56                                src_data + 1, src_size - 1);
57 
58   if (result != Z_OK)
59   {
60     #ifdef PANIC
61     *logofs << "UnpackAlpha: PANIC! Failure decompressing alpha data. "
62             << "Error is '" << zError(result) << "'.\n"
63             << logofs_flush;
64     #endif
65 
66     cerr << "Error" << ": Failure decompressing alpha data. "
67          << "Error is '" << zError(result) << "'.\n";
68 
69     return -1;
70   }
71   else if (check_size != (unsigned int) dst_size)
72   {
73     #ifdef PANIC
74     *logofs << "UnpackAlpha: PANIC! Size mismatch in alpha data. "
75             << "Resulting size is " << check_size << " with "
76             << "expected size " << dst_size << ".\n"
77             << logofs_flush;
78     #endif
79 
80     cerr << "Error" << ": Size mismatch in alpha data. "
81          << "Resulting size is " << check_size << " with "
82          << "expected size " << dst_size << ".\n";
83 
84     return -1;
85   }
86 
87   #ifdef TEST
88   *logofs << "UnpackAlpha: Decompressed " << src_size - 1
89           << " bytes to " << dst_size << " bytes of alpha data.\n"
90           << logofs_flush;
91   #endif
92 
93   return 1;
94 }
95 
UnpackAlpha(T_alpha * alpha,unsigned char * dst_data,int dst_size,int big_endian)96 int UnpackAlpha(T_alpha *alpha, unsigned char *dst_data,
97                     int dst_size, int big_endian)
98 {
99   unsigned int count = dst_size >> 2;
100 
101   unsigned int i;
102 
103   int shift;
104 
105   if (count != alpha -> entries)
106   {
107     #ifdef WARNING
108     *logofs << "UnpackAlpha: WARNING! Not applying the alpha with "
109             << count << " elements needed and " << alpha -> entries
110             << " available.\n" << logofs_flush;
111     #endif
112 
113     return 0;
114   }
115 
116   shift = (big_endian == 1 ? 0 : 3);
117 
118   for (i = 0; i < count; i++)
119   {
120     *(dst_data + shift) = *(alpha -> data + i);
121 
122     dst_data += 4;
123   }
124 
125   return 1;
126 }
127