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

« back to all changes in this revision

Viewing changes to base/gxclutil.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: gxclutil.c 12306 2011-03-23 21:34:20Z mvrhel $ */
 
14
/* $Id$ */
15
15
/* Command list writing utilities. */
16
16
 
17
17
#include "memory_.h"
57
57
    stats_cmd.op_counts[op]++;
58
58
    stats_cmd.op_sizes[op] += size;
59
59
    if (gs_debug_c('L')) {
60
 
        const char *const *sub = cmd_sub_op_names[op >> 4];
 
60
        const char *const *sub = cmd_sub_op_names[op >> 4];
61
61
 
62
 
        if (sub)
63
 
            dlprintf2(", %s(%u)\n", sub[op & 0xf], size);
64
 
        else
65
 
            dlprintf3(", %s %d(%u)\n", cmd_op_names[op >> 4], op & 0xf,
66
 
                      size);
67
 
        dflush();
 
62
        if (sub)
 
63
            dlprintf2(", %s(%u)\n", sub[op & 0xf], size);
 
64
        else
 
65
            dlprintf3(", %s %d(%u)\n", cmd_op_names[op >> 4], op & 0xf,
 
66
                      size);
 
67
        dflush();
68
68
    }
69
69
    return op;
70
70
}
84
84
    int ci, cj;
85
85
 
86
86
    dlprintf3("[l]counts: reset = %lu, found = %lu, added = %lu\n",
87
 
              stats_cmd.tile_reset, stats_cmd.tile_found,
88
 
              stats_cmd.tile_added);
 
87
              stats_cmd.tile_reset, stats_cmd.tile_found,
 
88
              stats_cmd.tile_added);
89
89
    dlprintf5("     diff 2.5 = %lu, 3 = %lu, 4 = %lu, 2 = %lu, >4 = %lu\n",
90
 
              stats_cmd_diffs[0], stats_cmd_diffs[1], stats_cmd_diffs[2],
91
 
              stats_cmd_diffs[3], stats_cmd_diffs[4]);
 
90
              stats_cmd_diffs[0], stats_cmd_diffs[1], stats_cmd_diffs[2],
 
91
              stats_cmd_diffs[3], stats_cmd_diffs[4]);
92
92
    dlprintf2("     same_band = %lu, other_band = %lu\n",
93
 
              stats_cmd.same_band, stats_cmd.other_band);
 
93
              stats_cmd.same_band, stats_cmd.other_band);
94
94
    for (ci = 0; ci < 0x100; ci += 0x10) {
95
 
        const char *const *sub = cmd_sub_op_names[ci >> 4];
96
 
 
97
 
        if (sub != 0) {
98
 
            dlprintf1("[l]  %s =", cmd_op_names[ci >> 4]);
99
 
            for (cj = ci; cj < ci + 0x10; cj += 2)
100
 
                dprintf6("\n\t%s = %lu(%lu), %s = %lu(%lu)",
101
 
                         sub[cj - ci],
102
 
                         stats_cmd.op_counts[cj], stats_cmd.op_sizes[cj],
103
 
                         sub[cj - ci + 1],
104
 
                   stats_cmd.op_counts[cj + 1], stats_cmd.op_sizes[cj + 1]);
105
 
        } else {
106
 
            ulong tcounts = 0, tsizes = 0;
107
 
 
108
 
            for (cj = ci; cj < ci + 0x10; cj++)
109
 
                tcounts += stats_cmd.op_counts[cj],
110
 
                    tsizes += stats_cmd.op_sizes[cj];
111
 
            dlprintf3("[l]  %s (%lu,%lu) =\n\t",
112
 
                      cmd_op_names[ci >> 4], tcounts, tsizes);
113
 
            for (cj = ci; cj < ci + 0x10; cj++)
114
 
                if (stats_cmd.op_counts[cj] == 0)
115
 
                    dputs(" -");
116
 
                else
117
 
                    dprintf2(" %lu(%lu)", stats_cmd.op_counts[cj],
118
 
                             stats_cmd.op_sizes[cj]);
119
 
        }
120
 
        dputs("\n");
 
95
        const char *const *sub = cmd_sub_op_names[ci >> 4];
 
96
 
 
97
        if (sub != 0) {
 
98
            dlprintf1("[l]  %s =", cmd_op_names[ci >> 4]);
 
99
            for (cj = ci; cj < ci + 0x10; cj += 2)
 
100
                dprintf6("\n\t%s = %lu(%lu), %s = %lu(%lu)",
 
101
                         sub[cj - ci],
 
102
                         stats_cmd.op_counts[cj], stats_cmd.op_sizes[cj],
 
103
                         sub[cj - ci + 1],
 
104
                   stats_cmd.op_counts[cj + 1], stats_cmd.op_sizes[cj + 1]);
 
105
        } else {
 
106
            ulong tcounts = 0, tsizes = 0;
 
107
 
 
108
            for (cj = ci; cj < ci + 0x10; cj++)
 
109
                tcounts += stats_cmd.op_counts[cj],
 
110
                    tsizes += stats_cmd.op_sizes[cj];
 
111
            dlprintf3("[l]  %s (%lu,%lu) =\n\t",
 
112
                      cmd_op_names[ci >> 4], tcounts, tsizes);
 
113
            for (cj = ci; cj < ci + 0x10; cj++)
 
114
                if (stats_cmd.op_counts[cj] == 0)
 
115
                    dputs(" -");
 
116
                else
 
117
                    dprintf2(" %lu(%lu)", stats_cmd.op_counts[cj],
 
118
                             stats_cmd.op_sizes[cj]);
 
119
        }
 
120
        dputs("\n");
121
121
    }
