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

« back to all changes in this revision

Viewing changes to base/gscdevn.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: gscdevn.c 11937 2010-12-06 20:30:42Z mvrhel $ */
 
14
/* $Id$ */
15
15
/* DeviceN color space and operation definition */
16
16
 
17
17
#include "memory_.h"
73
73
 
74
74
/* GC procedures */
75
75
 
76
 
static 
 
76
static
77
77
ENUM_PTRS_BEGIN(cs_DeviceN_enum_ptrs) return 0;
78
78
ENUM_PTR(0, gs_color_space, params.device_n.names);
79
79
ENUM_PTR(1, gs_color_space, params.device_n.map);
106
106
    int code;
107
107
 
108
108
    if (palt_cspace == 0 || !palt_cspace->type->can_be_alt_space)
109
 
        return_error(gs_error_rangecheck);
 
109
        return_error(gs_error_rangecheck);
110
110
 
111
111
    pcs = gs_cspace_alloc(pmem, &gs_color_space_type_DeviceN);
112
112
    if (pcs == NULL)
113
 
        return_error(gs_error_VMerror);
 
113
        return_error(gs_error_VMerror);
114
114
    pcsdevn = &pcs->params.device_n;
115
115
    pcsdevn->names = NULL;
116
116
    pcsdevn->map = NULL;
119
119
    /* Allocate space for color names list. */
120
120
    code = alloc_device_n_map(&pcsdevn->map, pmem, "gs_cspace_build_DeviceN");
121
121
    if (code < 0) {
122
 
        gs_free_object(pmem, pcs, "gs_cspace_new_DeviceN");
123
 
        return code;
 
122
        gs_free_object(pmem, pcs, "gs_cspace_new_DeviceN");
 
123
        return code;
124
124
    }
125
125
    /* Allocate space for color names list. */
126
126
    pnames = (gs_separation_name *)
127
 
        gs_alloc_byte_array(pmem, num_components, sizeof(gs_separation_name),
128
 
                          ".gs_cspace_build_DeviceN(names)");
 
127
        gs_alloc_byte_array(pmem, num_components, sizeof(gs_separation_name),
 
128
                          ".gs_cspace_build_DeviceN(names)");
129
129
    if (pnames == 0) {
130
 
        gs_free_object(pmem, pcsdevn->map, ".gs_cspace_build_DeviceN(map)");
131
 
        gs_free_object(pmem, pcs, "gs_cspace_new_DeviceN");
132
 
        return_error(gs_error_VMerror);
 
130
        gs_free_object(pmem, pcsdevn->map, ".gs_cspace_build_DeviceN(map)");
 
131
        gs_free_object(pmem, pcs, "gs_cspace_new_DeviceN");
 
132
        return_error(gs_error_VMerror);
133
133
    }
134
134
    pcs->base_space = palt_cspace;
135
135
    rc_increment_cs(palt_cspace);
142
142
/* Allocate and initialize a DeviceN map. */
143
143
int
144
144
alloc_device_n_map(gs_device_n_map ** ppmap, gs_memory_t * mem,
145
 
                   client_name_t cname)
 
145
                   client_name_t cname)
146
146
{
147
147
    gs_device_n_map *pimap;
148
148
 
149
149
    rc_alloc_struct_1(pimap, gs_device_n_map, &st_device_n_map, mem,
150
 
                      return_error(gs_error_VMerror), cname);
 
150
                      return_error(gs_error_VMerror), cname);
151
151
    pimap->tint_transform = 0;
152
152
    pimap->tint_transform_data = 0;
153
153
    pimap->cache_valid = false;
173
173
 
174
174
    /* Verify that we have a DeviceN color space */
175
175
    if (!pgs->saved)
176
 
        return_error(gs_error_rangecheck);
 
176
        return_error(gs_error_rangecheck);
177
177
    pdevncs = gs_currentcolorspace_inline(pgs->saved);
178
178
    if (pdevncs->type != &gs_color_space_type_DeviceN)
179
 
        return_error(gs_error_rangecheck);
 
179
        return_error(gs_error_rangecheck);
180
180
 
181
181
    /* Allocate an attribute list element for our linked list of attributes */
182
182
    rc_alloc_struct_1(patt, gs_device_n_attributes, &st_device_n_attributes,
183
 
                        pgs->memory, return_error(gs_error_VMerror),
184
 
                        "gs_attachattributrescolorspace");
 
