~ubuntu-branches/ubuntu/oneiric/ghostscript/oneiric

« back to all changes in this revision

Viewing changes to base/gsbitops.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2011-07-15 16:49:55 UTC
  • mfrom: (1.1.23 upstream)
  • Revision ID: james.westby@ubuntu.com-20110715164955-uga6qibao6kez05c
Tags: 9.04~dfsg~20110715-0ubuntu1
* New upstream release
   - GIT snapshot from Jult, 12 2011.
* debian/patches/020110406~a54df2d.patch,
  debian/patches/020110408~0791cc8.patch,
  debian/patches/020110408~507cbee.patch,
  debian/patches/020110411~4509a49.patch,
  debian/patches/020110412~78bb9a6.patch,
  debian/patches/020110418~a05ab8a.patch,
  debian/patches/020110420~20b6c78.patch,
  debian/patches/020110420~4ddefa2.patch: Removed upstream patches.
* debian/rules: Generate ABI version number (variable "abi") correctly,
  cutting off repackaging and pre-release parts.
* debian/rules: Added ./lcms2/ directory to DEB_UPSTREAM_REPACKAGE_EXCLUDES.
* debian/copyright: Added lcms2/* to the list of excluded files.
* debian/symbols.common: Updated for new upstream source. Applied patch
  which dpkg-gensymbols generated for debian/libgs9.symbols to this file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
2
2
   All Rights Reserved.
3
 
  
 
3
 
4
4
   This software is provided AS-IS with no warranty, either express or
5
5
   implied.
6
6
 
11
11
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12
12
*/
13
13
 
14
 
/* $Id: gsbitops.c 11723 2010-09-16 11:05:47Z robin $ */
 
14
/* $Id$ */
15
15
/* Bitmap filling, copying, and transforming operations */
16
16
#include "stdio_.h"
17
17
#include "memory_.h"
57
57
#define mono_masks mono_fill_masks
58
58
void
59
59
bits_fill_rectangle(byte * dest, int dest_bit, uint draster,
60
 
                    mono_fill_chunk pattern, int width_bits, int height)
 
60
                    mono_fill_chunk pattern, int width_bits, int height)