122
122
}
123
123
#endif /* DEBUG */
127
127
/* Write the commands for one band or band range. */
128
128
static int      /* ret 0 all ok, -ve error code, or +1 ok w/low-mem warning */
129
129
cmd_write_band(gx_device_clist_writer * cldev, int band_min, int band_max,
130
 
               cmd_list * pcl, gx_band_complexity_t *band_complexity, byte cmd_end)
 
130
               cmd_list * pcl, gx_band_complexity_t *band_complexity, byte cmd_end)
131
131
{
132
132
    const cmd_prefix *cp = pcl->head;
133
133
    int code_b = 0;
134
134
    int code_c = 0;
135
135
 
136
136
    if (cp != 0 || cmd_end != cmd_opv_end_run) {
137
 
        clist_file_ptr cfile = cldev->page_cfile;
138
 
        clist_file_ptr bfile = cldev->page_bfile;
139
 
        cmd_block cb;
140
 
        byte end = cmd_count_op(cmd_end, 1);
 
137
        clist_file_ptr cfile = cldev->page_cfile;
 
138
        clist_file_ptr bfile = cldev->page_bfile;
 
139
        cmd_block cb;
 
140
        byte end = cmd_count_op(cmd_end, 1);
141
141
 
142
 
        if (cfile == 0 || bfile == 0)
143
 
            return_error(gs_error_ioerror);
144
 
        cb.band_min = band_min;
145
 
        cb.band_max = band_max;
146
 
        cb.pos = cldev->page_info.io_procs->ftell(cfile);
147
 
        clist_copy_band_complexity(&cb.band_complexity, band_complexity);  
148
 
        if_debug4('l', "[l]writing for bands (%d,%d) at %ld K %d \n",
149
 
                  band_min, band_max, (long)cb.pos, cb.band_complexity.uses_color);
150
 
        cldev->page_info.io_procs->fwrite_chars(&cb, sizeof(cb), bfile);
151
 
        if (cp != 0) {
152
 
            pcl->tail->next = 0;        /* terminate the list */
153
 
            for (; cp != 0; cp = cp->next) {
 
142
        if (cfile == 0 || bfile == 0)
 
143
            return_error(gs_error_ioerror);
 
144
        cb.band_min = band_min;
 
145
        cb.band_max = band_max;
 
146
        cb.pos = cldev->page_info.io_procs->ftell(cfile);
 
147
        clist_copy_band_complexity(&cb.band_complexity, band_complexity);
 
148
        if_debug4('l', "[l]writing for bands (%d,%d) at %ld K %d \n",
 
149
                  band_min, band_max, (long)cb.pos, cb.band_complexity.uses_color);
 
150
        cldev->page_info.io_procs->fwrite_chars(&cb, sizeof(cb), bfile);
 
151
        if (cp != 0) {
 
152
            pcl->tail->next = 0;        /* terminate the list */
 
153
            for (; cp != 0; cp = cp->next) {
154
154
#ifdef DEBUG
155
 
                if ((const byte *)cp < cldev->cbuf ||
156
 
                    (const byte *)cp >= cldev->cend ||
157
 
                    cp->size > cldev->cend - (const byte *)cp
158
 
                    ) {
159
 
                    lprintf1("cmd_write_band error at 0x%lx\n", (ulong) cp);
160
 
                    return_error(gs_error_Fatal);
161
 
                }
 
155
                if ((const byte *)cp < cldev->cbuf ||
 
156
                    (const byte *)cp >= cldev->cend ||
 
157
                    cp->size > cldev->cend - (const byte *)cp
 
158
                    ) {
 
159
                    lprintf1("cmd_write_band error at 0x%lx\n", (ulong) cp);
 
160
                    return_error(gs_error_Fatal);
 
161
                }
162
162
#endif
163
 
                if_debug2('L',"[L]Wrote cmd id=%ld at %ld\n", cp->id, 
164
 
                    (long)cldev->page_info.io_procs->ftell(cfile));
165
 
                cldev->page_info.io_procs->fwrite_chars(cp + 1, cp->size, cfile);
166
 
            }
167
 
            pcl->head = pcl->tail = 0;
168
 
        }
169
 
        cldev->page_info.io_procs->fwrite_chars(&end, 1, cfile);
170
 
        process_interrupts(cldev->memory);
171
 
        code_b = cldev->page_info.io_procs->ferror_code(bfile);
172
 
        code_c = cldev->page_info.io_procs->ferror_code(cfile);
173
 
        if (code_b < 0)
174
 
            return_error(code_b);
175
 
        if (code_c < 0)
176
 
            return_error(code_c); 
 
163
                if_debug2('L',"[L]Wrote cmd id=%ld at %ld\n", cp->id,
 
164
                    (long)cldev->page_info.io_procs->ftell(cfile));
 
165
                cldev->page_info.io_procs->fwrite_chars(cp + 1, cp->size, cfile);
 
166
            }
 
167
            pcl->head = pcl->tail = 0;
 
168
        }
 
169
        cldev->page_info.io_procs->fwrite_chars(&end, 1, cfile);
 
170
        process_interrupts(cldev->memory);
 
171
        code_b = cldev->page_info.io_procs->ferror_code(bfile);
 
172
        code_c = cldev->page_info.io_procs->ferror_code(cfile);
 
173
        if (code_b < 0)
 
174
            return_error(code_b);
 
175
        if (code_c < 0)
 
176
            return_error(code_c);
177
177
    }
178
178
    return code_b | code_c;
179
179
}
195
195
    if (cfile == 0 || bfile == 0)