183
                        pgs->memory, return_error(gs_error_VMerror),
 
184
                        "gs_attachattributrescolorspace");
185
185
 
186
186
    /* Point our attribute list entry to the attribute color space */
187
187
    patt->colorant_name = sep_name;
201
201
 */
202
202
int
203
203
gs_cspace_set_devn_proc(gs_color_space * pcspace,
204
 
                        int (*proc)(const float *,
 
204
                        int (*proc)(const float *,
205
205
                                    float *,
206
206
                                    const gs_imager_state *,
207
207
                                    void *
208
 
                                    ),
209
 
                        void *proc_data
210
 
                        )
 
208
                                    ),
 
209
                        void *proc_data
 
210
                        )
211
211
{
212
212
    gs_device_n_map *pimap;
213
213
 
214
214
    if (gs_color_space_get_index(pcspace) != gs_color_space_index_DeviceN)
215
 
        return_error(gs_error_rangecheck);
 
215
        return_error(gs_error_rangecheck);
216
216
    pimap = pcspace->params.device_n.map;
217
217
    pimap->tint_transform = proc;
218
218
    pimap->tint_transform_data = proc_data;
233
233
/* Map a DeviceN color using a Function. */
234
234
int
235
235
map_devn_using_function(const float *in, float *out,
236
 
                        const gs_imager_state *pis, void *data)
 
236
                        const gs_imager_state *pis, void *data)
237
237
 
238
238
{
239
239
    gs_function_t *const pfn = data;
250
250
    gs_device_n_map *pimap;
251
251
 
252
252
    if (gs_color_space_get_index(pcspace) != gs_color_space_index_DeviceN ||
253
 
        pfn->params.m != pcspace->params.device_n.num_components ||
254
 
        pfn->params.n != gs_color_space_num_components(pcspace->base_space)
255
 
        )
256
 
        return_error(gs_error_rangecheck);
 
253
        pfn->params.m != pcspace->params.device_n.num_components ||
 
254
        pfn->params.n != gs_color_space_num_components(pcspace->base_space)
 
255
        )
 
256
        return_error(gs_error_rangecheck);
257
257
    pimap = pcspace->params.device_n.map;
258
258
    pimap->tint_transform = map_devn_using_function;
259
259
    pimap->tint_transform_data = pfn;
269
269
gs_cspace_get_devn_function(const gs_color_space *pcspace)
270
270
{
271
271
    if (gs_color_space_get_index(pcspace) == gs_color_space_index_DeviceN &&
272
 
        pcspace->params.device_n.map->tint_transform ==
273
 
          map_devn_using_function)
274
 
        return pcspace->params.device_n.map->tint_transform_data;
 
272
        pcspace->params.device_n.map->tint_transform ==
 
273
          map_devn_using_function)
 
274
        return pcspace->params.device_n.map->tint_transform_data;
275
275
    return 0;
276
276
}
277
277
 
291
291
    uint i;
292
292
 
293
293
    for (i = 0; i < pcs->params.device_n.num_components; ++i)
294
 
        pcc->paint.values[i] = 1.0;
 
294
        pcc->paint.values[i] = 1.0;
295
295
}
296
296
 
297
297
/* Force a DeviceN color into legal range. */
301
301
    uint i;
302
302
 
303
303
    for (i = 0; i < pcs->params.device_n.num_components; ++i) {
304
 
        floatp value = pcc->paint.values[i];
305
 
        pcc->paint.values[i] = (value <= 0 ? 0 : value >= 1 ? 1 : value);
 
304
        floatp value = pcc->paint.values[i];
 
305
        pcc->paint.values[i] = (value <= 0 ? 0 : value >= 1 ? 1 : value);
306
306
    }
307
307
}
308
308
 
309
309
/* Remap a DeviceN color. */
310
310
static const gs_color_space *
311
311
gx_concrete_space_DeviceN(const gs_color_space * pcs,
312
 
                          const gs_imager_state * pis)
 
312
                          const gs_imager_state * pis)