61
61
{
62
62
    uint bit;
63
63
    chunk right_mask;
66
66
    int last_bit;
67
67
 
68
68
#define FOR_EACH_LINE(stat)\
69
 
        do { stat } while ( inc_ptr(ptr, draster), --line_count )
 
69
        do { stat } while ( inc_ptr(ptr, draster), --line_count )
70
70
 
71
71
    dest += (dest_bit >> 3) & -chunk_align_bytes;
72
72
    ptr = (chunk *) dest;
74
74
    last_bit = width_bits + bit - (chunk_bits + 1);
75
75
 
76
76
    if (last_bit < 0) {         /* <=1 chunk */
77
 
        set_mono_thin_mask(right_mask, width_bits, bit);
78
 
        if (pattern == 0)
79
 
            FOR_EACH_LINE(*ptr &= ~right_mask;);
80
 
        else if (pattern == (mono_fill_chunk)(-1))
81
 
            FOR_EACH_LINE(*ptr |= right_mask;);
82
 
        else
83
 
            FOR_EACH_LINE(
84
 
                *ptr = (*ptr & ~right_mask) | (pattern & right_mask); );
 
77
        set_mono_thin_mask(right_mask, width_bits, bit);
 
78
        if (pattern == 0)
 
79
            FOR_EACH_LINE(*ptr &= ~right_mask;);
 
80
        else if (pattern == (mono_fill_chunk)(-1))
 
81
            FOR_EACH_LINE(*ptr |= right_mask;);
 
82
        else
 
83
            FOR_EACH_LINE(
 
84
                *ptr = (*ptr & ~right_mask) | (pattern & right_mask); );
85
85
    } else {
86
 
        chunk mask;
87
 
        int last = last_bit >> chunk_log2_bits;
88
 
 
89
 
        set_mono_left_mask(mask, bit);
90
 
        set_mono_right_mask(right_mask, (last_bit & chunk_bit_mask) + 1);
91
 
        switch (last) {
92
 
            case 0:             /* 2 chunks */
93
 
                if (pattern == 0)
94
 
                    FOR_EACH_LINE(*ptr &= ~mask; ptr[1] &= ~right_mask;);
95
 
                else if (pattern == (mono_fill_chunk)(-1))
96
 
                    FOR_EACH_LINE(*ptr |= mask; ptr[1] |= right_mask;);
97
 
                else
98
 
                    FOR_EACH_LINE(
99
 
                        *ptr = (*ptr & ~mask) | (pattern & mask);
100
 
                        ptr[1] = (ptr[1] & ~right_mask) | (pattern & right_mask); );
101
 
                break;
102
 
            case 1:             /* 3 chunks */
103
 
                if (pattern == 0)
104
 
                    FOR_EACH_LINE( *ptr &= ~mask;
105
 
                                   ptr[1] = 0;
106
 
                                   ptr[2] &= ~right_mask; );
107
 
                else if (pattern == (mono_fill_chunk)(-1))
108
 
                    FOR_EACH_LINE( *ptr |= mask;
109
 
                                   ptr[1] = ~(chunk) 0;
110
 
                                   ptr[2] |= right_mask; );
111
 
                else
112
 
                    FOR_EACH_LINE( *ptr = (*ptr & ~mask) | (pattern & mask);
113
 
                                    ptr[1] = pattern;
114
 
                                    ptr[2] = (ptr[2] & ~right_mask) | (pattern & right_mask); );
115
 
                break;
116
 
            default:{           /* >3 chunks */
117
 
                    uint byte_count = (last_bit >> 3) & -chunk_bytes;
118
 
 
119
 
                    if (pattern == 0)
120
 
                        FOR_EACH_LINE( *ptr &= ~mask;
121
 
                                       memset(ptr + 1, 0, byte_count);
122
 
                                       ptr[last + 1] &= ~right_mask; );
123
 
                    else if (pattern == (mono_fill_chunk)(-1))
124
 
                        FOR_EACH_LINE( *ptr |= mask;
125
 
                                       memset(ptr + 1, 0xff, byte_count);
126
 
                                       ptr[last + 1] |= right_mask; );
127
 
                    else
128
 
                        FOR_EACH_LINE(
129
 
                                *ptr = (*ptr & ~mask) | (pattern & mask);
130
 
                                memset(ptr + 1, (byte) pattern, byte_count);
131
 
                                ptr[last + 1] = (ptr[last + 1] & ~right_mask) |
132
 
                                                (pattern & right_mask);         );
133
 
                }
134
 
        }
 
86
        chunk mask;
 
87
        int last = last_bit >> chunk_log2_bits;
 
88
 
 
89
        set_mono_left_mask(mask, bit);
 
90
        set_mono_right_mask(right_mask, (last_bit & chunk_bit_mask) + 1);
 
91
        switch (last) {
 
92
            case 0:             /* 2 chunks */
 
93
                if (pattern == 0)
 
94
                    FOR_EACH_LINE(*ptr &= ~mask; ptr[1] &= ~right_mask;);
 
95
                else if (pattern == (mono_fill_chunk)(-1))
 
96
                    FOR_EACH_LINE(*ptr |= mask; ptr[1] |= right_mask;);
 
97
                else
 
98
                    FOR_EACH_LINE(
 
99
                        *ptr = (*ptr & ~mask) | (pattern & mask);
 
100
                        ptr[1] = (ptr[1] & ~right_mask) | (pattern & right_mask); );
 
101
                break;
 
102
            case 1:             /* 3 chunks */
 
103
                if (pattern == 0)
 
104
                    FOR_EACH_LINE( *ptr &= ~mask;
 
105
                                   ptr[1] = 0;
 
106
                                   ptr[2] &= ~right_mask; );
 
107
                else if (pattern == (mono_fill_chunk)(-1))
 
108
                    FOR_EACH_LINE( *ptr |= mask;
 
109
                                   ptr[1] = ~(chunk) 0;
 
110
                                   ptr[2] |= right_mask; );
 
111
                else
 
112
                    FOR_EACH_LINE( *ptr = (*ptr & ~mask) | (pattern & mask);
 
113
                                    ptr[1] = pattern;
 
114
                                    ptr[2] = (ptr[2] & ~right_mask) | (pattern & right_mask); );
 
115
                break;
 
116
            default:{           /* >3 chunks */
 
117
                    uint byte_count = (last_bit >> 3) & -chunk_bytes;
 
118
 
 
119
                    if (pattern == 0)
 
120
                        FOR_EACH_LINE( *ptr &= ~mask;
 
121
                                       memset(ptr + 1, 0, byte_count);
 
122
                                       ptr[last + 1] &= ~right_mask; );
 
123
                    else if (pattern == (mono_fill_chunk)(-1))
 
124
                        FOR_EACH_LINE( *ptr |= mask;
 
125
                                       memset(ptr + 1, 0xff, byte_count);
 
126
                                       ptr[last + 1] |= right_mask; );
 
127
                    else
 
128
                        FOR_EACH_LINE(
 
129
                                *ptr = (*ptr & ~mask) | (pattern & mask);
 
130
                                memset(ptr + 1, (byte) pattern, byte_count);
 
131
                                ptr[last + 1] = (ptr[last + 1] & ~right_mask) |
 
132
                                                (pattern & right_mask);         );
 
133
                }
 
134
        }
135
135
    }
136
136
#undef FOR_EACH_LINE
137
137
}
144
144
 */
145
145
void
146
146
bits_fill_rectangle_masked(byte * dest, int dest_bit, uint draster,
147
 
                    mono_fill_chunk pattern, mono_fill_chunk src_mask,
148
 
                    int width_bits, int height)
 
147
                    mono_fill_chunk pattern, mono_fill_chunk src_mask,
 
148
                    int width_bits, int height)