196
196
        return_error(gs_error_ioerror);
197
197
 
198
 
    /* Set up the command block information that 
 
198
    /* Set up the command block information that
199
199
       is stored in the bfile.  Note complexity information
200
200
       is filled in but not used. */
201
201
 
206
206
    cb.pos = cldev->page_info.io_procs->ftell(cfile);
207
207
 
208
208
    if_debug2('l', "[l]writing icc table band %d cb pos %ld\n",
209
 
                  band, (long)cb.pos);
 
209
                  band, (long)cb.pos);
210
210
 
211
211
    cldev->page_info.io_procs->fwrite_chars(&cb, sizeof(cb), bfile);
212
212
 
225
225
    if (code_b < 0)
226
226
        return_error(code_b);
227
227
    if (code_c < 0)
228
 
        return_error(code_c); 
 
228
        return_error(code_c);
229
229
 
230
230
    return code_b | code_c;
231
231
 
239
239
    gx_clist_state *pcls;
240
240
    int band;
241
241
    int code = cmd_write_band(cldev, cldev->band_range_min,
242
 
                              cldev->band_range_max,
243
 
                              &cldev->band_range_list, 
244
 
                              NULL, 
245
 
                              cmd_opv_end_run);
 
242
                              cldev->band_range_max,
 
243
                              &cldev->band_range_list,
 
244
                              NULL,
 
245
                              cmd_opv_end_run);
246
246
 
247
247
    int warning = code;
248
248
 
249
249
    for (band = 0, pcls = cldev->states;
250
 
         code >= 0 && band < nbands; band++, pcls++
251
 
         ) {
252
 
        code = cmd_write_band(cldev, band, band, &pcls->list, &pcls->band_complexity, cmd_end);
253
 
        warning |= code;
 
250
         code >= 0 && band < nbands; band++, pcls++
 
251
         ) {
 
252
        code = cmd_write_band(cldev, band, band, &pcls->list, &pcls->band_complexity, cmd_end);
 
253
        warning |= code;
254
254
    }
255
255
    /* If an error occurred, finish cleaning up the pointers. */
256
256
    for (; band < nbands; band++, pcls++)
257
 
        pcls->list.head = pcls->list.tail = 0;
 
257
        pcls->list.head = pcls->list.tail = 0;
258
258
    cldev->cnext = cldev->cbuf;
259
259
    cldev->ccl = 0;
260
260
#ifdef DEBUG
261
261
    if (gs_debug_c('l'))
262
 
        cmd_print_stats();
 
262
        cmd_print_stats();
263
263
#endif
264
264
    return_check_interrupt(cldev->memory, code != 0 ? code : warning);
265
265
}
276
276
    byte *dp = cldev->cnext;
277
277
 
278
278
    if (size + cmd_headroom > cldev->cend - dp) {
279
 
        if ((cldev->error_code =
 
279
        if ((cldev->error_code =
280
280
             cmd_write_buffer(cldev, cmd_opv_end_run)) != 0 ||
281
281
            (size + cmd_headroom > cldev->cend - cldev->cnext)) {
282
 
            if (cldev->error_code < 0)
283
 
                cldev->error_is_retryable = 0;  /* hard error */
284
 
            else {
285
 
                /* upgrade lo-mem warning into an error */
286
 
                if (!cldev->ignore_lo_mem_warnings)
287
 
                    cldev->error_code = gs_note_error(gs_error_VMerror);
288
 
                cldev->error_is_retryable = 1;
289
 
            }
290
 
            return 0;
291
 
        }
292
 
        else
293
 
            return cmd_put_list_op(cldev, pcl, size);
 
282
            if (cldev->error_code < 0)
 
283
                cldev->error_is_retryable = 0;  /* hard error */
 
284
            else {
 
285
                /* upgrade lo-mem warning into an error */
 
286
                if (!cldev->ignore_lo_mem_warnings)
 
287
                    cldev->error_code = gs_note_error(gs_error_VMerror);
 
288
                cldev->error_is_retryable = 1;
 
289
            }
 
290
            return 0;
 
291
        }
 
292
        else
 
293
            return cmd_put_list_op(cldev, pcl, size);
294
294
    }
295
295
    if (cldev->ccl == pcl) {    /* We're adding another command for the same band. */
296
 
        /* Tack it onto the end of the previous one. */
297
 
        cmd_count_add1(stats_cmd.same_band);
 
296
        /* Tack it onto the end of the previous one. */
 
297
        cmd_count_add1(stats_cmd.same_band);
298
298
#ifdef DEBUG
299
 
        if (pcl->tail->size > dp - (byte *) (pcl->tail + 1)) {
300
 
            lprintf1("cmd_put_list_op error at 0x%lx\n", (ulong) pcl->tail);
301
 
        }
 
299
        if (pcl->tail->size > dp - (byte *) (pcl->tail + 1)) {
 
300
            lprintf1("cmd_put_list_op error at 0x%lx\n", (ulong) pcl->tail);
 
301
        }
302
302
#endif
303
 
        if_debug2('L', ", to id=%ld , offset=%ld", pcl->tail->id, (long)pcl->tail->size);
304
 
        pcl->tail->size += size;
 
303
        if_debug2('L', ", to id=%ld , offset=%ld", pcl->tail->id, (long)pcl->tail->size);
 
304
        pcl->tail->size += size;
305
305
    } else {
306
 
        /* Skip to an appropriate alignment boundary. */
307
 
        /* (We assume the command buffer itself is aligned.) */
308
 
        cmd_prefix *cp = (cmd_prefix *)
309
 
            (dp + ((cldev->cbuf - dp) & (ARCH_ALIGN_PTR_MOD - 1)));
 
306
        /* Skip to an appropriate alignment boundary. */
 
307
        /* (We assume the command buffer itself is aligned.) */
 
308
        cmd_prefix *cp = (cmd_prefix *)
 
309
            (dp + ((cldev->cbuf - dp) & (ARCH_ALIGN_PTR_MOD - 1)));
310
310
 
311
 
        cmd_count_add1(stats_cmd.other_band);
312
 
        dp = (byte *) (cp + 1);
313
 
        if (pcl->tail != 0) {
 
311
        cmd_count_add1(stats_cmd.other_band);
 
312
        dp = (byte *) (cp + 1);
 
313
        if (pcl->tail != 0) {
314
314
#ifdef DEBUG
315
 
            if (pcl->tail < pcl->head ||
316
 
                pcl->tail->size > dp - (byte *) (pcl->tail + 1)
317
 
                ) {
318
 
                lprintf1("cmd_put_list_op error at 0x%lx\n",
319
 
                         (ulong) pcl->tail);
320
 
            }
 
315
            if (pcl->tail < pcl->head ||
 
316
                pcl->tail->size > dp - (byte *) (pcl->tail + 1)
 
317
                ) {
 
318
                lprintf1("cmd_put_list_op error at 0x%lx\n",
 
319
                         (ulong) pcl->tail);
 
320
            }
321
321
#endif
322
 
            pcl->tail->next = cp;
323
 
        } else
324
 
            pcl->head = cp;
325
 
        pcl->tail = cp;
326
 
        cldev->ccl = pcl;
327
 
        cp->size = size;
328
 
        cp->id = cldev->ins_count;
329
 
        if_debug1('L', ", id=%ld ", cldev->ins_count);
330
 
        cldev->ins_count++;
 
322
            pcl->tail->next = cp;
 
323
        } else
 
324
            pcl->head = cp;
 
325
        pcl->tail = cp;
 
326
        cldev->ccl = pcl;
 
327
        cp->size = size;
 
328
        cp->id = cldev->ins_count;
 
329
        if_debug1('L', ", id=%ld ", cldev->ins_count);
 
330
        cldev->ins_count++;
331
331
    }
332
332
    cldev->cnext = dp + size;
333
333
    return dp;
334
334
}
335
335
 