313
313
{
314
314
    bool is_lab = false;
315
315
#ifdef DEBUG
316
 
    /* 
 
316
    /*
317
317
     * Verify that the color space and imager state info match.
318
318
     */
319
319
    if (pcs->id != pis->color_component_map.cspace_id)
320
 
        dprintf("gx_concrete_space_DeviceN: color space id mismatch");
 
320
        dprintf("gx_concrete_space_DeviceN: color space id mismatch");
321
321
#endif
322
322
    /*
323
323
     * Check if we are using the alternate color space.
326
326
        /* Need to handle PS CIE space */
327
327
        if (gs_color_space_is_PSCIE(pcs->base_space)) {
328
328
            if (pcs->base_space->icc_equivalent == NULL) {
329
 
                gs_colorspace_set_icc_equivalent(pcs->base_space, 
 
329
                gs_colorspace_set_icc_equivalent(pcs->base_space,
330
330
                                                    &is_lab, pis->memory);
331
331
            }
332
332
            return (pcs->base_space->icc_equivalent);
333
 
        } 
 
333
        }
334
334
        return cs_concrete_space(pcs->base_space, pis);
335
335
    }
336
336
    /*
341
341
 
342
342
static int
343
343
gx_remap_DeviceN(const gs_client_color * pcc, const gs_color_space * pcs,
344
 
        gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
345
 
                       gs_color_select_t select)
 
344
        gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
 
345
                       gs_color_select_t select)
346
346
{
347
347
    frac conc[GS_CLIENT_COLOR_MAX_COMPONENTS];
348
348
    const gs_color_space *pconcs;
352
352
    gs_client_color temp;
353
353
 
354
354
    if ( pcs->cmm_icc_profile_data != NULL && pis->color_component_map.use_alt_cspace) {
355
 
        /* If needed, reorganize the data.  The ICC colorants tag drives the 
 
355
        /* If needed, reorganize the data.  The ICC colorants tag drives the
356
356
           the laydown order */
357
357
        if (pcs->cmm_icc_profile_data->devicen_permute_needed) {
358
358
            for ( k = 0; k < i; k++) {
366
366
    } else {
367
367
        code = (*pcs->type->concretize_color)(pcc, pcs, conc, pis, dev);
368
368
        if (code < 0)
369
 
            return code;
 
369
            return code;
370
370
        pconcs = cs_concrete_space(pcs, pis);
371
371
        code = (*pconcs->type->remap_concrete_color)(conc, pconcs, pdc, pis, dev, select);
372
372
        /* Save original color space and color info into dev color */
373
373
        i = any_abs(i);
374
374
        for (i--; i >= 0; i--)
375
 
            pdc->ccolor.paint.values[i] = pcc->paint.values[i];
 
375
            pdc->ccolor.paint.values[i] = pcc->paint.values[i];
376
376
        pdc->ccolor_valid = true;
377
377
        return code;
378
378
    }
380
380
 
381
381
static int
382
382
gx_concretize_DeviceN(const gs_client_color * pc, const gs_color_space * pcs,
383
 
                      frac * pconc, const gs_imager_state * pis, gx_device *dev)
 
383
                      frac * pconc, const gs_imager_state * pis, gx_device *dev)