149
149
{
150
150
    uint bit;
151
151
    chunk right_mask;
154
154
    int last_bit;
155
155
 
156
156
#define FOR_EACH_LINE(stat)\
157
 
        do { stat } while ( inc_ptr(ptr, draster), --line_count )
 
157
        do { stat } while ( inc_ptr(ptr, draster), --line_count )
158
158
 
159
159
    dest += (dest_bit >> 3) & -chunk_align_bytes;
160
160
    ptr = (chunk *) dest;
162
162
    last_bit = width_bits + bit - (chunk_bits + 1);
163
163
 
164
164
    if (last_bit < 0) {         /* <=1 chunk */
165
 
        set_mono_thin_mask(right_mask, width_bits, bit);
166
 
        right_mask &= ~src_mask;
167
 
        if (pattern == 0)
168
 
            FOR_EACH_LINE(*ptr &= ~right_mask;);
169
 
        else if (pattern == (mono_fill_chunk)(-1))
170
 
            FOR_EACH_LINE(*ptr |= right_mask;);
171
 
        else
172
 
            FOR_EACH_LINE(
173
 
                *ptr = (*ptr & ~right_mask) | (pattern & right_mask); );
 
165
        set_mono_thin_mask(right_mask, width_bits, bit);
 
166
        right_mask &= ~src_mask;
 
167
        if (pattern == 0)
 
168
            FOR_EACH_LINE(*ptr &= ~right_mask;);
 
169
        else if (pattern == (mono_fill_chunk)(-1))
 
170
            FOR_EACH_LINE(*ptr |= right_mask;);
 
171
        else
 
172
            FOR_EACH_LINE(
 
173
                *ptr = (*ptr & ~right_mask) | (pattern & right_mask); );
174
174
    } else {
175
 
        chunk mask;
176
 
        int last = last_bit >> chunk_log2_bits;
 
175
        chunk mask;
 
176
        int last = last_bit >> chunk_log2_bits;
177
177
 
178
 
        set_mono_left_mask(mask, bit);
179
 
        set_mono_right_mask(right_mask, (last_bit & chunk_bit_mask) + 1);
180
 
        mask &= ~src_mask;
181
 
        right_mask &= ~src_mask;
182
 
        switch (last) {
183
 
            case 0:             /* 2 chunks */
184
 
                if (pattern == 0)
185
 
                    FOR_EACH_LINE(*ptr &= ~mask; ptr[1] &= ~right_mask;);
186
 
                else if (pattern == (mono_fill_chunk)(-1))
187
 
                    FOR_EACH_LINE(*ptr |= mask; ptr[1] |= right_mask;);
188
 
                else
189
 
                    FOR_EACH_LINE(
190
 
                        *ptr = (*ptr & ~mask) | (pattern & mask);
191
 
                        ptr[1] = (ptr[1] & ~right_mask) | (pattern & right_mask); );
192
 
                break;
193
 
            case 1:             /* 3 chunks */
194
 
                if (pattern == 0)
195
 
                    FOR_EACH_LINE( *ptr &= ~mask;
196
 
                                   ptr[1] &= src_mask;
197
 
                                   ptr[2] &= ~right_mask; );
198
 
                else if (pattern == (mono_fill_chunk)(-1))
199
 
                    FOR_EACH_LINE( *ptr |= mask;
200
 
                                   ptr[1] |= ~src_mask;
201
 
                                   ptr[2] |= right_mask; );
202
 
                else
203
 
                    FOR_EACH_LINE( *ptr = (*ptr & ~mask) | (pattern & mask);
204
 
                                    ptr[1] =(ptr[1] & src_mask) | pattern;
205
 
                                    ptr[2] = (ptr[2] & ~right_mask) | (pattern & right_mask); );
206
 
                break;
207
 
            default:{           /* >3 chunks */
 
178
        set_mono_left_mask(mask, bit);
 
179
        set_mono_right_mask(right_mask, (last_bit & chunk_bit_mask) + 1);
 
180
        mask &= ~src_mask;
 
181
        right_mask &= ~src_mask;
 
182
        switch (last) {
 
183
            case 0:             /* 2 chunks */
 
184
                if (pattern == 0)
 
185
                    FOR_EACH_LINE(*ptr &= ~mask; ptr[1] &= ~right_mask;);
 
186
                else if (pattern == (mono_fill_chunk)(-1))
 
187
                    FOR_EACH_LINE(*ptr |= mask; ptr[1] |= right_mask;);
 
188
                else
 
189
                    FOR_EACH_LINE(
 
190
                        *ptr = (*ptr & ~mask) | (pattern & mask);
 
191
                        ptr[1] = (ptr[1] & ~right_mask) | (pattern & right_mask); );
 
192
                break;
 
193
            case 1:             /* 3 chunks */
 
194
                if (pattern == 0)
 
195
                    FOR_EACH_LINE( *ptr &= ~mask;
 
196
                                   ptr[1] &= src_mask;
 
197
                                   ptr[2] &= ~right_mask; );
 
198
                else if (pattern == (mono_fill_chunk)(-1))
 
199
                    FOR_EACH_LINE( *ptr |= mask;
 
200
                                   ptr[1] |= ~src_mask;
 
201
                                   ptr[2] |= right_mask; );
 
202
                else
 
203
                    FOR_EACH_LINE( *ptr = (*ptr & ~mask) | (pattern & mask);
 
204
                                    ptr[1] =(ptr[1] & src_mask) | pattern;
 
205
                                    ptr[2] = (ptr[2] & ~right_mask) | (pattern & right_mask); );
 
206
                break;
 
207
            default:{           /* >3 chunks */
208
208
                    int     i;
209
209
 
210
 
                    if (pattern == 0)
211
 
                        FOR_EACH_LINE( *ptr++ &= ~mask;
212
 
                                       for (i = 0; i < last; i++)
213
 
                                           *ptr++ &= src_mask;
214
 
                                       *ptr &= ~right_mask; );
215
 
                    else if (pattern == (mono_fill_chunk)(-1))
216
 
                        FOR_EACH_LINE( *ptr++ |= mask;
217
 
                                       for (i = 0; i < last; i++)
218
 
                                           *ptr++ |= ~src_mask;
219
 
                                        *ptr |= right_mask; );
220
 
                    else
221
 
                        FOR_EACH_LINE(
222
 
                            /* note: we know (pattern & ~src_mask) == pattern */
223
 
                            *ptr = (*ptr & ~mask) | (pattern & mask);
224
 
                            ++ptr;
225
 
                            for (i = 0; i < last; i++, ptr++)
 
210
                    if (pattern == 0)
 
211
                        FOR_EACH_LINE( *ptr++ &= ~mask;
 
212
                                       for (i = 0; i < last; i++)
 
213
                                           *ptr++ &= src_mask;
 
214
                                       *ptr &= ~right_mask; );
 
215
                    else if (pattern == (mono_fill_chunk)(-1))
 
216
                        FOR_EACH_LINE( *ptr++ |= mask;
 
217
                                       for (i = 0; i < last; i++)
 
218
                                           *ptr++ |= ~src_mask;
 
219
                                        *ptr |= right_mask; );
 
220
                    else
 
221
                        FOR_EACH_LINE(
 
222
                            /* note: we know (pattern & ~src_mask) == pattern */
 
223
                            *ptr = (*ptr & ~mask) | (pattern & mask);
 
224
                            ++ptr;
 
225
                            for (i = 0; i < last; i++, ptr++)
226
226
                                *ptr = (*ptr & src_mask) | pattern;
227
 
                                *ptr = (*ptr & ~right_mask) | (pattern & right_mask); );
228
 
                }
229
 
        }
 
227
                                *ptr = (*ptr & ~right_mask) | (pattern & right_mask); );
 
228
                }
 
229
        }
230
230
    }
231
231
#undef FOR_EACH_LINE
232
232
}
234
234
/* Replicate a bitmap horizontally in place. */
235
235
void
236
236
bits_replicate_horizontally(byte * data, uint width, uint height,
237
 
                 uint raster, uint replicated_width, uint replicated_raster)
 