336
 
/* Request a space in the buffer. 
 
336
/* Request a space in the buffer.
337
337
   Writes out the buffer if necessary.
338
338
   Returns the size of available space. */
339
339
int
340
340
cmd_get_buffer_space(gx_device_clist_writer * cldev, gx_clist_state * pcls, uint size)
341
341
{
342
342
    if (size + cmd_headroom > cldev->cend - cldev->cnext) {
343
 
        cldev->error_code = cmd_write_buffer(cldev, cmd_opv_end_run);
344
 
        if (cldev->error_code < 0) {
345
 
            cldev->error_is_retryable = 0;      /* hard error */
346
 
            return cldev->error_code;
347
 
        }
 
343
        cldev->error_code = cmd_write_buffer(cldev, cmd_opv_end_run);
 
344
        if (cldev->error_code < 0) {
 
345
            cldev->error_is_retryable = 0;      /* hard error */
 
346
            return cldev->error_code;
 
347
        }
348
348
    }
349
349
    return cldev->cend - cldev->cnext - cmd_headroom;
350
350
}
354
354
cmd_put_op(gx_device_clist_writer * cldev, gx_clist_state * pcls, uint size)
355
355
{
356
356
    if_debug3('L', "[L]band %d: size=%u, left=%u",
357
 
              (int)(pcls - cldev->states),
358
 
              size, 0);
 
357
              (int)(pcls - cldev->states),
 
358
              size, 0);
359
359
    return cmd_put_list_op(cldev, &pcls->list, size);
360
360
}
361
361
#endif
363
363
/* Add a command for a range of bands. */
364
364
byte *
365
365
cmd_put_range_op(gx_device_clist_writer * cldev, int band_min, int band_max,
366
 
                 uint size)
 
366
                 uint size)
367
367
{
368
368
    if_debug4('L', "[L]band range(%d,%d): size=%u, left=%u",
369
 
              band_min, band_max, size, 0);
370
 
    if (cldev->ccl != 0 && 
371
 
        (cldev->ccl != &cldev->band_range_list ||
372
 
         band_min != cldev->band_range_min ||
373
 
         band_max != cldev->band_range_max)
374
 
        ) {
375
 
        if ((cldev->error_code = cmd_write_buffer(cldev, cmd_opv_end_run)) != 0) {
376
 
            if (cldev->error_code < 0)
377
 
                cldev->error_is_retryable = 0;  /* hard error */
378
 
            else {
379
 
                /* upgrade lo-mem warning into an error */
380
 
                cldev->error_code = gs_error_VMerror;
381
 
                cldev->error_is_retryable = 1;
382
 
            }
383
 
            return 0;
384
 
        }
385
 
        cldev->band_range_min = band_min;
386
 
        cldev->band_range_max = band_max;
 
369
              band_min, band_max, size, 0);
 
370
    if (cldev->ccl != 0 &&
 
371
        (cldev->ccl != &cldev->band_range_list ||
 
372
         band_min != cldev->band_range_min ||
 
373
         band_max != cldev->band_range_max)
 
374
        ) {
 
375
        if ((cldev->error_code = cmd_write_buffer(cldev, cmd_opv_end_run)) != 0) {
 
376
            if (cldev->error_code < 0)
 
377
                cldev->error_is_retryable = 0;  /* hard error */
 
378
            else {
 
379
                /* upgrade lo-mem warning into an error */
 
380
                cldev->error_code = gs_error_VMerror;
 
381
                cldev->error_is_retryable = 1;
 
382
            }
 
383
            return 0;
 
384
        }
 
385
        cldev->band_range_min = band_min;
 
386
        cldev->band_range_max = band_max;
387
387
    }
388
388
    return cmd_put_list_op(cldev, &cldev->band_range_list, size);
389
389
}
395
395
    register int size = 1;