384
384
{
385
385
    int code, tcode = 0;
386
386
    gs_client_color cc;
389
389
    bool is_lab;
390
390
 
391
391
#ifdef DEBUG
392
 
    /* 
 
392
    /*
393
393
     * Verify that the color space and imager state info match.
394
394
     */
395
395
    if (pcs->id != pis->color_component_map.cspace_id)
396
 
        dprintf("gx_concretize_DeviceN: color space id mismatch");
 
396
        dprintf("gx_concretize_DeviceN: color space id mismatch");
397
397
#endif
398
398
 
399
399
    /*
403
403
 
404
404
    if (pis->color_component_map.use_alt_cspace) {
405
405
 
406
 
            /* Check the 1-element cache first. */
407
 
        if (map->cache_valid) {
408
 
            int i;
409
 
 
410
 
            for (i = pcs->params.device_n.num_components; --i >= 0;) {
411
 
                if (map->tint[i] != pc->paint.values[i])
412
 
                    break;
413
 
            }
414
 
            if (i < 0) {
415
 
                int num_out = gs_color_space_num_components(pacs);
416
 
 
417
 
                for (i = 0; i < num_out; ++i)
418
 
                    pconc[i] = map->conc[i];
419
 
                return 0;
420
 
            }
421
 
        }
 
406
            /* Check the 1-element cache first. */
 
407
        if (map->cache_valid) {
 
408
            int i;
 
409
 
 
410
            for (i = pcs->params.device_n.num_components; --i >= 0;) {
 
411
                if (map->tint[i] != pc->paint.values[i])
 
412
                    break;
 
413
            }
 
414
            if (i < 0) {
 
415
                int num_out = gs_color_space_num_components(pacs);
 
416
 
 
417
                for (i = 0; i < num_out; ++i)
 
418
                    pconc[i] = map->conc[i];
 
419
                return 0;
 
420
            }
 
421
        }
422
422
        tcode = (*pcs->params.device_n.map->tint_transform)
423
 
             (pc->paint.values, &cc.paint.values[0],
424
 
             pis, pcs->params.device_n.map->tint_transform_data);
 
423
             (pc->paint.values, &cc.paint.values[0],
 
424
             pis, pcs->params.device_n.map->tint_transform_data);
 
425
        (*pacs->type->restrict_color)(&cc, pacs);
425
426
        if (tcode < 0)
426
 
            return tcode;
 
427
            return tcode;
427
428
        /* First check if this was PS based. */
428
429
        if (gs_color_space_is_PSCIE(pacs)) {
429
430
            /* If we have not yet create the profile do that now */
438
439
            cc.paint.values[0] /= 100.0;
439
440
            cc.paint.values[1] = (cc.paint.values[1]+128)/255.0;
440
441
            cc.paint.values[2] = (cc.paint.values[2]+128)/255.0;
441
 
        } 
 
442
        }
442
443
        code = cs_concretize_color(&cc, pacs, pconc, pis, dev);
443
444
    }
444
445
    else {
445
 
        int i;
 
446
        int i;
446
447
 
447
 
        for (i = pcs->params.device_n.num_components; --i >= 0;)
448
 
            pconc[i] = gx_unit_frac(pc->paint.values[i]);
449
 
        return 0;
 
448
        for (i = pcs->params.device_n.num_components; --i >= 0;)
 
449
            pconc[i] = gx_unit_frac(pc->paint.values[i]);
 
450
        return 0;
450
451
    }
451
452
    return (code < 0 || tcode == 0 ? code : tcode);
452
453
}
453
454
 
454
455
static int
455
456
gx_remap_concrete_DeviceN(const frac * pconc, const gs_color_space * pcs,
456
 
        gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
457
 
                          gs_color_select_t select)
 
457
        gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
 
458
                          gs_color_select_t select)
458
459
{
459
460
#ifdef DEBUG
460
 
    /* 
 
461
    /*
461
462
     * Verify that the color space and imager state info match.
462
463
     */
463
464
    if (pcs->id != pis->color_component_map.cspace_id)
464
 
        dprintf("gx_remap_concrete_DeviceN: color space id mismatch");
 
465
        dprintf("gx_remap_concrete_DeviceN: color space id mismatch");
465
466
#endif
466
467
    if (pis->color_component_map.use_alt_cspace) {
467
468
        const gs_color_space *pacs = pcs->base_space;
468
469
 
469
 
        return (*pacs->type->remap_concrete_color)
470
 
                                (pconc, pacs, pdc, pis, dev, select);
 
470
        return (*pacs->type->remap_concrete_color)
 
471
                                (pconc, pacs, pdc, pis, dev, select);
471
472
    }
472
473
    else {
473
 
        gx_remap_concrete_devicen(pconc, pdc, pis, dev, select);
474
 
        return 0;
 
474
        gx_remap_concrete_devicen(pconc, pdc, pis, dev, select);
 
475
        return 0;
475
476
    }
476
477
}
477
478
 
490
491
    byte * pname;
491
492
    uint name_size;
492
493
    gs_devicen_color_map * pcolor_component_map
493
 
        = &pgs->color_component_map;
 
494
        = &pgs->color_component_map;
494
495
    gx_device * dev = pgs->device;
495
496
    bool non_match = false;
496
497
 
503
504
     * using an additive color model.
504
505
     */
505
506
    if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
506
 
        pcolor_component_map->use_alt_cspace = true;
507
 
        return 0;
 
507
        pcolor_component_map->use_alt_cspace = true;
 
508
        return 0;
508
509
    }
509
510
    /*
510
511
     * Now check the names of the color components.
511
512
     */
512
513
    non_match = false;