237
                 uint raster, uint replicated_width, uint replicated_raster)
238
238
{
239
239
    /* The current algorithm is extremely inefficient! */
240
240
    const byte *orig_row = data + (height - 1) * raster;
242
242
    uint y;
243
243
 
244
244
    if (!(width & 7)) {
245
 
        uint src_bytes = width >> 3;
246
 
        uint dest_bytes = replicated_width >> 3;
247
 
 
248
 
        for (y = height; y-- > 0;
249
 
             orig_row -= raster, tile_row -= replicated_raster
250
 
             ) {
251
 
            uint move = src_bytes;
252
 
            const byte *from = orig_row;
253
 
            byte *to = tile_row + dest_bytes - src_bytes;
254
 
 
255
 
            memmove(to, from, move);
256
 
            while (to - tile_row >= move) {
257
 
                from = to;
258
 
                to -= move;
259
 
                memmove(to, from, move);
260
 
                move <<= 1;
261
 
            }
262
 
            if (to != tile_row)
263
 
                memmove(tile_row, to, to - tile_row);
264
 
        }
 
245
        uint src_bytes = width >> 3;
 
246
        uint dest_bytes = replicated_width >> 3;
 
247
 
 
248
        for (y = height; y-- > 0;
 
249
             orig_row -= raster, tile_row -= replicated_raster
 
250
             ) {
 
251
            uint move = src_bytes;
 
252
            const byte *from = orig_row;
 
253
            byte *to = tile_row + dest_bytes - src_bytes;
 
254
 
 
255
            memmove(to, from, move);
 
256
            while (to - tile_row >= move) {
 
257
                from = to;
 
258
                to -= move;
 
259
                memmove(to, from, move);
 
260
                move <<= 1;
 
261
            }
 
262
            if (to != tile_row)
 
263
                memmove(tile_row, to, to - tile_row);
 
264
        }
265
265
    } else {
266
 
        /*
267
 
         * This algorithm is inefficient, but probably not worth improving.
268
 
         */
269
 
        uint bit_count = width & (uint)(-(int)width);  /* lowest bit: 1, 2, or 4 */
270
 
        uint left_mask = (0xff00 >> bit_count) & 0xff;
271
 
 
272
 
        for (y = height; y-- > 0;
273
 
             orig_row -= raster, tile_row -= replicated_raster
274
 
             ) {
275
 
            uint sx;
276
 
 
277
 
            for (sx = width; sx > 0;) {
278
 
                uint bits, dx;
279
 
 
280
 
                sx -= bit_count;
281
 
                bits = (orig_row[sx >> 3] << (sx & 7)) & left_mask;
282
 
                for (dx = sx + replicated_width; dx >= width;) {
283
 
                    byte *dp;
284
 
                    int dbit;
285
 
 
286
 
                    dx -= width;
287
 
                    dbit = dx & 7;
288
 
                    dp = tile_row + (dx >> 3);
289
 
                    *dp = (*dp & ~(left_mask >> dbit)) | (bits >> dbit);
290
 
                }
291
 
            }
292
 
        }
 
266
        /*
 
267
         * This algorithm is inefficient, but probably not worth improving.
 
268
         */
 
269
        uint bit_count = width & (uint)(-(int)width);  /* lowest bit: 1, 2, or 4 */
 
270
        uint left_mask = (0xff00 >> bit_count) & 0xff;
 
271
 
 
272
        for (y = height; y-- > 0;
 
273
             orig_row -= raster, tile_row -= replicated_raster
 
274
             ) {
 
275
            uint sx;
 
276
 
 
277
            for (sx = width; sx > 0;) {
 
278
                uint bits, dx;
 
279
 
 
280
                sx -= bit_count;
 
281
                bits = (orig_row[sx >> 3] << (sx & 7)) & left_mask;
 
282
                for (dx = sx + replicated_width; dx >= width;) {
 
283
                    byte *dp;
 
284
                    int dbit;
 
285
 
 
286
                    dx -= width;
 
287
                    dbit = dx & 7;
 
288
                    dp = tile_row + (dx >> 3);
 
289
                    *dp = (*dp & ~(left_mask >> dbit)) | (bits >> dbit);
 
290
                }
 
291
            }
 
292
        }
293
293
    }
294
294
}
295
295
 
296
296
/* Replicate a bitmap vertically in place. */
297
297
void
298
298
bits_replicate_vertically(byte * data, uint height, uint raster,
299
 
                          uint replicated_height)
 