396
396
 
397
397
    while (w > 0x7f)
398
 
        w >>= 7, size++;
 
398
        w >>= 7, size++;
399
399
    return size;
400
400
}
401
401
byte *
402
402
cmd_put_w(register uint w, register byte * dp)
403
403
{
404
404
    while (w > 0x7f)
405
 
        *dp++ = w | 0x80, w >>= 7;
 
405
        *dp++ = w | 0x80, w >>= 7;
406
406
    *dp = w;
407
407
    return dp + 1;
408
408
}
414
414
    register uint32_t v = w;
415
415
 
416
416
    while (v & 0x01FFFFFF)
417
 
        v <<= 7, size++;
 
417
        v <<= 7, size++;
418
418
    return size;
419
419
}
420
420
byte *
423
423
    register uint32_t v = w;
424
424
 
425
425
    while (v & 0x01FFFFFF)
426
 
        *dp++ = (v >> 24) | 1, v <<= 7;
 
426
        *dp++ = (v >> 24) | 1, v <<= 7;
427
427
    *dp = (v >> 24);
428
428
    return dp + 1;
429
429
}
430
430
 
431
 
 
432
 
 
433
431
/*
434
432
 * This next two arrays are used for the 'delta' mode of placing a color
435
433
 * in the clist.  These arrays are indexed by the number of bytes in the
455
453
#define tab_entry(x) ((x) & (~((gx_color_index) 0)))
456
454
 
457
455
const gx_color_index cmd_delta_offsets[] = {
458
 
        tab_entry(0),
459
 
        tab_entry(0),
460
 
        tab_entry(0x0808),
461
 
        tab_entry(0x102010),
462
 
        tab_entry(0x08080808),
463
 
        tab_entry(0x1020100808),
464
 
        tab_entry(0x080808080808),
465
 
        tab_entry(0x10201008080808),
466
 
        tab_entry(0x0808080808080808),
467
 
        };
 
456
        tab_entry(0),
 
457
        tab_entry(0),
 
458
        tab_entry(0x0808),
 
459
        tab_entry(0x102010),
 
460
        tab_entry(0x08080808),
 
461
        tab_entry(0x1020100808),
 
462
        tab_entry(0x080808080808),
 
463
        tab_entry(0x10201008080808),
 
464
        tab_entry(0x0808080808080808),
 
465
        };
468
466
 
469
467
static const gx_color_index cmd_delta_masks[] = {
470
 
        tab_entry(0),
471
 
        tab_entry(0),
472
 
        tab_entry(0x0f0f),
473
 
        tab_entry(0x1f3f1f),
474
 
        tab_entry(0x0f0f0f0f),
475
 
        tab_entry(0x1f3f1f0f0f),
476
 
        tab_entry(0x0f0f0f0f0f0f),
477
 
        tab_entry(0x1f3f1f0f0f0f0f),
478
 
        tab_entry(0x0f0f0f0f0f0f0f0f),
479
 
        };
 
468
        tab_entry(0),
 
469
        tab_entry(0),
 
470
        tab_entry(0x0f0f),
 
471
        tab_entry(0x1f3f1f),
 
472
        tab_entry(0x0f0f0f0f),
 
473
        tab_entry(0x1f3f1f0f0f),
 
474
        tab_entry(0x0f0f0f0f0f0f),
 
475
        tab_entry(0x1f3f1f0f0f0f0f),
 
476
        tab_entry(0x0f0f0f0f0f0f0f0f),
 
477
        };
480
478
 
481
479
#undef tab_entry
482
480
 
524
522
 */
525
523
int
526
524
cmd_put_color(gx_device_clist_writer * cldev, gx_clist_state * pcls,
527
 
              const clist_select_color_t * select,
528
 
              gx_color_index color, gx_color_index * pcolor)
 
525
              const clist_select_color_t * select,
 
526
              gx_color_index color, gx_color_index * pcolor)
529
527
{
530
528
    byte * dp;          /* This is manipulated by the set_cmd_put_op macro */
531
529
    gx_color_index diff = color - *pcolor;
533
531
    int code;
534
532
 
535
533
    if (diff == 0)
536
 
        return 0;
 
534
        return 0;
537
535
 
538
536
    /* If this is a tile color then send tile color type */
539
537
    if (select->tile_color) {
540
 
        code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_tile_color, 1);
541
 
        if (code < 0)
542
 
            return code;
 
538
        code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_tile_color, 1);
 
539
        if (code < 0)
 
540
            return code;
543
541
    }
544
542
    op = select->set_op;
545
543
    op_delta = select->delta_op;