513
514
    for(i = 0; i < num_comp; i++ ) {
514
 
        /*
515
 
         * Get the character string and length for the component name.
516
 
         */
517
 
        pcs->params.device_n.get_colorname_string(dev->memory, names[i], &pname, &name_size);
518
 
        /*
519
 
         * Compare the colorant name to the device's.  If the device's
520
 
         * compare routine returns GX_DEVICE_COLOR_MAX_COMPONENTS then the
521
 
         * colorant is in the SeparationNames list but not in the
522
 
         * SeparationOrder list.
523
 
         */
524
 
        colorant_number = (*dev_proc(dev, get_color_comp_index))
525
 
                    (dev, (const char *)pname, name_size, SEPARATION_NAME);
526
 
        if (colorant_number >= 0) {             /* If valid colorant name */
527
 
            pcolor_component_map->color_map[i] =
528
 
            (colorant_number == GX_DEVICE_COLOR_MAX_COMPONENTS) ? -1
529
 
                                                   : colorant_number;
530
 
        }
531
 
        else
532
 
            non_match = true;
 
515
        /*
 
516
         * Get the character string and length for the component name.
 
517
         */
 
518
        pcs->params.device_n.get_colorname_string(dev->memory, names[i], &pname, &name_size);
 
519
        /*
 
520
         * Compare the colorant name to the device's.  If the device's
 
521
         * compare routine returns GX_DEVICE_COLOR_MAX_COMPONENTS then the
 
522
         * colorant is in the SeparationNames list but not in the
 
523
         * SeparationOrder list.
 
524
         */
 
525
        colorant_number = (*dev_proc(dev, get_color_comp_index))
 
526
                    (dev, (const char *)pname, name_size, SEPARATION_NAME);
 
527
        if (colorant_number >= 0) {             /* If valid colorant name */
 
528
            pcolor_component_map->color_map[i] =
 
529
            (colorant_number == GX_DEVICE_COLOR_MAX_COMPONENTS) ? -1
 
530
                                                   : colorant_number;
 
531
        }
 
532
        else
 
533
            non_match = true;
533
534
    }
534
535
    pcolor_component_map->use_alt_cspace = non_match;
535
536
    return 0;
546
547
    /* See if we have an ICC profile that we can associate with
547
548
       this DeviceN color space */
548
549
    if (pgs->icc_manager->device_n != NULL) {
549
 
        /* An nclr profile is in the manager.  Grab one
550
 
           that matches */
551
 
        pcs->cmm_icc_profile_data = gsicc_finddevicen(pcs, pgs->icc_manager);
 
550
        /* An nclr profile is in the manager.  Grab one that matches. */
 
551
        cmm_profile_t *profdata = gsicc_finddevicen(pcs, pgs->icc_manager);
 
552
        if (profdata != NULL)
 
553
            rc_increment(profdata);
552
554
        if (pcs->cmm_icc_profile_data != NULL)
553
 
            rc_adjust(pcs->cmm_icc_profile_data, pcs->rc.ref_count, "gs_install_DeviceN");
 
555
            rc_decrement(pcs->cmm_icc_profile_data, "gx_install_DeviceN");
 
556
        pcs->cmm_icc_profile_data = profdata;
554
557
    }
555
558
    /* {csrc} was pgs->color_space->params.device_n.use_alt_cspace */
556
559
    ((gs_color_space *)pcs)->params.device_n.use_alt_cspace =
557
 
        using_alt_color_space(pgs);
 
560
        using_alt_color_space(pgs);
558
561
    if (pcs->params.device_n.use_alt_cspace && pcs->cmm_icc_profile_data == NULL ) {
559
562
        /* No nclr ICC profile */
560
563
        code = (pcs->base_space->type->install_cspace)
561
 
            (pcs->base_space, pgs);
 
564
            (pcs->base_space, pgs);
562
565
    } else if (pcs->params.device_n.use_alt_cspace) {
563
566
        gs_color_space *nclr_pcs;
564
567
        /* Need to install the nclr cspace */
565
568
        code = gs_cspace_build_ICC(&nclr_pcs, NULL, pgs->memory);
566
569
        nclr_pcs->cmm_icc_profile_data = pcs->cmm_icc_profile_data;
567
 
        rc_increment_cs(nclr_pcs);
 
570
        rc_increment(pcs->cmm_icc_profile_data);
 
571
        rc_increment_cs(nclr_pcs); // Suspicious - RJW
568
572
        rc_decrement_cs(pcs->base_space, "gx_install_DeviceN");
569
573
        pcs->base_space = nclr_pcs;
570
574
    }