299
                          uint replicated_height)
300
300
{
301
301
    byte *dest = data;
302
302
    uint h = replicated_height;
303
303
    uint size = raster * height;
304
304
 
305
305
    while (h > height) {
306
 
        memcpy(dest + size, dest, size);
307
 
        dest += size;
308
 
        h -= height;
 
306
        memcpy(dest + size, dest, size);
 
307
        dest += size;
 
308
        h -= height;
309
309
    }
310
310
}
311
311
 
313
313
/* Assume bits beyond the width are zero. */
314
314
void
315
315
bits_bounding_box(const byte * data, uint height, uint raster,
316
 
                  gs_int_rect * pbox)
 
316
                  gs_int_rect * pbox)
317
317
{
318
318
    register const ulong *lp;
319
319
    static const byte first_1[16] = {
320
 
        4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
 
320
        4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
321
321
    };
322
322
    static const byte last_1[16] = {
323
 
        0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4
 
323
        0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4
324
324
    };
325
325
 
326
326
    /* Count trailing blank rows. */
329
329
 
330
330
    lp = (const ulong *)(data + raster * height);
331
331
    while ((const byte *)lp > data && !lp[-1])
332
 
        --lp;
 
332
        --lp;
333
333
    if ((const byte *)lp == data) {
334
 
        pbox->p.x = pbox->q.x = pbox->p.y = pbox->q.y = 0;
335
 
        return;
 
334
        pbox->p.x = pbox->q.x = pbox->p.y = pbox->q.y = 0;
 
335
        return;
336
336
    }
337
337
    pbox->q.y = height = ((const byte *)lp - data + raster - 1) / raster;
338
338
 
340
340
 
341
341
    lp = (const ulong *)data;
342
342
    while (!*lp)
343
 
        ++lp;
 
343
        ++lp;
344
344
    {
345
 
        uint n = ((const byte *)lp - data) / raster;
 
345
        uint n = ((const byte *)lp - data) / raster;
346
346
 
347
 
        pbox->p.y = n;
348
 
        if (n)
349
 
            height -= n, data += n * raster;
 
347
        pbox->p.y = n;
 
348
        if (n)
 
349
            height -= n, data += n * raster;
350
350
    }
351
351
 
352
352
    /* Find the left and right edges. */
353
353
    /* We know that the first and last rows are non-blank. */
354
354
 
355
355
    {
356
 
        uint raster_longs = raster >> arch_log2_sizeof_long;
357
 
        uint left = raster_longs - 1, right = 0;
358
 
        ulong llong = 0, rlong = 0;
359
 
        const byte *q;
360
 
        uint h, n;
361
 
 
362
 
        for (q = data, h = height; h-- > 0; q += raster) {      /* Work from the left edge by longs. */
363
 
            for (lp = (const ulong *)q, n = 0;
364
 
                 n < left && !*lp; lp++, n++
365
 
                );
366
 
            if (n < left)
367
 
                left = n, llong = *lp;
368
 
            else
369
 
                llong |= *lp;
370
 
            /* Work from the right edge by longs. */
371
 
            for (lp = (const ulong *)(q + raster - sizeof(long)),
372
 
                 n = raster_longs - 1;
373
 
 
374
 
                 n > right && !*lp; lp--, n--
375
 
                );
376
 
            if (n > right)
377
 
                right = n, rlong = *lp;
378
 
            else
379
 
                rlong |= *lp;
380
 
        }
381
 
 
382
 
        /* Do binary subdivision on edge longs.  We assume that */
383
 
        /* sizeof(long) = 4 or 8. */
 
356
        uint raster_longs = raster >> arch_log2_sizeof_long;
 
357
        uint left = raster_longs - 1, right = 0;
 
358
        ulong llong = 0, rlong = 0;
 
359
        const byte *q;
 
360
        uint h, n;
 
361
 
 
362
        for (q = data, h = height; h-- > 0; q += raster) {      /* Work from the left edge by longs. */
 
363
            for (lp = (const ulong *)q, n = 0;
 
364
                 n < left && !*lp; lp++, n++
 
365
                );
 
366
            if (n < left)
 
367
                left = n, llong = *lp;
 
368
            else
 
369
                llong |= *lp;
 
370
            /* Work from the right edge by longs. */
 
371
            for (lp = (const ulong *)(q + raster - sizeof(long)),
 
372
                 n = raster_longs - 1;
 
373
 
 
374
                 n > right && !*lp; lp--, n--
 
375
                );
 
376
            if (n > right)
 
377
                right = n, rlong = *lp;
 
378
            else
 
379
                rlong |= *lp;
 
380
        }
 
381
 
 
382
        /* Do binary subdivision on edge longs.  We assume that */
 
383
        /* sizeof(long) = 4 or 8. */
384
384
#if arch_sizeof_long > 8
385
 
        Error_longs_are_too_large();
 
385
        Error_longs_are_too_large();
386
386
#endif
387
387
 
388
388
#if arch_is_big_endian
395
395
#  define right_justify_last(x,n) (x) >>= ((arch_sizeof_long * 8) - (n))
396
396
#endif
397
397
 
398
 
        left <<= arch_log2_sizeof_long + 3;
399
 
#if arch_sizeof_long == 8
400
 
        if (llong & ~last_bits(32))
401
 
            shift_out_last(llong, 32);
402
 
        else
403
 
            left += 32;
404
 
#endif
405
 
        if (llong & ~last_bits(16))
406
 
            shift_out_last(llong, 16);
407
 
        else
408
 
            left += 16;
409
 
        if (llong & ~last_bits(8))
410
 
            shift_out_last(llong, 8);
411
 
        else
412
 
            left += 8;
413
 
        right_justify_last(llong, 8);
414
 
        if (llong & 0xf0)
415
 
            left += first_1[(byte) llong >> 4];
416
 
        else
417
 
            left += first_1[(byte) llong] + 4;
418
 
 
419
 
        right <<= arch_log2_sizeof_long + 3;
420
 
#if arch_sizeof_long == 8
421
 
        if (!(rlong & last_bits(32)))
422
 
            shift_out_last(rlong, 32);
423
 
        else
424
 
            right += 32;
425
 
#endif
426
 
        if (!(rlong & last_bits(16)))
427
 
            shift_out_last(rlong, 16);
428
 
        else
429
 
            right += 16;
430
 
        if (!(rlong & last_bits(8)))
431
 
            shift_out_last(rlong, 8);
432
 
        else
433
 
            right += 8;
434
 
        right_justify_last(rlong, 8);
435
 
        if (!(rlong & 0xf))
436
 
            right += last_1[(byte) rlong >> 4];
437
 
        else
438
 
            right += last_1[(uint) rlong & 0xf] + 4;
439
 
 
440
 
        pbox->p.x = left;
441
 
        pbox->q.x = right;
 
398
        left <<= arch_log2_sizeof_long + 3;
 
399
#if arch_sizeof_long == 8
 
400
        if (llong & ~last_bits(32))
 
401
            shift_out_last(llong, 32);
 
402
        else
 
403
            left += 32;
 
404
#endif
 
405
        if (llong & ~last_bits(16))
 
406
            shift_out_last(llong, 16);
 
407
        else
 
408
            left += 16;
 
409
        if (llong & ~last_bits(8))
 
410
            shift_out_last(llong, 8);
 
411
        else
 
412
            left += 8;
 
413
        right_justify_last(llong, 8);
 
414
        if (llong & 0xf0)
 
415
            left += first_1[(byte) llong >> 4];
 
416
        else
 
417
            left += first_1[(byte) llong] + 4;
 
418
 
 
419
        right <<= arch_log2_sizeof_long + 3;
 
420
#if arch_sizeof_long == 8
 
421
        if (!(rlong & last_bits(32)))
 
422
            shift_out_last(rlong, 32);
 
423
        else
 
424
            right += 32;
 
425
#endif
 
426
        if (!(rlong & last_bits(16)))
 
427
            shift_out_last(rlong, 16);
 
428
        else
 
429
            right += 16;
 
430
        if (!(rlong & last_bits(8)))
 
431
            shift_out_last(rlong, 8);
 
432
        else
 
433
            right += 8;
 
434
        right_justify_last(rlong, 8);
 
435
        if (!(rlong & 0xf))
 
436
            right += last_1[(byte) rlong >> 4];
 
437
        else
 
438
            right += last_1[(uint) rlong & 0xf] + 4;
 
439
 
 
440
        pbox->p.x = left;
 
441
        pbox->q.x = right;
442
442
    }
443
443
}
444
444
 