546
544
    if (color == gx_no_color_index) {
547
 
        /*
548
 
         * We must handle this specially, because it may take more
549
 
         * bytes than the color depth.
550
 
         */
551
 
        code = set_cmd_put_op(dp, cldev, pcls, op + cmd_no_color_index, 1);
552
 
        if (code < 0)
553
 
            return code;
 
545
        /*
 
546
         * We must handle this specially, because it may take more
 
547
         * bytes than the color depth.
 
548
         */
 
549
        code = set_cmd_put_op(dp, cldev, pcls, op + cmd_no_color_index, 1);
 
550
        if (code < 0)
 
551
            return code;
554
552
    } else {
555
 
        /* Check if the "delta" mode command can be used. */
556
 
        int num_bytes = (cldev->clist_color_info.depth + 7) >> 3;  /* clist_color_info may be different than target device
 
553
        /* Check if the "delta" mode command can be used. */
 
554
        int num_bytes = (cldev->clist_color_info.depth + 7) >> 3;  /* clist_color_info may be different than target device
557
555
                                                                      due to transparency group during clist writing phase */
558
 
        int delta_bytes = (num_bytes + 1) / 2;
559
 
        gx_color_index delta_offset = cmd_delta_offsets[num_bytes];
560
 
        gx_color_index delta_mask = cmd_delta_masks[num_bytes];
561
 
        gx_color_index delta = (diff + delta_offset) & delta_mask;
562
 
        bool use_delta = (color == (*pcolor + delta - delta_offset));
563
 
        int bytes_dropped = 0;
564
 
        gx_color_index data = color;
565
 
        
566
 
        /*
567
 
         * If we use the full value mode, we do not send low order bytes
568
 
         * which are zero. Determine how many low order bytes are zero.
569
 
         */
570
 
        if (color == 0) {
571
 
            bytes_dropped = num_bytes;
572
 
        }
573
 
        else  {
574
 
            while ((data & 0xff) == 0) {
575
 
                bytes_dropped++;
576
 
                data >>= 8; 
577
 
            }
578
 
        }
579
 
        /* Now send one of the two command forms */
580
 
        if (use_delta && delta_bytes < (num_bytes - bytes_dropped)) {
581
 
            code = set_cmd_put_op(dp, cldev, pcls,
582
 
                                        op_delta, delta_bytes + 1);
583
 
            if (code < 0)
584
 
                return code;
585
 
            /*
586
 
             * If we have an odd number of bytes then use extra bits for
587
 
             * the high order three bytes of the color.
588
 
             */
589
 
            if ((num_bytes >= 3) && (num_bytes & 1)) {
590
 
                data = delta >> ((num_bytes - 3) * 8);
591
 
                dp[delta_bytes--] = (byte)(((data >> 13) & 0xf8) + ((data >> 11) & 0x07));
592
 
                dp[delta_bytes--] = (byte)(((data >> 3) & 0xe0) + (data & 0x1f));
593
 
            }
594
 
            for(; delta_bytes>0; delta_bytes--) {
595
 
                dp[delta_bytes] = (byte)((delta >> 4) + delta);
596
 
                delta >>= 16;
597
 
            }
598
 
        }
599
 
        else {
600
 
            num_bytes -= bytes_dropped;
601
 
            code = set_cmd_put_op(dp, cldev, pcls,
602
 
                                (byte)(op + bytes_dropped), num_bytes + 1);
603
 
            if (code < 0)
604
 
                return code;
605
 
            for(; num_bytes>0; num_bytes--) {
606
 
                dp[num_bytes] = (byte)data;
607
 
                data >>= 8;
608
 
            }
609
 
        }
 
556
        int delta_bytes = (num_bytes + 1) / 2;
 
557
        gx_color_index delta_offset = cmd_delta_offsets[num_bytes];
 
558
        gx_color_index delta_mask = cmd_delta_masks[num_bytes];
 
559
        gx_color_index delta = (diff + delta_offset) & delta_mask;
 
560
        bool use_delta = (color == (*pcolor + delta - delta_offset));
 
561
        int bytes_dropped = 0;
 
562
        gx_color_index data = color;
 
563
 
 
564
        /*
 
565
         * If we use the full value mode, we do not send low order bytes
 
566
         * which are zero. Determine how many low order bytes are zero.
 
567
         */
 
568
        if (color == 0) {
 
569
            bytes_dropped = num_bytes;
 
570
        }
 
571
        else  {
 
572
            while ((data & 0xff) == 0) {
 
573
                bytes_dropped++;
 
574
                data >>= 8;
 
575
            }
 
576
        }
 
577
        /* Now send one of the two command forms */
 
578
        if (use_delta && delta_bytes < (num_bytes - bytes_dropped)) {
 
579
            code = set_cmd_put_op(dp, cldev, pcls,
 
580
                                        op_delta, delta_bytes + 1);
 
581
            if (code < 0)
 
582
                return code;
 
583
            /*
 
584
             * If we have an odd number of bytes then use extra bits for
 
585
             * the high order three bytes of the color.
 
586
             */
 
587
            if ((num_bytes >= 3) && (num_bytes & 1)) {
 
588
                data = delta >> ((num_bytes - 3) * 8);
 
589
                dp[delta_bytes--] = (byte)(((data >> 13) & 0xf8) + ((data >> 11) & 0x07));
 
590
                dp[delta_bytes--] = (byte)(((data >> 3) & 0xe0) + (data & 0x1f));
 
591
            }
 
592
            for(; delta_bytes>0; delta_bytes--) {
 
593
                dp[delta_bytes] = (byte)((delta >> 4) + delta);
 
594
                delta >>= 16;
 
595
            }
 
596
        }
 
597
        else {
 
598
            num_bytes -= bytes_dropped;
 
599
            code = set_cmd_put_op(dp, cldev, pcls,
 
600
                                (byte)(op + bytes_dropped), num_bytes + 1);
 
601
            if (code < 0)
 
602
                return code;
 
603
            for(; num_bytes>0; num_bytes--) {
 
604
                dp[num_bytes] = (byte)data;
 
605
                data >>= 8;
 
606
            }
 
607
        }
610
608
    }
