~ubuntu-branches/ubuntu/raring/hplip/raring

« back to all changes in this revision

Viewing changes to prnt/hpcups/Mode9.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell
  • Date: 2009-12-14 20:08:44 UTC
  • mfrom: (2.1.118 lucid)
  • Revision ID: james.westby@ubuntu.com-20091214200844-z8qhqwgppbu3t7ze
Tags: 3.9.10-4
KBSD patch from KiBi (Closes: #560796)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************\
 
2
  Mode9.cpp : implementaiton of Mode9 class
 
3
 
 
4
  Copyright (c) 1996 - 2001, 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 "Mode9.h"
 
32
#include "Pipeline.h"
 
33
Mode9::Mode9 (unsigned int RasterSize, bool bPackedBits)
 
34
    : Compressor(RasterSize, true)
 
35
{
 
36
    if (constructor_error != NO_ERROR)  // if error in base constructor
 
37
        return;
 
38
 
 
39
    // Allocate double the RasterSize to accommodate worst case
 
40
    compressBuf = (BYTE*) new BYTE[RasterSize * 2];
 
41
    if (compressBuf == NULL)
 
42
        constructor_error=ALLOCMEM_ERROR;
 
43
 
 
44
    memset(compressBuf, 0, RasterSize * 2);
 
45
    memset(SeedRow,0,RasterSize);
 
46
 
 
47
    ResetSeedRow = false;
 
48
    m_bPackedBits = bPackedBits;
 
49
}
 
50
 
 
51
Mode9::~Mode9()
 
52
{ }
 
53
 
 
54
////////////////////////////////////////////////////////////////////////////
 
55
 
 
56
typedef union {
 
57
    unsigned char comchar;  /* command byte as char */
 
58
    struct
 
59
    {
 
60
#if defined(APDK_LITTLE_ENDIAN) || defined(LITTLE_ENDIAN_HW)
 
61
        unsigned replace_count:3;   /* replace count 1-7, 8=8+next byte */
 
62
        unsigned roff:4;    /* relative offset 0-14, 15=15+next byte */
 
63
        unsigned type:1;      /* type of replacement: 0=mode0, 1=mode1 */
 
64
#else
 
65
        unsigned type:1;      /* type of replacement: 0=mode0, 1=mode1 */
 
66
        unsigned roff:4;    /* relative offset 0-14, 15=15+next byte */
 
67
        unsigned replace_count:3;   /* replace count 1-7, 8=8+next byte */
 
68
#endif
 
69
    } bitf0;
 
70
    struct
 
71
    {
 
72
#if defined(APDK_LITTLE_ENDIAN) || defined(LITTLE_ENDIAN_HW)
 
73
        unsigned replace_count:5;   /* replace count 2-32, 33=33+next byte */
 
74
        unsigned roff:2;    /* relative offset 0-2, 3=3+next byte */
 
75
        unsigned type:1;      /* type of replacement: 0=mode0, 1=mode1 */
 
76
#else
 
77
        unsigned type:1;      /* type of replacement: 0=mode0, 1=mode1 */
 
78
        unsigned roff:2;    /* relative offset 0-2, 3=3+next byte */
 
79
        unsigned replace_count:5;   /* replace count 2-32, 33=33+next byte */
 
80
#endif
 
81
    } bitf1;
 
82
} Mode9_comtype;
 
83
 
 
84
#ifndef MIN
 
85
#define MIN(a,b)    (((a)>=(b))?(b):(a))
 
86
#endif
 
87
 
 
88
#define kPCLMode9           9
 
89
 
 
90
#define MAX_OFFSET0         14      /* Largest unscaled value an offset can have before extra byte is needed. */
 
91
#define OFFSET_START0       0
 
92
#define MAX_COUNT0          6       /* Largest unscaled value a count can have before extra byte is needed */
 
93
#define COUNT_START0        1       /* What a count of zero has a value of. */
 
94
 
 
95
#define MAX_OFFSET1         2
 
96
#define OFFSET_START1       0
 
97
#define MAX_COUNT1          30
 
98
#define COUNT_START1        2
 
99
 
 
100
//*********************************************************
 
101
// This is based on code that came from Kevin Hudson.
 
102
 
 
103
void Mode9::Flush()
 
104
{
 
105
    if (!seeded)
 
106
        return;
 
107
 
 
108
    compressedsize=0;
 
109
    iRastersReady=0;
 
110
    seeded = false;
 
111
    memset (SeedRow, 0, inputsize);
 
112
}
 
113
 
 
114
bool Mode9::Process(RASTERDATA* input)
 
115
// compresses input data,
 
116
// result in Mode9::compressbuf,
 
117
// updates compressedsize
 
118
{
 
119
    if (input==NULL || 
 
120
        (input->rasterdata[COLORTYPE_COLOR]==NULL && input->rasterdata[COLORTYPE_BLACK]==NULL))    // flushing pipeline
 
121
    {
 
122
        Flush();
 
123
        return false;
 
124
    }
 
125
    else
 
126
        seeded = true;
 
127
 
 
128
    if (!ResetSeedRow && input->rasterdata[myplane] == 0)
 
129
    {
 
130
        compressedsize=0;
 
131
        iRastersReady=1;
 
132
        return true;
 
133
    }
 
134
 
 
135
    memset(compressBuf, 0, inputsize * 2);
 
136
 
 
137
    unsigned int originalsize=input->rastersize[myplane];
 
138
    unsigned int size=input->rastersize[myplane];
 
139
    unsigned int layer;
 
140
 
 
141
    //  Convert 8 bit per pixel data into 1 bit per pixel data
 
142
    if (myplane == COLORTYPE_BLACK)
 
143
    {
 
144
        if (input->rasterdata[myplane] == 0)
 
145
        {
 
146
            memset(originalKData, 0, inputsize+1);
 
147
            size = originalsize = inputsize;
 
148
        }
 
149
        else
 
150
        {
 
151
            size = originalsize = (input->rastersize[myplane]+7)/8;
 
152
            memset(originalKData, 0, size);
 
153
 
 
154
            memcpy(originalKData, input->rasterdata[myplane], size);
 
155
            if (!m_bPackedBits)
 
156
            {
 
157
                int curBit = 0x80, curByte = 0;
 
158
                for (int i=0; i<input->rastersize[myplane]; i++)
 
159
                {
 
160
                    if (input->rasterdata[myplane][i])
 
161
                    {
 
162
                        originalKData[curByte] |= curBit;
 
163
                    }
 
164
                    if (curBit == 0x01)
 
165
                    {
 
166
                        curByte++;
 
167
                        curBit = 0x80;
 
168
                    }
 
169
                    else
 
170
                    {
 
171
                        curBit = curBit >> 1;
 
172
                    }
 
173
                }
 
174
            }
 
175
            ResetSeedRow = true;
 
176
        }
 
177
    }
 
178
    if ((myphase) && (myphase->prev))       // if in pipeline, as opposed to autonomous call
 
179
    {
 
180
        layer = myphase->prev->Exec->iRastersDelivered;
 
181
    }
 
182
    else layer = 1;
 
183
 
 
184
    if (myplane == COLORTYPE_BLACK)
 
185
    {
 
186
        layer = 1;
 
187
    }
 
188
 
 
189
    layer--;    // using as offset
 
190
    char *sptr = (char *)(&SeedRow[size*layer]);
 
191
 
 
192
    BYTE *nptr;
 
193
    if (myplane == COLORTYPE_BLACK)
 
194
    {
 
195
        nptr = originalKData;
 
196
    }
 
197
    else
 
198
    {
 
199
        nptr = input->rasterdata[myplane];
 
200
    }
 
201
    BYTE *tempPtr;
 
202
    char last_byte;
 
203
    unsigned int    offset,byte_count,rem_count;
 
204
    Mode9_comtype       command;
 
205
    char* dest=    (char*) compressBuf;
 
206
    register char *dptr=dest;
 
207
 
 
208
    while ( size > 0 )
 
209
    {
 
210
        offset = 0;
 
211
 
 
212
        if (seeded)
 
213
        {
 
214
            /* find a difference between the seed row and this row. */
 
215
            while ((*sptr++ == *nptr++) && (offset < size) )
 
216
            {
 
217
                offset++;
 
218
            }
 
219
            sptr--;
 
220
            nptr--;
 
221
        }
 
222
 
 
223
        if ( offset >= size )   /* too far to find diff, bail */
 
224
          goto bail;
 
225
 
 
226
        size -= offset;
 
227
 
 
228
        if ((*nptr != nptr[1]) || (size < 2))   /************  if doing a mode 0 **********/
 
229
        {
 
230
            command.bitf0.type = 0;
 
231
            last_byte = *nptr++;   /* keep track of the last_byte */
 
232
            sptr++;        /* seed pointer must keep up with nptr */
 
233
            byte_count = 1;
 
234
 
 
235
            /* Now find all of the bytes in a row that don't match
 
236
               either a run of mode3 or mode 1.  A slight
 
237
               optimization here would be to not jump out of this
 
238
               run of mode 0 for a single mode 3 or two mode 1
 
239
               bytes if we have to jump right back into mode 0,
 
240
               especially if there are already 7 mode 0 bytes here
 
241
               (we've already spent the extra byte for the
 
242
               byte-count) */
 
243
            while ((*sptr++ != *nptr) && (last_byte != *nptr) && (byte_count < size))
 
244
            {
 
245
               byte_count++;
 
246
               last_byte = *nptr++;
 
247
            }
 
248
            sptr--;
 
249
 
 
250
            /* Adjust the count if the last_byte == current_byte.
 
251
               Save these bytes for the upcomming run of mode 1. */
 
252
            if ((byte_count < size) && (last_byte == (char)*nptr))
 
253
            {
 
254
                nptr--;  /* Now sptr points to first byte in the new run of mode 1. */
 
255
                sptr--;
 
256
                byte_count--;
 
257
            }
 
258
 
 
259
            size -= byte_count;
 
260
            /* Now output full command.  If offset is over 14 then
 
261
               need optional offset bytes.  If byte count is over 7
 
262
               then need optional byte count. */
 
263
 
 
264
            if (offset > (MAX_OFFSET0+OFFSET_START0))
 
265
                command.bitf0.roff = MAX_OFFSET0+1;
 
266
            else
 
267
                command.bitf0.roff = offset-OFFSET_START0;
 
268
 
 
269
            if (byte_count > (MAX_COUNT0+COUNT_START0))
 
270
                command.bitf0.replace_count = MAX_COUNT0+1;
 
271
            else
 
272
                command.bitf0.replace_count = byte_count-COUNT_START0;
 
273
 
 
274
            *dptr++ = command.comchar;
 
275
 
 
276
            if (offset > (MAX_OFFSET0+OFFSET_START0))
 
277
            {
 
278
                offset -= (MAX_OFFSET0+OFFSET_START0+1);
 
279
                if (offset == 0)
 
280
                {
 
281
                    *dptr++ = 0;
 
282
                }
 
283
                else
 
284
                {
 
285
                     while( offset )
 
286
                     {
 
287
                       *dptr++ = MIN ( offset, 255 );
 
288
 
 
289
                       if ( offset == 255 )
 
290
                       *dptr++ = 0;
 
291
 
 
292
                        offset -= MIN ( offset, 255 );
 
293
                    }
 
294
                }
 
295
            }
 
296
 
 
297
            if (byte_count > (MAX_COUNT0+COUNT_START0))
 
298
            {
 
299
                rem_count = byte_count - (MAX_COUNT0+COUNT_START0+1);
 
300
                if (rem_count == 0)
 
301
                    *dptr++ = 0;
 
302
                else
 
303
                {
 
304
                    while( rem_count )
 
305
                    {
 
306
                        *dptr++ = MIN ( rem_count, 255 );
 
307
 
 
308
                        if ( rem_count == 255 )
 
309
                        *dptr++ = 0;
 
310
 
 
311
                         rem_count -= MIN ( rem_count, 255 );
 
312
                    }
 
313
                }
 
314
            }
 
315
 
 
316
            /* Now output the run of bytes.  First set up a pointer to the first source byte. */
 
317
 
 
318
            tempPtr = nptr - byte_count;
 
319
            for(;byte_count;byte_count--)
 
320
            {
 
321
                *dptr++ = *tempPtr++;
 
322
            }
 
323
 
 
324
        } else      /************ If doing a mode 1 *************/
 
325
        {
 
326
            /* mode 1, next two bytes are equal */
 
327
            command.bitf1.type = 1;
 
328
            nptr++;
 
329
            last_byte = *nptr++;
 
330
            byte_count = 2;
 
331
 
 
332
            while ((last_byte == *nptr++) && (byte_count < size))
 
333
            {
 
334
               byte_count++;
 
335
            }
 
336
            nptr--;
 
337
            sptr += byte_count;
 
338
            size -= byte_count;
 
339
 
 
340
            if (offset > (MAX_OFFSET1+OFFSET_START1))
 
341
                command.bitf1.roff = MAX_OFFSET1+1;
 
342
            else
 
343
                command.bitf1.roff = offset-OFFSET_START1;
 
344
 
 
345
            if (byte_count > (MAX_COUNT1+COUNT_START1))
 
346
                command.bitf1.replace_count = MAX_COUNT1+1;
 
347
            else
 
348
                command.bitf1.replace_count =  byte_count-COUNT_START1;
 
349
 
 
350
            *dptr++ = command.comchar;
 
351
 
 
352
            if (offset > (MAX_OFFSET1+OFFSET_START1))
 
353
            {
 
354
                offset -= (MAX_OFFSET1+OFFSET_START1+1);
 
355
                if (offset == 0)
 
356
                {
 
357
                 *dptr++ = 0;
 
358
                }
 
359
                else
 
360
                {
 
361
                     while( offset )
 
362
                     {
 
363
                        *dptr++ = MIN ( offset, 255 );
 
364
 
 
365
                        if ( offset == 255 )
 
366
                            *dptr++ = 0;
 
367
 
 
368
                        offset -= MIN ( offset, 255 );
 
369
                    }
 
370
                }
 
371
            }  /* if (offset > MAX...  */
 
372
 
 
373
            if (byte_count > (MAX_COUNT1+COUNT_START1))
 
374
            {
 
375
                rem_count = byte_count - (MAX_COUNT1+COUNT_START1+1);
 
376
                if (rem_count == 0)
 
377
                    *dptr++ = 0;
 
378
                else
 
379
                {
 
380
                    while( rem_count )
 
381
                    {
 
382
                        *dptr++ = MIN ( rem_count, 255 );
 
383
 
 
384
                        if ( rem_count == 255 )
 
385
                            *dptr++ = 0;
 
386
 
 
387
                        rem_count -= MIN ( rem_count, 255 );
 
388
                    }
 
389
                 }
 
390
             }  /* if (byte_count > ... */
 
391
 
 
392
             *dptr++ = last_byte;  /* Now output the repeated byte. */
 
393
        }
 
394
    }  /* while (size > 0) */
 
395
 
 
396
bail:
 
397
    size = static_cast<int>((dptr - dest));
 
398
    compressedsize = size;
 
399
    if (myplane == COLORTYPE_BLACK)
 
400
    {
 
401
        memcpy(&(SeedRow[layer*originalsize]), originalKData, originalsize);
 
402
    }
 
403
    else
 
404
    {
 
405
        memcpy(&(SeedRow[layer*originalsize]), input->rasterdata[myplane], originalsize);
 
406
    }
 
407
    seeded = true;
 
408
    iRastersReady=1;
 
409
 
 
410
    return true;
 
411
}
 
412
 
 
413
bool Mode9::NextOutputRaster(RASTERDATA& next_raster)
 
414
// since we return 1-for-1, just return result first call
 
415
{
 
416
    if (iRastersReady==0){
 
417
        return false;
 
418
    }
 
419
    iRastersReady=0;
 
420
    if (myplane == COLORTYPE_BLACK)
 
421
    {
 
422
        if (compressedsize != 0)
 
423
        {
 
424
            next_raster.rastersize[COLORTYPE_BLACK] = compressedsize;
 
425
            next_raster.rasterdata[COLORTYPE_BLACK] = compressBuf;
 
426
        }
 
427
        else
 
428
        {
 
429
            next_raster.rastersize[COLORTYPE_BLACK] = 0;
 
430
            next_raster.rasterdata[COLORTYPE_BLACK] = raster.rasterdata[COLORTYPE_BLACK];
 
431
        }
 
432
        next_raster.rastersize[COLORTYPE_COLOR] = raster.rastersize[COLORTYPE_COLOR];
 
433
        next_raster.rasterdata[COLORTYPE_COLOR] = raster.rasterdata[COLORTYPE_COLOR];
 
434
        return true;
 
435
    }
 
436
 
 
437
    if (myplane == COLORTYPE_COLOR)
 
438
    {
 
439
        if (compressedsize != 0)
 
440
        {
 
441
            next_raster.rastersize[COLORTYPE_COLOR] = compressedsize;
 
442
            next_raster.rasterdata[COLORTYPE_COLOR] = compressBuf;
 
443
        }
 
444
        else
 
445
        {
 
446
            next_raster.rastersize[COLORTYPE_COLOR] = 0;
 
447
            next_raster.rasterdata[COLORTYPE_COLOR] = raster.rasterdata[COLORTYPE_COLOR];
 
448
        }
 
449
        next_raster.rastersize[COLORTYPE_BLACK] = raster.rastersize[COLORTYPE_BLACK];
 
450
        next_raster.rasterdata[COLORTYPE_BLACK] = raster.rasterdata[COLORTYPE_BLACK];
 
451
    }
 
452
 
 
453
    return true;
 
454
}
 
455