455
455
    int dest_bit = dest->x * dest_depth;
456
456
    byte *dest_row = dest->data.write + (dest_bit >> 3);
457
457
    enum {
458
 
        EXTRACT_SLOW = 0,
459
 
        EXTRACT_4_TO_1,
460
 
        EXTRACT_32_TO_8
 
458
        EXTRACT_SLOW = 0,
 
459
        EXTRACT_4_TO_1,
 
460
        EXTRACT_32_TO_8
461
461
    } loop_case = EXTRACT_SLOW;
462
462
    int y;
463
463
 
465
465
    dest_bit &= 7;
466
466
    /* Check for the fast CMYK cases. */
467
467
    if (!(source_bit | dest_bit)) {
468
 
        switch (source_depth) {
469
 
        case 4:
470
 
            loop_case =
471
 
                (dest_depth == 1 && !(source->raster & 3) &&
472
 
                 !(source->x & 1) ? EXTRACT_4_TO_1 :
473
 
                 EXTRACT_SLOW);
474
 
            break;
475
 
        case 32:
476
 
            if (dest_depth == 8 && !(shift & 7)) {
477
 
                loop_case = EXTRACT_32_TO_8;
478
 
                source_row += 3 - (shift >> 3);
479
 
            }
480
 
            break;
481
 
        }
 
468
        switch (source_depth) {
 
469
        case 4:
 
470
            loop_case =
 
471
                (dest_depth == 1 && !(source->raster & 3) &&
 
472
                 !(source->x & 1) ? EXTRACT_4_TO_1 :
 
473
                 EXTRACT_SLOW);
 
474
            break;
 
475
        case 32:
 
476
            if (dest_depth == 8 && !(shift & 7)) {
 
477
                loop_case = EXTRACT_32_TO_8;
 
478
                source_row += 3 - (shift >> 3);
 
479
            }
 
480
            break;
 
481
        }
482
482
    }