611
609
    *pcolor = color;
612
610
    return 0;
613
611
}
614
612
 
615
 
 
616
613
/* Put out a command to set the tile colors. */
617
614
int
618
615
cmd_set_tile_colors(gx_device_clist_writer * cldev, gx_clist_state * pcls,
619
 
                    gx_color_index color0, gx_color_index color1)
 
616
                    gx_color_index color0, gx_color_index color1)
620
617
{
621
618
    int code = 0;
622
619
 
623
620
    if (color0 != pcls->tile_colors[0]) {
624
 
        code = cmd_put_color(cldev, pcls,
625
 
                             &clist_select_tile_color0,
626
 
                             color0, &pcls->tile_colors[0]);
627
 
        if (code != 0)
628
 
            return code;
 
621
        code = cmd_put_color(cldev, pcls,
 
622
                             &clist_select_tile_color0,
 
623
                             color0, &pcls->tile_colors[0]);
 
624
        if (code != 0)
 
625
            return code;
629
626
    }
630
627
    if (color1 != pcls->tile_colors[1])
631
 
        code = cmd_put_color(cldev, pcls,
632
 
                             &clist_select_tile_color1,
633
 
                             color1, &pcls->tile_colors[1]);
 
628
        code = cmd_put_color(cldev, pcls,
 
629
                             &clist_select_tile_color1,
 
630
                             color1, &pcls->tile_colors[1]);
634
631
    return code;
635
632
}
636
633
 
637
634
/* Put out a command to set the tile phase. */
638
635
int
639
636
cmd_set_tile_phase_generic(gx_device_clist_writer * cldev, gx_clist_state * pcls,
640
 
                   int px, int py, bool all_bands)
 
637
                   int px, int py, bool all_bands)
641
638
{
642
639
    int pcsize;
643
640
    byte *dp;
645
642
 
646
643
    pcsize = 1 + cmd_size2w(px, py);
647
644
    if (all_bands)
648
 
        code = set_cmd_put_all_op(dp, cldev, (byte)cmd_opv_set_tile_phase, pcsize);
 
645
        code = set_cmd_put_all_op(dp, cldev, (byte)cmd_opv_set_tile_phase, pcsize);
649
646
    else
650
 
        code = set_cmd_put_op(dp, cldev, pcls, (byte)cmd_opv_set_tile_phase, pcsize);
 
647
        code = set_cmd_put_op(dp, cldev, pcls, (byte)cmd_opv_set_tile_phase, pcsize);
651
648
    if (code < 0)
652
 
        return code;
 
649
        return code;
653
650
    ++dp;
654
651
    pcls->tile_phase.x = px;
655
652
    pcls->tile_phase.y = py;
659
656
 
660
657
int
661
658
cmd_set_tile_phase(gx_device_clist_writer * cldev, gx_clist_state * pcls,
662
 
                   int px, int py)
 
659
                   int px, int py)
663
660
{
664
661
    return cmd_set_tile_phase_generic(cldev, pcls, px, py, false);
665
662
}
666
663
 
667
 
 
668
664
/* Write a command to enable or disable the logical operation. */
669
665
int
670
666
cmd_put_enable_lop(gx_device_clist_writer * cldev, gx_clist_state * pcls,
671
 
                   int enable)
 
667
                   int enable)
672
668
{
673
669
    byte *dp;
674
670
    int code = set_cmd_put_op(dp, cldev, pcls,
675
 
                              (byte)(enable ? cmd_opv_enable_lop :
676
 
                                     cmd_opv_disable_lop),
677
 
                              1);
 
671
                              (byte)(enable ? cmd_opv_enable_lop :
 
672
                                     cmd_opv_disable_lop),
 
673
                              1);
678
674
 
679
675
    if (code < 0)
680
 
        return code;
 
676
        return code;
681
677
    pcls->lop_enabled = enable;
682
678
    return 0;
683
679
}
686
682
/* This routine is only called if the path extensions are included. */
687
683
int
688
684
cmd_put_enable_clip(gx_device_clist_writer * cldev, gx_clist_state * pcls,
689
 
                    int enable)
 
685
                    int enable)
690
686
{
691
687
    byte *dp;
692
688
    int code = set_cmd_put_op(dp, cldev, pcls,
693
 
                              (byte)(enable ? cmd_opv_enable_clip :
694
 
                                     cmd_opv_disable_clip),
695
 
                              1);
 
689
                              (byte)(enable ? cmd_opv_enable_clip :
 
690
                                     cmd_opv_disable_clip),
 
691
                              1);
696
692
 
697
693
    if (code < 0)
698
 
        return code;
 
694
        return code;
699
695
    pcls->clip_enabled = enable;
700
696
    return 0;
701
697
}
703
699
/* Write a command to set the logical operation. */
704
700
int
705
701
cmd_set_lop(gx_device_clist_writer * cldev, gx_clist_state * pcls,
706
 
            gs_logical_operation_t lop)
 
702
            gs_logical_operation_t lop)
