Tizen 2.1 base
[platform/upstream/hplip.git] / prnt / hpcups / LidilCompress.cpp
1 /*****************************************************************************\
2   LidilCompress.cpp : Implementation of LidilCompress class
3
4   Copyright (c) 1996 - 2009, Hewlett-Packard Co.
5   All rights reserved.
6
7   Redistribution and use in source and binary forms, with or without
8   modification, are permitted provided that the following conditions
9   are met:
10   1. Redistributions of source code must retain the above copyright
11      notice, this list of conditions and the following disclaimer.
12   2. Redistributions in binary form must reproduce the above copyright
13      notice, this list of conditions and the following disclaimer in the
14      documentation and/or other materials provided with the distribution.
15   3. Neither the name of Hewlett-Packard nor the names of its
16      contributors may be used to endorse or promote products derived
17      from this software without specific prior written permission.
18
19   THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
20   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
22   NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24   TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25   OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26   ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 \*****************************************************************************/
30
31 #include "CommonDefinitions.h"
32 #include "LidilCompress.h"
33
34 UInt16 LidilCompress::FlushImage ()
35 {
36     UInt16    command;
37     UInt16    wsize;
38     UInt16    bsize;
39     UInt16    *from_ptr;
40     int       index;
41
42     wsize = m_image_cnt;
43     bsize = 0;
44
45     if (wsize)
46     {
47         from_ptr = m_image_ptr;
48
49         command = FILL_IMAGE_CMD | (wsize-1);
50
51         index = 0;
52         *m_out_ptr++ = command;
53         for (UInt16 i = 0; i < wsize; i++)
54         {
55             *m_out_ptr++ = *from_ptr++;
56         }
57         bsize = ((m_image_cnt+1) * 2);
58         m_out_cnt += bsize;
59
60         m_image_cnt = 0;
61     }
62
63     return bsize;
64 }
65
66 UInt16 LidilCompress::FlushCopy (UInt16 value)
67 {
68     UInt16    command;
69     UInt16    size;
70
71     size = m_copy_cnt;
72     if (size)
73     {
74         UInt16  *uP = m_out_ptr++;
75         size = 2;
76         if (value == 0)
77         {
78             command = FILL_0000_CMD | (m_copy_cnt-1);
79         }
80         else if (value == 0xFFFF)
81         {
82             command = FILL_FFFF_CMD | (m_copy_cnt-1);
83         }
84         else
85         {
86             command = FILL_NEXT_CMD | (m_copy_cnt-1);
87             *m_out_ptr++ = value;
88             size = 4;
89         }
90
91         *uP = command;
92         m_out_cnt += size;
93         m_copy_cnt = 0;
94     }
95     return size;
96 }
97
98 void LidilCompress::CompressData (Int16 compressionmode)
99 {
100     Int16   i;
101     UInt16  *in_ptr;
102     UInt16  in;
103     UInt16  last=0;
104     UInt16  copy_item;
105     UInt16  data_length;
106
107     LDLCOMPMODE mode = IN_NOT;
108
109
110     m_out_cnt = 0;
111     m_image_cnt = 0;
112     m_copy_cnt = 0;
113
114     m_out_ptr = &m_out_array[8];
115     data_length = m_data_length;
116
117     if ((data_length & 1) != 0)
118     {
119     //    ErrorTrap((char *)"Data length is odd.");
120     }
121
122     copy_item = 0;
123     in_ptr = &m_raw_data[0];
124
125     for (i=0; i<data_length; i+=2)
126     {
127         in = *in_ptr;
128
129         switch(mode)
130         {
131             case IN_NOT:
132             {
133                 /* default the first entry to 'image' */
134                 last = in;
135                 m_image_ptr = in_ptr;
136                 m_image_cnt = 1;
137                 mode = IN_FIRST;
138                 break;
139             }
140
141             case IN_FIRST:
142             {
143 #if ALLOW_FILL_NEXT_CMD
144                 if (last == in)
145 #else
146                 if ((last == in) && ((in==0xFFFF) || (in == 0)) )
147 #endif
148                 {
149                     mode = IN_COPY;
150                     m_copy_cnt = 2;
151                     m_image_cnt = 0;
152                     copy_item = in;
153                 }
154                 else
155                 {
156                     mode = IN_IMAGE;
157                     m_image_cnt++;
158                     last = in;
159                 }
160                 break;
161             }
162
163             case IN_COPY:
164             {
165                 if (last == in)
166                 {
167                     m_copy_cnt++;
168                 }
169                 else
170                 {
171                     /* revisit - could allow 2 words of copy if the data is
172                     0000 or FFFF */
173
174                     /* convert a copy cnt of 2 to an image */
175                     UInt16 copy_count = m_copy_cnt;
176
177                     if (copy_count <= m_run_length)
178                     {
179                         if (m_image_cnt == 0)
180                         {
181                             /* point the pointer to the first element */
182                             m_image_ptr = in_ptr - copy_count;
183                         }
184                         m_image_cnt += (1+copy_count);
185                      m_copy_cnt = 0;
186                     }
187                     else
188                     {
189                         /* have enough to be a legal copy */
190
191                         (void) FlushImage ();
192
193                         (void) FlushCopy (copy_item);
194
195                         m_image_ptr = in_ptr;
196                         m_image_cnt = 1;
197                     }
198                     mode = IN_IMAGE;
199                     last = in;
200                 }
201                 break;
202             }
203
204             case IN_IMAGE:
205             {
206 #if ALLOW_FILL_NEXT_CMD
207                 if (last == in)
208 #else
209                 if ((last == in) && ((in==0xFFFF) || (in == 0)) )
210 #endif
211                 {
212                     m_image_cnt--;
213
214                     mode = IN_COPY;
215                     copy_item = in;
216                     m_copy_cnt = 2;
217                 }
218                 else /* different */
219                 {
220                     last = in;
221                     m_image_cnt++;
222                 }
223                 break;
224             }
225
226             default:
227             {
228                 break;
229             }
230         }
231         in_ptr++;
232     } /* next data - end of processing */
233
234     /* flush out the remainder */
235
236     switch(mode)
237     {
238         case IN_COPY:
239         {
240             /* have enough to be a legal copy */
241             (void) FlushImage ();
242
243             (void) FlushCopy (copy_item);
244             break;
245         }
246         case IN_IMAGE:
247         case IN_FIRST:
248         {
249             (void) FlushImage ();
250             break;
251         }
252         default:
253             break;
254     }
255
256     if (m_out_cnt > 2048+16)
257     {
258     //    ErrorTrap("out cnt too big");
259     //    exit (-7);
260     }
261 }
262
263 bool LidilCompress::GetFrameInfo (BYTE **outdata, UInt16 *data_size)
264 {
265     *outdata = (unsigned char *) &m_out_array[0];
266     *data_size = m_out_cnt;
267     return(true);
268 }
269
270 bool LidilCompress::Init (UInt16 *data, UInt16 datasize)
271 {
272         m_image_ptr   = data;
273         m_raw_data    = data;
274         m_data_length = datasize;
275
276         m_run_length = MAX_RUNLENGTH;
277
278         return(true);
279 }
280