483
483
    for (y = 0; y < height;
484
 
         ++y, source_row += source->raster, dest_row += dest->raster
485
 
        ) {
486
 
        int x;
487
 
 
488
 
        switch (loop_case) {
489
 
        case EXTRACT_4_TO_1: {
490
 
            const byte *src = source_row;
491
 
            byte *dst = dest_row;
492
 
 
493
 
            /* Do groups of 8 pixels. */
494
 
            for (x = width; x >= 8; src += 4, x -= 8) {
495
 
                bits32 sword =
496
 
                    (*(const bits32 *)src >> shift) & 0x11111111;
497
 
 
498
 
                *dst++ =
499
 
                    byte_acegbdfh_to_abcdefgh[(
 
484
         ++y, source_row += source->raster, dest_row += dest->raster
 
485
        ) {
 
486
        int x;
 
487
 
 
488
        switch (loop_case) {
 
489
        case EXTRACT_4_TO_1: {
 
490
            const byte *src = source_row;
 
491
            byte *dst = dest_row;
 
492
 
 
493
            /* Do groups of 8 pixels. */
 
494
            for (x = width; x >= 8; src += 4, x -= 8) {
 
495
                bits32 sword =
 
496
                    (*(const bits32 *)src >> shift) & 0x11111111;
 
497
 
 
498
                *dst++ =
 
499
                    byte_acegbdfh_to_abcdefgh[(
500
500
#if arch_is_big_endian
501
 
                    (sword >> 21) | (sword >> 14) | (sword >> 7) | sword
 
501
                    (sword >> 21) | (sword >> 14) | (sword >> 7) | sword
502
502
#else
503
 
                    (sword << 3) | (sword >> 6) | (sword >> 15) | (sword >> 24)
 
503
                    (sword << 3) | (sword >> 6) | (sword >> 15) | (sword >> 24)
504
504
#endif
505
 
                                        ) & 0xff];
506
 
            }
507
 
            if (x) {
508
 
                /* Do the final 1-7 pixels. */
509
 
                uint test = 0x10 << shift, store = 0x80;
510
 
 
511
 
                do {
512
 
                    *dst = (*src & test ? *dst | store : *dst & ~store);
513
 
                    if (test >= 0x10)
514
 
                        test >>= 4;
515
 
                    else
516
 
                        test <<= 4, ++src;
517
 
                    store >>= 1;
518
 
                } while (--x > 0);
519
 
            }
520
 
            break;
521
 
        }
522
 
        case EXTRACT_32_TO_8: {
523
 
            const byte *src = source_row;
524
 
            byte *dst = dest_row;
525
 
 
526
 
            for (x = width; x > 0; src += 4, --x)
527
 
                *dst++ = *src;
528
 
            break;
529
 
        }
530
 
        default: {
531
 
            sample_load_declare_setup(sptr, sbit, source_row, source_bit,
532
 
                                      source_depth);
533
 
            sample_store_declare_setup(dptr, dbit, dbbyte, dest_row, dest_bit,
534
 
                                       dest_depth);
535
 
 
536
 
            sample_store_preload(dbbyte, dptr, dbit, dest_depth);
537
 
            for (x = width; x > 0; --x) {
538
 
                gx_color_index color;
539
 
                uint pixel;
540
 
 
541
 
                sample_load_next_any(color, sptr, sbit, source_depth);
542
 
                pixel = (color >> shift) & plane_mask;
543
 
                sample_store_next8(pixel, dptr, dbit, dest_depth, dbbyte);
544
 
            }
545
 
            sample_store_flush(dptr, dbit, dest_depth, dbbyte);
546
 
        }
547
 
        }
 
505
                                        ) & 0xff];
 
506
            }
 
507
            if (x) {
 
508
                /* Do the final 1-7 pixels. */
 
509
                uint test = 0x10 << shift, store = 0x80;
 
510
 
 
511
                do {
 
512
                    *dst = (*src & test ? *dst | store : *dst & ~store);
 
513
                    if (test >= 0x10)
 
514
                        test >>= 4;
 
515
                    else
 
516
                        test <<= 4, ++src;
 
517
                    store >>= 1;
 
518
                } while (--x > 0);
 
519
            }
 
520
            break;
 
521
        }
 
522
        case EXTRACT_32_TO_8: {
 
523
            const byte *src = source_row;
 
524
            byte *dst = dest_row;
 
525
 
 
526
            for (x = width; x > 0; src += 4, --x)
 
527
                *dst++ = *src;
 
528
            break;
 
529
        }
 
530
        default: {
 
531
            sample_load_declare_setup(sptr, sbit, source_row, source_bit,
 
532
                                      source_depth);
 
533
            sample_store_declare_setup(dptr, dbit, dbbyte, dest_row, dest_bit,
 
534
                                       dest_depth);
 
535
 
 
536
            sample_store_preload(dbbyte, dptr, dbit, dest_depth);
 
537
            for (x = width; x > 0; --x) {
 
538
                gx_color_index color;
 
539
                uint pixel;
 
540
 
 
541
                sample_load_next_any(color, sptr, sbit, source_depth);
 
542
                pixel = (color >> shift) & plane_mask;
 
543
                sample_store_next8(pixel, dptr, dbit, dest_depth, dbbyte);
 
544
            }
 
545
            sample_store_flush(dptr, dbit, dest_depth, dbbyte);
 
546
        }
 
547
        }
548
548
    }
549
549
    return 0;
550
550
}
564
564
    int dest_bit = dest->x * dest_depth;
565
565
    byte *dest_row = dest->data.write + (dest_bit >> 3);
566
566
    enum {
567
 
        EXPAND_SLOW = 0,
568
 
        EXPAND_1_TO_4,
569
 
        EXPAND_8_TO_32
 
567
        EXPAND_SLOW = 0,
 
568
        EXPAND_1_TO_4,
 
569
        EXPAND_8_TO_32
570
570
    } loop_case = EXPAND_SLOW;
571
571
    int y;
572
572
 
573
573
    source_bit &= 7;
574
574
    /* Check for the fast CMYK cases. */