574
578
     */
575
579
    if (code >= 0)
576
580
        code = dev_proc(pgs->device, update_spot_equivalent_colors)
577
 
                                                        (pgs->device, pgs);
 
581
                                                        (pgs->device, pgs);
578
582
    return code;
579
583
}
580
584
 
585
589
    gs_devicen_color_map *  pcmap = &pgs->color_component_map;
586
590
 
587
591
    if (pcmap->use_alt_cspace) {
588
 
        const gs_color_space_type* base_type = pcs->base_space->type;
589
 
        
590
 
        /* If the base space is DeviceCMYK, handle overprint as DeviceCMYK */
591
 
        if ( base_type->index == gs_color_space_index_DeviceCMYK )
592
 
                return base_type->set_overprint( pcs->base_space, pgs );
593
 
        else
594
 
                return gx_spot_colors_set_overprint( pcs->base_space, pgs);
 
592
        const gs_color_space_type* base_type = pcs->base_space->type;
 
593
 
 
594
        /* If the base space is DeviceCMYK, handle overprint as DeviceCMYK */
 
595
        if ( base_type->index == gs_color_space_index_DeviceCMYK )
 
596
                return base_type->set_overprint( pcs->base_space, pgs );
 
597
        else
 
598
                return gx_spot_colors_set_overprint( pcs->base_space, pgs);
595
599
    }
596
600
    else {
597
601
        gs_overprint_params_t   params;
605
609
                int     mcomp = pcmap->color_map[i];
606
610
 
607
611
                if (mcomp >= 0)
608
 
                    gs_overprint_set_drawn_comp( params.drawn_comps, mcomp);
 
612
                    gs_overprint_set_drawn_comp( params.drawn_comps, mcomp);
609
613
            }
610
614
        }
611
615
 
622
626
 
623
627
    rc_decrement_only(pcs->params.device_n.map, "gx_adjust_DeviceN");
624
628
    while (patt != NULL) {
625
 
        pnextatt = patt->next;
626
 
        rc_decrement_cs(patt->cspace, "gx_final_DeviceN");
 
629
        pnextatt = patt->next;
 
630
        rc_decrement_cs(patt->cspace, "gx_final_DeviceN");
627
631
        rc_decrement(patt, "gx_adjust_DeviceN");
628
 
        patt = pnextatt;
 
632
        patt = pnextatt;
629
633
    }
630
634
}
631
635
 
632
636
/* ---------------- Serialization. -------------------------------- */
633
637
 
634
 
int 
 
638
int
635
639
gx_serialize_device_n_map(const gs_color_space * pcs, gs_device_n_map * m, stream * s)
636
640
{
637
641
    const gs_function_t *pfn;
638
642
 
639
643
    if (m->tint_transform != map_devn_using_function)
640
 
        return_error(gs_error_unregistered); /* Unimplemented. */
 
644
        return_error(gs_error_unregistered); /* Unimplemented. */
641
645
    pfn = (const gs_function_t *)m->tint_transform_data;
642
646
    return gs_function_serialize(pfn, s);
643
647
}
644
648
 
645
 
static int 
 
649
static int
646
650
gx_serialize_DeviceN(const gs_color_space * pcs, stream * s)
647
651
{
648
652
    const gs_device_n_params * p = &pcs->params.device_n;
650
654
    int code = gx_serialize_cspace_type(pcs, s);
651
655
 
652
656
    if (code < 0)
653
 
        return code;
 
657
        return code;
654
658
    code = sputs(s, (const byte *)&p->num_components, sizeof(p->num_components), &n);
655
659
    if (code < 0)
656
 
        return code;
 
660
        return code;
657
661
    code = sputs(s, (const byte *)&p->names[0], sizeof(p->names[0]) * p->num_components, &n);
658
662
    if (code < 0)
659
 
        return code;
 
663
        return code;
660
664
    code = cs_serialize(pcs->base_space, s);
661
665
    if (code < 0)
662
 
        return code;
 
666
        return code;
663
667
    return gx_serialize_device_n_map(pcs, p->map, s);
664
668
    /* p->use_alt_cspace isn't a property of the space. */
665
669
}