707
703
{
708
704
    byte *dp;
709
705
    uint lop_msb = lop >> 6;
710
706
    int code = set_cmd_put_op(dp, cldev, pcls,
711
 
                              cmd_opv_set_misc, 2 + cmd_size_w(lop_msb));
 
707
                              cmd_opv_set_misc, 2 + cmd_size_w(lop_msb));
712
708
 
713
709
    if (code < 0)
714
 
        return code;
 
710
        return code;
715
711
    dp[1] = cmd_set_misc_lop + (lop & 0x3f);
716
712
    cmd_put_w(lop_msb, dp + 2);
717
713
    pcls->lop = lop;
722
718
/* needed. */
723
719
int
724
720
cmd_update_lop(gx_device_clist_writer *cldev, gx_clist_state *pcls,
725
 
               gs_logical_operation_t lop)
 
721
               gs_logical_operation_t lop)
726
722
{
727
723
    int code;
728
724
 
729
725
    if (lop == lop_default)
730
 
        return cmd_disable_lop(cldev, pcls);
 
726
        return cmd_disable_lop(cldev, pcls);
731
727
    code = cmd_set_lop(cldev, pcls, lop);
732
728
    if (code < 0)
733
 
        return code;
 
729
        return code;
734
730
    return cmd_enable_lop(cldev, pcls);
735
731
}
736
732
 
737
733
/* Write a parameter list */
738
734
int     /* ret 0 all ok, -ve error */
739
735
cmd_put_params(gx_device_clist_writer *cldev,
740
 
               gs_param_list *param_list) /* NB open for READ */
 
736
               gs_param_list *param_list) /* NB open for READ */
741
737
{
742
738
    byte *dp;
743
739
    int code;
746
742
 
747
743
    /* Get serialized list's length + try to get it into local var if it fits. */
748
744
    param_length = code =
749
 
        gs_param_list_serialize(param_list, local_buf, sizeof(local_buf));
 
745
        gs_param_list_serialize(param_list, local_buf, sizeof(local_buf));
750
746
    if (param_length > 0) {
751
 
        /* Get cmd buffer space for serialized */
752
 
        code = set_cmd_put_all_op(dp, cldev, cmd_opv_extend,
753
 
                                  2 + sizeof(unsigned) + param_length);
754
 
        if (code < 0)
755
 
            return code;
756
 
 
757
 
        /* write param list to cmd list: needs to all fit in cmd buffer */
758
 
        if_debug1('l', "[l]put_params, length=%d\n", param_length);
759
 
        dp[1] = cmd_opv_ext_put_params;
760
 
        dp += 2;
761
 
        memcpy(dp, &param_length, sizeof(unsigned));
762
 
        dp += sizeof(unsigned);
763
 
        if (param_length > sizeof(local_buf)) {
764
 
            int old_param_length = param_length;
765
 
 
766
 
            param_length = code =
767
 
                gs_param_list_serialize(param_list, dp, old_param_length);
768
 
            if (param_length >= 0)
769
 
                code = (old_param_length != param_length ?
770
 
                        gs_note_error(gs_error_unknownerror) : 0);
771
 
            if (code < 0) {
772
 
                /* error serializing: back out by writing a 0-length parm list */
773
 
                memset(dp - sizeof(unsigned), 0, sizeof(unsigned));
774
 
                cmd_shorten_list_op(cldev, &cldev->band_range_list,
775
 
                                    old_param_length);
776
 
            }
777
 
        } else
778
 
            memcpy(dp, local_buf, param_length);            /* did this when computing length */
 
747
        /* Get cmd buffer space for serialized */
 
748
        code = set_cmd_put_all_op(dp, cldev, cmd_opv_extend,
 
749
                                  2 + sizeof(unsigned) + param_length);
 
750
        if (code < 0)
 
751
            return code;
 
752
 
 
753
        /* write param list to cmd list: needs to all fit in cmd buffer */
 
754
        if_debug1('l', "[l]put_params, length=%d\n", param_length);
 
755
        dp[1] = cmd_opv_ext_put_params;
 
756
        dp += 2;
 
757
        memcpy(dp, &param_length, sizeof(unsigned));
 
758
        dp += sizeof(unsigned);
 
759
        if (param_length > sizeof(local_buf)) {
 
760
            int old_param_length = param_length;
 
761
 
 
762
            param_length = code =
 
763
                gs_param_list_serialize(param_list, dp, old_param_length);
 
764
            if (param_length >= 0)
 
765
                code = (old_param_length != param_length ?
 
766
                        gs_note_error(gs_error_unknownerror) : 0);
 
767
            if (code < 0) {
 
768
                /* error serializing: back out by writing a 0-length parm list */
 
769
                memset(dp - sizeof(unsigned), 0, sizeof(unsigned));
 
770
                cmd_shorten_list_op(cldev, &cldev->band_range_list,
 
771
                                    old_param_length);
 
772
            }
 
773
        } else
 
774
            memcpy(dp, local_buf, param_length);            /* did this when computing length */
779
775
    }
780
776
    return code;
781
777
}
787
783
    ss->K = -1;
788
784
    ss->Columns = width;
789
785
#if 0 /* Disabled due to a crash with ppmraw -r216 c327.bin :
790
 
         the decoding filter overruns in 1 byte.         
 
786
         the decoding filter overruns in 1 byte.
791
787
       */
792
788
    ss->EndOfBlock = false;
793
789
#else
841
837
    sget_matrix(&s, pmat);
842
838
    return cbp + stell(&s);
843
839
}
844