575
575
    if (!(source_bit || (dest_bit & 31) || (dest->raster & 3))) {
576
 
        switch (dest_depth) {
577
 
        case 4:
578
 
            if (source_depth == 1)
579
 
                loop_case = EXPAND_1_TO_4;
580
 
            break;
581
 
        case 32:
582
 
            if (source_depth == 8 && !(shift & 7))
583
 
                loop_case = EXPAND_8_TO_32;
584
 
            break;
585
 
        }
 
576
        switch (dest_depth) {
 
577
        case 4:
 
578
            if (source_depth == 1)
 
579
                loop_case = EXPAND_1_TO_4;
 
580
            break;
 
581
        case 32:
 
582
            if (source_depth == 8 && !(shift & 7))
 
583
                loop_case = EXPAND_8_TO_32;
 
584
            break;
 
585
        }
586
586
    }
587
587
    dest_bit &= 7;
588
588
    switch (loop_case) {
591
591
#if arch_is_big_endian
592
592
#  define word_shift (shift)
593
593
#else
594
 
        int word_shift = 24 - shift;
 
594
        int word_shift = 24 - shift;
595
595
#endif
596
 
        for (y = 0; y < height;
597
 
             ++y, source_row += source->raster, dest_row += dest->raster
598
 
             ) {
599
 
            int x;
600
 
            const byte *src = source_row;
601
 
            bits32 *dst = (bits32 *)dest_row;
 
596
        for (y = 0; y < height;
 
597
             ++y, source_row += source->raster, dest_row += dest->raster
 
598
             ) {
 
599
            int x;
 
600
            const byte *src = source_row;
 
601
            bits32 *dst = (bits32 *)dest_row;
602
602
 
603
 
            for (x = width; x > 0; --x)
604
 
                *dst++ = (bits32)(*src++) << word_shift;
605
 
        }
 
603
            for (x = width; x > 0; --x)
 
604
                *dst++ = (bits32)(*src++) << word_shift;
 
605
        }
606
606
#undef word_shift
607
607
    }
608
 
        break;
 
608
        break;
609
609
 
610
610
    case EXPAND_1_TO_4:
611
611
    default:
612
 
        for (y = 0; y < height;
613
 
             ++y, source_row += source->raster, dest_row += dest->raster
614
 
             ) {
615
 
            int x;
616
 
            sample_load_declare_setup(sptr, sbit, source_row, source_bit,
617
 
                                      source_depth);
618
 
            sample_store_declare_setup(dptr, dbit, dbbyte, dest_row, dest_bit,
619
 
                                       dest_depth);
620
 
 
621
 
            sample_store_preload(dbbyte, dptr, dbit, dest_depth);
622
 
            for (x = width; x > 0; --x) {
623
 
                uint color;
624
 
                gx_color_index pixel;
625
 
 
626
 
                sample_load_next8(color, sptr, sbit, source_depth);
627
 
                pixel = color << shift;
628
 
                sample_store_next_any(pixel, dptr, dbit, dest_depth, dbbyte);
629
 
            }
630
 
            sample_store_flush(dptr, dbit, dest_depth, dbbyte);
631
 
        }
632
 
        break;
 
612
        for (y = 0; y < height;
 
613
             ++y, source_row += source->raster, dest_row += dest->raster
 
614
             ) {
 
615
            int x;
 
616
            sample_load_declare_setup(sptr, sbit, source_row, source_bit,
 
617
                                      source_depth);
 
618
            sample_store_declare_setup(dptr, dbit, dbbyte, dest_row, dest_bit,
 
619
                                       dest_depth);
 
620
 
 
621
            sample_store_preload(dbbyte, dptr, dbit, dest_depth);
 
622
            for (x = width; x > 0; --x) {
 
623
                uint color;
 
624
                gx_color_index pixel;
 
625
 
 
626
                sample_load_next8(color, sptr, sbit, source_depth);
 
627
                pixel = color << shift;
 
628
                sample_store_next_any(pixel, dptr, dbit, dest_depth, dbbyte);
 
629
            }
 
630
            sample_store_flush(dptr, dbit, dest_depth, dbbyte);
 
631
        }
 
632
        break;
633
633
 
634
634
    }
635
635
    return 0;
640
640
/* Fill a rectangle of bytes. */
641
641
void
642
642
bytes_fill_rectangle(byte * dest, uint raster,
643
 
                     byte value, int width_bytes, int height)
 
643
                     byte value, int width_bytes, int height)
644
644
{
645
645
    while (height-- > 0) {
646
 
        memset(dest, value, width_bytes);
647
 
        dest += raster;
 
646
        memset(dest, value, width_bytes);
 
647
        dest += raster;
648
648
    }
649
649
}
650
650
 
651
651
/* Copy a rectangle of bytes. */
652
652
void
653
653
bytes_copy_rectangle(byte * dest, uint dest_raster,
654
 
             const byte * src, uint src_raster, int width_bytes, int height)
 
654
             const byte * src, uint src_raster, int width_bytes, int height)
655
655
{
656
656
    while (height-- > 0) {
657
 
        memcpy(dest, src, width_bytes);
658
 
        src += src_raster;
659
 
        dest += dest_raster;
 
657
        memcpy(dest, src, width_bytes);
 
658
        src += src_raster;
 
659
        dest += dest_raster;
660
660
    }
661
661
}
662
662
 
663
663
/* Copy a rectangle of bytes zeroing any padding bytes. */
664
664
void
665
665
bytes_copy_rectangle_zero_padding(byte * dest, uint dest_raster,
666
 
             const byte * src, uint src_raster, int width_bytes, int height)
 
666
             const byte * src, uint src_raster, int width_bytes, int height)
667
667
{
668
668
    int padlen = dest_raster;
669
669
    if (padlen < 0)